fastbuffer.h

Go to the documentation of this file.
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