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_cHttpBasicBodyParser.c Source File

NyLPC_cHttpBasicBodyParser.c

00001 #include "NyLPC_cHttpBasicBodyParser.h"
00002 #include <ctype.h>
00003 
00004 void NyLPC_cHttpBasicBodyParser_initialize(NyLPC_TcHttpBasicBodyParser_t* i_inst,struct NyLPC_TcHttpBasicBodyParser_Handler* i_handler)
00005 {
00006     i_inst->_handler=i_handler;
00007     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_NULL;
00008 }
00009 #define NyLPC_cHttpBasicBodyParser_finalize(i_inst)
00010 
00011 /**
00012  * パーサの開始処理をします。
00013  * 関数は、parseInit->parseChar[n回]->(parseStream)->parseFinishの順でコールします。
00014  * parseChar、又はparseStreamでエラーが発生した場合は、後続の関数を呼び出すことは出来ません。
00015  * parseCharでEOHに達した場合、parseCharまたはparseStreamを続けて呼ぶことは出来ません。
00016  * parseFinishはparseCharまたはparseStreamでEOHに達した場合のみ呼び出すことが出来ます。
00017  */
00018 void NyLPC_cHttpBasicBodyParser_parseInit(NyLPC_TcHttpBasicBodyParser_t* i_inst,const struct NyLPC_THttpBasicHeader* i_info)
00019 {
00020     switch(i_info->transfer_encoding)
00021     {
00022     case NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED:
00023         i_inst->_encode_type=NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED;
00024         i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START;
00025         i_inst->_data.chunked.recv_len=0;
00026         break;
00027     default:
00028         i_inst->_encode_type=NyLPC_THttpMessgeHeader_TransferEncoding_NONE;
00029         i_inst->_data.normal.content_length=i_info->content_length;
00030         i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_BODY;
00031         break;
00032     }
00033 }
00034 
00035 /**
00036  * パーサの処理を閉じます。
00037  * @return
00038  * パース処理が正常に終了したかの真偽値
00039  */
00040 NyLPC_TBool NyLPC_cHttpBasicBodyParser_parseFinish(NyLPC_TcHttpBasicBodyParser_t* i_inst)
00041 {
00042     NyLPC_TBool ret=(i_inst->_status==NyLPC_TcHttpBasicBodyParser_ST_EOB);
00043     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_NULL;
00044     return ret;
00045 }
00046 #define HTTP_CR 0x0D
00047 #define HTTP_LF 0x0A
00048 #define HTTP_SP 0x20
00049 /**
00050  * HTTPストリームをパースします。
00051  * @return
00052  * 処理した文字列の長さ。-1の場合エラーである。
00053  * それ以外の場合ステータスをチェックすること。
00054  * NyLPC_TcHttpBasicBodyParser_ST_ERROR
00055  */
00056 NyLPC_TInt32 NyLPC_cHttpBasicBodyParser_parseChar(NyLPC_TcHttpBasicBodyParser_t* i_inst,const NyLPC_TChar* i_c,NyLPC_TInt32 i_size)
00057 {
00058     NyLPC_TInt32 i;
00059     NyLPC_TChar c;
00060     switch(i_inst->_encode_type){
00061     case NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED:
00062         for(i=0;i<i_size;)
00063         {
00064             c=*(i_c+i);
00065             //[:START:][:SP:][:EXT:][:BODY:][:END:]
00066             switch(i_inst->_status)
00067             {
00068             case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_BODY:
00069                 //OnRecv
00070                 if(!i_inst->_handler->bodyHandler(i_inst,c)){
00071                     i_inst->_data.chunked.recv_len--;
00072                     //中断
00073                     if(i_inst->_data.chunked.recv_len==0){
00074                         //content length分だけ読み取った
00075                         i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_FOOTER;
00076                     }
00077                     return i+1;
00078                 }
00079                 i_inst->_data.chunked.recv_len--;
00080                 if(i_inst->_data.chunked.recv_len==0){
00081                     //content length分だけ読み取った
00082                     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_FOOTER;
00083                 }
00084                 i++;//次の文字へ
00085                 break;
00086             // HEX
00087             case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START:
00088                 if(isxdigit((int)c)){
00089                     i_inst->_data.chunked.recv_len=i_inst->_data.chunked.recv_len*16+NyLPC_ctox(c);
00090                     //一応最大チャンクサイズは決めておこうか。
00091                     if(i_inst->_data.chunked.recv_len>0x0fffffff){
00092                         NyLPC_OnErrorGoto(ERROR);
00093                     }
00094                     i++;//次の文字へ
00095                 }else if(c==HTTP_SP){
00096                     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_SP;
00097                     i++;//次の文字へ
00098                 }else if(c==HTTP_CR || c==HTTP_LF){
00099                     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_EXT;
00100                     //読取位置を変化させずにEXTへ
00101                 }else{
00102                     NyLPC_OnErrorGoto(ERROR);
00103                 }
00104                 break;
00105             case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_SP:
00106                 if(c==HTTP_SP){
00107                     i++;//次の文字へ
00108                 }else{
00109                     //ext
00110                     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_EXT;
00111                 }
00112                 break;
00113             case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_EXT:
00114                 //EXTの内容は読まない。
00115                 if(c==HTTP_LF){
00116                     if(i_inst->_data.chunked.recv_len==0){
00117                         //chunksize=0でCRLFを検出したらend-chunk
00118                         i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_END;
00119                     }else{
00120                         //chunksize>0でCRLFを検出したらBODY検出
00121                         i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_BODY;
00122                     }
00123                 }else{
00124                     //nothing to do
00125                 }
00126                 i++;//次の文字へ
00127                 break;
00128             case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_FOOTER:
00129                 //CRLF待ち
00130                 if(c==HTTP_CR){
00131                     //無視
00132                 }else if(c==HTTP_LF){
00133                     //確定
00134                     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START;
00135                 }else{
00136                     NyLPC_OnErrorGoto(ERROR);
00137                 }
00138                 i++;
00139                 break;
00140             case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_END:
00141                 //CRLF待ち
00142                 if(c==HTTP_CR){
00143                     //無視
00144                 }else if(c==HTTP_LF){
00145                     //確定
00146                     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_EOB;
00147                     return i+1;
00148                 }else{
00149                     NyLPC_OnErrorGoto(ERROR);
00150                 }
00151                 i++;
00152                 break;
00153             default:
00154                 NyLPC_OnErrorGoto(ERROR);
00155             }
00156         }
00157         return i_size;
00158     case NyLPC_THttpMessgeHeader_TransferEncoding_NONE:
00159         if(i_inst->_status!=NyLPC_TcHttpBasicBodyParser_ST_BODY){
00160             NyLPC_OnErrorGoto(ERROR);
00161         }
00162         for(i=0;i<i_size;i++)
00163         {
00164             if(i_inst->_data.normal.content_length>0){
00165                 //OnRecv
00166                 if(!i_inst->_handler->bodyHandler(i_inst,*(i_c+i))){
00167                     i++;
00168                     i_inst->_data.normal.content_length--;
00169                     break;//中断(遷移無し)
00170                 }
00171                 i_inst->_data.normal.content_length--;
00172             }else{
00173                 //content-length==0;全て受信
00174                 break;
00175             }
00176         }
00177         if(i_inst->_data.normal.content_length==0){
00178             //content length分だけ読み取った
00179             i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_EOB;
00180             return i;
00181         }
00182         return i;
00183     }
00184 ERROR:
00185     //ERROR
00186     i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_ERROR;
00187     return -1;
00188 }
00189 
00190