OSDN Git Service

jsonrpcparserにBSTR型を追加
[mimic/MiMicSDK.git] / lib / src / http / json / NyLPC_cJsonRpcParser.c
index fb5ef54..eb471ed 100644 (file)
@@ -1,5 +1,5 @@
 #include "NyLPC_cJsonRpcParser.h"\r
-\r
+#include <ctype.h>\r
 //\r
 //     NyLPC_TJsonRpcParserResult\r
 //\r
@@ -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]));\r
        return NyLPC_TBool_TRUE;\r
 }\r
-NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val)\r
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val, NyLPC_TUInt8* o_len)\r
 {\r
        if(i_struct->method.param_index[i_idx]==0xff){\r
                return NyLPC_TBool_FALSE;\r
@@ -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){\r
                return NyLPC_TBool_FALSE;\r
        }\r
-       *o_val = ((NyLPC_TChar*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]));\r
+       *o_val = ((NyLPC_TChar*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]+1));\r
+       if (o_len){\r
+               *o_len = *((NyLPC_TUInt8*)(*o_val-1));\r
+       }\r
+       return NyLPC_TBool_TRUE;\r
+}\r
+NyLPC_TBool NyLPC_TJsonRpcParserResult_getByteArray(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TUInt8** o_val, NyLPC_TUInt8* o_len)\r
+{\r
+       if (i_struct->method.param_index[i_idx] == 0xff){\r
+               return NyLPC_TBool_FALSE;\r
+       }\r
+       if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_BSTRING){\r
+               return NyLPC_TBool_FALSE;\r
+       }\r
+       *o_val = ((NyLPC_TUInt8*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx] + 1));\r
+       if (o_len){\r
+               *o_len = *((NyLPC_TUInt8*)(*o_val - 1));\r
+       }\r
        return NyLPC_TBool_TRUE;\r
 }\r
+\r
 NyLPC_TBool NyLPC_TJsonRpcParserResult_getByte(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TUInt8* o_val)\r
 {\r
        if(i_struct->method.param_index[i_idx]==0xff){\r
@@ -140,17 +158,53 @@ static const struct NyLPC_TJsonRpcClassDef* findFunction(const struct NyLPC_TJso
        }\r
        return NULL;\r
 }\r
-#define PARAM_ST_START 1\r
-#define PARAM_ST_VAL   2\r
-#define PARAM_ST_INT   3\r
-#define PARAM_ST_UINT  4\r
-#define PARAM_ST_STR   5\r
-#define PARAM_ST_NEXT  6\r
-#define PARAM_ST_BYTE  7\r
+/**\r
+ * putchar_paramのステータス値\r
+ */\r
+#define PARAM_ST_START                  1\r
+#define PARAM_ST_VAL                    2\r
+#define PARAM_ST_INT                    3\r
+#define PARAM_ST_UINT                   4\r
+#define PARAM_ST_STR                    5\r
+#define PARAM_ST_STR_ESCAPE_HEX         6\r
+#define PARAM_ST_STR_ESCAPE             7\r
+#define PARAM_ST_BYTE                   8\r
+#define PARAM_ST_BSTR                   9\r
+#define PARAM_ST_NEXT                  11\r
 \r
-static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)\r
+\r
+/**\r
+ * シングルエスケープ文字列をエスケープされた文字列へ変換します。\r
+ */\r
+static NyLPC_TBool convertSingleCharEscape(const char i_s, char* o_out)\r
+{\r
+       switch (i_s){\r
+       case '0':       *o_out = '\0'; break;\r
+       case 'r':       *o_out = '\r'; break;\r
+       case 'n':       *o_out = '\n'; break;\r
+       case 't':       *o_out = '\t'; break;\r
+       case '\'':      *o_out = '\''; break;\r
+       case '\"':      *o_out = '\"'; break;\r
+       case '\\':      *o_out = '\\'; break;\r
+       default:\r
+               return NyLPC_TBool_FALSE;\r
+       }\r
+       return NyLPC_TBool_TRUE;\r
+}\r
+/**\r
+ * 符号付整数値を構成する文字セットであるかを返します。\r
+ */\r
+static NyLPC_TBool isSignedCharSet(const char i_c)\r
 {\r
+       return (strchr("-0123456789", i_c) != NULL);\r
+}\r
+/**\r
+ * 整数を構成する文字セットであるかを返します。\r
+ */\r
+#define isUnSignedCharSet(i_c) isdigit(i_c)\r
 \r
+static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)\r
+{\r
        switch (i_inst->_pst){\r
        case PARAM_ST_START:\r
                if (i_c == '['){\r
@@ -180,7 +234,7 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)
                }\r
                switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i_inst->_pcounter]){\r
                case NyLPC_cJsonRpcParser_TYPE_INT32:\r
-                       if (strchr("-0123456789", i_c) == NULL){\r
+                       if(!isSignedCharSet(i_c)){\r
                                goto ERROR;\r
                        }\r
                        i_inst->_pst = PARAM_ST_INT;\r
@@ -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;\r
                        break;\r
                case NyLPC_cJsonRpcParser_TYPE_UINT32:\r
-                       if (strchr("0123456789", i_c) == NULL){\r
+                       if (!isUnSignedCharSet(i_c)){\r
                                goto ERROR;\r
                        }\r
                        i_inst->_pst = PARAM_ST_UINT;\r
@@ -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;\r
                        break;\r
                case NyLPC_cJsonRpcParser_TYPE_BYTE:\r
-                       if (strchr("0123456789", i_c) == NULL){\r
+                       if (!isUnSignedCharSet(i_c)){\r
                                goto ERROR;\r
                        }\r
                        i_inst->_pst = PARAM_ST_BYTE;\r
@@ -208,14 +262,67 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)
                        if (i_c != '"'){\r
                                goto ERROR;\r
                        }\r
+                       i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;\r
+                       i_inst->_pcounter++;\r
+                       if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){\r
+                               goto ERROR;\r
+                       }\r
+                       i_inst->_work.str.n++;//文字数の記憶領域\r
                        i_inst->_pst = PARAM_ST_STR;\r
-                       break;\r
+                       return;//開始時に1バイト予約するから手順が違う\r
+               case NyLPC_cJsonRpcParser_TYPE_BSTRING:\r
+                       if (i_c != '"'){\r
+                               goto ERROR;\r
+                       }\r
+                       i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;\r
+                       i_inst->_pcounter++;\r
+                       if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){\r
+                               goto ERROR;\r
+                       }\r
+                       i_inst->_work.str.n++;//文字数の記憶領域\r
+                       i_inst->_pst = PARAM_ST_BSTR;\r
+                       i_inst->_work.str.st = 0;\r
+                       return;//開始時に1バイト予約するから手順が違う\r
                default:\r
                        goto ERROR;\r
                }\r
                i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;\r
                i_inst->_pcounter++;\r
                return;\r
+       case PARAM_ST_STR_ESCAPE_HEX:\r
+               //16進数構成文字のみ\r
+               if (!isxdigit((int)i_c)){\r
+                       goto ERROR;\r
+               }\r
+               i_inst->_work.str.vt = (i_inst->_work.str.vt << 4) | NyLPC_ctox(i_c);\r
+               i_inst->_work.str.st++;\r
+               //2文字目で値を確定\r
+               if (i_inst->_work.str.st>=2){\r
+                       if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){\r
+                               goto ERROR;\r
+                       }\r
+                       i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_inst->_work.str.vt;\r
+                       i_inst->_work.str.n++;\r
+                       i_inst->_pst = PARAM_ST_STR;\r
+               }\r
+               return;\r
+       case PARAM_ST_STR_ESCAPE:\r
+               if(i_c=='x'){\r
+                       i_inst->_pst = PARAM_ST_STR_ESCAPE_HEX;\r
+                       i_inst->_work.str.st = 0;\r
+                       i_inst->_work.str.vt = 0;\r
+               }\r
+               else{\r
+                       if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){\r
+                               goto ERROR;\r
+                       }\r
+                       if (!convertSingleCharEscape(i_c,&i_inst->_result->method.param_buf[i_inst->_work.str.n])){\r
+                               goto ERROR;\r
+                       }\r
+                       i_inst->_work.str.n++;\r
+                       i_inst->_pst = PARAM_ST_STR;\r
+               }\r
+               return;\r
        case PARAM_ST_STR:\r
                if (i_c == '"'){\r
                        //完了\r
@@ -224,9 +331,14 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)
                        }\r
                        i_inst->_result->method.param_buf[i_inst->_work.str.n] = '\0';\r
                        i_inst->_work.str.n++;\r
+                       //文字数を更新\r
+                       *((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;\r
                        i_inst->_pst = PARAM_ST_NEXT;\r
                        return;\r
                }\r
+               else if (i_c=='\\'){\r
+                       i_inst->_pst = PARAM_ST_STR_ESCAPE;\r
+               }\r
                else{\r
                        if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){\r
                                goto ERROR;\r
@@ -235,8 +347,40 @@ static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)
                        i_inst->_work.str.n++;\r
                }\r
                return;\r
+       case PARAM_ST_BSTR:\r
+               if (i_c == '"'){\r
+                       if (i_inst->_work.str.st != 0){\r
+                               goto ERROR;\r
+                       }\r
+                       //文字数を更新\r
+                       *((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;\r
+                       i_inst->_pst = PARAM_ST_NEXT;\r
+                       return;\r
+               }\r
+               else{\r
+                       //16進数構成文字のみ\r
+                       if (!isxdigit((int)i_c)){\r
+                               goto ERROR;\r
+                       }\r
+                       switch(i_inst->_work.str.st){\r
+                       case 0:\r
+                               i_inst->_work.str.vt = NyLPC_ctox(i_c);\r
+                               i_inst->_work.str.st++;\r
+                               break;\r
+                       case 1:\r
+                               i_inst->_work.str.vt = (i_inst->_work.str.vt << 4) | NyLPC_ctox(i_c);\r
+                               if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){\r
+                                       goto ERROR;\r
+                               }\r
+                               i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_inst->_work.str.vt;\r
+                               i_inst->_work.str.n++;\r
+                               i_inst->_work.str.st = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               return;\r
        case PARAM_ST_INT:\r
-               if (strchr("0123456789", i_c) != NULL){\r
+               if (isUnSignedCharSet(i_c)){\r
                        i_inst->_work.int32.v = i_inst->_work.int32.v * 10 + (i_c - '0');\r
                        return;\r
                }\r
@@ -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;\r
                return;\r
        case PARAM_ST_UINT:\r
-               if (strchr("0123456789", i_c) != NULL){\r
+               if (isUnSignedCharSet(i_c)){\r
                        i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');\r
                        return;\r
                }\r
@@ -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;\r
                return;\r
        case PARAM_ST_BYTE:\r
-               if (strchr("0123456789", i_c) != NULL){\r
+               if (isUnSignedCharSet(i_c)){\r
                        i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');\r
                        return;\r
                }\r
@@ -426,16 +570,16 @@ void NyLPC_cJsonRpcParser_putChar(NyLPC_TcJsonRpcParser_t* i_inst,char i_c)
                        //無視\r
                        return;\r
                }\r
-               if(strchr("0123456789",i_c)!=NULL){\r
-                       i_inst->_work.uint32=(i_c-'0');\r
+               if (isUnSignedCharSet(i_c)){\r
+                       i_inst->_work.uint32 = (i_c - '0');\r
                        i_inst->_st=NyLPC_TcJsonRpcParser_ST_VAL_UINT;\r
                        return;\r
                }\r
                //エラー\r
                goto ERROR;\r
        case NyLPC_TcJsonRpcParser_ST_VAL_UINT:\r
-               if(strchr("0123456789",i_c)!=NULL){\r
-                       i_inst->_work.uint32=i_inst->_work.uint32*10+(i_c-'0');\r
+               if (isUnSignedCharSet(i_c)){\r
+                       i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');\r
                        return;\r
                }\r
                if(strchr(" ,}",i_c)!=NULL){\r
@@ -526,6 +670,8 @@ const struct NyLPC_TJsonRpcMethodDef test_method[]=
        { "func9", "ss" },\r
        { "f10", "suu" },\r
        { "f11", "bbbb" },\r
+       { "f12", "usu" },\r
+       { "f13", "uBu" },\r
        { NULL, "" }\r
 };\r
 \r
@@ -550,7 +696,7 @@ void NyLPC_cJsonRpcParser_putText(NyLPC_TcJsonRpcParser_t* i_inst, const NyLPC_T
        NyLPC_TUInt32 u32;\r
        NyLPC_TInt32 i32;\r
        NyLPC_TChar* c;\r
-       NyLPC_TUInt8 u8;\r
+       NyLPC_TUInt8 u8,l8;\r
 \r
 \r
        for (i = 0; i < i_size; i++){\r
@@ -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]){\r
                        case 'u':NyLPC_TJsonRpcParserResult_getUInt32(i_inst->_result,i, &u32); printf("%u,", u32); break;\r
                        case 'd':NyLPC_TJsonRpcParserResult_getInt32(i_inst->_result, i, &i32); printf("%d,", i32); break;\r
-                       case 's':NyLPC_TJsonRpcParserResult_getStr(i_inst->_result, i, &c); printf("%s,", c); break;\r
+                       case 's':NyLPC_TJsonRpcParserResult_getStr(i_inst->_result, i, &c, &l8); printf("%s:%d,", c, l8); break;\r
+                       case 'B':NyLPC_TJsonRpcParserResult_getByteArray(i_inst->_result, i, &c, &l8); printf("--:%d,", l8); break;\r
                        case 'b':NyLPC_TJsonRpcParserResult_getByte(i_inst->_result, i, &u8); printf("%u,", u8); break;\r
                        }\r
                }\r
@@ -615,7 +762,7 @@ void main(void)
        };\r
 #else\r
        const char* t[] = {\r
-               "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\":[]}",//YES\r
+/*             "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\":[]}",//YES\r
                "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\": [] }",//YES\r
                "{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [-123] }",//YES\r
                "{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [\"123\"] }",//NG\r
@@ -639,6 +786,9 @@ void main(void)
                "{\"version\":\"2.0\",\"method\":\"ns:class:f10\",\"params\": [\"01234567890123\",22,33] }",//OK\r
                "{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 0 , 1 ,2,3] }",//OK\r
                "{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 15 , 1 ,2,3a] }",//NG\r
+*/\r
+               "{\"version\":\"2.0\",\"method\":\"ns:class:f13\",\"params\": [2,\"0011223344ff\",1] }",//NG\r
+//             "{\"version\":\"2.0\",\"method\":\"ns:class:f12\",\"params\": [2,\"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",1] }",//NG\r
                NULL\r
        };\r
 #endif\r
@@ -648,6 +798,7 @@ void main(void)
                NyLPC_cJsonRpcParser_initialize(&inst, test_def_array);\r
                NyLPC_cJsonRpcParser_initParser(&inst, &ret);\r
                NyLPC_cJsonRpcParser_putText(&inst, t[i], strlen(t[i]));\r
+               continue;\r
        }\r
        printf("end\n");\r
        return;\r