gwenhywfar  4.7.0beta
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  } while (rv==GWEN_ERROR_INTERRUPTED);
213 
214  if (rv<0) {
215  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
216  return rv;
217  }
218  else if (rv==0) {
219  DBG_INFO(GWEN_LOGDOMAIN, "EOF met (%d)", bytesRead);
220  break;
221  }
222  GWEN_RingBuffer_SkipBytesWrite(xio->readBuffer, rv);
223  bytesInBuffer=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer);
224  if (bytesInBuffer==0) {
225  DBG_ERROR(GWEN_LOGDOMAIN, "Still no bytes available?? TSNH!");
226  return GWEN_ERROR_INTERNAL;
227  }
228  }
229 
230  /* read data from ring buffer */
231  psrc=(const uint8_t*)GWEN_RingBuffer_GetReadPointer(xio->readBuffer);
232  while(bytesSkipped<bytesInBuffer && bytesRead<(size-1)) {
233  uint8_t c;
234 
235  c=*psrc;
236  if (c!=13) {
237  *(buffer++)=c;
238  bytesRead++;
239  }
240  psrc++;
241  bytesSkipped++;
242  if (c==10) {
244  break;
245  }
246  }
247  GWEN_RingBuffer_SkipBytesRead(xio->readBuffer, bytesSkipped);
248  }
249  *buffer=0;
250 
251  return bytesRead;
252  }
253 }
254 
255 
256 
258  const uint8_t *buffer,
259  uint32_t size) {
260  GWEN_SYNCIO_BUFFERED *xio;
261  GWEN_SYNCIO *baseIo;
262 
263  assert(sio);
264  xio=GWEN_INHERIT_GETDATA(GWEN_SYNCIO, GWEN_SYNCIO_BUFFERED, sio);
265  assert(xio);
266 
267  baseIo=GWEN_SyncIo_GetBaseIo(sio);
268  if (baseIo) {
269  uint32_t flags;
270 
271  flags=GWEN_SyncIo_GetFlags(sio);
272  if (flags & GWEN_SYNCIO_FLAGS_TRANSPARENT) {
273  int rv;
274 
275  /* transparent mode, write directly to base io */
276  do {
277  rv=GWEN_SyncIo_Write(baseIo, buffer, size);
278  } while (rv==GWEN_ERROR_INTERRUPTED);
279 
280  if (rv<0) {
281  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
282  return rv;
283  }
284  return rv;
285  }
286  else {
287  int rv;
288 
289  if (size) {
290  rv=GWEN_SyncIo_WriteForced(baseIo, buffer, size);
291  if (rv<0) {
292  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
293  return rv;
294  }
295  }
296 
297  if (flags & GWEN_SYNCIO_FLAGS_DOSMODE) {
298  do {
299  rv=GWEN_SyncIo_Write(baseIo, (const uint8_t*) "\r\n", 2);
300  } while (rv==GWEN_ERROR_INTERRUPTED);
301  }
302  else {
303  do {
304  rv=GWEN_SyncIo_Write(baseIo, (const uint8_t*) "\n", 1);
305  } while (rv==GWEN_ERROR_INTERRUPTED);
306  }
307 
308  if (rv<0) {
309  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
310  return rv;
311  }
312 
313  return size;
314  }
315  }
316  else {
317  DBG_INFO(GWEN_LOGDOMAIN, "No base layer");
318  return GWEN_ERROR_INTERNAL;
319  }
320 }
321 
322 
323 
325  int rv;
326 
327  /* read a single line */
328  do {
329  uint8_t *p;
330  uint32_t l;
331 
332  GWEN_Buffer_AllocRoom(tbuf, 1024);
333  p=(uint8_t*) GWEN_Buffer_GetPosPointer(tbuf);
335  rv=GWEN_SyncIo_Read(sio, p, l);
336  if (rv<0) {
337  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
338  return rv;
339  }
340  else if (rv>0) {
341  GWEN_Buffer_IncrementPos(tbuf, rv);
343  if (p[rv-1]==10) {
344  p[rv-1]=0;
345  break;
346  }
347  }
348  else if (rv==0)
349  break;
350  } while(rv>0);
351 
352  if (GWEN_Buffer_GetUsedBytes(tbuf)<1) {
353  DBG_INFO(GWEN_LOGDOMAIN, "Nothing received: EOF met");
354  return GWEN_ERROR_EOF;
355  }
356 
357  return 0;
358 }
359 
360 
361 
363  GWEN_BUFFER *tbuf;
364  int rv;
365  int lineCount=0;
366 
367  if (maxLines==0) {
368  DBG_ERROR(GWEN_LOGDOMAIN, "Maxlines==0");
369  return GWEN_ERROR_INVALID;
370  }
371 
372  /* read every line of the file */
373  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
374  while( (maxLines==-1) || (lineCount<maxLines) ) {
376  if (rv<0) {
377  if (rv==GWEN_ERROR_EOF)
378  break;
379  else {
380  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
381  return rv;
382  }
383  }
384  else {
386  lineCount++;
387  }
388  GWEN_Buffer_Reset(tbuf);
389  }
390  GWEN_Buffer_free(tbuf);
391 
392  return 0;
393 }
394 
395 
396 
397 
398 
399