gwenhywfar  4.99.8beta
syncio.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Tue Apr 27 2010
3  copyright : (C) 2010 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #define DISABLE_DEBUGLOG
30 
31 
32 #include "syncio_p.h"
33 #include "syncio_file.h"
34 #include "syncio_buffered.h"
35 
36 #include <gwenhywfar/misc.h>
37 #include <gwenhywfar/debug.h>
38 
39 #include <assert.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 
44 
46 GWEN_LIST_FUNCTIONS(GWEN_SYNCIO, GWEN_SyncIo)
47 
48 
49 
50 
51 GWEN_SYNCIO *GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo) {
52  GWEN_SYNCIO *sio;
53 
54  assert(typeName);
55  GWEN_NEW_OBJECT(GWEN_SYNCIO, sio);
56  sio->refCount=1;
57  GWEN_INHERIT_INIT(GWEN_SYNCIO, sio);
58  GWEN_LIST_INIT(GWEN_SYNCIO, sio);
59 
60  sio->typeName=strdup(typeName);
61  sio->baseIo=baseIo;
62 
63  return sio;
64 }
65 
66 
67 
69  assert(sio);
70  assert(sio->refCount);
71  sio->refCount++;
72 }
73 
74 
75 
77  if (sio) {
78  assert(sio->refCount);
79  if (sio->refCount==1) {
82  GWEN_SyncIo_free(sio->baseIo);
83  free(sio->typeName);
84  sio->refCount=0;
85  GWEN_FREE_OBJECT(sio);
86  }
87  else
88  sio->refCount--;
89  }
90 }
91 
92 
93 
95  assert(sio);
96  assert(sio->refCount);
97  if (sio->connectFn)
98  return sio->connectFn(sio);
99  else
100  return 0;
101 }
102 
103 
104 
106  assert(sio);
107  assert(sio->refCount);
108  if (sio->disconnectFn)
109  return sio->disconnectFn(sio);
110  else
111  return 0;
112 }
113 
114 
115 
117  assert(sio);
118  assert(sio->refCount);
119  if (sio->flushFn)
120  return sio->flushFn(sio);
121  else
122  return 0;
123 }
124 
125 
126 
128  uint8_t *buffer,
129  uint32_t size) {
130  assert(sio);
131  assert(sio->refCount);
132  if (sio->readFn)
133  return sio->readFn(sio, buffer, size);
134  else
135  return GWEN_ERROR_EOF;
136 }
137 
138 
139 
141  const uint8_t *buffer,
142  uint32_t size) {
143  assert(sio);
144  assert(sio->refCount);
145  if (sio->writeFn)
146  return sio->writeFn(sio, buffer, size);
147  else
148  return GWEN_ERROR_BROKEN_PIPE;
149 }
150 
151 
152 
153 uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio) {
154  assert(sio);
155  assert(sio->refCount);
156  return sio->flags;
157 }
158 
159 
160 
161 void GWEN_SyncIo_SetFlags(GWEN_SYNCIO *sio, uint32_t fl) {
162  assert(sio);
163  assert(sio->refCount);
164  sio->flags=fl;
165 }
166 
167 
168 
169 void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl) {
170  assert(sio);
171  assert(sio->refCount);
172  sio->flags|=fl;
173 }
174 
175 
176 
177 void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl) {
178  assert(sio);
179  assert(sio->refCount);
180  sio->flags&=~fl;
181 }
182 
183 
184 
186  assert(sio);
187  assert(sio->refCount);
188  return sio->status;
189 }
190 
191 
192 
194  assert(sio);
195  assert(sio->refCount);
196  sio->status=st;
197 }
198 
199 
200 
201 const char *GWEN_SyncIo_GetTypeName(const GWEN_SYNCIO *sio) {
202  assert(sio);
203  assert(sio->refCount);
204  return sio->typeName;
205 }
206 
207 
208 
210  assert(sio);
211  assert(sio->refCount);
212  return sio->baseIo;
213 }
214 
215 
216 
217 GWEN_SYNCIO *GWEN_SyncIo_GetBaseIoByTypeName(const GWEN_SYNCIO *sio, const char *typeName) {
218  GWEN_SYNCIO *baseIo;
219 
220  assert(sio);
221  assert(sio->refCount);
222 
223  baseIo=sio->baseIo;
224  while(baseIo) {
225  if (baseIo->typeName && strcasecmp(baseIo->typeName, typeName)==0)
226  return baseIo;
227  baseIo=baseIo->baseIo;
228  }
229 
230  return NULL;
231 }
232 
233 
234 
237 
238  assert(sio);
239  assert(sio->refCount);
240  of=sio->connectFn;
241  sio->connectFn=fn;
242  return of;
243 }
244 
245 
246 
249 
250  assert(sio);
251  assert(sio->refCount);
252  of=sio->disconnectFn;
253  sio->disconnectFn=fn;
254  return of;
255 }
256 
257 
258 
261 
262  assert(sio);
263  assert(sio->refCount);
264  of=sio->flushFn;
265  sio->flushFn=fn;
266  return of;
267 }
268 
269 
270 
273 
274  assert(sio);
275  assert(sio->refCount);
276  of=sio->readFn;
277  sio->readFn=fn;
278  return of;
279 }
280 
281 
282 
285 
286  assert(sio);
287  assert(sio->refCount);
288  of=sio->writeFn;
289  sio->writeFn=fn;
290  return of;
291 }
292 
293 
294 
296  const uint8_t *buffer,
297  uint32_t size) {
298  if (size==0) {
299  int rv;
300 
301  do {
302  rv=GWEN_SyncIo_Write(sio, buffer, size);
303  }
304  while (rv==GWEN_ERROR_INTERRUPTED);
305  if (rv<0) {
306  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
307  return rv;
308  }
309  return 0;
310  }
311  else {
312  uint32_t todo;
313 
314  todo=size;
315  while(todo) {
316  int rv;
317 
318  do {
319  rv=GWEN_SyncIo_Write(sio, buffer, todo);
320  }
321  while (rv==GWEN_ERROR_INTERRUPTED);
322 
323  if (rv<0) {
324  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
325  return rv;
326  }
327  todo-=rv;
328  buffer+=rv;
329  }
330 
331  return size;
332  }
333 }
334 
335 
336 
338  uint8_t *buffer,
339  uint32_t size) {
340  uint32_t todo;
341 
342  todo=size;
343  while(todo) {
344  int rv;
345 
346  do {
347  rv=GWEN_SyncIo_Read(sio, buffer, todo);
348  }
349  while (rv==GWEN_ERROR_INTERRUPTED);
350 
351  if (rv<0) {
352  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
353  return rv;
354  }
355  else if (rv==0) {
356  DBG_ERROR(GWEN_LOGDOMAIN, "EOF met");
357  return GWEN_ERROR_EOF;
358  }
359  todo-=rv;
360  buffer+=rv;
361  }
362 
363  return size;
364 }
365 
366 
367 
368 int GWEN_SyncIo_WriteString(GWEN_SYNCIO *sio, const char *s) {
369  int rv;
370 
371  rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) s, s?strlen(s):0);
372  if (rv<0) {
373  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
374  return rv;
375  }
376 
377  return 0;
378 }
379 
380 
381 
382 int GWEN_SyncIo_WriteLine(GWEN_SYNCIO *sio, const char *s) {
383  int rv;
384 
385  rv=GWEN_SyncIo_WriteString(sio, s);
386  if (rv<0) {
387  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
388  return rv;
389  }
390 
392  rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) "\r\n", 2);
393  else
394  rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) "\n", 1);
395  if (rv<0) {
396  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
397  return rv;
398  }
399 
400  return 0;
401 }
402 
403 
404 
406  return GWEN_SyncIo_WriteForced(sio, (const uint8_t*) &s, 1);
407 }
408 
409 
410 
412  int maxLines,
413  GWEN_STRINGLIST *sl) {
414  GWEN_SYNCIO *sio;
415  GWEN_SYNCIO *baseSio;
416  int rv;
417 
418  /* open checksums from file */
421  sio=GWEN_SyncIo_Buffered_new(baseSio);
422 
423  rv=GWEN_SyncIo_Connect(sio);
424  if (rv<0) {
425  DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fname?fname:"<no filename>");
426  GWEN_SyncIo_free(sio);
427  return rv;
428  }
429 
430  /* read up to maxlines lines from file */
431  rv=GWEN_SyncIo_Buffered_ReadLinesToStringList(sio, maxLines, sl);
432  if (rv<0) {
433  DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fname?fname:"<no filename>");
435  GWEN_SyncIo_free(sio);
436  return rv;
437  }
438 
439  /* close file */
441  GWEN_SyncIo_free(sio);
442  return 0;
443 }
444 
445 
446 
447 
448 int GWEN_SyncIo_Helper_PartiallyReadFile(const char *fName, uint8_t *buffer, uint32_t size) {
449  GWEN_SYNCIO *sio;
450  uint32_t todo;
451  int rv;
452 
453  /* open file */
456 
457  rv=GWEN_SyncIo_Connect(sio);
458  if (rv<0) {
459  DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fName?fName:"<no filename>");
460  GWEN_SyncIo_free(sio);
461  return rv;
462  }
463 
464  /* read file */
465  todo=size;
466  while(todo) {
467  int rv;
468 
469  do {
470  rv=GWEN_SyncIo_Read(sio, buffer, todo);
471  }
472  while (rv==GWEN_ERROR_INTERRUPTED);
473 
474  if (rv<0) {
475  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
477  GWEN_SyncIo_free(sio);
478  return rv;
479  }
480  else if (rv==0) {
481  DBG_INFO(GWEN_LOGDOMAIN, "EOF met");
482  break;
483  }
484  todo-=rv;
485  buffer+=rv;
486  }
487 
488  /* close file */
490  GWEN_SyncIo_free(sio);
491 
492  return size-todo;
493 }
494 
495 
496 
497 int GWEN_SyncIo_Helper_ReadFile(const char *fName, GWEN_BUFFER *dbuf) {
498  GWEN_SYNCIO *sio;
499  int rv;
500  int bytesRead=0;
501  int64_t fileSize=0;
502 
503  /* open file */
506 
507  rv=GWEN_SyncIo_Connect(sio);
508  if (rv<0) {
509  DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fName?fName:"<no filename>");
510  GWEN_SyncIo_free(sio);
511  return rv;
512  }
513 
516  if (fileSize>GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf))
517  GWEN_Buffer_AllocRoom(dbuf, (uint32_t) fileSize);
518 
519  /* read file */
520  while(1) {
521  uint32_t l;
522  uint8_t *p;
523 
524  GWEN_Buffer_AllocRoom(dbuf, 4096);
526  p=(uint8_t*) GWEN_Buffer_GetPosPointer(dbuf);
527 
528  do {
529  rv=GWEN_SyncIo_Read(sio, p, l);
530  }
531  while (rv==GWEN_ERROR_INTERRUPTED);
532 
533  if (rv<0) {
534  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
536  GWEN_SyncIo_free(sio);
537  return rv;
538  }
539  else if (rv==0) {
540  DBG_INFO(GWEN_LOGDOMAIN, "EOF met");
541  break;
542  }
543  bytesRead+=rv;
544 
545  GWEN_Buffer_IncrementPos(dbuf, rv);
547  }
548 
549  /* close file */
551  GWEN_SyncIo_free(sio);
552 
553  return bytesRead;
554 }
555 
556 
557 
558 
int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.c:295
GWENHYWFAR_API int64_t GWEN_SyncIo_File_Seek(GWEN_SYNCIO *sio, int64_t pos, GWEN_SYNCIO_FILE_WHENCE whence)
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:94
int GWEN_SyncIo_Helper_PartiallyReadFile(const char *fName, uint8_t *buffer, uint32_t size)
Definition: syncio.c:448
void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:177
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:273
#define GWEN_INHERIT_FINI(t, element)
Definition: inherit.h:238
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
Definition: buffer.c:569
#define GWEN_SYNCIO_FILE_FLAGS_READ
Definition: syncio_file.h:53
int GWEN_SyncIo_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:127
GWENHYWFAR_CB int(* GWEN_SYNCIO_FLUSH_FN)(GWEN_SYNCIO *sio)
Definition: syncio.h:208
GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn)
Definition: syncio.c:283
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:92
#define NULL
Definition: binreloc.c:290
GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn)
Definition: syncio.c:235
int GWEN_SyncIo_Helper_ReadFile(const char *fName, GWEN_BUFFER *dbuf)
Definition: syncio.c:497
uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio)
Definition: syncio.c:153
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:513
int GWEN_SyncIo_Buffered_ReadLinesToStringList(GWEN_SYNCIO *sio, int maxLines, GWEN_STRINGLIST *sl)
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_SyncIo_SetStatus(GWEN_SYNCIO *sio, GWEN_SYNCIO_STATUS st)
Definition: syncio.c:193
#define GWEN_ERROR_BROKEN_PIPE
Definition: error.h:75
GWEN_SYNCIO * GWEN_SyncIo_GetBaseIo(const GWEN_SYNCIO *sio)
Definition: syncio.c:209
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:588
GWENHYWFAR_CB int(* GWEN_SYNCIO_READ_FN)(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.h:211
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:495
#define GWEN_ERROR_INTERRUPTED
Definition: error.h:74
GWENHYWFAR_CB int(* GWEN_SYNCIO_WRITE_FN)(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.h:217
int GWEN_SyncIo_WriteLine(GWEN_SYNCIO *sio, const char *s)
Definition: syncio.c:382
GWEN_SYNCIO_FLUSH_FN GWEN_SyncIo_SetFlushFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_FLUSH_FN fn)
Definition: syncio.c:259
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:86
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
GWEN_SYNCIO * GWEN_SyncIo_Buffered_new(GWEN_SYNCIO *baseIo)
int GWEN_SyncIo_Helper_ReadFileToStringList(const char *fname, int maxLines, GWEN_STRINGLIST *sl)
Definition: syncio.c:411
GWENHYWFAR_CB int(* GWEN_SYNCIO_CONNECT_FN)(GWEN_SYNCIO *sio)
Definition: syncio.h:206
int GWEN_SyncIo_ReadForced(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:337
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
GWEN_SYNCIO_STATUS GWEN_SyncIo_GetStatus(const GWEN_SYNCIO *sio)
Definition: syncio.c:185
#define GWEN_INHERIT_INIT(t, element)
Definition: inherit.h:223
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
GWEN_SYNCIO * GWEN_SyncIo_GetBaseIoByTypeName(const GWEN_SYNCIO *sio, const char *typeName)
Definition: syncio.c:217
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:76
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:169
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_EOF
Definition: error.h:96
GWENHYWFAR_CB int(* GWEN_SYNCIO_DISCONNECT_FN)(GWEN_SYNCIO *sio)
Definition: syncio.h:207
int GWEN_SyncIo_WriteString(GWEN_SYNCIO *sio, const char *s)
Definition: syncio.c:368
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:105
void GWEN_SyncIo_SetFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:161
GWEN_SYNCIO * GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo)
Definition: syncio.c:51
GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn)
Definition: syncio.c:247
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:164
#define GWEN_SYNCIO_FLAGS_DOSMODE
Definition: syncio.h:59
const char * GWEN_SyncIo_GetTypeName(const GWEN_SYNCIO *sio)
Definition: syncio.c:201
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
int GWEN_SyncIo_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.c:140
GWENHYWFAR_API GWEN_SYNCIO * GWEN_SyncIo_File_new(const char *path, GWEN_SYNCIO_FILE_CREATIONMODE cm)
GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn)
Definition: syncio.c:271
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
void GWEN_SyncIo_Attach(GWEN_SYNCIO *sio)
Definition: syncio.c:68
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
#define GWEN_INHERIT_FUNCTIONS(t)
Definition: inherit.h:163
int GWEN_SyncIo_Flush(GWEN_SYNCIO *sio)
Definition: syncio.c:116
GWEN_SYNCIO_STATUS
Definition: syncio.h:45
int GWEN_SyncIo_WriteChar(GWEN_SYNCIO *sio, char s)
Definition: syncio.c:405