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

NyLPC_cHttpStream.c

00001 /*********************************************************************************
00002  * PROJECT: MiMic
00003  * --------------------------------------------------------------------------------
00004  *
00005  * This file is part of MiMic
00006  * Copyright (C)2011 Ryo Iizuka
00007  *
00008  * MiMic is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License as published
00010  * by the Free Software Foundation, either version 3 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public License
00019  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00020  *
00021  * For further information please contact.
00022  *  http://nyatla.jp/
00023  *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
00024  *
00025  *********************************************************************************/
00026 #include "NyLPC_cHttpStream.h"
00027 
00028 
00029 
00030 #if NyLPC_CONFIG_cHttpStream_DEBUG == 1
00031 #include <stdio.h>
00032 char _wbuf[1024];
00033 const char* _rbuf;
00034 int _rbuf_len;
00035 void NyLPC_iTcpSocket_initialized(void* inst,const char* rb,int l)
00036 {
00037     _rbuf=rb;
00038     _rbuf_len=l;
00039 
00040 }
00041 void* NyLPC_iIpTcpSocket_allocSendBuf(void* inst,NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_len,NyLPC_TUInt32 i_to)
00042 {
00043     *o_len=30;
00044     return _wbuf;
00045 }
00046 NyLPC_TBool NyLPC_iTcpSocket_psend(void* inst,void* i_buf,NyLPC_TUInt16 i_len,NyLPC_TUInt32 i_to)
00047 {
00048     printf("%.*s",i_len,i_buf);
00049     return NyLPC_TBool_TRUE;
00050 }
00051 NyLPC_TInt32 NyLPC_iTcpSocket_precv(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_wait_msec)
00052 {
00053     int l=(_rbuf_len>100)?100:_rbuf_len;
00054     *o_buf_ptr=_rbuf;
00055     return l;
00056 }
00057 void NyLPC_iTcpSocket_pseek(void* i_inst,NyLPC_TUInt16 i_seek)
00058 {
00059     _rbuf+=i_seek;
00060     _rbuf_len-=i_seek;
00061 }
00062 
00063 void* NyLPC_iTcpSocket_releaseSendBuf(NyLPC_TiTcpSocket_t* i_inst,void* i_buf_ptr)
00064 {
00065     return NULL;
00066 }
00067 #endif
00068 
00069 
00070 static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_timeout);
00071 static NyLPC_TBool write_func(void* i_inst,const void* i_data,NyLPC_TInt32 i_length);
00072 static void pseek_func(void* i_inst,NyLPC_TUInt16 i_seek);
00073 static NyLPC_TBool flush_func(void* i_inst);
00074 static void setReadEncoding_func(void* i_inst,NyLPC_TiHttpPtrStream_ET i_et);
00075 static void setWriteEncoding_func(void* i_inst,NyLPC_TiHttpPtrStream_ET i_et);
00076 
00077 
00078 /**
00079  * HTTP送信バッファのヒント値
00080  */
00081 #define HTTP_TX_BUF_HINT 1024
00082 
00083 //関数テーブル
00084 const static struct NyLPC_TiHttpPtrStream_TInterface _interface=
00085 {
00086         pread_func,
00087         write_func,
00088         pseek_func,
00089         flush_func,
00090         setReadEncoding_func,
00091         setWriteEncoding_func
00092 };
00093 
00094 /**
00095  * i_bufに5バイトのchunkedヘッダを書きます。
00096  */
00097 static void put_chunked_header(NyLPC_TUInt16 i_val,NyLPC_TUInt8* o_buf)
00098 {
00099     const static char* D="0123456789ABCDEF";
00100     *(o_buf+0)=D[((i_val&0x0f00)>>8)];
00101     *(o_buf+1)=D[((i_val&0x00f0)>>4)];
00102     *(o_buf+2)=D[ (i_val&0x000f)];
00103     *(o_buf+3)='\r';
00104     *(o_buf+4)='\n';
00105 }
00106 /**
00107  * 接続済のソケットをストリームに抽象化します。
00108  */
00109 NyLPC_TBool NyLPC_cHttpStream_initialize(NyLPC_TcHttpStream_t* i_inst,NyLPC_TiTcpSocket_t* i_ref_sock)
00110 {
00111     i_inst->super.absfunc=&_interface;
00112     i_inst->_ref_sock=i_ref_sock;
00113     i_inst->we_type=NyLPC_TiHttpPtrStream_ET_NONE;
00114     i_inst->re_type=NyLPC_TiHttpPtrStream_ET_NONE;
00115     i_inst->txb=NULL;
00116     return NyLPC_TBool_TRUE;
00117 }
00118 
00119 void NyLPC_cHttpStream_finalize(NyLPC_TcHttpStream_t* i_inst)
00120 {
00121     if(i_inst->txb!=NULL){
00122         NyLPC_iTcpSocket_releaseSendBuf(i_inst->_ref_sock,i_inst->txb);
00123     }
00124 }
00125 
00126 //
00127 //  インタフェイス
00128 //
00129 
00130 static NyLPC_TInt32 pread_func(void* i_inst,const void** o_buf_ptr,NyLPC_TUInt32 i_timeout)
00131 {
00132     NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst;
00133     return NyLPC_iTcpSocket_precv(inst->_ref_sock,o_buf_ptr,i_timeout);
00134 }
00135 
00136 static NyLPC_TBool write_func(void* i_inst,const void* i_data,NyLPC_TInt32 i_length)
00137 {
00138     NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst;
00139     NyLPC_TUInt16 s,free_size;
00140     NyLPC_TUInt32 l;
00141     const char* src=(const char*)i_data;
00142     l=((i_length<0)?strlen(src):i_length);
00143     while(l>0){
00144         //送信バッファがNULLなら、割り当て。
00145         if(inst->txb==NULL){
00146             inst->txb=(NyLPC_TUInt8*)NyLPC_iTcpSocket_allocSendBuf(inst->_ref_sock,HTTP_TX_BUF_HINT,&s,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT);
00147             if(inst->txb==NULL){
00148                 return NyLPC_TBool_FALSE;
00149             }
00150             //chunked encodingなら、先頭5バイト+末尾2バイトを予約する. 000
00151             if(inst->we_type==NyLPC_TiHttpPtrStream_ET_CHUNKED){
00152                 inst->tx_len=5;
00153                 inst->txb_size=s-7;
00154             }else{
00155                 inst->tx_len=0;
00156                 inst->txb_size=s;
00157             }
00158         }
00159         //書き込み可能サイズの計算
00160         free_size=inst->txb_size-inst->tx_len;
00161         if((NyLPC_TInt32)free_size>l){
00162             //書き込み可能サイズがi_length未満なら、バッファに貯めるだけ。
00163             memcpy(inst->txb+inst->tx_len,src,l);
00164             inst->tx_len+=(NyLPC_TUInt16)l;
00165             break;
00166         }
00167         //バッファフルになるなら、送信する。
00168         memcpy(inst->txb+inst->tx_len,src,free_size);
00169         inst->tx_len+=free_size;
00170         //書き込み
00171         if(!flush_func(i_inst)){
00172             //書込みエラー・・・
00173             return NyLPC_TBool_FALSE;
00174         }
00175         //読み出し位置の調整
00176         l-=free_size;
00177         src+=free_size;
00178     };
00179     return NyLPC_TBool_TRUE;
00180 }
00181 
00182 
00183 static void pseek_func(void* i_inst,NyLPC_TUInt16 i_seek)
00184 {
00185     NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst;
00186 
00187     NyLPC_iTcpSocket_pseek(inst->_ref_sock,i_seek);
00188 }
00189 
00190 /**
00191  * キャッシュに保持してるデータを出力する。
00192  */
00193 static NyLPC_TBool flush_func(void* i_inst)
00194 {
00195     NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst;
00196     if(inst->txb==NULL){
00197         return NyLPC_TBool_TRUE;
00198     }
00199     //chunkedの場合は、header/footerをセットする。
00200     if(inst->we_type==NyLPC_TiHttpPtrStream_ET_CHUNKED){
00201         //5バイト分のヘッダを記述。
00202         put_chunked_header(inst->tx_len-5,inst->txb);
00203         *(inst->txb+inst->tx_len)=0x0d;
00204         *(inst->txb+inst->tx_len+1)=0x0a;
00205         inst->tx_len+=2;
00206     }
00207     //送信する。
00208     if(!NyLPC_iTcpSocket_psend(inst->_ref_sock,inst->txb,inst->tx_len,NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT)){
00209         //失敗。
00210         NyLPC_iTcpSocket_releaseSendBuf(inst->_ref_sock,inst->txb);
00211         inst->txb=NULL;
00212         return NyLPC_TBool_FALSE;
00213     }
00214     //キャッシュを開放
00215     inst->txb=NULL;
00216     return NyLPC_TBool_TRUE;
00217 }
00218 static void setReadEncoding_func(void* i_inst,NyLPC_TiHttpPtrStream_ET i_et)
00219 {
00220     //未実装。(この関数は不要?)
00221     NyLPC_Abort();
00222     return;
00223 }
00224 static void setWriteEncoding_func(void* i_inst,NyLPC_TiHttpPtrStream_ET i_et)
00225 {
00226     NyLPC_TcHttpStream_t* inst=(NyLPC_TcHttpStream_t*)i_inst;
00227     if(inst->we_type==i_et)
00228     {
00229         return;
00230     }
00231     //バッファがあるならフラッシュしてしまう。
00232     if(inst->txb!=NULL){
00233         if(!flush_func(i_inst)){
00234             return;
00235         }
00236     }
00237     //モードの切り替え。
00238     inst->we_type=i_et;
00239 }