This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
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 }
Generated on Tue Jul 12 2022 15:46:15 by 1.7.2