Jun Furutani / libMiMic

Fork of libMiMic by Ryo Iizuka

Revision:
2:b96c1e90d120
Parent:
1:9f6a78395432
--- a/core/http/NyLPC_cHttpBasicHeaderParser.cpp	Mon Mar 25 05:23:49 2013 +0000
+++ b/core/http/NyLPC_cHttpBasicHeaderParser.cpp	Wed Mar 27 12:07:47 2013 +0000
@@ -42,23 +42,7 @@
 
 
 
-/**
- * HeaderParserのステータス定義値。
- */
-typedef NyLPC_TUInt8 NyLPC_TcHttpBasicHeaderParser_ST;
-#define NyLPC_TcHttpBasicHeaderParser_ST_START                  ((NyLPC_TcHttpBasicHeaderParser_ST)0x01)//HTTPステータスラインか、リクエストライン
-#define NyLPC_TcHttpBasicHeaderParser_ST_RL_URL                 ((NyLPC_TcHttpBasicHeaderParser_ST)0x12)//URL
-#define NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION             ((NyLPC_TcHttpBasicHeaderParser_ST)0x13)//VERSION
-#define NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE          ((NyLPC_TcHttpBasicHeaderParser_ST)0x21)//ステータスコード
-#define NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON              ((NyLPC_TcHttpBasicHeaderParser_ST)0x22)//Reason-Phrase
-#define NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD                ((NyLPC_TcHttpBasicHeaderParser_ST)0x31)//MESSAGE
-#define NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM               ((NyLPC_TcHttpBasicHeaderParser_ST)0x32)//MESSAGEパラメータ部
-#define NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH      ((NyLPC_TcHttpBasicHeaderParser_ST)0x33)//MESSAGEContentLength
-#define NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION         ((NyLPC_TcHttpBasicHeaderParser_ST)0x34)//MESSAGEConnection
-#define NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING   ((NyLPC_TcHttpBasicHeaderParser_ST)0x35)//TransferEncoding
-#define NyLPC_TcHttpBasicHeaderParser_ST_MSG_RANGE              ((NyLPC_TcHttpBasicHeaderParser_ST)0x36)//Range
-#define NyLPC_TcHttpBasicHeaderParser_ST_EOH                    ((NyLPC_TcHttpBasicHeaderParser_ST)0x7F)//終わり
-#define NyLPC_TcHttpBasicHeaderParser_ST_ERROR                  ((NyLPC_TcHttpBasicHeaderParser_ST)0x80)//終わり
+
 
 
 
@@ -71,10 +55,7 @@
 #define HTTP_DM ':' 
 
 
-/*
-    プライベート関数
-*/
-#define NyLPC_TcHttpBasicHeaderParser_ST_isError(i_v) ((i_v)==NyLPC_TcHttpBasicHeaderParser_ST_ERROR)
+
 
 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_Connection(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out);
 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_ContentLength(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out);
@@ -116,8 +97,8 @@
  */
 static const struct NyLPC_TcHttpBasicHeaderParser_Handler _default_handler=
 {
-        default_message_handler,
-        default_urlHandler
+    default_message_handler,
+    default_urlHandler
 };
 
 
@@ -127,96 +108,224 @@
 ----------------------------------------*/
 
 
-void NyLPC_cHttpBasicHeaderParser_initialize(NyLPC_TcHttpBasicHeaderParser_t* i_inst)
+void NyLPC_cHttpBasicHeaderParser_initialize(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const struct NyLPC_TcHttpBasicHeaderParser_Handler* i_handler)
 {
     NyLPC_cStr_initialize(&(i_inst->_wsb),i_inst->_wsb_buf,NyLPC_cHttpBasicHeaderParser_SIZE_OF_WBS);
-    i_inst->_handler=&_default_handler;
+    i_inst->_handler=(i_handler==NULL?&_default_handler:i_handler);
+}
+
+/**
+ * parserの初期化
+ */
+void NyLPC_cHttpBasicHeaderParser_parseInit(NyLPC_TcHttpBasicHeaderParser_t* i_inst,struct NyLPC_THttpBasicHeader* o_out)
+{
+    //出力構造体を初期化
+    o_out->connection=NyLPC_THttpMessgeHeader_Connection_NONE;
+    o_out->content_length=NyLPC_THttpContentLength_INVALID_LENGTH;
+    o_out->transfer_encoding=NyLPC_THttpMessgeHeader_TransferEncoding_NONE;
+    i_inst->_st=NyLPC_TcHttpBasicHeaderParser_ST_START;
+}
+/**
+ * parseCharがNyLPC_TcHttpBasicHeaderParser_ST_EOHを返却したらコールすること。
+ */
+NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parseFinish(NyLPC_TcHttpBasicHeaderParser_t* i_inst,struct NyLPC_THttpBasicHeader* o_out)
+{
+    if(i_inst->_st!=NyLPC_TcHttpBasicHeaderParser_ST_EOH)
+    {
+        return NyLPC_TBool_FALSE;
+    }
+    //整合性チェック
+    if(!testHeader(o_out,&i_inst->_rcode)){
+        i_inst->_st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR;
+        return NyLPC_TBool_FALSE;
+    }
+    return NyLPC_TBool_TRUE;
 }
+/**
+ * 文字列をパースします。
+ * コール前にNyLPC_cHttpBasicHeaderParser_parseInitでパーサを開始してください。
+ * @return
+ * パースした文字列の長さ。-1の場合はエラー。
+ * TRUEの場合、NyLPC_cHttpBasicHeaderParser_getParseStatus関数で状態をチェックして、後続の処理を選択してください。
+ */
+NyLPC_TInt32 NyLPC_cHttpBasicHeaderParser_parseChar(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_c,NyLPC_TInt32 i_size,struct NyLPC_THttpBasicHeader* o_out)
+{
+    int i;
+    NyLPC_TChar c;
+    //Errorチェック
+    if(NyLPC_TcHttpBasicHeaderParser_ST_ERROR==i_inst->_st)
+    {
+        return 0;
+    }
+    for(i=0;i<i_size;i++){
+        c=*(i_c+i);
+        switch(i_inst->_st)
+        {
+        case NyLPC_TcHttpBasicHeaderParser_ST_START:
+            i_inst->_st=parseStartLine(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM:
+            i_inst->_st=parseMessageParam(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD:
+            i_inst->_st=parseMessage1(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_RL_URL:
+            i_inst->_st=parseRequestUrl(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION:
+            i_inst->_st=parseVersion(i_inst,c,NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE:
+            i_inst->_st=parseStatusCode(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON:
+            i_inst->_st=parseReason(i_inst,c);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH:
+            i_inst->_st=parseMessage_ContentLength(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION:
+            i_inst->_st=parseMessage_Connection(i_inst,c,o_out);
+            break;
+        case NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING:
+            i_inst->_st=parseMessage_TransferEncoding(i_inst,c,o_out);
+            break;
+        default:
+            i_inst->_rcode=500;
+            i_inst->_st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR;
+        }
+        if(NyLPC_TcHttpBasicHeaderParser_ST_isError(i_inst->_st)){
+            //エラー起こしたら終了。
+            return i;
+        }else if(i_inst->_st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){
+            //ヘッダ終端なら終了。
+            return i+1;
+        }
+    }
+    return i_size;
+}
+
+
 
 /**
  * ストリームから読み出して、パースします。
+ * コール前にNyLPC_cHttpBasicHeaderParser_parseInitでパーサを開始してください。
+ * @return
+ * FALSE-失敗/TRUE-成功
+ * 関数が成功した場合、NyLPC_cHttpBasicHeaderParser_parseFinishでパーサを閉じることが出来ます。
  */
-NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parse(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TcHttpStream_t* i_stream,struct NyLPC_THttpBasicHeader* o_out)
+NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parseStream(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TcHttpStream_t* i_stream,struct NyLPC_THttpBasicHeader* o_out)
 {
-    NyLPC_TcHttpBasicHeaderParser_ST st;
     const char* rp_base;
     NyLPC_TInt32 rsize;
-    char c;
-    int i;
-
-    //出力構造体を初期化
-    st=NyLPC_TcHttpBasicHeaderParser_ST_START;
-    o_out->connection=NyLPC_THttpMessgeHeader_Connection_NONE;
-    o_out->content_length=NyLPC_THttpContentLength_INVALID_LENGTH;
-    o_out->transfer_encoding=NyLPC_THttpMessgeHeader_TransferEncoding_NONE;
-
     for(;;){
         //タイムアウト付でストリームから読み出し。
         rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base));
         if(rsize<=0){
             return NyLPC_TBool_FALSE;
         }
-        for(i=0;i<rsize;i++){
-            c=*(rp_base+i);
-            switch(st)
-            {
-            case NyLPC_TcHttpBasicHeaderParser_ST_START:
-                st=parseStartLine(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM:
-                st=parseMessageParam(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD:
-                st=parseMessage1(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_RL_URL:
-                st=parseRequestUrl(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION:
-                st=parseVersion(i_inst,c,NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE:
-                st=parseStatusCode(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON:
-                st=parseReason(i_inst,c);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH:
-                st=parseMessage_ContentLength(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION:
-                st=parseMessage_Connection(i_inst,c,o_out);
-                break;
-            case NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING:
-                st=parseMessage_TransferEncoding(i_inst,c,o_out);
-                break;
-            default:
-                i_inst->_rcode=500;
-                st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR;
-            }
-            //エラー起こしたら終了。
-            if(NyLPC_TcHttpBasicHeaderParser_ST_isError(st)){
-                return NyLPC_TBool_FALSE;
-            }
+        rsize=NyLPC_cHttpBasicHeaderParser_parseChar(i_inst,rp_base,rsize,o_out);
+        if(i_inst->_st==NyLPC_TcHttpBasicHeaderParser_ST_ERROR){
+            //パース失敗
+            NyLPC_iHttpPtrStream_rseek(i_stream,rsize);
+            return NyLPC_TBool_FALSE;
+        }
+        if(i_inst->_st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){
             //パース成功
-            if(st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){
-                //整合性チェック
-                if(!testHeader(o_out,&i_inst->_rcode)){
-                    st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR;
-                    return NyLPC_TBool_FALSE;
-                }
-                //シーク
-                NyLPC_iHttpPtrStream_rseek(i_stream,i+1);
-                return NyLPC_TBool_TRUE;
-            }
+            NyLPC_iHttpPtrStream_rseek(i_stream,rsize);
+            return NyLPC_TBool_TRUE;
         }
-        //シーク
         NyLPC_iHttpPtrStream_rseek(i_stream,(NyLPC_TUInt16)rsize);
     }
     return NyLPC_TBool_FALSE;
 }
 
 
+///**
+// * ストリームから読み出して、パースします。
+// */
+//NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parse(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TcHttpStream_t* i_stream,struct NyLPC_THttpBasicHeader* o_out)
+//{
+//  NyLPC_TcHttpBasicHeaderParser_ST st;
+//  const char* rp_base;
+//  NyLPC_TInt32 rsize;
+//  char c;
+//  int i;
+//
+//  //出力構造体を初期化
+//  st=NyLPC_TcHttpBasicHeaderParser_ST_START;
+//  o_out->connection=NyLPC_THttpMessgeHeader_Connection_NONE;
+//  o_out->content_length=NyLPC_THttpContentLength_INVALID_LENGTH;
+//  o_out->transfer_encoding=NyLPC_THttpMessgeHeader_TransferEncoding_NONE;
+//
+//  for(;;){
+//      //タイムアウト付でストリームから読み出し。
+//      rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base));
+//      if(rsize<=0){
+//          return NyLPC_TBool_FALSE;
+//      }
+//      for(i=0;i<rsize;i++){
+//          c=*(rp_base+i);
+//          switch(st)
+//          {
+//          case NyLPC_TcHttpBasicHeaderParser_ST_START:
+//              st=parseStartLine(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM:
+//              st=parseMessageParam(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD:
+//              st=parseMessage1(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_RL_URL:
+//              st=parseRequestUrl(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION:
+//              st=parseVersion(i_inst,c,NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE:
+//              st=parseStatusCode(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON:
+//              st=parseReason(i_inst,c);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH:
+//              st=parseMessage_ContentLength(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION:
+//              st=parseMessage_Connection(i_inst,c,o_out);
+//              break;
+//          case NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING:
+//              st=parseMessage_TransferEncoding(i_inst,c,o_out);
+//              break;
+//          default:
+//              i_inst->_rcode=500;
+//              st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR;
+//          }
+//          //エラー起こしたら終了。
+//          if(NyLPC_TcHttpBasicHeaderParser_ST_isError(st)){
+//              return NyLPC_TBool_FALSE;
+//          }
+//          //パース成功
+//          if(st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){
+//              //整合性チェック
+//              if(!testHeader(o_out,&i_inst->_rcode)){
+//                  st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR;
+//                  return NyLPC_TBool_FALSE;
+//              }
+//              //シーク
+//              NyLPC_iHttpPtrStream_rseek(i_stream,i+1);
+//              return NyLPC_TBool_TRUE;
+//          }
+//      }
+//      //シーク
+//      NyLPC_iHttpPtrStream_rseek(i_stream,(NyLPC_TUInt16)rsize);
+//  }
+//  return NyLPC_TBool_FALSE;
+//}
+
+
 
 /*----------------------------------------
     private関数
@@ -701,4 +810,3 @@
 Error:
     return NyLPC_TBool_FALSE;
 }
-