feature support msg seriable

This commit is contained in:
tqcq 2023-12-02 11:05:25 +08:00
parent be8fb56962
commit 0e45bc72ba
6 changed files with 2803 additions and 15 deletions

2489
3party/tpl/tpl.c Normal file

File diff suppressed because it is too large Load Diff

137
3party/tpl/tpl.h Normal file
View File

@ -0,0 +1,137 @@
/*
Copyright (c) 2005-2013, Troy D. Hanson http://troydhanson.github.com/tpl/
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TPL_H
#define TPL_H
#include <stddef.h> /* size_t */
#include <stdarg.h> /* va_list */
#ifdef __INTEL_COMPILER
#include <tbb/tbbmalloc_proxy.h>
#endif /* Intel Compiler efficient memcpy etc */
#ifdef _MSC_VER
typedef unsigned int uint32_t;
#else
#include <inttypes.h> /* uint32_t */
#endif
#if defined __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#ifdef TPL_EXPORTS
#define TPL_API __declspec(dllexport)
#else /* */
#ifdef TPL_NOLIB
#define TPL_API
#else
#define TPL_API __declspec(dllimport)
#endif /* TPL_NOLIB */
#endif /* TPL_EXPORTS*/
#else
#define TPL_API
#endif
/* bit flags (external) */
#define TPL_FILE (1 << 0)
#define TPL_MEM (1 << 1)
#define TPL_PREALLOCD (1 << 2)
#define TPL_EXCESS_OK (1 << 3)
#define TPL_FD (1 << 4)
#define TPL_UFREE (1 << 5)
#define TPL_DATAPEEK (1 << 6)
#define TPL_FXLENS (1 << 7)
#define TPL_GETSIZE (1 << 8)
/* do not add flags here without renumbering the internal flags! */
/* flags for tpl_gather mode */
#define TPL_GATHER_BLOCKING 1
#define TPL_GATHER_NONBLOCKING 2
#define TPL_GATHER_MEM 3
/* Hooks for error logging, memory allocation functions and fatal */
typedef int (tpl_print_fcn)(const char *fmt, ...);
typedef void *(tpl_malloc_fcn)(size_t sz);
typedef void *(tpl_realloc_fcn)(void *ptr, size_t sz);
typedef void (tpl_free_fcn)(void *ptr);
typedef void (tpl_fatal_fcn)(const char *fmt, ...);
typedef struct tpl_hook_t {
tpl_print_fcn *oops;
tpl_malloc_fcn *malloc;
tpl_realloc_fcn *realloc;
tpl_free_fcn *free;
tpl_fatal_fcn *fatal;
size_t gather_max;
} tpl_hook_t;
typedef struct tpl_node {
int type;
void *addr;
void *data; /* r:tpl_root_data*. A:tpl_atyp*. ow:szof type */
int num; /* length of type if its a C array */
size_t ser_osz; /* serialization output size for subtree */
struct tpl_node *children; /* my children; linked-list */
struct tpl_node *next,*prev; /* my siblings (next child of my parent) */
struct tpl_node *parent; /* my parent */
} tpl_node;
/* used when un/packing 'B' type (binary buffers) */
typedef struct tpl_bin {
void *addr;
uint32_t sz;
} tpl_bin;
/* for async/piecemeal reading of tpl images */
typedef struct tpl_gather_t {
char *img;
int len;
} tpl_gather_t;
/* Callback used when tpl_gather has read a full tpl image */
typedef int (tpl_gather_cb)(void *img, size_t sz, void *data);
/* Prototypes */
TPL_API tpl_node *tpl_map(char *fmt,...); /* define tpl using format */
TPL_API void tpl_free(tpl_node *r); /* free a tpl map */
TPL_API int tpl_pack(tpl_node *r, int i); /* pack the n'th packable */
TPL_API int tpl_unpack(tpl_node *r, int i); /* unpack the n'th packable */
TPL_API int tpl_dump(tpl_node *r, int mode, ...); /* serialize to mem/file */
TPL_API int tpl_load(tpl_node *r, int mode, ...); /* set mem/file to unpack */
TPL_API int tpl_Alen(tpl_node *r, int i); /* array len of packable i */
TPL_API char* tpl_peek(int mode, ...); /* sneak peek at format string */
TPL_API int tpl_gather( int mode, ...); /* non-blocking image gather */
TPL_API int tpl_jot(int mode, ...); /* quick write a simple tpl */
TPL_API tpl_node *tpl_map_va(char *fmt, va_list ap);
#if defined __cplusplus
}
#endif
#endif /* TPL_H */

View File

@ -26,3 +26,12 @@ target_link_libraries(crpc PRIVATE antlr4_static)
target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime) target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime)
target_include_directories(crpc PRIVATE src/gen/ src/) target_include_directories(crpc PRIVATE src/gen/ src/)
FILE(GLOB_RECURSE TEST_SRC_LIST ${CMAKE_CURRENT_BINARY_DIR}/gen/*.c)
add_executable(test ${TEST_SRC_LIST}
test/test.c
${CMAKE_CURRENT_SOURCE_DIR}/3party/tpl/tpl.c
)
target_include_directories(test PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/gen/
${CMAKE_CURRENT_SOURCE_DIR}/3party/tpl
)

View File

@ -141,7 +141,7 @@ CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message)
ss << std::endl; ss << std::endl;
ss << "int32_t " << message->id() << "_Serialize(" << message->id() ss << "int32_t " << message->id() << "_Serialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size);" << std::endl; << "* message, char** buffer, int32_t *buffer_size);" << std::endl;
ss << "int32_t " << message->id() << "_Deserialize(" << message->id() ss << "int32_t " << message->id() << "_Deserialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size);" << std::endl; << "* message, char* buffer, int32_t buffer_size);" << std::endl;
ss << std::endl; ss << std::endl;
@ -185,41 +185,77 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message)
ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl; ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl;
ss << "#include <string.h>" << std::endl; ss << "#include <string.h>" << std::endl;
ss << "#include <stdlib.h>" << std::endl; ss << "#include <stdlib.h>" << std::endl;
ss << "#include <tpl.h>" << std::endl;
ss << std::endl; ss << std::endl;
return ss.str(); return ss.str();
} }
static std::string GetTPLMap(std::vector<Item::Ptr> items)
{
std::stringstream ss;
ss << "S(";
for (auto &item : items) {
switch(item->type()) {
case Item::Type::kInt32:
ss << "i";
break;
case Item::Type::kString:
ss << "s";
break;
case Item::Type::kMessage:
// donothing
break;
}
}
ss << ")";
return ss.str();
}
std::string std::string
CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << "int32_t " << message->id() << "_Serialize(" << message->id() ss << "int32_t " << message->id() << "_Serialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size) {" << std::endl; << "* message, char** buffer, int32_t* buffer_size) {" << std::endl;
ss << " int32_t offset = 0;" << std::endl; if (!message->items().empty()) {
for (auto &item : message->items()) { std::string tpl_format = GetTPLMap(message->items());
auto c_item = CItem::Create(item); ss << " do {" << std::endl;
ss << c_item->GenerateSerializeCodeBlock(message->id()) << std::endl; ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", message);" << std::endl;
ss << " tpl_pack(tn, 0);" << std::endl;
ss << " tpl_dump(tn, TPL_MEM, buffer, buffer_size);" << std::endl;
ss << " tpl_free(tn);" << std::endl;
ss << " return *buffer_size; " << std::endl;
ss << " } while (0);" << std::endl;
} }
ss << " return offset;" << std::endl; ss << " return 0; " << std::endl;
ss << "}" << std::endl; ss << "}" << std::endl;
ss << std::endl;
return ss.str(); return ss.str();
} }
std::string std::string
CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message) CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << "int32_t " << message->id() << "_Deserialize(" << message->id() ss << "int32_t " << message->id() << "_Deserialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size) {" << std::endl; << "* message, char* buffer, int32_t buffer_size) {" << std::endl;
ss << " int32_t offset = 0;" << std::endl; if (!message->items().empty()) {
for (auto &item : message->items()) { std::string tpl_format = GetTPLMap(message->items());
auto c_item = CItem::Create(item); ss << " do {" << std::endl;
ss << c_item->GenerateDeserializeCodeBlock(message->id()) << std::endl; ss << " " << message->id() << "_Destroy(message);" << std::endl;
ss << " size_t dump_sz = buffer_size;" << std::endl;
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", message);" << std::endl;
ss << " tpl_load(tn, TPL_MEM, buffer, dump_sz);" << std::endl;
ss << " tpl_unpack(tn, 0);" << std::endl;
ss << " tpl_free(tn);" << std::endl;
ss << " return dump_sz; " << std::endl;
ss << " } while (0);" << std::endl;
} }
ss << " return offset;" << std::endl; ss << " return 0; " << std::endl;
ss << "}" << std::endl; ss << "}" << std::endl;
ss << std::endl;
return ss.str(); return ss.str();
} }

117
test/test.c Normal file
View File

@ -0,0 +1,117 @@
//
// Created by tqcq on 2023/12/2.
//
#include "StatusResponse.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "tpl.h"
struct ms_t {
char c;
int i;
char s[2];
char o;
char *x;
char y;
double d;
};
void TestTPL() {
tpl_node *tn;
struct ms_t ms = {/*.c =*/ 'a', /*.i =*/ 1, /*.s =*/ {'h','i'}, /*.o =*/ 'o', /*.x =*/ "matilda", /*.y =*/ 'y', /*.d =*/ 3.14 };
struct ms_t ms2;
char buffer[1024];
int dump_sz = 0;
tn = tpl_map("S(cic#cscf)", &ms, 2);
tpl_pack(tn,0);
// tpl_dump(tn,TPL_FILE,"/tmp/test70.tpl");
tpl_dump(tn,TPL_MEM,buffer,&dump_sz);
tpl_free(tn);
memset(&ms2,0,sizeof(struct ms_t));
tn = tpl_map("S(cic#cscf)", &ms2, 2);
// tpl_load(tn,TPL_FILE,"/tmp/test70.tpl");
tpl_load(tn,TPL_MEM,buffer,dump_sz);
tpl_unpack(tn,0);
tpl_free(tn);
printf("%c\n%d\n%c%c\n%c\n%s\n%c\n%f\n", ms2.c, ms2.i, ms2.s[0], ms2.s[1], ms2.o, ms2.x, ms2.y, ms2.d);
free(ms2.x);
}
void TestTPL2() {
tpl_node *tn;
char *s,*t;
void *addr;
int sz;
tn = tpl_map("s",&s);
s = "hello, world!";
tpl_pack(tn,0);
tpl_dump(tn,TPL_MEM,&addr,&sz);
tpl_free(tn);
tn = tpl_map("s",&t);
tpl_load(tn,TPL_MEM,addr,sz);
tpl_unpack(tn,0);
printf("t is %s\n", t);
free(t);
tpl_free(tn);
free(addr);
}
struct TestS {
int32_t a;
char* str;
};
void TestTPL3() {
struct TestS s;
s.a = 1;
s.str = "hello";
tpl_node *tn = tpl_map("S(is)", &s);
tpl_pack(tn, 0);
char *buffer;
int dump_sz = 0;
tpl_dump(tn, TPL_MEM, &buffer, &dump_sz);
tpl_free(tn);
printf("dump_sz: %d\n", dump_sz);
memset(&s, 0, sizeof(struct TestS));
tn = tpl_map("S(is)", &s);
tpl_load(tn, TPL_MEM, buffer, dump_sz);
tpl_unpack(tn, 0);
tpl_free(tn);
printf("%d\n%s\n", s.a, s.str);
}
int main(int argc, char*argv[]) {
// TestTPL3();
char *buffer;
int dump_sz = 0;
StatusResponse response;
{
StatusResponse_Init(&response);
StatusResponse_set_code(&response, 200);
StatusResponse_set_msg(&response, "OK");
dump_sz = StatusResponse_Serialize(&response, &buffer, &dump_sz);
StatusResponse_Destroy(&response);
}
printf("dump_sz: %d\n", dump_sz);
{
StatusResponse_Init(&response);
StatusResponse_Deserialize(&response, buffer, dump_sz);
printf("code: %d\n", StatusResponse_get_code(&response));
printf("msg: %s\n", StatusResponse_get_msg(&response));
StatusResponse_Destroy(&response);
}
return 0;
}