00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef GWEN_FASTBUFFER_H
00015 #define GWEN_FASTBUFFER_H
00016
00017
00018 #include <gwenhywfar/iolayer.h>
00019 #include <gwenhywfar/buffer.h>
00020
00021
00022 #define GWEN_FAST_BUFFER_FLAGS_DOSMODE 0x00000001
00023
00024
00032 typedef struct {
00033 GWEN_IO_LAYER *io;
00034 uint32_t bufferSize;
00035 uint32_t bufferReadPos;
00036 uint32_t bufferWritePos;
00037 uint32_t guiid;
00038 int msecs;
00039 uint32_t flags;
00040 uint32_t bytesWritten;
00041 uint32_t bytesRead;
00042 uint8_t buffer[1];
00043 } GWEN_FAST_BUFFER;
00044
00045
00046
00047 #ifdef __cplusplus
00048 extern "C" {
00049 #endif
00050
00051
00052 GWENHYWFAR_API GWEN_FAST_BUFFER *GWEN_FastBuffer_new(uint32_t bsize,
00053 GWEN_IO_LAYER *io,
00054 uint32_t guiid,
00055 int msecs);
00056
00057 GWENHYWFAR_API void GWEN_FastBuffer_free(GWEN_FAST_BUFFER *fb);
00058
00059
00060 GWENHYWFAR_API uint32_t GWEN_FastBuffer_GetFlags(const GWEN_FAST_BUFFER *fb);
00061 GWENHYWFAR_API void GWEN_FastBuffer_SetFlags(GWEN_FAST_BUFFER *fb, uint32_t fl);
00062 GWENHYWFAR_API void GWEN_FastBuffer_AddFlags(GWEN_FAST_BUFFER *fb, uint32_t fl);
00063 GWENHYWFAR_API void GWEN_FastBuffer_SubFlags(GWEN_FAST_BUFFER *fb, uint32_t fl);
00064
00065 GWENHYWFAR_API uint32_t GWEN_FastBuffer_GetBytesWritten(const GWEN_FAST_BUFFER *fb);
00066 GWENHYWFAR_API uint32_t GWEN_FastBuffer_GetBytesRead(const GWEN_FAST_BUFFER *fb);
00067
00068 GWENHYWFAR_API int GWEN_FastBuffer_ReadLine(GWEN_FAST_BUFFER *fb, uint8_t *p, int len);
00069 GWENHYWFAR_API int GWEN_FastBuffer_ReadLineToBuffer(GWEN_FAST_BUFFER *fb, GWEN_BUFFER *buf);
00070
00071
00072 #ifdef __cplusplus
00073 }
00074 #endif
00075
00076
00082 #define GWEN_FASTBUFFER_PEEKBYTE(fb, var) {\
00083 if (fb->bufferReadPos>=fb->bufferWritePos) { \
00084 int fb_peekbyte_rv; \
00085 \
00086 fb_peekbyte_rv=GWEN_Io_Layer_ReadBytes(fb->io, fb->buffer, fb->bufferSize, 0, \
00087 fb->guiid, fb->msecs); \
00088 if (fb_peekbyte_rv<0) { \
00089 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", fb_peekbyte_rv); \
00090 var=fb_peekbyte_rv; \
00091 } \
00092 else { \
00093 fb->bufferWritePos=fb_peekbyte_rv; \
00094 fb->bufferReadPos=0; \
00095 var=((int)((fb->buffer[fb->bufferReadPos])) & 0xff); \
00096 } \
00097 } \
00098 else { \
00099 var=((int)((fb->buffer[fb->bufferReadPos])) & 0xff); \
00100 } \
00101 }
00102
00103
00108 #define GWEN_FASTBUFFER_READBYTE(fb, var) {\
00109 if (fb->bufferReadPos>=fb->bufferWritePos) { \
00110 int fb_readbyte_rv; \
00111 \
00112 fb_readbyte_rv=GWEN_Io_Layer_ReadBytes(fb->io, fb->buffer, fb->bufferSize, 0,\
00113 fb->guiid, fb->msecs); \
00114 if (fb_readbyte_rv<0) { \
00115 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", fb_readbyte_rv); \
00116 var=fb_readbyte_rv; \
00117 } \
00118 else { \
00119 fb->bufferWritePos=fb_readbyte_rv; \
00120 fb->bufferReadPos=0; \
00121 var=((int)((fb->buffer[fb->bufferReadPos++])) & 0xff); \
00122 fb->bytesRead++; \
00123 } \
00124 } \
00125 else { \
00126 var=((int)((fb->buffer[fb->bufferReadPos++])) & 0xff); \
00127 fb->bytesRead++; \
00128 } \
00129 }
00130
00131
00136 #define GWEN_FASTBUFFER_WRITEBYTE(fb, var, chr) {\
00137 if (fb->bufferWritePos>=fb->bufferSize) { \
00138 int fb_writeByte_rv; \
00139 \
00140 fb_writeByte_rv=GWEN_Io_Layer_WriteBytes(fb->io, fb->buffer, fb->bufferWritePos, \
00141 GWEN_IO_REQUEST_FLAGS_WRITEALL, \
00142 fb->guiid, fb->msecs); \
00143 if (fb_writeByte_rv<(int)(fb->bufferWritePos)) { \
00144 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", fb_writeByte_rv); \
00145 var=fb_writeByte_rv; \
00146 } \
00147 else { \
00148 var=0; \
00149 fb->bufferWritePos=0; \
00150 fb->buffer[fb->bufferWritePos++]=chr; \
00151 fb->bytesWritten++; \
00152 } \
00153 } \
00154 else { \
00155 var=0; \
00156 fb->buffer[fb->bufferWritePos++]=chr; \
00157 fb->bytesWritten++; \
00158 } \
00159 }
00160
00161
00166 #define GWEN_FASTBUFFER_FLUSH(fb, var) {\
00167 int fb_flush_rv; \
00168 \
00169 fb_flush_rv=GWEN_Io_Layer_WriteBytes(fb->io, fb->buffer, fb->bufferWritePos, \
00170 GWEN_IO_REQUEST_FLAGS_WRITEALL | GWEN_IO_REQUEST_FLAGS_FLUSH, \
00171 fb->guiid, fb->msecs); \
00172 if (fb_flush_rv<(int)(fb->bufferWritePos)) { \
00173 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", fb_flush_rv); \
00174 var=fb_flush_rv; \
00175 } \
00176 else { \
00177 var=0; \
00178 fb->bufferWritePos=0; \
00179 } \
00180 }
00181
00182
00190 #define GWEN_FASTBUFFER_READBYTES(fb, var, p, len) { \
00191 int fb_readbyte_bytes;\
00192 \
00193 var=0; \
00194 if (fb->bufferReadPos>=fb->bufferWritePos) { \
00195 int fb_readbyte_rv; \
00196 \
00197 fb_readbyte_rv=GWEN_Io_Layer_ReadBytes(fb->io, fb->buffer, fb->bufferSize, 0, fb->guiid, fb->msecs); \
00198 if (fb_readbyte_rv<0) { \
00199 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", fb_readbyte_rv); \
00200 var=fb_readbyte_rv; \
00201 } \
00202 else {\
00203 fb->bufferWritePos=fb_readbyte_rv; \
00204 fb->bufferReadPos=0; \
00205 }\
00206 }\
00207 if (var==0) {\
00208 fb_readbyte_bytes=fb->bufferWritePos-fb->bufferReadPos;\
00209 if (fb_readbyte_bytes>len)\
00210 fb_readbyte_bytes=len;\
00211 if (fb_readbyte_bytes) {\
00212 memmove(p, fb->buffer+fb->bufferReadPos, fb_readbyte_bytes);\
00213 fb->bufferReadPos+=fb_readbyte_bytes;\
00214 fb->bytesRead+=fb_readbyte_bytes; \
00215 }\
00216 var=fb_readbyte_bytes;\
00217 }\
00218 }
00219
00220
00221
00222 #define GWEN_FASTBUFFER_READLINE(fb, var, p, len) {\
00223 int fb_readline_bytes;\
00224 \
00225 var=0;\
00226 if (fb->bufferReadPos>=fb->bufferWritePos) {\
00227 int fb_readline_rv;\
00228 \
00229 fb_readline_rv=GWEN_Io_Layer_ReadBytes(fb->io, fb->buffer, fb->bufferSize, 0,\
00230 fb->guiid, fb->msecs);\
00231 if (fb_readline_rv<0) {\
00232 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", fb_readline_rv);\
00233 var=fb_readline_rv;\
00234 }\
00235 else {\
00236 fb->bufferWritePos=fb_rv; \
00237 fb->bufferReadPos=0; \
00238 }\
00239 }\
00240 if (var==0) {\
00241 fb_readline_bytes=fb->bufferWritePos-fb->bufferReadPos;\
00242 if (fb_readline_bytes>len)\
00243 fb_readline_bytes=len;\
00244 if (fb_readline_bytes) {\
00245 uint8_t *fb_readline_p;\
00246 \
00247 fb_readline_p=(uint8_t*)p;\
00248 \
00249 while(fb_readline_bytes) {\
00250 uint8_t c;\
00251 \
00252 c=fb->buffer[fb->bufferReadPos++];\
00253 fb->bytesRead++; \
00254 fb_readline_bytes--;\
00255 if (c==10) {\
00256 *(fb_readline_p++)=c;\
00257 var++;\
00258 break;\
00259 }\
00260 else if (c!=13) {\
00261 *(fb_readline_p++)=c;\
00262 var++;\
00263 }\
00264 }\
00265 }\
00266 }\
00267 }
00268
00269
00270
00271 #define GWEN_FASTBUFFER_READLINEFORCED(fb, var, p, len) {\
00272 int fb_readlineforced_len;\
00273 uint8_t *fb_readlineforced_p;\
00274 \
00275 fb_readlineforced_len=len;\
00276 fb_readlineforced_p=(uint8_t*)p;\
00277 var=0;\
00278 while(fb_readlineforced_len && var==0) {\
00279 int fb_readlineforced_rv;\
00280 \
00281 GWEN_FASTBUFFER_READLINE(fb, fb_readlineforced_rv, fb_readlineforced_p, fb_readlineforced_len);\
00282 if (fb_readlineforced_rv<0) {\
00283 var=fb_readlineforced_rv;\
00284 break;\
00285 }\
00286 else if (fb_readlineforced_rv==0) {\
00287 var=GWEN_ERROR_EOF;\
00288 break;\
00289 }\
00290 else {\
00291 if (fb_readlineforced_p[fb_readlineforced_rv-1]==10) {\
00292 fb_readlineforced_p[fb_readlineforced_rv-1]=0;\
00293 var=fb_readlineforced_rv;\
00294 break;\
00295 }\
00296 fb_readlineforced_len-=fb_readlineforced_rv;\
00297 fb_readlineforced_p+=fb_readlineforced_rv;\
00298 }\
00299 }\
00300 if (var==0) {\
00301 DBG_INFO(GWEN_LOGDOMAIN, "No line within %d bytes", len);\
00302 var=GWEN_ERROR_BAD_SIZE;\
00303 }\
00304 }
00305
00306
00307
00308 #define GWEN_FASTBUFFER_READFORCED(fb, var, p, len) {\
00309 int fb_readforced_len;\
00310 uint8_t *fb_readforced_p;\
00311 \
00312 fb_readforced_len=len;\
00313 fb_readforced_p=(uint8_t*)p;\
00314 var=0;\
00315 while(fb_readforced_len && var==0) {\
00316 int fb_readforced_rv;\
00317 \
00318 GWEN_FASTBUFFER_READBYTES(fb, fb_readforced_rv, fb_readforced_p, fb_readforced_len);\
00319 if (fb_readforced_rv<0) {\
00320 var=fb_readforced_rv;\
00321 break;\
00322 }\
00323 else if (fb_readforced_rv==0) {\
00324 var=GWEN_ERROR_EOF;\
00325 break;\
00326 }\
00327 else {\
00328 fb_readforced_len-=fb_readforced_rv;\
00329 fb_readforced_p+=fb_readforced_rv;\
00330 }\
00331 }\
00332 }
00333
00334
00335
00343 #define GWEN_FASTBUFFER_WRITEBYTES(fb, var, p, len) {\
00344 int fb_writebytes_bytes;\
00345 int fb_writebytes_len;\
00346 \
00347 fb_writebytes_len=len;\
00348 if (fb_writebytes_len==-1)\
00349 fb_writebytes_len=strlen((const char*)p);\
00350 var=0; \
00351 if (fb->bufferWritePos>=fb->bufferSize) { \
00352 int fb_writebytes_rv; \
00353 \
00354 fb_writebytes_rv=GWEN_Io_Layer_WriteBytes(fb->io, fb->buffer, fb->bufferWritePos, \
00355 GWEN_IO_REQUEST_FLAGS_WRITEALL, \
00356 fb->guiid, fb->msecs); \
00357 if (fb_writebytes_rv<(int)(fb->bufferWritePos)) { \
00358 DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d)", fb_writebytes_rv); \
00359 var=fb_writebytes_rv; \
00360 } \
00361 else {\
00362 fb->bufferWritePos=0; \
00363 }\
00364 }\
00365 if (var==0) {\
00366 fb_writebytes_bytes=fb->bufferSize-fb->bufferWritePos;\
00367 if (fb_writebytes_bytes>fb_writebytes_len)\
00368 fb_writebytes_bytes=fb_writebytes_len;\
00369 if (fb_writebytes_bytes) {\
00370 memmove(fb->buffer+fb->bufferWritePos, p, fb_writebytes_bytes);\
00371 fb->bufferWritePos+=fb_writebytes_bytes;\
00372 fb->bytesWritten+=fb_writebytes_bytes; \
00373 }\
00374 var=fb_writebytes_bytes;\
00375 }\
00376 }
00377
00378
00386 #define GWEN_FASTBUFFER_WRITEFORCED(fb, var, p, len) {\
00387 int fb_writeforced_len;\
00388 const uint8_t *fb_writeforced_p;\
00389 \
00390 fb_writeforced_len=len;\
00391 if (fb_writeforced_len==-1) \
00392 fb_writeforced_len=strlen((const char*)p);\
00393 fb_writeforced_p=(const uint8_t*)p;\
00394 var=0;\
00395 while(fb_writeforced_len && var==0) {\
00396 int fb_writeforced_rv;\
00397 \
00398 GWEN_FASTBUFFER_WRITEBYTES(fb, fb_writeforced_rv, fb_writeforced_p, fb_writeforced_len);\
00399 if (fb_writeforced_rv<0) {\
00400 var=fb_writeforced_rv;\
00401 break;\
00402 }\
00403 else if (fb_writeforced_rv==0) {\
00404 var=GWEN_ERROR_EOF;\
00405 break;\
00406 }\
00407 else {\
00408 fb_writeforced_len-=fb_writeforced_rv;\
00409 fb_writeforced_p+=fb_writeforced_rv;\
00410 }\
00411 }\
00412 }
00413
00414
00415
00416 #define GWEN_FASTBUFFER_WRITELINE(fb, var, p) {\
00417 int fb_writeline_rv;\
00418 int fb_writeline_len=strlen((const char*)p);\
00419 \
00420 GWEN_FASTBUFFER_WRITEFORCED(fb, fb_writeline_rv, p, fb_writeline_len);\
00421 if (fb_writeline_rv<0)\
00422 var=fb_writeline_rv;\
00423 else {\
00424 if (fb->flags & GWEN_FAST_BUFFER_FLAGS_DOSMODE) {\
00425 GWEN_FASTBUFFER_WRITEFORCED(fb, fb_writeline_rv, "\r\n", 2);\
00426 }\
00427 else {\
00428 GWEN_FASTBUFFER_WRITEFORCED(fb, fb_writeline_rv, "\n", 1);\
00429 }\
00430 if (fb_writeline_rv<0)\
00431 var=fb_writeline_rv;\
00432 else\
00433 var=0;\
00434 }\
00435 }
00436
00437
00438
00446 #define GWEN_FASTBUFFER_COPYBYTES(fb1, fb2, var, len) { \
00447 int fb_copybytes_bytes;\
00448 \
00449 var=0; \
00450 if (fb1->bufferReadPos>=fb1->bufferWritePos) { \
00451 int fb_copybytes_rv; \
00452 \
00453 fb_copybytes_rv=GWEN_Io_Layer_ReadBytes(fb1->io, fb1->buffer, fb1->bufferSize, 0, \
00454 fb1->guiid, fb1->msecs); \
00455 if (fb_copybytes_rv<0) { \
00456 DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d)", fb_copybytes_rv); \
00457 var=fb_copybytes_rv; \
00458 } \
00459 else {\
00460 fb1->bufferWritePos=fb_copybytes_rv; \
00461 fb1->bufferReadPos=0; \
00462 }\
00463 }\
00464 if (var==0) {\
00465 fb_bytes=fb1->bufferWritePos-fb1->bufferReadPos;\
00466 if (fb_copybytes_bytes>len)\
00467 fb_copybytes_bytes=len;\
00468 if (fb_copybytes_bytes) {\
00469 int fb_copybytes_rv;\
00470 \
00471 GWEN_FASTBUFFER_WRITEBYTES(fb2, fb_copybytes_rv, (fb1->buffer+fb1->bufferReadPos), fb_bytes);\
00472 var=fb_copybytes_rv;\
00473 if (fb_copybytes_rv>0) {\
00474 fb1->bufferReadPos+=fb_copybytes_rv;\
00475 fb1->bytesRead+=fb_copybytes_rv; \
00476 }\
00477 }\
00478 }\
00479 }
00480
00481
00482
00491 #define GWEN_FASTBUFFER_COPYFORCED(fb1, fb2, var, p, len) {\
00492 int fb_copyforced_len;\
00493 uint8_t *fb_copyforced_p;\
00494 \
00495 fb_copyforced_len=len;\
00496 fb_copyforced_p=(uint8_t*)p;\
00497 var=0;\
00498 while(fb_copyforced_len && var==0) {\
00499 int fb_copyforced_rv;\
00500 \
00501 GWEN_FASTBUFFER_COPYBYTES(fb1, fb2, fb_copyforced_rv, fb_copyforced_p, fb_copyforced_len);\
00502 if (fb_copyforced_rv<0) {\
00503 var=fb_copyforced_rv;\
00504 break;\
00505 }\
00506 else if (fb_copyforced_rv==0)\
00507 var=GWEN_ERROR_EOF;\
00508 else {\
00509 fb_len-=fb_copyforced_rv;\
00510 fb_p+=fb_copyforced_rv;\
00511 }\
00512 }\
00513 }
00514
00515
00516
00517
00518 #endif
00519
00520
00521