gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 begin : Tue Apr 27 2010 00003 copyright : (C) 2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * Please see toplevel file COPYING for license details * 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