This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NyLPC_cJsonRpcParser.c Source File

NyLPC_cJsonRpcParser.c

00001 #include "NyLPC_cJsonRpcParser.h"
00002 #include <ctype.h>
00003 //
00004 //  NyLPC_TJsonRpcParserResult
00005 //
00006 
00007 
00008 NyLPC_TBool NyLPC_TJsonRpcParserResult_getUInt32(const union NyLPC_TJsonRpcParserResult* i_struct,NyLPC_TInt16 i_idx,NyLPC_TUInt32* o_val)
00009 {
00010     if(i_struct->method.param_index[i_idx]==0xff){
00011         return NyLPC_TBool_FALSE;
00012     }
00013     if(i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx]!=NyLPC_cJsonRpcParser_TYPE_UINT32){
00014         return NyLPC_TBool_FALSE;
00015     }
00016     *o_val = *((NyLPC_TUInt32*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]));
00017     return NyLPC_TBool_TRUE;
00018 }
00019 NyLPC_TBool NyLPC_TJsonRpcParserResult_getInt32(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TInt32* o_val)
00020 {
00021     if(i_struct->method.param_index[i_idx]==0xff){
00022         return NyLPC_TBool_FALSE;
00023     }
00024     if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_INT32){
00025         return NyLPC_TBool_FALSE;
00026     }
00027     *o_val = *((NyLPC_TInt32*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]));
00028     return NyLPC_TBool_TRUE;
00029 }
00030 NyLPC_TBool NyLPC_TJsonRpcParserResult_getStr(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TChar** o_val, NyLPC_TUInt8* o_len)
00031 {
00032     if(i_struct->method.param_index[i_idx]==0xff){
00033         return NyLPC_TBool_FALSE;
00034     }
00035     if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_STRING){
00036         return NyLPC_TBool_FALSE;
00037     }
00038     *o_val = ((NyLPC_TChar*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx]+1));
00039     if (o_len){
00040         *o_len = *((NyLPC_TUInt8*)(*o_val-1));
00041     }
00042     return NyLPC_TBool_TRUE;
00043 }
00044 NyLPC_TBool NyLPC_TJsonRpcParserResult_getByteArray(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, const NyLPC_TUInt8** o_val, NyLPC_TUInt8* o_len)
00045 {
00046     if (i_struct->method.param_index[i_idx] == 0xff){
00047         return NyLPC_TBool_FALSE;
00048     }
00049     if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_BSTRING){
00050         return NyLPC_TBool_FALSE;
00051     }
00052     *o_val = ((NyLPC_TUInt8*)(i_struct->method.param_buf + i_struct->method.param_index[i_idx] + 1));
00053     if (o_len){
00054         *o_len = *((NyLPC_TUInt8*)(*o_val - 1));
00055     }
00056     return NyLPC_TBool_TRUE;
00057 }
00058 
00059 NyLPC_TBool NyLPC_TJsonRpcParserResult_getByte(const union NyLPC_TJsonRpcParserResult* i_struct, NyLPC_TInt16 i_idx, NyLPC_TUInt8* o_val)
00060 {
00061     if(i_struct->method.param_index[i_idx]==0xff){
00062         return NyLPC_TBool_FALSE;
00063     }
00064     if (i_struct->method.class_def->functions[i_struct->method.func_number].param_patt[i_idx] != NyLPC_cJsonRpcParser_TYPE_BYTE){
00065         return NyLPC_TBool_FALSE;
00066     }
00067     *o_val = *(i_struct->method.param_buf + i_struct->method.param_index[i_idx]);
00068     return NyLPC_TBool_TRUE;
00069 }
00070 
00071 
00072 //
00073 //  NyLPC_cJsonRpcParser
00074 //
00075 
00076 
00077 
00078 #define NAME_ID_UNKNOWN     0
00079 #define NAME_ID_VERSION     1
00080 #define NAME_ID_METHOD      2
00081 #define NAME_ID_RESULT      3
00082 #define NAME_ID_PARAMS      4
00083 #define NAME_ID_ID          5
00084 
00085 const struct NyLPC_TTextIdTbl method_name_tbl[]=
00086 {
00087     {"jsonrpc",NAME_ID_VERSION},
00088     {"method",NAME_ID_METHOD},
00089     {"params",NAME_ID_PARAMS},
00090     {"id",NAME_ID_ID},
00091     {NULL,NAME_ID_UNKNOWN}
00092 };
00093 
00094 
00095 static const struct NyLPC_TJsonRpcClassDef* findFunction(const struct NyLPC_TJsonRpcClassDef** i_tbl, const NyLPC_TChar* i_method_path, NyLPC_TUInt8* o_function_idx);
00096 static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c);
00097 static NyLPC_TUInt8 valTerminator2St(NyLPC_TChar i_c);
00098 
00099 
00100 void NyLPC_cJsonRpcParser_initialize(
00101     NyLPC_TcJsonRpcParser_t* i_inst,
00102     const struct NyLPC_TJsonRpcClassDef** i_class_def)
00103 {
00104     i_inst->_class_def=i_class_def;
00105 }
00106 void NyLPC_cJsonRpcParser_initParser(NyLPC_TcJsonRpcParser_t* i_inst,union NyLPC_TJsonRpcParserResult* i_result)
00107 {
00108     i_inst->_result=i_result;
00109     i_result->type=NyLPC_TJsonRpcParserResult_TYPE_UNKNOWN;
00110     i_inst->_st = NyLPC_TcJsonRpcParser_ST_START;
00111     i_inst->_pcounter = 0;
00112     memset(i_result->raw.param_index, 0xff, NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX);
00113 }
00114 
00115 
00116 
00117 static const struct NyLPC_TJsonRpcClassDef* findFunction(const struct NyLPC_TJsonRpcClassDef** i_tbl,const NyLPC_TChar* i_method_path,NyLPC_TUInt8* o_function_idx)
00118 {
00119     const NyLPC_TChar* ns;
00120     const NyLPC_TChar* class_;
00121     const NyLPC_TChar* method;
00122     NyLPC_TUInt8 fidx;
00123     int l;
00124     //namespaceの抽出
00125     ns=i_method_path;
00126     class_=strchr(i_method_path,':');
00127     if(class_==NULL){
00128         return NULL;
00129     }
00130     class_++;
00131     //functionの抽出
00132     method=strchr(class_,':');
00133     if(method==NULL){
00134         return NULL;
00135     }
00136     method++;
00137     while((*i_tbl)!=NULL){
00138         l=class_-ns-1;
00139         if(strncmp((*i_tbl)->names_pace,ns,l)!=0 || (*(ns+l))!=':'){
00140             i_tbl++;
00141             continue;
00142         }
00143         l=method-class_-1;
00144         if(strncmp((*i_tbl)->class_name,class_,l)!=0 || (*(class_+l))!=':'){
00145             i_tbl++;
00146             continue;
00147         }
00148         fidx=0;
00149         while(((*i_tbl)->functions+fidx)->name!=NULL){
00150             if(strcmp(((*i_tbl)->functions+fidx)->name,method)!=0){
00151                 fidx++;
00152                 continue;
00153             }
00154             *o_function_idx=fidx;
00155             return (*i_tbl);
00156         }
00157         break;
00158     }
00159     return NULL;
00160 }
00161 /**
00162  * putchar_paramのステータス値
00163  */
00164 #define PARAM_ST_START           1
00165 #define PARAM_ST_VAL             2
00166 #define PARAM_ST_INT             3
00167 #define PARAM_ST_UINT            4
00168 #define PARAM_ST_STR             5
00169 #define PARAM_ST_STR_ESCAPE_HEX  6
00170 #define PARAM_ST_STR_ESCAPE      7
00171 #define PARAM_ST_BYTE            8
00172 #define PARAM_ST_BSTR            9
00173 #define PARAM_ST_NEXT           11
00174 
00175 
00176 /**
00177  * シングルエスケープ文字列をエスケープされた文字列へ変換します。
00178  */
00179 static NyLPC_TBool convertSingleCharEscape(const char i_s, char* o_out)
00180 {
00181     switch (i_s){
00182     case '0':   *o_out = '\0'; break;
00183     case 'r':   *o_out = '\r'; break;
00184     case 'n':   *o_out = '\n'; break;
00185     case 't':   *o_out = '\t'; break;
00186     case '\'':  *o_out = '\''; break;
00187     case '\"':  *o_out = '\"'; break;
00188     case '\\':  *o_out = '\\'; break;
00189     default:
00190         return NyLPC_TBool_FALSE;
00191     }
00192     return NyLPC_TBool_TRUE;
00193 }
00194 /**
00195  * 符号付整数値を構成する文字セットであるかを返します。
00196  */
00197 static NyLPC_TBool isSignedCharSet(const char i_c)
00198 {
00199     return (strchr("-0123456789", i_c) != NULL);
00200 }
00201 /**
00202  * 整数を構成する文字セットであるかを返します。
00203  */
00204 #define isUnSignedCharSet(i_c) isdigit((int)(i_c))
00205 
00206 static void putchar_params(NyLPC_TcJsonRpcParser_t* i_inst, char i_c)
00207 {
00208     switch (i_inst->_pst){
00209     case PARAM_ST_START:
00210         if (i_c == '['){
00211             //パース開始
00212             i_inst->_work.str.n = 0;
00213             i_inst->_pst = PARAM_ST_VAL;
00214             return;
00215         }
00216         if (strchr(" ", i_c) != NULL){
00217             //無視
00218             return;
00219         }
00220         //エラー
00221         goto ERROR;
00222     case PARAM_ST_VAL:
00223         if (i_inst->_pcounter >= NyLPC_TJsonRpcParserResult_NUMBER_OF_PARAM_INDEX){
00224             goto ERROR;
00225         }
00226         if (strchr(" ", i_c) != NULL){
00227             //無視
00228             return;
00229         }
00230         if (strchr("]", i_c) != NULL){
00231             i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT;
00232             i_inst->_pcounter = 0xff;
00233             return;
00234         }
00235         switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i_inst->_pcounter]){
00236         case NyLPC_cJsonRpcParser_TYPE_INT32:
00237             if(!isSignedCharSet(i_c)){
00238                 goto ERROR;
00239             }
00240             i_inst->_pst = PARAM_ST_INT;
00241             i_inst->_work.int32.s = i_c == '-' ? -1 : 1;
00242             i_inst->_work.int32.v = i_c == '-' ? 0 : (i_c - '0');
00243             i_inst->_work.str.n = ((i_inst->_work.str.n + 3) / 4) * 4;
00244             break;
00245         case NyLPC_cJsonRpcParser_TYPE_UINT32:
00246             if (!isUnSignedCharSet(i_c)){
00247                 goto ERROR;
00248             }
00249             i_inst->_pst = PARAM_ST_UINT;
00250             i_inst->_work.uint32 = (i_c - '0');
00251             //開始位置を4バイト境界に
00252             i_inst->_work.str.n = ((i_inst->_work.str.n + 3) / 4) * 4;
00253             break;
00254         case NyLPC_cJsonRpcParser_TYPE_BYTE:
00255             if (!isUnSignedCharSet(i_c)){
00256                 goto ERROR;
00257             }
00258             i_inst->_pst = PARAM_ST_BYTE;
00259             i_inst->_work.uint32 = (i_c - '0');
00260             break;
00261         case NyLPC_cJsonRpcParser_TYPE_STRING:
00262             if (i_c != '"'){
00263                 goto ERROR;
00264             }
00265             i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;
00266             i_inst->_pcounter++;
00267             if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00268                 goto ERROR;
00269             }
00270             i_inst->_work.str.n++;//文字数の記憶領域
00271             i_inst->_pst = PARAM_ST_STR;
00272             return;//開始時に1バイト予約するから手順が違う
00273         case NyLPC_cJsonRpcParser_TYPE_BSTRING:
00274             if (i_c != '"'){
00275                 goto ERROR;
00276             }
00277             i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;
00278             i_inst->_pcounter++;
00279             if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00280                 goto ERROR;
00281             }
00282             i_inst->_work.str.n++;//文字数の記憶領域
00283             i_inst->_pst = PARAM_ST_BSTR;
00284             i_inst->_work.str.st = 0;
00285             return;//開始時に1バイト予約するから手順が違う
00286         default:
00287             goto ERROR;
00288         }
00289         i_inst->_result->method.param_index[i_inst->_pcounter] = i_inst->_work.str.n;
00290         i_inst->_pcounter++;
00291         return;
00292     case PARAM_ST_STR_ESCAPE_HEX:
00293         //16進数構成文字のみ
00294         if (!isxdigit((int)i_c)){
00295             goto ERROR;
00296         }
00297         i_inst->_work.str.vt = (i_inst->_work.str.vt << 4) | NyLPC_ctox(i_c);
00298         i_inst->_work.str.st++;
00299         //2文字目で値を確定
00300         if (i_inst->_work.str.st>=2){
00301             if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00302                 goto ERROR;
00303             }
00304             i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_inst->_work.str.vt;
00305             i_inst->_work.str.n++;
00306             i_inst->_pst = PARAM_ST_STR;
00307         }
00308         return;
00309     case PARAM_ST_STR_ESCAPE:
00310         if(i_c=='x'){
00311             i_inst->_pst = PARAM_ST_STR_ESCAPE_HEX;
00312             i_inst->_work.str.st = 0;
00313             i_inst->_work.str.vt = 0;
00314         }
00315         else{
00316             if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00317                 goto ERROR;
00318             }
00319             if (!convertSingleCharEscape(i_c,&i_inst->_result->method.param_buf[i_inst->_work.str.n])){
00320                 goto ERROR;
00321             }
00322             i_inst->_work.str.n++;
00323             i_inst->_pst = PARAM_ST_STR;
00324         }
00325         return;
00326     case PARAM_ST_STR:
00327         if (i_c == '"'){
00328             //完了
00329             if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00330                 goto ERROR;
00331             }
00332             i_inst->_result->method.param_buf[i_inst->_work.str.n] = '\0';
00333             i_inst->_work.str.n++;
00334             //文字数を更新
00335             *((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;
00336             i_inst->_pst = PARAM_ST_NEXT;
00337             return;
00338         }
00339         else if (i_c=='\\'){
00340             i_inst->_pst = PARAM_ST_STR_ESCAPE;
00341         }
00342         else{
00343             if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00344                 goto ERROR;
00345             }
00346             i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_c;
00347             i_inst->_work.str.n++;
00348         }
00349         return;
00350     case PARAM_ST_BSTR:
00351         if (i_c == '"'){
00352             if (i_inst->_work.str.st != 0){
00353                 goto ERROR;
00354             }
00355             //文字数を更新
00356             *((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;
00357             i_inst->_pst = PARAM_ST_NEXT;
00358             return;
00359         }
00360         else{
00361             //16進数構成文字のみ
00362             if (!isxdigit((int)i_c)){
00363                 goto ERROR;
00364             }
00365             switch(i_inst->_work.str.st){
00366             case 0:
00367                 i_inst->_work.str.vt = NyLPC_ctox(i_c);
00368                 i_inst->_work.str.st++;
00369                 break;
00370             case 1:
00371                 i_inst->_work.str.vt = (i_inst->_work.str.vt << 4) | NyLPC_ctox(i_c);
00372                 if (i_inst->_work.str.n >= NyLPC_TJsonRpcParserResult_PARAM_BUF){
00373                     goto ERROR;
00374                 }
00375                 i_inst->_result->method.param_buf[i_inst->_work.str.n] = i_inst->_work.str.vt;
00376                 i_inst->_work.str.n++;
00377                 i_inst->_work.str.st = 0;
00378                 break;
00379             }
00380         }
00381         return;
00382     case PARAM_ST_INT:
00383         if (isUnSignedCharSet(i_c)){
00384             i_inst->_work.int32.v = i_inst->_work.int32.v * 10 + (i_c - '0');
00385             return;
00386         }
00387         switch (i_c){
00388         case ' ':
00389             i_inst->_pst = PARAM_ST_NEXT; break;
00390         case ',':
00391             i_inst->_pst = PARAM_ST_VAL; break;
00392         case ']':
00393             i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
00394         default:
00395             goto ERROR;
00396         }
00397         //4バイト境界に揃える
00398         i_inst->_work.str.n += 4;
00399         if (i_inst->_work.str.n > NyLPC_TJsonRpcParserResult_PARAM_BUF){
00400             goto ERROR;
00401         }
00402         *((NyLPC_TInt32*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 4])) = i_inst->_work.int32.v*i_inst->_work.int32.s;
00403         return;
00404     case PARAM_ST_UINT:
00405         if (isUnSignedCharSet(i_c)){
00406             i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');
00407             return;
00408         }
00409         switch (i_c){
00410         case ' ':
00411             i_inst->_pst = PARAM_ST_NEXT; break;
00412         case ',':
00413             i_inst->_pst = PARAM_ST_VAL; break;
00414         case ']':
00415             i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
00416         default:
00417             goto ERROR;
00418         }
00419         i_inst->_work.str.n += 4;
00420         if (i_inst->_work.str.n > NyLPC_TJsonRpcParserResult_PARAM_BUF){
00421             goto ERROR;
00422         }
00423         *((NyLPC_TUInt32*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 4])) = i_inst->_work.uint32;
00424         return;
00425     case PARAM_ST_BYTE:
00426         if (isUnSignedCharSet(i_c)){
00427             i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');
00428             return;
00429         }
00430         switch (i_c){
00431         case ' ':
00432             i_inst->_pst = PARAM_ST_NEXT; break;
00433         case ',':
00434             i_inst->_pst = PARAM_ST_VAL; break;
00435         case ']':
00436             i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
00437         default:
00438             goto ERROR;
00439         }
00440         i_inst->_work.str.n ++;
00441         if (i_inst->_work.str.n > NyLPC_TJsonRpcParserResult_PARAM_BUF){
00442             goto ERROR;
00443         }
00444         *((NyLPC_TUInt8*)&(i_inst->_result->method.param_buf[i_inst->_work.str.n - 1])) = (NyLPC_TUInt8)(i_inst->_work.uint32&0xff);
00445         return;
00446     case PARAM_ST_NEXT:
00447         switch (i_c){
00448         case ' ':break;
00449         case ',':
00450             i_inst->_pst = PARAM_ST_VAL; break;
00451         case ']':
00452             i_inst->_st = NyLPC_TcJsonRpcParser_ST_NEXT; break;
00453         default:
00454             goto ERROR;
00455         }
00456         return;
00457     }
00458 ERROR:
00459     i_inst->_st = NyLPC_TcJsonRpcParser_ST_ERROR;
00460     return;
00461 }
00462 
00463 
00464 /**
00465 * NyLPC_cJsonRpcParser_putCharのサブ関数
00466 */
00467 static NyLPC_TUInt8 valTerminator2St(NyLPC_TChar i_c)
00468 {
00469     switch (i_c){
00470     case ' ':
00471         return NyLPC_TcJsonRpcParser_ST_NEXT;
00472     case '}':
00473         return NyLPC_TcJsonRpcParser_ST_END;
00474     case ',':
00475         return NyLPC_TcJsonRpcParser_ST_NAME_Q;
00476     default:
00477         //ないはず
00478         return NyLPC_TcJsonRpcParser_ST_ERROR;
00479     }
00480 }
00481 
00482 /** 文字列をパーサに入力してパーサの状態を遷移させます。
00483 
00484 */
00485 void NyLPC_cJsonRpcParser_putChar(NyLPC_TcJsonRpcParser_t* i_inst,char i_c)
00486 {
00487     switch(i_inst->_st){
00488     case NyLPC_TcJsonRpcParser_ST_PARAMS:
00489         putchar_params(i_inst,i_c);
00490         return;
00491     case NyLPC_TcJsonRpcParser_ST_START:
00492         if(i_c=='{'){
00493             i_inst->_st=NyLPC_TcJsonRpcParser_ST_NAME_Q;
00494             return;
00495         }
00496         if(strchr(" ",i_c)!=NULL){
00497             //無視
00498             return;
00499         }
00500         //エラー
00501         goto ERROR;
00502     case NyLPC_TcJsonRpcParser_ST_NAME_Q:
00503         if(i_c=='"'){
00504             i_inst->_st=NyLPC_TcJsonRpcParser_ST_NAME_STR;
00505             i_inst->_work.str.n=0;
00506             return;
00507         }
00508         if(strchr(" ",i_c)!=NULL){
00509             //無視
00510             return;
00511         }
00512         //エラー
00513         goto ERROR;
00514     case NyLPC_TcJsonRpcParser_ST_NAME_STR:
00515         if(i_c=='"'){
00516             //完了
00517             i_inst->_work.str.buf[i_inst->_work.str.n]='\0';
00518             //メソッドIDを記録
00519             i_inst->_name_id=NyLPC_TTextIdTbl_getMatchId(i_inst->_work.str.buf,method_name_tbl);
00520             i_inst->_st=NyLPC_TcJsonRpcParser_ST_NV_SEP;
00521             switch(i_inst->_name_id){
00522             case NAME_ID_METHOD:
00523             case NAME_ID_RESULT:
00524                 if(i_inst->_result->type!=NyLPC_TJsonRpcParserResult_TYPE_UNKNOWN){
00525                     goto ERROR;
00526                 }
00527                 break;
00528             case NAME_ID_PARAMS:
00529                 if (i_inst->_pcounter != 0){
00530                     goto ERROR;
00531                 }
00532                 break;
00533             default:
00534                 break;
00535             }
00536             return;
00537         }
00538         i_inst->_work.str.n++;
00539         if(i_inst->_work.str.n>=NyLPC_TcJsonRpcParser_WORK_MAX){
00540             //文字列長すぎでござる。
00541             goto ERROR;
00542         }
00543         i_inst->_work.str.buf[i_inst->_work.str.n-1]=i_c;
00544         return;
00545     case NyLPC_TcJsonRpcParser_ST_NV_SEP:
00546         if(i_c==':'){
00547             if (i_inst->_name_id == NAME_ID_PARAMS){
00548                 i_inst->_pst = PARAM_ST_START;
00549                 i_inst->_st = NyLPC_TcJsonRpcParser_ST_PARAMS;
00550             }
00551             else{
00552                 i_inst->_st = NyLPC_TcJsonRpcParser_ST_VAL;
00553                 i_inst->_work.str.n = 0;
00554             }
00555             return;
00556         }
00557         if(strchr(" ",i_c)!=NULL){
00558             //無視
00559             return;
00560         }
00561         //エラー
00562         goto ERROR;
00563     case NyLPC_TcJsonRpcParser_ST_VAL:
00564         if(i_c=='"'){
00565             i_inst->_st=NyLPC_TcJsonRpcParser_ST_VAL_STR;
00566             i_inst->_work.str.n=0;
00567             return;
00568         }
00569         if(strchr(" ",i_c)!=NULL){
00570             //無視
00571             return;
00572         }
00573         if (isUnSignedCharSet(i_c)){
00574             i_inst->_work.uint32 = (i_c - '0');
00575             i_inst->_st=NyLPC_TcJsonRpcParser_ST_VAL_UINT;
00576             return;
00577         }
00578         //エラー
00579         goto ERROR;
00580     case NyLPC_TcJsonRpcParser_ST_VAL_UINT:
00581         if (isUnSignedCharSet(i_c)){
00582             i_inst->_work.uint32 = i_inst->_work.uint32 * 10 + (i_c - '0');
00583             return;
00584         }
00585         if(strchr(" ,}",i_c)!=NULL){
00586             //確定
00587             switch(i_inst->_name_id){
00588             case NAME_ID_ID:
00589                 i_inst->_result->method.id=i_inst->_work.uint32;
00590                 break;
00591             case NAME_ID_UNKNOWN:
00592                 //知らないIDは無視
00593                 break;
00594             default:
00595                 //数値を受け入れないパラメータ
00596                 goto ERROR;
00597             }
00598             i_inst->_st=valTerminator2St(i_c);
00599             return;
00600         }
00601         goto ERROR;
00602     case NyLPC_TcJsonRpcParser_ST_VAL_STR:
00603         if(i_c=='"'){
00604             i_inst->_work.str.buf[i_inst->_work.str.n]='\0';
00605             //確定
00606             switch(i_inst->_name_id){
00607             case NAME_ID_VERSION:
00608                 if(strcmp(i_inst->_work.str.buf,"2.0")!=0){
00609                     goto ERROR;
00610                 }
00611                 break;
00612             case NAME_ID_METHOD:
00613                 i_inst->_result->method._type=NyLPC_TJsonRpcParserResult_TYPE_METHOD;
00614                 i_inst->_result->method.class_def=findFunction(i_inst->_class_def,i_inst->_work.str.buf,&(i_inst->_result->method.func_number));
00615                 if(i_inst->_result->method.class_def==NULL){
00616                     goto ERROR;
00617                 }
00618                 break;
00619             case NAME_ID_UNKNOWN:
00620                 //知らないIDは無視
00621                 break;
00622             default:
00623                 //文字列を受け入れないパラメータ
00624                 goto ERROR;
00625             }
00626             i_inst->_st=NyLPC_TcJsonRpcParser_ST_NEXT;
00627             return;
00628         }
00629         i_inst->_work.str.n++;
00630         if(i_inst->_work.str.n>=NyLPC_TcJsonRpcParser_WORK_MAX){
00631             //文字列長すぎでござる。
00632             goto ERROR;
00633         }
00634         i_inst->_work.str.buf[i_inst->_work.str.n-1]=i_c;
00635         return;
00636     case NyLPC_TcJsonRpcParser_ST_NEXT:
00637         if(i_c==','){
00638             i_inst->_st=NyLPC_TcJsonRpcParser_ST_NAME_Q;
00639         }else if(i_c=='}'){
00640             i_inst->_st=NyLPC_TcJsonRpcParser_ST_END;
00641         }else if(strchr(" ",i_c)!=NULL){
00642             //nothing to do
00643         }else{
00644             goto ERROR;
00645         }
00646         return;
00647     default:
00648         goto ERROR;
00649     }
00650 ERROR:
00651     i_inst->_st = NyLPC_TcJsonRpcParser_ST_ERROR;
00652     return;
00653 }
00654 
00655 #define COMMENT_DEBUG
00656 #ifndef COMMENT_DEBUG
00657 
00658 const struct NyLPC_TJsonRpcMethodDef test_method[]=
00659 {
00660     { "func" , ""},
00661     { "func1", "d" },
00662     { "func2", "dd" },
00663     { "func3", "u" },
00664     { "func4", "uu" },
00665     { "func5", "uss" },
00666     { "func5", "uss" },
00667     { "func6", "s" },
00668     { "func7", "sd" },
00669     { "func8", "su" },
00670     { "func9", "ss" },
00671     { "f10", "suu" },
00672     { "f11", "bbbb" },
00673     { "f12", "usu" },
00674     { "f13", "uBu" },
00675     { NULL, "" }
00676 };
00677 
00678 const struct NyLPC_TJsonRpcClassDef test_def=
00679 {
00680     "ns","class",
00681     test_method
00682 };
00683 
00684 /**
00685  * テスト用のアレイ
00686  */
00687 const struct NyLPC_TJsonRpcClassDef* test_def_array[]=
00688 {
00689     &test_def,
00690     NULL
00691 };
00692 
00693 void NyLPC_cJsonRpcParser_putText(NyLPC_TcJsonRpcParser_t* i_inst, const NyLPC_TChar* i_text,NyLPC_TUInt16 i_size)
00694 {
00695     NyLPC_TUInt16 i;
00696     NyLPC_TUInt32 u32;
00697     NyLPC_TInt32 i32;
00698     NyLPC_TChar* c;
00699     NyLPC_TUInt8 u8,l8;
00700 
00701 
00702     for (i = 0; i < i_size; i++){
00703         NyLPC_cJsonRpcParser_putChar(i_inst,i_text[i]);
00704         if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_ERROR){
00705             break;
00706         }
00707         else if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_END){
00708             break;
00709         }
00710     }
00711     if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_ERROR){
00712         printf("ERROR!\n");
00713     }
00714     else if (i_inst->_st == NyLPC_TcJsonRpcParser_ST_END){
00715         printf("OK!\n");
00716         for (int i = 0; i_inst->_result->method.param_index[i] != 0xff && i<i_inst->_pcounter; i++){
00717             switch (i_inst->_result->method.class_def->functions[i_inst->_result->method.func_number].param_patt[i]){
00718             case 'u':NyLPC_TJsonRpcParserResult_getUInt32(i_inst->_result,i, &u32); printf("%u,", u32); break;
00719             case 'd':NyLPC_TJsonRpcParserResult_getInt32(i_inst->_result, i, &i32); printf("%d,", i32); break;
00720             case 's':NyLPC_TJsonRpcParserResult_getStr(i_inst->_result, i, &c, &l8); printf("%s:%d,", c, l8); break;
00721             case 'B':NyLPC_TJsonRpcParserResult_getByteArray(i_inst->_result, i, &c, &l8); printf("--:%d,", l8); break;
00722             case 'b':NyLPC_TJsonRpcParserResult_getByte(i_inst->_result, i, &u8); printf("%u,", u8); break;
00723             }
00724         }
00725         printf("\n");
00726     }
00727     else{
00728         printf("CONTINUE...\n");
00729     }
00730 }
00731 
00732 void main(void)
00733 {
00734     NyLPC_TcJsonRpcParser_t inst;
00735     union NyLPC_TJsonRpcParserResult ret;
00736 
00737 //JSONCORE
00738 //#define JSONCORE 1
00739 #ifdef JSONCORE
00740     const char* t[] = {
00741         "{\"0123\"\"2.0\"}",//NO
00742         "{\"01234567890123456789\":\"2.0\"}",//NO
00743         "{\"0123\":\"01234567890123456789\"}",//NO
00744         "{\"version\":\"2.0\"}",//YES
00745         "{\"version\":\"2.1\"}",//NO
00746         " {  \"version\"  :  \"2.0\"  }",//YES
00747         "{\"version\":\"2.0\",}",//NO
00748         "{\"version\":\"2.0\" \"test\":\"t\"}",//NO
00749         "{\"version\":\"2.0\",\"method\":}",//NO
00750         "{\"version\":\"2.0\",\"method\":\"ns:class:func\"}",//YES
00751         "{\"version\":\"2.0\",\"method\":\"ns2:class:func\"}",//NO
00752         "{\"version\":\"2.0\",\"method\":\"ns:class2:func\"}",//NO
00753         "{\"version\":\"2.0\",\"method\":\"ns:class:func2\"}",//NO
00754         "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"method\":\"\"}",//NO
00755         "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"id\":0}",//YES
00756         "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"id\":\"123\"}",//YES
00757         "{\"version\":\"2.0\",\"method\":123}",//NO
00758         "{\"version\":\"2.0\",\"test\":123}",//YES
00759         "{\"version\":\"2.0\",\"test\":123, \"test\":123 }",//YES
00760         "{\"version\":\"2.0\",\"test\":123 ,\"test\":123 }",//YES
00761         NULL
00762     };
00763 #else
00764     const char* t[] = {
00765 /*      "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\":[]}",//YES
00766         "{\"version\":\"2.0\",\"method\":\"ns:class:func\",\"params\": [] }",//YES
00767         "{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [-123] }",//YES
00768         "{\"version\":\"2.0\",\"method\":\"ns:class:func1\",\"params\": [\"123\"] }",//NG
00769         "{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 1 , 456 ] }",//YES
00770         "{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 123 , 456 a] }",//NG
00771         "{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 123a] }",//NG
00772         "{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [ 123,456] }",//OK
00773         "{\"version\":\"2.0\",\"method\":\"ns:class:func2\",\"params\": [123,456] }",//YES
00774         "{\"version\":\"2.0\",\"method\":\"ns:class:func3\",\"params\": [123] }",//YES
00775         "{\"version\":\"2.0\",\"method\":\"ns:class:func3\",\"params\": [\"123\"] }",//NG
00776         "{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123 , 456 ] }",//YES
00777         "{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123 , 456 a] }",//NG
00778         "{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123a] }",//NG
00779         "{\"version\":\"2.0\",\"method\":\"ns:class:func4\",\"params\": [ 123,456] }",//OK
00780         "{\"version\":\"2.0\",\"method\":\"ns:class:func5\",\"params\": [123, \"abc\" , \"abc\"] }",//OK
00781         "{\"version\":\"2.0\",\"method\":\"ns:class:func6\",\"params\": [\"01234567890123456789012\"] }",//OK
00782         "{\"version\":\"2.0\",\"method\":\"ns:class:func6\",\"params\": [1] }",//NG
00783         "{\"version\":\"2.0\",\"method\":\"ns:class:func8\",\"params\": [\"012345678901234567\",1,1] }",//OK
00784         "{\"version\":\"2.0\",\"method\":\"ns:class:func8\",\"params\": [\"012345678901234567\",1] }",//OK
00785         "{\"version\":\"2.0\",\"method\":\"ns:class:func7\",\"params\": [\"012345678901234567\",1] }",//OK
00786         "{\"version\":\"2.0\",\"method\":\"ns:class:f10\",\"params\": [\"01234567890123\",22,33] }",//OK
00787         "{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 0 , 1 ,2,3] }",//OK
00788         "{\"version\":\"2.0\",\"method\":\"ns:class:f11\",\"params\": [ 15 , 1 ,2,3a] }",//NG
00789 */
00790         "{\"version\":\"2.0\",\"method\":\"ns:class:f13\",\"params\": [2,\"0011223344ff\",1] }",//NG
00791 //      "{\"version\":\"2.0\",\"method\":\"ns:class:f12\",\"params\": [2,\"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\",1] }",//NG
00792         NULL
00793     };
00794 #endif
00795     int i;
00796 
00797     for (i = 0;t[i]!=NULL; i++){
00798         NyLPC_cJsonRpcParser_initialize(&inst, test_def_array);
00799         NyLPC_cJsonRpcParser_initParser(&inst, &ret);
00800         NyLPC_cJsonRpcParser_putText(&inst, t[i], strlen(t[i]));
00801         continue;
00802     }
00803     printf("end\n");
00804     return;
00805 
00806 }
00807 #endif
00808