Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
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 16:22:57 by
