开发过程中,对于自定义协议的打包,可以借助stream完成。
stream.h
#pragma once#include <stdio.h>
#include <string.h>typedef struct stream
{char d[256];size_t size;size_t len;size_t pos;
} stream, *pstream;void stem_init(pstream s);
void stem_push(pstream s, void *value, size_t vsize, int flip);
void stem_dump(pstream s, FILE *f);#define stem_push_func(type) \
inline void stem_push_##type(pstream s, type v, int flip) \
{ stem_push(s, &v, sizeof(v), flip); }#define stem_push_func_i(type) \
stem_push_func(type) \
inline void stem_push_u##type(pstream s, unsigned type v, int flip) \
{ stem_push(s, &v, sizeof(v), flip); }stem_push_func_i(char)
stem_push_func_i(short)
stem_push_func_i(int)
stem_push_func(float)
stem_push_func(double)inline void stem_push_string(pstream s, const char *str)
{stem_push(s, (void*)str, strlen(str), 0);
}
stream.c
#include <assert.h>
#include <memory.h>
#include "stream.h"void stem_init(pstream s)
{s->size = 256;s->len = s->pos = 0;memset(s->d, 0, s->size);
}void stem_push(pstream s, void *value, size_t vsize, int flip)
{assert(s);assert(vsize <= s->size - s->pos);if (!flip){memcpy(s->d + s->pos, value, vsize);}else{char *pe = (char*)value + vsize;switch (vsize){case 1:*(s->d + s->pos + 0) = *--pe;break;case 2:*(s->d + s->pos + 0) = *--pe;*(s->d + s->pos + 1) = *--pe;break;case 4:*(s->d + s->pos + 0) = *--pe;*(s->d + s->pos + 1) = *--pe;*(s->d + s->pos + 2) = *--pe;*(s->d + s->pos + 3) = *--pe;break;case 8:*(s->d + s->pos + 0) = *--pe;*(s->d + s->pos + 1) = *--pe;*(s->d + s->pos + 2) = *--pe;*(s->d + s->pos + 3) = *--pe;*(s->d + s->pos + 4) = *--pe;*(s->d + s->pos + 5) = *--pe;*(s->d + s->pos + 6) = *--pe;*(s->d + s->pos + 7) = *--pe;break;default:for (size_t i = 0; i < vsize; i++){memcpy(s->d + s->pos + i, --pe, 1);}break;}}s->len += vsize;s->pos += vsize;
}void stem_dump(pstream s, FILE *f)
{if (s->len){for (size_t i = 0; i < s->len; i++)fprintf(f, "%02x ", (unsigned char)s->d[i]);fprintf(f, "\n");}else{fputs("stream:[]", f);}
}
main.c
#include "stream.h"int main()
{stream s;stem_init(&s);stem_push_char(&s, 'a', 0);stem_push_uchar(&s, 'b', 0);stem_push_short(&s, -1234, 0);stem_push_ushort(&s, 4455, 0);stem_push_int(&s, 0xAABBCCDD, 1);stem_push_uint(&s, 0xAABBCCDD, 0);stem_push_float(&s, 3.14f, 0);stem_push_double(&s, 6.155, 0);stem_push_string(&s, "hello, world!");stem_dump(&s, stdout);int x = 0xDDCCBBAA;unsigned int ux = 0xAABBCCDD;printf("\n");printf("x: %d\n", x);printf("ux: %u\n", ux);printf("\n");printf("char: %c\n", *(s.d + 0));printf("uchar: %c\n", *(s.d + 1));printf("short: %d\n", *(short*)(s.d + 2));printf("ushort: %d\n", *(unsigned short*)(s.d + 4));printf("int: %i\n", *(int*)(s.d + 6));printf("uint: %u\n", *(unsigned int*)(s.d + 10));printf("float: %f\n", *(float*)(s.d + 14));printf("doulbe: %f\n", *(double*)(s.d + 18));printf("string: %s\n", (s.d + 26));
}