From 1b05d1d04e9cf891703a199b335f0a9d145f89db Mon Sep 17 00:00:00 2001 From: nyatla Date: Sun, 29 Jun 2014 12:56:38 +0000 Subject: [PATCH] =?utf8?q?jsonrpcparser=E3=81=ABBSTR=E5=9E=8B=E3=82=92?= =?utf8?q?=E8=BF=BD=E5=8A=A0=20jsonrpc::memory=E3=82=92=E8=BF=BD=E5=8A=A0?= =?utf8?q?=20NyLPC=5FcFormatWriter=E3=81=ABBSTR=E3=82=92=E8=BF=BD=E5=8A=A0?= =?utf8?q?=E3=80=82length=E8=A8=88=E7=AE=97=E3=81=AE=E6=9C=80=E9=81=A9?= =?utf8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.osdn.jp/svnroot/mimic/trunk@379 47198e57-cb75-475f-84c4-a814cd6f29e0 --- lib/src/NyLPC_cMiMicEnv.c | 2 +- lib/src/http/json/NyLPC_cJsonRpcParser.c | 201 +++++++++++++++++++++--- lib/src/http/json/NyLPC_cJsonRpcParser.h | 25 ++- lib/src/include/NyLPC_config.h | 4 +- lib/src/include/NyLPC_jsonrpc.h | 42 +++++ lib/src/jsonrpc/NyLPC_cJsonRpcFunction.h | 26 +++ lib/src/jsonrpc/NyLPC_cJsonRpcFunction_Memory.c | 133 ++++++++++++++++ lib/src/utils/NyLPC_cFormatWriter.c | 119 +++++++------- lib/src/utils/NyLPC_cFormatWriter.h | 12 +- 9 files changed, 461 insertions(+), 103 deletions(-) create mode 100644 lib/src/include/NyLPC_jsonrpc.h create mode 100644 lib/src/jsonrpc/NyLPC_cJsonRpcFunction.h create mode 100644 lib/src/jsonrpc/NyLPC_cJsonRpcFunction_Memory.c diff --git a/lib/src/NyLPC_cMiMicEnv.c b/lib/src/NyLPC_cMiMicEnv.c index ff5e22c..907f1a9 100644 --- a/lib/src/NyLPC_cMiMicEnv.c +++ b/lib/src/NyLPC_cMiMicEnv.c @@ -1,7 +1,7 @@ #include "NyLPC_cMiMicEnv.h" #include "../uip/NyLPC_cUipService_protected.h" -const static char* VERSION="MiMic/1.5.8"; +const static char* VERSION="MiMic/1.5.10"; #if NyLPC_MCU==NyLPC_MCU_LPC4088 const static char* MCU="LPC4088"; diff --git a/lib/src/http/json/NyLPC_cJsonRpcParser.c b/lib/src/http/json/NyLPC_cJsonRpcParser.c index fb5ef54..eb471ed 100644 --- a/lib/src/http/json/NyLPC_cJsonRpcParser.c +++ b/lib/src/http/json/NyLPC_cJsonRpcParser.c @@ -1,5 +1,5 @@ #include "NyLPC_cJsonRpcParser.h" - +#include // // NyLPC_TJsonRpcParserResult // @@ -27,7 +27,7 @@ NyLPC_TBool NyLPC_TJsonRpcParserResult_getInt32(const union NyLPC_TJsonRpcParser *o_val = *((NyLPC_TInt32*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx])); return NyLPC_TBool_TRUE; } -NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val) +NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val, NyLPC_TUInt8* o_len) { if(i_struct->method.param_index[i_idx]==0xff){ return NyLPC_TBool_FALSE; @@ -35,9 +35,27 @@ NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserRe if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_STRING){ return NyLPC_TBool_FALSE; } - *o_val = ((NyLPC_TChar*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx])); + *o_val = ((NyLPC_TChar*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]+1)); + if (o_len){ + *o_len = *((NyLPC_TUInt8*)(*o_val-1)); + } + return NyLPC_TBool_TRUE; +} +NyLPC_TBool NyLPC_TJsonRpcParserResult_getByteArray(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TUInt8** o_val, NyLPC_TUInt8* o_len) +{ + if (i_struct->method.param_index[i_idx] == 0xff){ + return NyLPC_TBool_FALSE; + } + if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_BSTRING){ + return NyLPC_TBool_FALSE; + } + *o_val = ((NyLPC_TUInt8*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx] + 1)); + if (o_len){ + *o_len = *((NyLPC_TUInt8*)(*o_val - 1)); + } return NyLPC_TBool_TRUE; } + NyLPC_TBool NyLPC_TJsonRpcParserResult_getByte(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TUInt8* o_val) { if(i_struct->method.param_index[i_idx]==0xff){ @@ -140,17 +158,53 @@ static const struct NyLPC_TJsonRpcClassDef* findFunction(const struct NyLPC_TJso } return NULL; } -#define PARAM_ST_START 1 -#define PARAM_ST_VAL 2 -#define PARAM_ST_INT 3 -#define PARAM_ST_UINT 4 -#define PARAM_ST_STR 5 -#define PARAM_ST_NEXT 6 -#define PARAM_ST_BYTE 7 +/** + * putchar_paramのステータス値 + */ +#define PARAM_ST_START 1 +#define PARAM_ST_VAL 2 +#define PARAM_ST_INT 3 +#define PARAM_ST_UINT 4 +#define PARAM_ST_STR 5 +#define PARAM_ST_STR_ESCAPE_HEX 6 +#define PARAM_ST_STR_ESCAPE 7 +#define PARAM_ST_BYTE 8 +#define PARAM_ST_BSTR 9 +#define PARAM_ST_NEXT 11 -static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) + +/** + * シングルエスケープ文字列をエスケープされた文字列へ変換します。 + */ +static NyLPC_TBool convertSingleCharEscape(const char i_s, char* o_out) +{ + switch (i_s){ + case '0': *o_out = '\0'; break; + case 'r': *o_out = '\r'; break; + case 'n': *o_out = '\n'; break; + case 't': *o_out = '\t'; break; + case '\'': *o_out = '\''; break; + case '\"': *o_out = '\"'; break; + case '\\': *o_out = '\\'; break; + default: + return NyLPC_TBool_FALSE; + } + return NyLPC_TBool_TRUE; +} +/** + * 符号付整数値を構成する文字セットであるかを返します。 + */ +static NyLPC_TBool isSignedCharSet(const char i_c) { + return (strchr("-0123456789", i_c) != NULL); +} +/** + * 整数を構成する文字セットであるかを返します。 + */ +#define isUnSignedCharSet(i_c) isdigit(i_c) +static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) +{ switch (i_inst->_pst){ case PARAM_ST_START: if (i_c == '['){ @@ -180,7 +234,7 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) } switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i_inst->_pcounter]){ case NyLPC_cJsonRpcParser_TYPE_INT32: - if (strchr("-0123456789", i_c) == NULL){ + if(!isSignedCharSet(i_c)){ goto ERROR; } i_inst->_pst = PARAM_ST_INT; @@ -189,7 +243,7 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) i_inst->_work.str.n = ((i_inst->_work.str.n + 3) / 4) * 4; break; case NyLPC_cJsonRpcParser_TYPE_UINT32: - if (strchr("0123456789", i_c) == NULL){ + if (!isUnSignedCharSet(i_c)){ goto ERROR; } i_inst->_pst = PARAM_ST_UINT; @@ -198,7 +252,7 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) i_inst->_work.str.n = ((i_inst->_work.str.n + 3) / 4) * 4; break; case NyLPC_cJsonRpcParser_TYPE_BYTE: - if (strchr("0123456789", i_c) == NULL){ + if (!isUnSignedCharSet(i_c)){ goto ERROR; } i_inst->_pst = PARAM_ST_BYTE; @@ -208,14 +262,67 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) if (i_c != '"'){ goto ERROR; } + i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n; + i_inst->_pcounter++; + if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){ + goto ERROR; + } + i_inst->_work.str.n++;//文字数の記憶領域 i_inst->_pst = PARAM_ST_STR; - break; + return;//開始時に1バイト予約するから手順が違う + case NyLPC_cJsonRpcParser_TYPE_BSTRING: + if (i_c != '"'){ + goto ERROR; + } + i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n; + i_inst->_pcounter++; + if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){ + goto ERROR; + } + i_inst->_work.str.n++;//文字数の記憶領域 + i_inst->_pst = PARAM_ST_BSTR; + i_inst->_work.str.st = 0; + return;//開始時に1バイト予約するから手順が違う default: goto ERROR; } i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n; i_inst->_pcounter++; return; + case PARAM_ST_STR_ESCAPE_HEX: + //16進数構成文字のみ + if (!isxdigit((int)i_c)){ + goto ERROR; + } + i_inst->_work.str.vt = (i_inst->_work.str.vt << 4) | NyLPC_ctox(i_c); + i_inst->_work.str.st++; + //2文字目で値を確定 + if (i_inst->_work.str.st>=2){ + if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){ + goto ERROR; + } + i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_inst->_work.str.vt; + i_inst->_work.str.n++; + i_inst->_pst = PARAM_ST_STR; + } + return; + case PARAM_ST_STR_ESCAPE: + if(i_c=='x'){ + i_inst->_pst = PARAM_ST_STR_ESCAPE_HEX; + i_inst->_work.str.st = 0; + i_inst->_work.str.vt = 0; + } + else{ + if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){ + goto ERROR; + } + if (!convertSingleCharEscape(i_c,&i_inst->_result->method.param_buf[i_inst->_work.str.n])){ + goto ERROR; + } + i_inst->_work.str.n++; + i_inst->_pst = PARAM_ST_STR; + } + return; case PARAM_ST_STR: if (i_c == '"'){ //完了 @@ -224,9 +331,14 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) } i_inst->_result->method.param_buf[i_inst->_work.str.n] = '\0'; i_inst->_work.str.n++; + //文字数を更新 + *((NyLPC_TUInt8*)(i_inst->_result->method.param_buf+i_inst->_result->method.param_index[i_inst->_pcounter - 1])) = i_inst->_work.str.n - i_inst->_result->method.param_index[i_inst->_pcounter - 1]-2; i_inst->_pst = PARAM_ST_NEXT; return; } + else if (i_c=='\\'){ + i_inst->_pst = PARAM_ST_STR_ESCAPE; + } else{ if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){ goto ERROR; @@ -235,8 +347,40 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) i_inst->_work.str.n++; } return; + case PARAM_ST_BSTR: + if (i_c == '"'){ + if (i_inst->_work.str.st != 0){ + goto ERROR; + } + //文字数を更新 + *((NyLPC_TUInt8*)(i_inst->_result->method.param_buf + i_inst->_result->method.param_index[i_inst->_pcounter - 1])) = i_inst->_work.str.n - i_inst->_result->method.param_index[i_inst->_pcounter - 1] - 1; + i_inst->_pst = PARAM_ST_NEXT; + return; + } + else{ + //16進数構成文字のみ + if (!isxdigit((int)i_c)){ + goto ERROR; + } + switch(i_inst->_work.str.st){ + case 0: + i_inst->_work.str.vt = NyLPC_ctox(i_c); + i_inst->_work.str.st++; + break; + case 1: + i_inst->_work.str.vt = (i_inst->_work.str.vt << 4) | NyLPC_ctox(i_c); + if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){ + goto ERROR; + } + i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_inst->_work.str.vt; + i_inst->_work.str.n++; + i_inst->_work.str.st = 0; + break; + } + } + return; case PARAM_ST_INT: - if (strchr("0123456789", i_c) != NULL){ + if (isUnSignedCharSet(i_c)){ i_inst->_work.int32.v = i_inst->_work.int32.v * 10 + (i_c - '0'); return; } @@ -258,7 +402,7 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) *((NyLPC_TInt32*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 4])) = i_inst->_work.int32.v*i_inst->_work.int32.s; return; case PARAM_ST_UINT: - if (strchr("0123456789", i_c) != NULL){ + if (isUnSignedCharSet(i_c)){ i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0'); return; } @@ -279,7 +423,7 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c) *((NyLPC_TUInt32*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 4])) = i_inst->_work.uint32; return; case PARAM_ST_BYTE: - if (strchr("0123456789", i_c) != NULL){ + if (isUnSignedCharSet(i_c)){ i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0'); return; } @@ -426,16 +570,16 @@ void NyLPC_cJsonRpcParser_putChar(NyLPC_TcJsonRpcParser_t* i_inst,char i_c) //無視 return; } - if(strchr("0123456789",i_c)!=NULL){ - i_inst->_work.uint32=(i_c-'0'); + if (isUnSignedCharSet(i_c)){ + i_inst->_work.uint32 = (i_c - '0'); i_inst->_st=NyLPC_TcJsonRpcParser_ST_VAL_UINT; return; } //エラー goto ERROR; case NyLPC_TcJsonRpcParser_ST_VAL_UINT: - if(strchr("0123456789",i_c)!=NULL){ - i_inst->_work.uint32=i_inst->_work.uint32*10+(i_c-'0'); + if (isUnSignedCharSet(i_c)){ + i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0'); return; } if(strchr(" ,}",i_c)!=NULL){ @@ -526,6 +670,8 @@ const struct NyLPC_TJsonRpcMethodDef test_method[]= { "func9", "ss" }, { "f10", "suu" }, { "f11", "bbbb" }, + { "f12", "usu" }, + { "f13", "uBu" }, { NULL, "" } }; @@ -550,7 +696,7 @@ void NyLPC_cJsonRpcParser_putText(NyLPC_TcJsonRpcParser_t* i_inst, const NyLPC_T NyLPC_TUInt32 u32; NyLPC_TInt32 i32; NyLPC_TChar* c; - NyLPC_TUInt8 u8; + NyLPC_TUInt8 u8,l8; for (i = 0; i < i_size; i++){ @@ -571,7 +717,8 @@ void NyLPC_cJsonRpcParser_putText(NyLPC_TcJsonRpcParser_t* i_inst, const NyLPC_T switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i]){ case 'u':NyLPC_TJsonRpcParserResult_getUInt32(i_inst->_result,i, &u32); printf("%u,", u32); break; case 'd':NyLPC_TJsonRpcParserResult_getInt32(i_inst->_result, i, &i32); printf("%d,", i32); break; - case 's':NyLPC_TJsonRpcParserResult_getStr(i_inst->_result, i, &c); printf("%s,", c); break; + case 's':NyLPC_TJsonRpcParserResult_getStr(i_inst->_result, i, &c, &l8); printf("%s:%d,", c, l8); break; + case 'B':NyLPC_TJsonRpcParserResult_getByteArray(i_inst->_result, i, &c, &l8); printf("--:%d,", l8); break; case 'b':NyLPC_TJsonRpcParserResult_getByte(i_inst->_result, i, &u8); printf("%u,", u8); break; } } @@ -615,7 +762,7 @@ void main(void) }; #else const char* t[] = { - "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\":[]}",//YES +/* "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\":[]}",//YES "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\": [] }",//YES "{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [-123] }",//YES "{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [\"123\"] }",//NG @@ -639,6 +786,9 @@ void main(void) "{\"version\":\"2.0\",\"method\":\"ns:class:f10\",\"params\": [\"01234567890123\",22,33] }",//OK "{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 0 , 1 ,2,3] }",//OK "{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 15 , 1 ,2,3a] }",//NG +*/ + "{\"version\":\"2.0\",\"method\":\"ns:class:f13\",\"params\": [2,\"0011223344ff\",1] }",//NG +// "{\"version\":\"2.0\",\"method\":\"ns:class:f12\",\"params\": [2,\"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",1] }",//NG NULL }; #endif @@ -648,6 +798,7 @@ void main(void) NyLPC_cJsonRpcParser_initialize(&inst, test_def_array); NyLPC_cJsonRpcParser_initParser(&inst, &ret); NyLPC_cJsonRpcParser_putText(&inst, t[i], strlen(t[i])); + continue; } printf("end\n"); return; diff --git a/lib/src/http/json/NyLPC_cJsonRpcParser.h b/lib/src/http/json/NyLPC_cJsonRpcParser.h index c67b028..3035c97 100644 --- a/lib/src/http/json/NyLPC_cJsonRpcParser.h +++ b/lib/src/http/json/NyLPC_cJsonRpcParser.h @@ -40,7 +40,9 @@ struct NyLPC_TJsonRpcMethodDef * */ const char* param_patt; @@ -70,7 +72,7 @@ struct NyLPC_TJsonRpcClassDef #define NyLPC_TJsonRpcParserResult_TYPE_RESULT 1 #define NyLPC_TJsonRpcParserResult_TYPE_METHOD 2 -/** NyLPC_TJsonRpcParserResultが格納できる引数の最大数。パラメータの最大数に等しくなります。*/ +/** NyLPC_TJsonRpcParserResultが格納できる引数の最大数。パラメータの最大数に等しくなります。 */ #define NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX 32 /** * NyLPC_TJsonRpcParserResultが格納できるパラメータの総バイト数。 @@ -86,7 +88,7 @@ struct NyLPC_TJsonRpcClassDef union NyLPC_TJsonRpcParserResult { NyLPC_TUInt8 type; //タイプ - /** この構造体は type==NyLPC_TJsonRpcParserResult_TYPE_METHODのときに有効です。*/ + /** この構造体は type==NyLPC_TJsonRpcParserResult_TYPE_METHODのときに有効です。 */ struct{ NyLPC_TUInt8 _type; //タイプ NyLPC_TUInt8 func_number; //確定した関数番号。 @@ -94,7 +96,7 @@ union NyLPC_TJsonRpcParserResult NyLPC_TInt32 id; //idパラメータの値 NyLPC_TChar param_buf[NyLPC_TJsonRpcParserResult_PARAM_BUF]; NyLPC_TUInt8 param_index[NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX]; - /** 関数の含まれるクラスへのポインタ。*/ + /** 関数の含まれるクラスへのポインタ。 */ const struct NyLPC_TJsonRpcClassDef* class_def; }method; struct{ @@ -138,7 +140,12 @@ NyLPC_TBool NyLPC_TJsonRpcParserResult_getInt32(const union NyLPC_TJsonRpcParser /** * i_idx番目のパラメータをchar[]としてo_valへ取り出します。 */ -NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val); +NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val, NyLPC_TUInt8* o_len); +/** +* i_idx番目のパラメータをuchar[]としてo_valへ取り出します。 +*/ +NyLPC_TBool NyLPC_TJsonRpcParserResult_getByteArray(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TUInt8** o_val, NyLPC_TUInt8* o_len); + /** * i_idx番目のパラメータをuint8としてo_valへ取り出します。 */ @@ -156,6 +163,7 @@ NyLPC_TBool NyLPC_TJsonRpcParserResult_getByte(const union NyLPC_TJsonRpcParserR #define NyLPC_cJsonRpcParser_TYPE_UINT32 'u' #define NyLPC_cJsonRpcParser_TYPE_STRING 's' #define NyLPC_cJsonRpcParser_TYPE_BYTE 'b' +#define NyLPC_cJsonRpcParser_TYPE_BSTRING 'B' /** * JsonRPCメッセージをパースします。パース出来るメッセージは以下の通りです。 @@ -194,8 +202,8 @@ typedef NyLPC_TUInt8 NyLPC_TcJsonRpcParser_TStatus; -/** NyLPC_TcJsonRpcParserの定数値です。 字句解析ワークメモリの長さ。256未満8*n-1の数を指定してください。 */ -#define NyLPC_TcJsonRpcParser_WORK_MAX 47 +/** NyLPC_TcJsonRpcParserの定数値です。 字句解析ワークメモリの長さ。256未満8*n-4の数を指定してください。 */ +#define NyLPC_TcJsonRpcParser_WORK_MAX (48-4) /** * クラス構造体です。 @@ -207,6 +215,9 @@ struct NyLPC_TcJsonRpcParser struct{ NyLPC_TChar buf[NyLPC_TcJsonRpcParser_WORK_MAX]; //文字解析メモリ NyLPC_TUInt8 n; //字句解析の文字数 + NyLPC_TUInt8 st; //字句解析のサブステータス + NyLPC_TUInt8 vt; //数字エスケープ解釈のテンポラリ + NyLPC_TUInt8 _padding; // }str; struct{ NyLPC_TInt32 v; diff --git a/lib/src/include/NyLPC_config.h b/lib/src/include/NyLPC_config.h index abca024..386e2e1 100644 --- a/lib/src/include/NyLPC_config.h +++ b/lib/src/include/NyLPC_config.h @@ -99,8 +99,8 @@ extern "C" { //PACKED STRUCTの無効化 #define PACK_STRUCT_END //OSタイプによりMCUを修正 - #undef NyLPC_ARCH - #define NyLPC_MCU NyLPC_MCU_UNKNOWN +# undef NyLPC_MCU +# define NyLPC_MCU NyLPC_MCU_UNKNOWN #endif diff --git a/lib/src/include/NyLPC_jsonrpc.h b/lib/src/include/NyLPC_jsonrpc.h new file mode 100644 index 0000000..a0ffb66 --- /dev/null +++ b/lib/src/include/NyLPC_jsonrpc.h @@ -0,0 +1,42 @@ +/********************************************************************************* + * PROJECT: MiMic + * -------------------------------------------------------------------------------- + * + * This file is part of MiMic + * Copyright (C)2011 Ryo Iizuka + * + * MiMic is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * For further information please contact. + * http://nyatla.jp/ + * or + * + *********************************************************************************/ +/** + * @file + * このファイルは、jsonRPCディレクトリ以下に宣言されるヘッダファイルを集積します。 + */ +#ifndef NYLPC_JSONRPC_H_ +#define NYLPC_JSONRPC_H_ +#include "../jsonrpc/NyLPC_cJsonRpcFunction.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/lib/src/jsonrpc/NyLPC_cJsonRpcFunction.h b/lib/src/jsonrpc/NyLPC_cJsonRpcFunction.h new file mode 100644 index 0000000..f6feed4 --- /dev/null +++ b/lib/src/jsonrpc/NyLPC_cJsonRpcFunction.h @@ -0,0 +1,26 @@ +/* + * NyLPC_cJsonRpcFunction.h + * + * Created on: 2014/06/28 + * Author: nyatla + */ + +#ifndef NYLPC_CJSONRPCFUNCTION_H_ +#define NYLPC_CJSONRPCFUNCTION_H_ +#include "NyLPC_net.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * メモリ操作API + * paramにはNyLPC_modJsonRPCのポインタが必要です。 + */ +extern const struct NyLPC_TJsonRpcClassDef NyLPC_cJsonRpcFunction_Memory; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* NYLPC_CJSONRPCFUNCTION_H_ */ diff --git a/lib/src/jsonrpc/NyLPC_cJsonRpcFunction_Memory.c b/lib/src/jsonrpc/NyLPC_cJsonRpcFunction_Memory.c new file mode 100644 index 0000000..d573d60 --- /dev/null +++ b/lib/src/jsonrpc/NyLPC_cJsonRpcFunction_Memory.c @@ -0,0 +1,133 @@ +#include "NyLPC_net.h" + +///** +// * 1バイトをメモリに書き込む +// */ +//static NyLPC_TBool write(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +//{ +// //ubb +// NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; +// NyLPC_TUInt8* addr; +// NyLPC_TUInt8 v,mask; +// if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,((NyLPC_TUInt32*)&addr))){ +// if(NyLPC_TJsonRpcParserResult_getByte(i_rpc,1,((NyLPC_TUInt8*)&v))){ +// if(NyLPC_TJsonRpcParserResult_getByte(i_rpc,2,((NyLPC_TUInt8*)&mask))){ +// *addr=((*addr)&(~mask))|((*addr)|mask); +// return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,""); +// } +// } +// } +// NyLPC_cModJsonRpc_putError(mod,i_rpc->method.id,NyLPC_TJsonRpcErrorCode_INVALID_PARAMS); +// return NyLPC_TBool_FALSE; +//} +///** +// * 1バイトをメモリから読み込む +// */ +//static NyLPC_TBool read(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +//{ +// //u +// NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; +// NyLPC_TUInt8* addr; +// if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,((NyLPC_TUInt32*)&addr))){ +// return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,"%u",(int)(*addr)); +// } +// NyLPC_cModJsonRpc_putError(mod,i_rpc->method.id,NyLPC_TJsonRpcErrorCode_INVALID_PARAMS); +// return NyLPC_TBool_FALSE; +//} +// +///** +// * write32 +// */ +//static NyLPC_TBool write32(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +//{ +// //uuu +// NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; +// NyLPC_TUInt32* addr; +// NyLPC_TUInt32 v,mask; +// if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,((NyLPC_TUInt32*)&addr))){ +// if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,1,((NyLPC_TUInt32*)&v))){ +// if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,2,((NyLPC_TUInt32*)&mask))){ +// *addr=((*addr)&(~mask))|((*addr)|mask); +// return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,""); +// } +// } +// } +// NyLPC_cModJsonRpc_putError(mod,i_rpc->method.id,NyLPC_TJsonRpcErrorCode_INVALID_PARAMS); +// return NyLPC_TBool_FALSE; +//} +///** +// * read32 +// */ +//static NyLPC_TBool read32(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +//{ +// //u +// NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; +// NyLPC_TUInt32* addr; +// NyLPC_TUInt32 v; +// if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,((NyLPC_TUInt32*)&addr))){ +// v=(*addr); +// return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,"%u",v); +// } +// NyLPC_cModJsonRpc_putError(mod,i_rpc->method.id,NyLPC_TJsonRpcErrorCode_INVALID_PARAMS); +// return NyLPC_TBool_FALSE; +//} +/** + * 準備(特にやることない) + */ +static NyLPC_TBool init(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +{ + //uB + NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; + return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,""); +} + +/** + * メモリブロックを書き込む + */ +static NyLPC_TBool write(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +{ + //uB + NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; + NyLPC_TUInt8* addr; + const NyLPC_TUInt8* v; + NyLPC_TUInt8 l; + if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,((NyLPC_TUInt32*)&addr))){ + if(NyLPC_TJsonRpcParserResult_getByteArray(i_rpc,1,&v,&l)){ + memcpy(addr,v,l); + return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,""); + } + } + NyLPC_cModJsonRpc_putError(mod,i_rpc->method.id,NyLPC_TJsonRpcErrorCode_INVALID_PARAMS); + return NyLPC_TBool_FALSE; +} +/** + * メモリブロックを読み込む + */ +static NyLPC_TBool read(const union NyLPC_TJsonRpcParserResult* i_rpc,void* i_param) +{ + //uu + NyLPC_TcModJsonRpc_t* mod=(NyLPC_TcModJsonRpc_t*)i_param; + NyLPC_TUInt8* addr; + NyLPC_TUInt32 l; + if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,0,((NyLPC_TUInt32*)&addr))){ + if(NyLPC_TJsonRpcParserResult_getUInt32(i_rpc,1,((NyLPC_TUInt32*)&l))){ + return NyLPC_cModJsonRpc_putResult(mod,i_rpc->method.id,"\"%.*B\"",(int)l,addr); + } + } + NyLPC_cModJsonRpc_putError(mod,i_rpc->method.id,NyLPC_TJsonRpcErrorCode_INVALID_PARAMS); + return NyLPC_TBool_FALSE; +} + + + +const static struct NyLPC_TJsonRpcMethodDef func_table[]= +{ + { "init" ,"" ,init}, + { "write" ,"uB" ,write}, + { "read" ,"uu" ,read}, + { NULL ,NULL ,NULL} +}; + +const struct NyLPC_TJsonRpcClassDef NyLPC_cJsonRpcFunction_Memory={ + "MiMic","Memory",func_table +}; diff --git a/lib/src/utils/NyLPC_cFormatWriter.c b/lib/src/utils/NyLPC_cFormatWriter.c index 39e49e4..26af5fc 100644 --- a/lib/src/utils/NyLPC_cFormatWriter.c +++ b/lib/src/utils/NyLPC_cFormatWriter.c @@ -73,20 +73,16 @@ NyLPC_TBool NyLPC_cFormatWriter_print(NyLPC_cFormatWriter_printHandler i_handler continue; case 'u': //ワークを空にする。 - if(ol>0){ - i_handler(i_inst,wk,ol); + if (ol>0){ + i_handler(i_inst, wk, ol); + ol = 0; } - ut=va_arg(args,NyLPC_TUInt32); - ol=15; - wk[ol--]='\0'; - do{ - wk[ol--]='0'+(ut%10); - ut/=10; - }while(ut>0); - i_handler(i_inst,(wk+ol+1),14-ol); - ol=0; + NyLPC_uitoa((va_arg(args, NyLPC_TUInt32)), wk, 10); + //強制コミット + i_handler(i_inst, wk, strlen(wk)); rp++; continue; + //16進数 case 'x': //ワークを空にする。 if(ol>0){ @@ -98,7 +94,30 @@ NyLPC_TBool NyLPC_cFormatWriter_print(NyLPC_cFormatWriter_printHandler i_handler i_handler(i_inst,wk,strlen(wk)); rp++; continue; -// case 'X': + //BYTE値のHEXエンコード文字列(XX形式のテキスト。%.*Bのみ) + case 'B': + switch(ftype){ + case FTYPE_LENGTH: + //%.*Bの場合 + ut=va_arg(args,NyLPC_TUInt32); + break; + default: + ut=0; + } + sp=va_arg(args,const char*); + while(ut>0){ + //2文字以上の空きがないなら書き込み + if (ol >= (NUM_OF_WORK - 2)){ + i_handler(i_inst, wk, ol); + ol = 0; + } + NyLPC_uitoa2((int)(*sp), wk + ol, 16, 2); + ol += 2; + sp++; + ut--; + } + rp++; + continue; case '%': wk[ol]='%'; ol++; @@ -141,7 +160,6 @@ NyLPC_TInt16 NyLPC_cFormatWriter_length(const NyLPC_TChar* i_fmt,va_list args) NyLPC_TUInt32 ut; NyLPC_TUInt8 ftype; NyLPC_TInt16 len=0; - NyLPC_TInt16 ol=0; while(*rp!='\0'){ if(*rp=='%'){ ftype=FTYPE_NOTHING; @@ -157,8 +175,7 @@ NyLPC_TInt16 NyLPC_cFormatWriter_length(const NyLPC_TChar* i_fmt,va_list args) goto FMT_NEXT; } //その他 - wk[ol]=*rp; - ol++; + len++; rp++; break; case 's': @@ -172,29 +189,18 @@ NyLPC_TInt16 NyLPC_cFormatWriter_length(const NyLPC_TChar* i_fmt,va_list args) } sp=va_arg(args,const char*); while(*sp!=0 && ut>0){ - wk[ol]=*sp; - ol++; + len++; sp++; - //バッファフルなら書込み。 - if(ol>=NUM_OF_WORK){ - len+=NUM_OF_WORK; - ol=0; - } ut--; } rp++; continue; case 'c': - wk[ol]=(char)va_arg(args,int); + va_arg(args,int); + len++; rp++; - ol++; break; case 'd': - //ワークを空にする。 - if(ol>0){ - len+=ol; - ol=0; - } NyLPC_itoa((va_arg(args,int)),wk,10); //強制コミット len+=(NyLPC_TInt16)strlen(wk); @@ -202,62 +208,49 @@ NyLPC_TInt16 NyLPC_cFormatWriter_length(const NyLPC_TChar* i_fmt,va_list args) continue; case 'u': //ワークを空にする。 - if(ol>0){ - len+=ol; - } - ut=va_arg(args,NyLPC_TUInt32); - ol=15; - wk[ol--]='\0'; - do{ - wk[ol--]='0'+(ut%10); - ut/=10; - }while(ut>0); - len+=14-ol; - ol=0; + NyLPC_uitoa((va_arg(args, NyLPC_TUInt32)), wk, 10); + //強制コミット + len += (NyLPC_TInt16)strlen(wk); rp++; continue; case 'x': - //ワークを空にする。 - if(ol>0){ - len+=ol; - ol=0; - } NyLPC_uitoa((va_arg(args,unsigned int)),wk,16); //強制コミット len+=(NyLPC_TInt16)strlen(wk); rp++; continue; -// case 'X': + //BYTE値のHEXエンコード文字列(XX形式のテキスト。%.*Bのみ) + case 'B': + switch(ftype){ + case FTYPE_LENGTH: + //%.*Bの場合 + ut=va_arg(args,NyLPC_TUInt32); + break; + default: + ut=0; + } + sp=va_arg(args,const char*); + len += (NyLPC_TInt16)ut * 2; + rp++; + continue; case '%': - wk[ol]='%'; - ol++; + len++; rp++; break; case '\0': //オワタ(ループ抜けるためにrpはそのまま。) break; default: - wk[ol]=*rp; - ol++; - } - //バッファフルなら書込み。 - if(ol>=NUM_OF_WORK){ - len+=NUM_OF_WORK; - ol=0; + len++; } }else if(*rp==0){ //オワタ break; }else{ - wk[ol]=*rp; - ol++; + len++; rp++; - if(ol>=NUM_OF_WORK){ - len+=NUM_OF_WORK; - ol=0; - } } } //どこかでエラーが起こってればFALSE返す。 - return len+ol; + return len; } diff --git a/lib/src/utils/NyLPC_cFormatWriter.h b/lib/src/utils/NyLPC_cFormatWriter.h index 7ada3d7..524dd0c 100644 --- a/lib/src/utils/NyLPC_cFormatWriter.h +++ b/lib/src/utils/NyLPC_cFormatWriter.h @@ -12,11 +12,13 @@ typedef NyLPC_TBool(*NyLPC_cFormatWriter_printHandler)(void* i_inst,const void* * printfライクな書式出力関数です。i_handlerへi_fmtに示される書式文字列を出力します。 * @param i_fmt * フォーマット文字列。以下の形式をサポートします。 - * %d - * %u - * %c - * %% - * %s,%.*s + * %d int値 + * %u uint値 + * %c char値 + * %% '%' + * %s,%.*s 文字列 + * 独自拡張 + * %.*B BYTE配列をXX形式で並べた文字列 * */ NyLPC_TBool NyLPC_cFormatWriter_print(NyLPC_cFormatWriter_printHandler i_handler,void* i_inst,const NyLPC_TChar* i_fmt,va_list args); -- 2.11.0