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