gwenhywfar  4.99.8beta
syncio_buffered.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 
33 #include "syncio_buffered_p.h"
34 #include "i18n_l.h"
35 
36 #include <gwenhywfar/misc.h>
37 #include <gwenhywfar/debug.h>
38 #include <gwenhywfar/gui.h>
39 
40 #include <assert.h>
41 #include <errno.h>
42 #include <string.h>
43 
44 
45 
46 GWEN_INHERIT(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED)
47 
48 
49 
51  GWEN_SYNCIO *sio;
52  GWEN_SYNCIO_BUFFERED *xio;
53 
54  assert(baseIo);
56  GWEN_NEW_OBJECT(GWEN_SYNCIO_BUFFERED, xio);
57  GWEN_INHERIT_SETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio, xio, GWEN_SyncIo_Buffered_FreeData);
58 
63 
64  xio->readBuffer=GWEN_RingBuffer_new(1024);
65 
66  return sio;
67 }
68 
69 
70 
72  GWEN_SYNCIO_BUFFERED *xio;
73 
74  xio=(GWEN_SYNCIO_BUFFERED*) p;
75  GWEN_RingBuffer_free(xio->readBuffer);
76  GWEN_FREE_OBJECT(xio);
77 }
78 
79 
80 
82  GWEN_SYNCIO *baseIo;
83 
84  //GWEN_RingBuffer_Reset(xio->readBuffer);
85  baseIo=GWEN_SyncIo_GetBaseIo(sio);
86  if (baseIo) {
87  int rv;
88 
89  rv=GWEN_SyncIo_Connect(baseIo);
90  if (rv<0) {
91  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
92  return rv;
93  }
94 
95  return rv;
96  }
97 
98  return 0;
99 }
100 
101 
102 
104  GWEN_SYNCIO *baseIo;
105 
106  baseIo=GWEN_SyncIo_GetBaseIo(sio);
107  if (baseIo) {
108  int rv;
109 
110  rv=GWEN_SyncIo_Disconnect(baseIo);
111  if (rv<0) {
112  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
113  return rv;
114  }
115 
116  return rv;
117  }
118 
119  return 0;
120 }
121 
122 
123 
125  uint8_t *buffer,
126  uint32_t size) {
127  GWEN_SYNCIO_BUFFERED *xio;
128  uint32_t flags;
129 
130  assert(size);
131 
132  assert(sio);
133  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio);
134  assert(xio);
135 
136  if (xio->readBuffer==NULL) {
137  DBG_ERROR(GWEN_LOGDOMAIN, "No buffer");
138  return GWEN_ERROR_INTERNAL;
139  }
140 
142  flags=GWEN_SyncIo_GetFlags(sio);
143  if (flags & GWEN_SYNCIO_FLAGS_TRANSPARENT) {
144  uint32_t bytesInBuffer;
145 
146  bytesInBuffer=GWEN_RingBuffer_GetUsedBytes(xio->readBuffer);
147  if (bytesInBuffer) {
148  int rv;
149  uint32_t i;
150 
151  /* still bytes in buffer, return them first */
152  if (size>bytesInBuffer)
153  i=bytesInBuffer;
154  else
155  i=size;
156  rv=GWEN_RingBuffer_ReadBytes(xio->readBuffer, (char*) buffer, &i);
157  if (rv<0) {
158  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
159  return rv;
160  }
161  /* bytes read */
162  return i;
163  }
164  else {
165  GWEN_SYNCIO *baseIo;
166 
167  baseIo=GWEN_SyncIo_GetBaseIo(sio);
168  if (baseIo) {
169  int rv;
170 
171  rv=GWEN_SyncIo_Read(baseIo, buffer, size);
172  if (rv<0) {
173  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
174  return rv;
175  }
176  return rv;
177  }
178  else {
179  DBG_INFO(GWEN_LOGDOMAIN, "No base layer");
180  return GWEN_ERROR_INTERNAL;
181  }
182  }
183  }
184  else {
185  uint32_t bytesRead=0;
186 
187  while(bytesRead==0) {
188  uint32_t bytesInBuffer;
189  const uint8_t *psrc;
190  uint32_t bytesSkipped=0;
191 
192  bytesInBuffer=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer);
193  if (bytesInBuffer==0) {
194  uint32_t bytesFree;
195  GWEN_SYNCIO *baseIo;
196  int rv;
197 
198  /* fill buffer */
199  bytesFree=GWEN_RingBuffer_GetMaxUnsegmentedWrite(xio->readBuffer);
200  if (bytesFree==0) {
201  DBG_ERROR(GWEN_LOGDOMAIN, "No unsegmente read and write. TSNH!");
202  return GWEN_ERROR_INTERNAL;
203  }
204 
205  baseIo=GWEN_SyncIo_GetBaseIo(sio);
206  assert(baseIo);
207 
208  do {
209  rv=GWEN_SyncIo_Read(baseIo,
210  (uint8_t*) GWEN_RingBuffer_GetWritePointer(xio->readBuffer),
211  bytesFree);
212  }
213  while (rv==GWEN_ERROR_INTERRUPTED);
214 
215  if (rv<0) {
216  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
217  return rv;
218  }
219  else if (rv==0) {
220  DBG_INFO(GWEN_LOGDOMAIN, "EOF met (%d)", bytesRead);
221  break;
222  }
223  GWEN_RingBuffer_SkipBytesWrite(xio->readBuffer, rv);
224  bytesInBuffer=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer);
225  if (bytesInBuffer==0) {
226  DBG_ERROR(GWEN_LOGDOMAIN, "Still no bytes available?? TSNH!");
227  return GWEN_ERROR_INTERNAL;
228  }
229  }
230 
231  /* read data from ring buffer */
232  psrc=(const uint8_t*)GWEN_RingBuffer_GetReadPointer(xio->readBuffer);
233  while(bytesSkipped<bytesInBuffer && bytesRead<(size-1)) {
234  uint8_t c;
235 
236  c=*psrc;
237  if (c!=13) {
238  *(buffer++)=c;
239  bytesRead++;
240  }
241  psrc++;
242  bytesSkipped++;
243  if (c==10) {
245  break;
246  }
247  }
248  GWEN_RingBuffer_SkipBytesRead(xio->readBuffer, bytesSkipped);
249  }
250  *buffer=0;
251 
252  return bytesRead;
253  }
254 }
255 
256 
257 
259  const uint8_t *buffer,
260  uint32_t size) {
261  GWEN_SYNCIO_BUFFERED *xio;
262  GWEN_SYNCIO *baseIo;
263 
264  assert(sio);
265  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio);
266  assert(xio);
267 
268  baseIo=GWEN_SyncIo_GetBaseIo(sio);
269  if (baseIo) {
270  uint32_t flags;
271 
272  flags=GWEN_SyncIo_GetFlags(sio);
273  if (flags & GWEN_SYNCIO_FLAGS_TRANSPARENT) {
274  int rv;
275 
276  /* transparent mode, write directly to base io */
277  do {
278  rv=GWEN_SyncIo_Write(baseIo, buffer, size);
279  }
280  while (rv==GWEN_ERROR_INTERRUPTED);
281 
282  if (rv<0) {
283  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
284  return rv;
285  }
286  return rv;
287  }
288  else {
289  int rv;
290 
291  if (size) {
292  rv=GWEN_SyncIo_WriteForced(baseIo, buffer, size);
293  if (rv<0) {
294  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
295  return rv;
296  }
297  }
298 
299  if (flags & GWEN_SYNCIO_FLAGS_DOSMODE) {
300  do {
301  rv=GWEN_SyncIo_Write(baseIo, (const uint8_t*) "\r\n", 2);
302  }
303  while (rv==GWEN_ERROR_INTERRUPTED);
304  }
305  else {
306  do {
307  rv=GWEN_SyncIo_Write(baseIo, (const uint8_t*) "\n", 1);
308  }
309  while (rv==GWEN_ERROR_INTERRUPTED);
310  }
311 
312  if (rv<0) {
313  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
314  return rv;
315  }
316 
317  return size;
318  }
319  }
320  else {
321  DBG_INFO(GWEN_LOGDOMAIN, "No base layer");
322  return GWEN_ERROR_INTERNAL;
323  }
324 }
325 
326 
327 
329  int rv;
330 
331  /* read a single line */
332  do {
333  uint8_t *p;
334  uint32_t l;
335 
336  GWEN_Buffer_AllocRoom(tbuf, 1024);
337  p=(uint8_t*) GWEN_Buffer_GetPosPointer(tbuf);
339  rv=GWEN_SyncIo_Read(sio, p, l);
340  if (rv<0) {
341  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
342  return rv;
343  }
344  else if (rv>0) {
345  GWEN_Buffer_IncrementPos(tbuf, rv);
347  if (p[rv-1]==10) {
348  p[rv-1]=0;
349  break;
350  }
351  }
352  else if (rv==0)
353  break;
354  }
355  while(rv>0);
356 
357  if (GWEN_Buffer_GetUsedBytes(tbuf)<1) {
358  DBG_INFO(GWEN_LOGDOMAIN, "Nothing received: EOF met");
359  return GWEN_ERROR_EOF;
360  }
361 
362  return 0;
363 }
364 
365 
366 
368  GWEN_BUFFER *tbuf;
369  int rv;
370  int lineCount=0;
371 
372  if (maxLines==0) {
373  DBG_ERROR(GWEN_LOGDOMAIN, "Maxlines==0");
374  return GWEN_ERROR_INVALID;
375  }
376 
377  /* read every line of the file */
378  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
379  while( (maxLines==-1) || (lineCount<maxLines) ) {
381  if (rv<0) {
382  if (rv==GWEN_ERROR_EOF)
383  break;
384  else {
385  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
386  return rv;
387  }
388  }
389  else {
391  lineCount++;
392  }
393  GWEN_Buffer_Reset(tbuf);
394  }
395  GWEN_Buffer_free(tbuf);
396 
397  return 0;
398 }
399 
400 
401 
402 
403 
404 
int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.c:295
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:94
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
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
Definition: buffer.c:569
#define GWEN_ERROR_INVALID
Definition: error.h:67
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:266
int GWEN_SyncIo_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:127
const char * GWEN_RingBuffer_GetReadPointer(const GWEN_RINGBUFFER *rb)
Definition: ringbuffer.c:339
uint32_t GWEN_RingBuffer_GetMaxUnsegmentedWrite(GWEN_RINGBUFFER *rb)
Definition: ringbuffer.c:126
int GWEN_SyncIo_Buffered_ReadLineToBuffer(GWEN_SYNCIO *sio, GWEN_BUFFER *tbuf)
#define GWEN_SYNCIO_BUFFERED_TYPE
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
#define GWEN_SYNCIO_FLAGS_TRANSPARENT
Definition: syncio.h:55
uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio)
Definition: syncio.c:153
int GWEN_RingBuffer_ReadBytes(GWEN_RINGBUFFER *rb, char *buffer, uint32_t *size)
Definition: ringbuffer.c:182
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
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
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
char * GWEN_RingBuffer_GetWritePointer(const GWEN_RINGBUFFER *rb)
Definition: ringbuffer.c:346
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:684
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:495
#define GWEN_ERROR_INTERRUPTED
Definition: error.h:74
void GWENHYWFAR_CB GWEN_SyncIo_Buffered_FreeData(void *bp, void *p)
#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_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:230
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:54
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:169
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Connect(GWEN_SYNCIO *sio)
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_EOF
Definition: error.h:96
uint32_t GWEN_RingBuffer_GetUsedBytes(const GWEN_RINGBUFFER *rb)
Definition: ringbuffer.c:220
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:105
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
GWEN_SYNCIO * GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo)
Definition: syncio.c:51
void GWEN_RingBuffer_SkipBytesRead(GWEN_RINGBUFFER *rb, uint32_t psize)
Definition: ringbuffer.c:146
void GWEN_RingBuffer_free(GWEN_RINGBUFFER *rb)
Definition: ringbuffer.c:55
uint32_t GWEN_RingBuffer_GetMaxUnsegmentedRead(GWEN_RINGBUFFER *rb)
Definition: ringbuffer.c:105
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
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
GWEN_RINGBUFFER * GWEN_RingBuffer_new(unsigned int size)
Definition: ringbuffer.c:42
int GWEN_SyncIo_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.c:140
#define GWEN_SYNCIO_FLAGS_PACKET_END
Definition: syncio.h:58
#define GWEN_INHERIT(bt, t)
Definition: inherit.h:264
GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn)
Definition: syncio.c:271
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
#define GWEN_INHERIT_SETDATA(bt, t, element, data, fn)
Definition: inherit.h:292
void GWEN_RingBuffer_SkipBytesWrite(GWEN_RINGBUFFER *rb, uint32_t psize)
Definition: ringbuffer.c:163
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Disconnect(GWEN_SYNCIO *sio)
#define GWEN_INHERIT_GETDATA(bt, t, element)
Definition: inherit.h:271