syncio.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 #include "syncio_p.h"
00033 #include "syncio_file.h"
00034 #include "syncio_buffered.h"
00035 
00036 #include <gwenhywfar/misc.h>
00037 #include <gwenhywfar/debug.h>
00038 
00039 #include <assert.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 
00043 
00044 
00045 GWEN_INHERIT_FUNCTIONS(GWEN_SYNCIO)
00046 GWEN_LIST_FUNCTIONS(GWEN_SYNCIO, GWEN_SyncIo)
00047 
00048 
00049 
00050 
00051 GWEN_SYNCIO *GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo) {
00052   GWEN_SYNCIO *sio;
00053 
00054   assert(typeName);
00055   GWEN_NEW_OBJECT(GWEN_SYNCIO, sio);
00056   sio->refCount=1;
00057   GWEN_INHERIT_INIT(GWEN_SYNCIO, sio);
00058   GWEN_LIST_INIT(GWEN_SYNCIO, sio);
00059 
00060   sio->typeName=strdup(typeName);
00061   sio->baseIo=baseIo;
00062 
00063   return sio;
00064 }
00065 
00066 
00067 
00068 void GWEN_SyncIo_Attach(GWEN_SYNCIO *sio) {
00069   assert(sio);
00070   assert(sio->refCount);
00071   sio->refCount++;
00072 }
00073 
00074 
00075 
00076 void GWEN_SyncIo_free(GWEN_SYNCIO *sio) {
00077   if (sio) {
00078     assert(sio->refCount);
00079     if (sio->refCount==1) {
00080       GWEN_LIST_FINI(GWEN_SYNCIO, sio);
00081       GWEN_INHERIT_FINI(GWEN_SYNCIO, sio);
00082       GWEN_SyncIo_free(sio->baseIo);
00083       free(sio->typeName);
00084       sio->refCount=0;
00085       GWEN_FREE_OBJECT(sio);
00086     }
00087     else
00088       sio->refCount--;
00089   }
00090 }
00091 
00092 
00093 
00094 int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio) {
00095   assert(sio);
00096   assert(sio->refCount);
00097   if (sio->connectFn)
00098     return sio->connectFn(sio);
00099   else
00100     return 0;
00101 }
00102 
00103 
00104 
00105 int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio) {
00106   assert(sio);
00107   assert(sio->refCount);
00108   if (sio->disconnectFn)
00109     return sio->disconnectFn(sio);
00110   else
00111     return 0;
00112 }
00113 
00114 
00115 
00116 int GWEN_SyncIo_Flush(GWEN_SYNCIO *sio) {
00117   assert(sio);
00118   assert(sio->refCount);
00119   if (sio->flushFn)
00120     return sio->flushFn(sio);
00121   else
00122     return 0;
00123 }
00124 
00125 
00126 
00127 int GWEN_SyncIo_Read(GWEN_SYNCIO *sio,
00128                      uint8_t *buffer,
00129                      uint32_t size) {
00130   assert(sio);
00131   assert(sio->refCount);
00132   if (sio->readFn)
00133     return sio->readFn(sio, buffer, size);
00134   else
00135     return GWEN_ERROR_EOF;
00136 }
00137 
00138 
00139 
00140 int GWEN_SyncIo_Write(GWEN_SYNCIO *sio,
00141                       const uint8_t *buffer,
00142                       uint32_t size) {
00143   assert(sio);
00144   assert(sio->refCount);
00145   if (sio->writeFn)
00146     return sio->writeFn(sio, buffer, size);
00147   else
00148     return GWEN_ERROR_BROKEN_PIPE;
00149 }
00150 
00151 
00152 
00153 uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio) {
00154   assert(sio);
00155   assert(sio->refCount);
00156   return sio->flags;
00157 }
00158 
00159 
00160 
00161 void GWEN_SyncIo_SetFlags(GWEN_SYNCIO *sio, uint32_t fl) {
00162   assert(sio);
00163   assert(sio->refCount);
00164   sio->flags=fl;
00165 }
00166 
00167 
00168 
00169 void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl) {
00170   assert(sio);
00171   assert(sio->refCount);
00172   sio->flags|=fl;
00173 }
00174 
00175 
00176 
00177 void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl) {
00178   assert(sio);
00179   assert(sio->refCount);
00180   sio->flags&=~fl;
00181 }
00182 
00183 
00184 
00185 GWEN_SYNCIO_STATUS GWEN_SyncIo_GetStatus(const GWEN_SYNCIO *sio) {
00186   assert(sio);
00187   assert(sio->refCount);
00188   return sio->status;
00189 }
00190 
00191 
00192 
00193 void GWEN_SyncIo_SetStatus(GWEN_SYNCIO *sio, GWEN_SYNCIO_STATUS st) {
00194   assert(sio);
00195   assert(sio->refCount);
00196   sio->status=st;
00197 }
00198 
00199 
00200 
00201 const char *GWEN_SyncIo_GetTypeName(const GWEN_SYNCIO *sio) {
00202   assert(sio);
00203   assert(sio->refCount);
00204   return sio->typeName;
00205 }
00206 
00207 
00208 
00209 GWEN_SYNCIO *GWEN_SyncIo_GetBaseIo(const GWEN_SYNCIO *sio) {
00210   assert(sio);
00211   assert(sio->refCount);
00212   return sio->baseIo;
00213 }
00214 
00215 
00216 
00217 GWEN_SYNCIO *GWEN_SyncIo_GetBaseIoByTypeName(const GWEN_SYNCIO *sio, const char *typeName) {
00218   GWEN_SYNCIO *baseIo;
00219 
00220   assert(sio);
00221   assert(sio->refCount);
00222 
00223   baseIo=sio->baseIo;
00224   while(baseIo) {
00225     if (baseIo->typeName && strcasecmp(baseIo->typeName, typeName)==0)
00226       return baseIo;
00227     baseIo=baseIo->baseIo;
00228   }
00229 
00230   return NULL;
00231 }
00232 
00233 
00234 
00235 GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn) {
00236   GWEN_SYNCIO_CONNECT_FN of;
00237 
00238   assert(sio);
00239   assert(sio->refCount);
00240   of=sio->connectFn;
00241   sio->connectFn=fn;
00242   return of;
00243 }
00244 
00245 
00246 
00247 GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn) {
00248   GWEN_SYNCIO_DISCONNECT_FN of;
00249 
00250   assert(sio);
00251   assert(sio->refCount);
00252   of=sio->disconnectFn;
00253   sio->disconnectFn=fn;
00254   return of;
00255 }
00256 
00257 
00258 
00259 GWEN_SYNCIO_FLUSH_FN GWEN_SyncIo_SetFlushFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_FLUSH_FN fn) {
00260   GWEN_SYNCIO_FLUSH_FN of;
00261 
00262   assert(sio);
00263   assert(sio->refCount);
00264   of=sio->flushFn;
00265   sio->flushFn=fn;
00266   return of;
00267 }
00268 
00269 
00270 
00271 GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn) {
00272   GWEN_SYNCIO_READ_FN of;
00273 
00274   assert(sio);
00275   assert(sio->refCount);
00276   of=sio->readFn;
00277   sio->readFn=fn;
00278   return of;
00279 }
00280 
00281 
00282 
00283 GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn) {
00284   GWEN_SYNCIO_WRITE_FN of;
00285 
00286   assert(sio);
00287   assert(sio->refCount);
00288   of=sio->writeFn;
00289   sio->writeFn=fn;
00290   return of;
00291 }
00292 
00293 
00294 
00295 int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio,
00296                             const uint8_t *buffer,
00297                             uint32_t size) {
00298   if (size==0) {
00299     int rv;
00300 
00301     do {
00302       rv=GWEN_SyncIo_Write(sio, buffer, size);
00303     } while (rv==GWEN_ERROR_INTERRUPTED);
00304     if (rv<0) {
00305       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00306       return rv;
00307     }
00308     return 0;
00309   }
00310   else {
00311     uint32_t todo;
00312 
00313     todo=size;
00314     while(todo) {
00315       int rv;
00316 
00317       do {
00318         rv=GWEN_SyncIo_Write(sio, buffer, todo);
00319       } while (rv==GWEN_ERROR_INTERRUPTED);
00320 
00321       if (rv<0) {
00322         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00323         return rv;
00324       }
00325       todo-=rv;
00326       buffer+=rv;
00327     }
00328 
00329     return size;
00330   }
00331 }
00332 
00333 
00334 
00335 int GWEN_SyncIo_ReadForced(GWEN_SYNCIO *sio,
00336                            uint8_t *buffer,
00337                            uint32_t size) {
00338   uint32_t todo;
00339 
00340   todo=size;
00341   while(todo) {
00342     int rv;
00343 
00344     do {
00345       rv=GWEN_SyncIo_Read(sio, buffer, todo);
00346     } while (rv==GWEN_ERROR_INTERRUPTED);
00347 
00348     if (rv<0) {
00349       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00350       return rv;
00351     }
00352     else if (rv==0) {
00353       DBG_ERROR(GWEN_LOGDOMAIN, "EOF met");
00354       return GWEN_ERROR_EOF;
00355     }
00356     todo-=rv;
00357     buffer+=rv;
00358   }
00359 
00360   return size;
00361 }
00362 
00363 
00364 
00365 int GWEN_SyncIo_WriteString(GWEN_SYNCIO *sio, const char *s) {
00366   int rv;
00367 
00368   rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) s, s?strlen(s):0);
00369   if (rv<0) {
00370     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00371     return rv;
00372   }
00373 
00374   return 0;
00375 }
00376 
00377 
00378 
00379 int GWEN_SyncIo_WriteLine(GWEN_SYNCIO *sio, const char *s) {
00380   int rv;
00381 
00382   rv=GWEN_SyncIo_WriteString(sio, s);
00383   if (rv<0) {
00384     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00385     return rv;
00386   }
00387 
00388   if (GWEN_SyncIo_GetFlags(sio) & GWEN_SYNCIO_FLAGS_DOSMODE)
00389     rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) "\r\n", 2);
00390   else
00391     rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) "\n", 1);
00392   if (rv<0) {
00393     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00394     return rv;
00395   }
00396 
00397   return 0;
00398 }
00399 
00400 
00401 
00402 int GWEN_SyncIo_WriteChar(GWEN_SYNCIO *sio, char s) {
00403   return GWEN_SyncIo_WriteForced(sio, (const uint8_t*) &s, 1);
00404 }
00405 
00406 
00407 
00408 int GWEN_SyncIo_Helper_ReadFileToStringList(const char *fname,
00409                                             int maxLines,
00410                                             GWEN_STRINGLIST *sl) {
00411   GWEN_SYNCIO *sio;
00412   GWEN_SYNCIO *baseSio;
00413   int rv;
00414 
00415   /* open checksums from file */
00416   baseSio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
00417   GWEN_SyncIo_SetFlags(baseSio, GWEN_SYNCIO_FILE_FLAGS_READ);
00418   sio=GWEN_SyncIo_Buffered_new(baseSio);
00419 
00420   rv=GWEN_SyncIo_Connect(sio);
00421   if (rv<0) {
00422     DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fname?fname:"<no filename>");
00423     GWEN_SyncIo_free(sio);
00424     return rv;
00425   }
00426 
00427   /* read up to maxlines lines from file */
00428   rv=GWEN_SyncIo_Buffered_ReadLinesToStringList(sio, maxLines, sl);
00429   if (rv<0) {
00430     DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fname?fname:"<no filename>");
00431     GWEN_SyncIo_Disconnect(sio);
00432     GWEN_SyncIo_free(sio);
00433     return rv;
00434   }
00435 
00436   /* close file */
00437   GWEN_SyncIo_Disconnect(sio);
00438   GWEN_SyncIo_free(sio);
00439   return 0;
00440 }
00441 
00442 
00443