io_memory.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id: crypttoken.h 1113 2007-01-10 09:14:16Z martin $
00005     begin       : Wed Mar 16 2005
00006     copyright   : (C) 2005 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *          Please see toplevel file COPYING for license details           *
00011  ***************************************************************************/
00012 
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016 
00017 
00018 #include "io_memory_p.h"
00019 #include <gwenhywfar/iolayer_be.h>
00020 #include <gwenhywfar/iorequest_be.h>
00021 
00022 #include "i18n_l.h"
00023 #include <gwenhywfar/misc.h>
00024 #include <gwenhywfar/debug.h>
00025 #include <gwenhywfar/gui.h>
00026 
00027 #include <assert.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <unistd.h>
00031 #include <fcntl.h>
00032 
00033 
00034 
00035 
00036 GWEN_INHERIT(GWEN_IO_LAYER, GWEN_IO_LAYER_MEMORY)
00037 
00038 
00039 
00040 GWEN_IO_LAYER *GWEN_Io_LayerMemory_new(GWEN_BUFFER *buffer) {
00041   GWEN_IO_LAYER *io;
00042   GWEN_IO_LAYER_MEMORY *xio;
00043 
00044   io=GWEN_Io_Layer_new(GWEN_IO_LAYER_MEMORY_TYPE, NULL);
00045   assert(io);
00046   GWEN_NEW_OBJECT(GWEN_IO_LAYER_MEMORY, xio);
00047   assert(xio);
00048   GWEN_INHERIT_SETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_MEMORY, io, xio, GWEN_Io_LayerMemory_freeData);
00049 
00050   GWEN_Io_Layer_SetWorkOnRequestsFn(io, GWEN_Io_LayerMemory_WorkOnRequests);
00051   GWEN_Io_Layer_SetAddRequestFn(io, GWEN_Io_LayerMemory_AddRequest);
00052   GWEN_Io_Layer_SetDelRequestFn(io, GWEN_Io_LayerMemory_DelRequest);
00053   GWEN_Io_Layer_SetHasWaitingRequestsFn(io, GWEN_Io_LayerMemory_HasWaitingRequests);
00054 
00055   xio->buffer=buffer;
00056 
00057   GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00058 
00059   return io;
00060 }
00061 
00062 
00063 
00064 GWEN_IO_LAYER *GWEN_Io_LayerMemory_fromString(const uint8_t *p, int size) {
00065   GWEN_BUFFER *buf;
00066   GWEN_IO_LAYER *io;
00067 
00068   if (size==-1)
00069     size=strlen((const char*)p);
00070   buf=GWEN_Buffer_new(0, size, 0, 1);
00071   GWEN_Buffer_AppendBytes(buf, (const char*)p, size);
00072   GWEN_Buffer_Rewind(buf);
00073   io=GWEN_Io_LayerMemory_new(buf);
00074   assert(io);
00075   GWEN_Io_Layer_AddFlags(io, GWEN_IO_LAYER_FLAGS_TAKEOVER);
00076 
00077   return io;
00078 }
00079 
00080 
00081 
00082 GWENHYWFAR_CB
00083 void GWEN_Io_LayerMemory_freeData(void *bp, void *p) {
00084   GWEN_IO_LAYER *io;
00085   GWEN_IO_LAYER_MEMORY *xio;
00086 
00087   io=(GWEN_IO_LAYER*) bp;
00088   assert(io);
00089   xio=(GWEN_IO_LAYER_MEMORY*) p;
00090   assert(xio);
00091 
00092   if (GWEN_Io_Layer_GetFlags(io) & GWEN_IO_LAYER_FLAGS_TAKEOVER) {
00093     GWEN_Buffer_free(xio->buffer);
00094     xio->buffer=(GWEN_BUFFER*)-1;
00095   }
00096 
00097   GWEN_FREE_OBJECT(xio);
00098 }
00099 
00100 
00101 
00102 GWEN_BUFFER *GWEN_Io_LayerMemory_GetBuffer(const GWEN_IO_LAYER *io) {
00103   GWEN_IO_LAYER_MEMORY *xio;
00104 
00105   assert(io);
00106   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_MEMORY, io);
00107   assert(xio);
00108 
00109   return xio->buffer;
00110 }
00111 
00112 
00113 
00114 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerMemory_WorkOnRequests(GWEN_IO_LAYER *io) {
00115   GWEN_IO_LAYER_MEMORY *xio;
00116 
00117   assert(io);
00118   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_MEMORY, io);
00119   assert(xio);
00120 
00121   return GWEN_Io_Layer_WorkResultBlocking;
00122 }
00123 
00124 
00125 
00126 int GWEN_Io_LayerMemory_AddRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00127   GWEN_IO_LAYER_MEMORY *xio;
00128   GWEN_IO_LAYER_STATUS st;
00129 
00130   assert(io);
00131   xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_MEMORY, io);
00132   assert(xio);
00133 
00134   st=GWEN_Io_Layer_GetStatus(io);
00135 
00136   switch(GWEN_Io_Request_GetType(r)) {
00137   case GWEN_Io_Request_TypeRead:
00138     /* check status */
00139     if (st!=GWEN_Io_Layer_StatusConnected) {
00140       DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00141       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00142       return GWEN_ERROR_NOT_OPEN;
00143     }
00144     else {
00145       uint32_t bytes;
00146       uint32_t bytesLeft;
00147       uint32_t bpos;
00148       const uint8_t *src;
00149       uint8_t *dst;
00150 
00151       bpos=GWEN_Io_Request_GetBufferPos(r);
00152       dst=GWEN_Io_Request_GetBufferPtr(r);
00153       dst+=bpos;
00154       src=(const uint8_t*)GWEN_Buffer_GetPosPointer(xio->buffer);
00155       bytes=GWEN_Io_Request_GetBufferSize(r)-bpos;
00156       bytesLeft=GWEN_Buffer_GetBytesLeft(xio->buffer);
00157       if (bytesLeft==0) {
00158         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_EOF);
00159         return GWEN_ERROR_EOF;
00160       }
00161       if (bytes>bytesLeft)
00162         bytes=bytesLeft;
00163 
00164       if (bytes) {
00165         memmove(dst, src, bytes);
00166         GWEN_Buffer_IncrementPos(xio->buffer, bytes);
00167         bpos+=bytes;
00168         GWEN_Io_Request_SetBufferPos(r, bpos);
00169       }
00170 
00171       if ((bpos>=GWEN_Io_Request_GetBufferSize(r)) ||
00172           !(GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_READALL)) {
00173         /* return bytes we have so far */
00174         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00175         return 0;
00176       }
00177     }
00178     break;
00179 
00180   case GWEN_Io_Request_TypeWrite:
00181     /* check status */
00182     if (st!=GWEN_Io_Layer_StatusConnected) {
00183       DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00184       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00185       return GWEN_ERROR_NOT_OPEN;
00186     }
00187     else {
00188       int rv=0;
00189       uint32_t bytes;
00190 
00191       bytes=GWEN_Io_Request_GetBufferSize(r);
00192       if (bytes)
00193         rv=GWEN_Buffer_AppendBytes(xio->buffer, (const char*)GWEN_Io_Request_GetBufferPtr(r), bytes);
00194       if (rv) {
00195         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00196         GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00197         return rv;
00198       }
00199       GWEN_Io_Request_SetBufferPos(r, bytes);
00200       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00201       return 0;
00202     }
00203     break;
00204 
00205   case GWEN_Io_Request_TypeDisconnect:
00206     /* check status */
00207     if (st!=GWEN_Io_Layer_StatusConnected) {
00208       DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00209       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00210       return GWEN_ERROR_NOT_OPEN;
00211     }
00212     else {
00213       /* closed */
00214       GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00215       GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00216     }
00217     break;
00218 
00219   default:
00220     DBG_INFO(GWEN_LOGDOMAIN, "This request type is not supported (%d)", GWEN_Io_Request_GetType(r));
00221     GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_SUPPORTED);
00222     return GWEN_ERROR_NOT_SUPPORTED;
00223   }
00224 
00225   return 0;
00226 }
00227 
00228 
00229 
00230 int GWEN_Io_LayerMemory_DelRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00231   return GWEN_ERROR_INVALID;
00232 }
00233 
00234 
00235 
00236 int GWEN_Io_LayerMemory_HasWaitingRequests(GWEN_IO_LAYER *io) {
00237   return 0;
00238 }
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 

Generated on Wed Jul 9 13:12:28 2008 for gwenhywfar by  doxygen 1.5.6