feature support msg seriable
This commit is contained in:
parent
be8fb56962
commit
0e45bc72ba
2489
3party/tpl/tpl.c
Normal file
2489
3party/tpl/tpl.c
Normal file
File diff suppressed because it is too large
Load Diff
137
3party/tpl/tpl.h
Normal file
137
3party/tpl/tpl.h
Normal 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 */
|
||||||
|
|
@ -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
|
||||||
|
)
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,4 +26,4 @@ service Device {
|
|||||||
rpc UnlockApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
|
rpc UnlockApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
|
||||||
rpc ChangeApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
|
rpc ChangeApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
|
||||||
rpc VerifyApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
|
rpc VerifyApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
|
||||||
}
|
}
|
||||||
|
117
test/test.c
Normal file
117
test/test.c
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user