00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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
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
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
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
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
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