gwenhywfar
4.3.3
|
00001 /*************************************************************************** 00002 begin : Tue Apr 27 2010 00003 copyright : (C) 2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library 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 GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00021 * MA 02111-1307 USA * 00022 * * 00023 ***************************************************************************/ 00024 00025 #ifdef HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #define DISABLE_DEBUGLOG 00030 00031 00032 00033 #include "syncio_buffered_p.h" 00034 #include "i18n_l.h" 00035 00036 #include <gwenhywfar/misc.h> 00037 #include <gwenhywfar/debug.h> 00038 #include <gwenhywfar/gui.h> 00039 00040 #include <assert.h> 00041 #include <errno.h> 00042 #include <string.h> 00043 00044 00045 00046 GWEN_INHERIT(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED) 00047 00048 00049 00050 GWEN_SYNCIO *GWEN_SyncIo_Buffered_new(GWEN_SYNCIO *baseIo) { 00051 GWEN_SYNCIO *sio; 00052 GWEN_SYNCIO_BUFFERED *xio; 00053 00054 assert(baseIo); 00055 sio=GWEN_SyncIo_new(GWEN_SYNCIO_BUFFERED_TYPE, baseIo); 00056 GWEN_NEW_OBJECT(GWEN_SYNCIO_BUFFERED, xio); 00057 GWEN_INHERIT_SETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio, xio, GWEN_SyncIo_Buffered_FreeData); 00058 00059 GWEN_SyncIo_SetConnectFn(sio, GWEN_SyncIo_Buffered_Connect); 00060 GWEN_SyncIo_SetDisconnectFn(sio, GWEN_SyncIo_Buffered_Disconnect); 00061 GWEN_SyncIo_SetReadFn(sio, GWEN_SyncIo_Buffered_Read); 00062 GWEN_SyncIo_SetWriteFn(sio, GWEN_SyncIo_Buffered_Write); 00063 00064 xio->readBuffer=GWEN_RingBuffer_new(1024); 00065 00066 return sio; 00067 } 00068 00069 00070 00071 void GWENHYWFAR_CB GWEN_SyncIo_Buffered_FreeData(void *bp, void *p) { 00072 GWEN_SYNCIO_BUFFERED *xio; 00073 00074 xio=(GWEN_SYNCIO_BUFFERED*) p; 00075 GWEN_RingBuffer_free(xio->readBuffer); 00076 GWEN_FREE_OBJECT(xio); 00077 } 00078 00079 00080 00081 int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Connect(GWEN_SYNCIO *sio) { 00082 GWEN_SYNCIO *baseIo; 00083 00084 //GWEN_RingBuffer_Reset(xio->readBuffer); 00085 baseIo=GWEN_SyncIo_GetBaseIo(sio); 00086 if (baseIo) { 00087 int rv; 00088 00089 rv=GWEN_SyncIo_Connect(baseIo); 00090 if (rv<0) { 00091 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00092 return rv; 00093 } 00094 00095 return rv; 00096 } 00097 00098 return 0; 00099 } 00100 00101 00102 00103 int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Disconnect(GWEN_SYNCIO *sio) { 00104 GWEN_SYNCIO *baseIo; 00105 00106 baseIo=GWEN_SyncIo_GetBaseIo(sio); 00107 if (baseIo) { 00108 int rv; 00109 00110 rv=GWEN_SyncIo_Disconnect(baseIo); 00111 if (rv<0) { 00112 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00113 return rv; 00114 } 00115 00116 return rv; 00117 } 00118 00119 return 0; 00120 } 00121 00122 00123 00124 int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Read(GWEN_SYNCIO *sio, 00125 uint8_t *buffer, 00126 uint32_t size) { 00127 GWEN_SYNCIO_BUFFERED *xio; 00128 uint32_t flags; 00129 00130 assert(size); 00131 00132 assert(sio); 00133 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio); 00134 assert(xio); 00135 00136 if (xio->readBuffer==NULL) { 00137 DBG_ERROR(GWEN_LOGDOMAIN, "No buffer"); 00138 return GWEN_ERROR_INTERNAL; 00139 } 00140 00141 GWEN_SyncIo_SubFlags(sio, GWEN_SYNCIO_FLAGS_PACKET_END); 00142 flags=GWEN_SyncIo_GetFlags(sio); 00143 if (flags & GWEN_SYNCIO_FLAGS_TRANSPARENT) { 00144 uint32_t bytesInBuffer; 00145 00146 bytesInBuffer=GWEN_RingBuffer_GetUsedBytes(xio->readBuffer); 00147 if (bytesInBuffer) { 00148 int rv; 00149 uint32_t i; 00150 00151 /* still bytes in buffer, return them first */ 00152 if (size>bytesInBuffer) 00153 i=bytesInBuffer; 00154 else 00155 i=size; 00156 rv=GWEN_RingBuffer_ReadBytes(xio->readBuffer, (char*) buffer, &i); 00157 if (rv<0) { 00158 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00159 return rv; 00160 } 00161 /* bytes read */ 00162 return i; 00163 } 00164 else { 00165 GWEN_SYNCIO *baseIo; 00166 00167 baseIo=GWEN_SyncIo_GetBaseIo(sio); 00168 if (baseIo) { 00169 int rv; 00170 00171 rv=GWEN_SyncIo_Read(baseIo, buffer, size); 00172 if (rv<0) { 00173 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00174 return rv; 00175 } 00176 return rv; 00177 } 00178 else { 00179 DBG_INFO(GWEN_LOGDOMAIN, "No base layer"); 00180 return GWEN_ERROR_INTERNAL; 00181 } 00182 } 00183 } 00184 else { 00185 uint32_t bytesRead=0; 00186 00187 while(bytesRead==0) { 00188 uint32_t bytesInBuffer; 00189 const uint8_t *psrc; 00190 uint32_t bytesSkipped=0; 00191 00192 bytesInBuffer=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer); 00193 if (bytesInBuffer==0) { 00194 uint32_t bytesFree; 00195 GWEN_SYNCIO *baseIo; 00196 int rv; 00197 00198 /* fill buffer */ 00199 bytesFree=GWEN_RingBuffer_GetMaxUnsegmentedWrite(xio->readBuffer); 00200 if (bytesFree==0) { 00201 DBG_ERROR(GWEN_LOGDOMAIN, "No unsegmente read and write. TSNH!"); 00202 return GWEN_ERROR_INTERNAL; 00203 } 00204 00205 baseIo=GWEN_SyncIo_GetBaseIo(sio); 00206 assert(baseIo); 00207 00208 do { 00209 rv=GWEN_SyncIo_Read(baseIo, 00210 (uint8_t*) GWEN_RingBuffer_GetWritePointer(xio->readBuffer), 00211 bytesFree); 00212 } while (rv==GWEN_ERROR_INTERRUPTED); 00213 00214 if (rv<0) { 00215 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00216 return rv; 00217 } 00218 else if (rv==0) { 00219 DBG_INFO(GWEN_LOGDOMAIN, "EOF met (%d)", bytesRead); 00220 break; 00221 } 00222 GWEN_RingBuffer_SkipBytesWrite(xio->readBuffer, rv); 00223 bytesInBuffer=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer); 00224 if (bytesInBuffer==0) { 00225 DBG_ERROR(GWEN_LOGDOMAIN, "Still no bytes available?? TSNH!"); 00226 return GWEN_ERROR_INTERNAL; 00227 } 00228 } 00229 00230 /* read data from ring buffer */ 00231 psrc=(const uint8_t*)GWEN_RingBuffer_GetReadPointer(xio->readBuffer); 00232 while(bytesSkipped<bytesInBuffer && bytesRead<(size-1)) { 00233 uint8_t c; 00234 00235 c=*psrc; 00236 if (c!=13) { 00237 *(buffer++)=c; 00238 bytesRead++; 00239 } 00240 psrc++; 00241 bytesSkipped++; 00242 if (c==10) { 00243 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FLAGS_PACKET_END); 00244 break; 00245 } 00246 } 00247 GWEN_RingBuffer_SkipBytesRead(xio->readBuffer, bytesSkipped); 00248 } 00249 *buffer=0; 00250 00251 return bytesRead; 00252 } 00253 } 00254 00255 00256 00257 int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Write(GWEN_SYNCIO *sio, 00258 const uint8_t *buffer, 00259 uint32_t size) { 00260 GWEN_SYNCIO_BUFFERED *xio; 00261 GWEN_SYNCIO *baseIo; 00262 00263 assert(sio); 00264 xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio); 00265 assert(xio); 00266 00267 baseIo=GWEN_SyncIo_GetBaseIo(sio); 00268 if (baseIo) { 00269 uint32_t flags; 00270 00271 flags=GWEN_SyncIo_GetFlags(sio); 00272 if (flags & GWEN_SYNCIO_FLAGS_TRANSPARENT) { 00273 int rv; 00274 00275 /* transparent mode, write directly to base io */ 00276 do { 00277 rv=GWEN_SyncIo_Write(baseIo, buffer, size); 00278 } while (rv==GWEN_ERROR_INTERRUPTED); 00279 00280 if (rv<0) { 00281 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00282 return rv; 00283 } 00284 return rv; 00285 } 00286 else { 00287 int rv; 00288 00289 if (size) { 00290 rv=GWEN_SyncIo_WriteForced(baseIo, buffer, size); 00291 if (rv<0) { 00292 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00293 return rv; 00294 } 00295 } 00296 00297 if (flags & GWEN_SYNCIO_FLAGS_DOSMODE) { 00298 do { 00299 rv=GWEN_SyncIo_Write(baseIo, (const uint8_t*) "\r\n", 2); 00300 } while (rv==GWEN_ERROR_INTERRUPTED); 00301 } 00302 else { 00303 do { 00304 rv=GWEN_SyncIo_Write(baseIo, (const uint8_t*) "\n", 1); 00305 } while (rv==GWEN_ERROR_INTERRUPTED); 00306 } 00307 00308 if (rv<0) { 00309 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00310 return rv; 00311 } 00312 00313 return size; 00314 } 00315 } 00316 else { 00317 DBG_INFO(GWEN_LOGDOMAIN, "No base layer"); 00318 return GWEN_ERROR_INTERNAL; 00319 } 00320 } 00321 00322 00323 00324 int GWEN_SyncIo_Buffered_ReadLineToBuffer(GWEN_SYNCIO *sio, GWEN_BUFFER *tbuf) { 00325 int rv; 00326 00327 /* read a single line */ 00328 do { 00329 uint8_t *p; 00330 uint32_t l; 00331 00332 GWEN_Buffer_AllocRoom(tbuf, 1024); 00333 p=(uint8_t*) GWEN_Buffer_GetPosPointer(tbuf); 00334 l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf); 00335 rv=GWEN_SyncIo_Read(sio, p, l); 00336 if (rv<0) { 00337 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00338 return rv; 00339 } 00340 else if (rv>0) { 00341 GWEN_Buffer_IncrementPos(tbuf, rv); 00342 GWEN_Buffer_AdjustUsedBytes(tbuf); 00343 if (p[rv-1]==10) { 00344 p[rv-1]=0; 00345 break; 00346 } 00347 } 00348 else if (rv==0) 00349 break; 00350 } while(rv>0); 00351 00352 if (GWEN_Buffer_GetUsedBytes(tbuf)<1) { 00353 DBG_INFO(GWEN_LOGDOMAIN, "Nothing received: EOF met"); 00354 return GWEN_ERROR_EOF; 00355 } 00356 00357 return 0; 00358 } 00359 00360 00361 00362 int GWEN_SyncIo_Buffered_ReadLinesToStringList(GWEN_SYNCIO *sio, int maxLines, GWEN_STRINGLIST *sl) { 00363 GWEN_BUFFER *tbuf; 00364 int rv; 00365 int lineCount=0; 00366 00367 if (maxLines==0) { 00368 DBG_ERROR(GWEN_LOGDOMAIN, "Maxlines==0"); 00369 return GWEN_ERROR_INVALID; 00370 } 00371 00372 /* read every line of the file */ 00373 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 00374 while( (maxLines==-1) || (lineCount<maxLines) ) { 00375 rv=GWEN_SyncIo_Buffered_ReadLineToBuffer(sio, tbuf); 00376 if (rv<0) { 00377 if (rv==GWEN_ERROR_EOF) 00378 break; 00379 else { 00380 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00381 return rv; 00382 } 00383 } 00384 else { 00385 GWEN_StringList_AppendString(sl, GWEN_Buffer_GetStart(tbuf), 0, 0); 00386 lineCount++; 00387 } 00388 GWEN_Buffer_Reset(tbuf); 00389 } 00390 GWEN_Buffer_free(tbuf); 00391 00392 return 0; 00393 } 00394 00395 00396 00397 00398 00399