OSDN Git Service

update libMiMic
[mimic/MiMicSDK.git] / lib / src / net / httpd / mod / NyLPC_cModJsonRpc.c
1 #include "NyLPC_cModJsonRpc.h"\r
2 \r
3 \r
4 \r
5 \r
6 void NyLPC_cModJsonRpc_initialize(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_ref_root_path,const struct NyLPC_TJsonRpcClassDef** i_class_tbl)\r
7 {\r
8         NyLPC_cModWebSocket_initialize(&i_inst->super,i_ref_root_path);\r
9         NyLPC_cJsonRpcParser_initialize(&i_inst->_rpc_parser,i_class_tbl);\r
10 }\r
11 void NyLPC_cModJsonRpc_finalize(NyLPC_TcModJsonRpc_t* i_inst)\r
12 {\r
13         NyLPC_cJsonRpcParser_finalize(&i_inst->_rpc_parser);\r
14         NyLPC_cModWebSocket_finalize(&i_inst->super);\r
15 }\r
16 #define NyLPC_cModJsonRpc_canHandle(i,c) NyLPC_cModWebSocket_canHandle(&((i)->super),(c))\r
17 \r
18 #define NyLPC_cModJsonRpc_close(i,t) NyLPC_cModWebSocket_close(&((i)->super),(t))\r
19 \r
20 \r
21 NyLPC_TBool NyLPC_cModJsonRpc_execute(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection)\r
22 {\r
23         //executeで強制初期化\r
24         NyLPC_cJsonRpcParser_initParser(&i_inst->_rpc_parser,&i_inst->_result);\r
25         return NyLPC_cModWebSocket_execute(&((i_inst)->super),i_connection);\r
26 }\r
27 \r
28 static NyLPC_TInt32 readHandler(void* i_param,NyLPC_TChar i_c)\r
29 {\r
30         NyLPC_TcModJsonRpc_t* inst=(NyLPC_TcModJsonRpc_t*)i_param;\r
31         NyLPC_cJsonRpcParser_putChar(&inst->_rpc_parser,i_c);\r
32         switch(NyLPC_cJsonRpcParser_getStatus(&(inst->_rpc_parser))){\r
33         case NyLPC_TcJsonRpcParser_ST_END:\r
34                 return 0;//終端到達。中断\r
35         case NyLPC_TcJsonRpcParser_ST_ERROR:\r
36                 return -1;//エラー\r
37         default:\r
38                 return 1;//次の文字をリクエスト\r
39         }\r
40 }\r
41 \r
42 \r
43 NyLPC_TBool NyLPC_cModJsonRpc_processRpcMessage(NyLPC_TcModJsonRpc_t* i_inst)\r
44 {\r
45         //終了した場合のみパーサステータスを初期化。\r
46         switch(NyLPC_cJsonRpcParser_getStatus(&i_inst->_rpc_parser)){\r
47         case NyLPC_TcJsonRpcParser_ST_END:\r
48                 NyLPC_cJsonRpcParser_initParser(&i_inst->_rpc_parser,&i_inst->_result);\r
49                 break;\r
50         case NyLPC_TcJsonRpcParser_ST_ERROR:\r
51                 //パーサがエラーを検出してたら何もしない。\r
52                 return NyLPC_TBool_FALSE;\r
53         }\r
54         //コールバックハンドラで受信\r
55         if(NyLPC_cModWebSocket_readCB(&(i_inst->super),readHandler,i_inst)<0){\r
56                 return NyLPC_TBool_FALSE;\r
57         }\r
58         return NyLPC_TBool_TRUE;\r
59 }\r
60 \r
61 const union NyLPC_TJsonRpcParserResult* NyLPC_cModJsonRpc_getMessage(NyLPC_TcModJsonRpc_t* i_inst)\r
62 {\r
63         return (NyLPC_cJsonRpcParser_getStatus(&i_inst->_rpc_parser)!=NyLPC_TcJsonRpcParser_ST_END)?NULL:(&i_inst->_result);\r
64 }\r
65 \r
66 NyLPC_TBool NyLPC_cModJsonRpc_putRawMessageV(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_fmt,va_list i_args)\r
67 {\r
68         return NyLPC_cModWebSocket_writeFormatV(&i_inst->super,i_fmt,i_args);\r
69 }\r
70 NyLPC_TBool NyLPC_cModJsonRpc_putRawMessage(NyLPC_TcModJsonRpc_t* i_inst,const NyLPC_TChar* i_fmt,...)\r
71 {\r
72         NyLPC_TBool r;\r
73         va_list a;\r
74         va_start(a,i_fmt);\r
75         r=NyLPC_cModWebSocket_writeFormatV(&i_inst->super,i_fmt,a);\r
76         va_end(a);\r
77         return r;\r
78 }\r
79 \r
80 \r
81 \r
82 /**\r
83  * @param i_params_fmt\r
84  * パラメータ部のフォーマット文字列です。NyLPC_cFormatWriterと同等の構文を使用できます。\r
85  * ここで指定した書式文字列は、"そのまま"パラメータ部に表示されます。文字列を返す場合は、次のように\"でエスケープしてください。\r
86  * '0,1,2,-1,\"result\",3'\r
87  */\r
88 NyLPC_TBool NyLPC_cModJsonRpc_putResult(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,const NyLPC_TChar* i_params_fmt,...)\r
89 {\r
90         NyLPC_TBool r;\r
91         va_list a;\r
92         //書き込み文字数の事前計算\r
93         va_start(a,i_params_fmt);\r
94         r=NyLPC_cModJsonRpc_putResultV(i_inst,i_id,i_params_fmt,a);\r
95         va_end(a);\r
96         return r;\r
97 }\r
98 \r
99 /**\r
100  * @param i_params_fmt\r
101  * パラメータ部のフォーマット文字列です。NyLPC_cFormatWriterと同等の構文を使用できます。\r
102  * ここで指定した書式文字列は、"そのまま"パラメータ部に表示されます。文字列を返す場合は、次のように\"でエスケープしてください。\r
103  * '0,1,2,-1,\"result\",3'\r
104  */\r
105 NyLPC_TBool NyLPC_cModJsonRpc_putResultV(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,const NyLPC_TChar* i_params_fmt,va_list i_a)\r
106 {\r
107         NyLPC_TBool r;\r
108         va_list a;\r
109         NyLPC_TInt16 l;\r
110 \r
111         //書き込み文字数の事前計算\r
112         NyLPC_va_copy(a,i_a);\r
113         l=NyLPC_cModWebSocket_testFormat(&i_inst->super,"{\"jsonrpc\":\"2.0\",\"result\":[");\r
114         l+=NyLPC_cModWebSocket_testFormatV(&i_inst->super,i_params_fmt,a);\r
115         l+=NyLPC_cModWebSocket_testFormat(&i_inst->super,"],\"id\":%d}",i_id);\r
116         va_end(a);\r
117 \r
118         //バルク書き込み\r
119         NyLPC_cModWebSocket_startBulkWrite(&i_inst->super,l);\r
120         r=NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"{\"jsonrpc\":\"2.0\",\"result\":[");\r
121         r=r&&NyLPC_cModWebSocket_writeBulkFormatV(&i_inst->super,i_params_fmt,i_a);\r
122         r=r&&NyLPC_cModWebSocket_writeBulkFormat(&i_inst->super,"],\"id\":%d}",i_id);\r
123         r=r&&NyLPC_cModWebSocket_endBulkWrite(&i_inst->super);\r
124         return r;\r
125 }\r
126 \r
127 struct CodeMsgTbl{\r
128         const char* n;\r
129         NyLPC_TInt32 id;\r
130 };\r
131 \r
132 const static struct CodeMsgTbl _table[]=\r
133 {\r
134         {"Parse error",NyLPC_TJsonRpcErrorCode_PARSE_ERROR},\r
135         {"Invalid Request",NyLPC_TJsonRpcErrorCode_INVALID_REQUEST},\r
136         {"Method not found",NyLPC_TJsonRpcErrorCode_METHOD_NOT_FOUND},\r
137         {"Invalid params",NyLPC_TJsonRpcErrorCode_INVALID_PARAMS},\r
138         {"Internal error",NyLPC_TJsonRpcErrorCode_INTERNAL_ERROR},\r
139         {"Server error",NyLPC_TJsonRpcErrorCode_SERVER_ERROR_BASE}\r
140 };\r
141 static const NyLPC_TChar* code2msg(NyLPC_TInt32 i_id)\r
142 {\r
143         int i;\r
144         for(i=0;i<6;i++){\r
145                 if(i_id==_table[i].id){\r
146                         return _table[i].n;\r
147                 }\r
148         }\r
149         return _table[5].n;\r
150 }\r
151 \r
152 NyLPC_TBool NyLPC_cModJsonRpc_putError(NyLPC_TcModJsonRpc_t* i_inst,NyLPC_TUInt32 i_id,NyLPC_TInt32 i_code)\r
153 {\r
154         return NyLPC_cModWebSocket_writeFormat(&i_inst->super,"{\"jsonrpc\":\"2.0\",\"error\":{\"code\": %d, \"message\": \"%s\"},\"id\":%d}",i_code,code2msg(i_code),i_id);\r
155 }\r