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