gwenhywfar  4.3.3
syncio_buffered.c
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  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or         *
00009  *   modify it under the terms of the GNU Lesser General Public            *
00010  *   License as published by the Free Software Foundation; either          *
00011  *   version 2.1 of the License, or (at your option) any later version.    *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00016  *   Lesser General Public License for more details.                       *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU Lesser General Public      *
00019  *   License along with this library; if not, write to the Free Software   *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
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   //GWEN_RingBuffer_Reset(xio->readBuffer);
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       /* still bytes in buffer, return them first */
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       /* bytes read */
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         /* fill buffer */
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       /* read data from ring buffer */
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       /* transparent mode, write directly to base io */
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   /* read a single line */
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   /* read every line of the file */
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