C语言使用stream完成协议封送

发布于:2024-11-11 ⋅ 阅读:(212) ⋅ 点赞:(0)

开发过程中,对于自定义协议的打包,可以借助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));
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到