gwenhywfar 5.14.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
46GWEN_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);
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
#define NULL
Definition binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:451
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
Definition buffer.c:527
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition buffer.c:653
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition buffer.c:468
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition buffer.c:548
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition buffer.c:89
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition buffer.c:277
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition buffer.c:285
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define GWEN_ERROR_INTERNAL
Definition error.h:125
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_INTERRUPTED
Definition error.h:74
#define GWEN_ERROR_EOF
Definition error.h:96
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_UNUSED
#define GWENHYWFAR_CB
#define GWEN_INHERIT_SETDATA(bt, t, element, data, fn)
Definition inherit.h:300
#define GWEN_INHERIT(bt, t)
Definition inherit.h:264
#define GWEN_INHERIT_GETDATA(bt, t, element)
Definition inherit.h:279
#define GWEN_LOGDOMAIN
Definition logger.h:32
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
void GWEN_RingBuffer_SkipBytesWrite(GWEN_RINGBUFFER *rb, uint32_t psize)
Definition ringbuffer.c:167
void GWEN_RingBuffer_SkipBytesRead(GWEN_RINGBUFFER *rb, uint32_t psize)
Definition ringbuffer.c:149
int GWEN_RingBuffer_ReadBytes(GWEN_RINGBUFFER *rb, char *buffer, uint32_t *size)
Definition ringbuffer.c:187
GWEN_RINGBUFFER * GWEN_RingBuffer_new(unsigned int size)
Definition ringbuffer.c:42
uint32_t GWEN_RingBuffer_GetMaxUnsegmentedRead(GWEN_RINGBUFFER *rb)
Definition ringbuffer.c:107
uint32_t GWEN_RingBuffer_GetUsedBytes(const GWEN_RINGBUFFER *rb)
Definition ringbuffer.c:226
void GWEN_RingBuffer_free(GWEN_RINGBUFFER *rb)
Definition ringbuffer.c:56
const char * GWEN_RingBuffer_GetReadPointer(const GWEN_RINGBUFFER *rb)
Definition ringbuffer.c:358
char * GWEN_RingBuffer_GetWritePointer(const GWEN_RINGBUFFER *rb)
Definition ringbuffer.c:366
uint32_t GWEN_RingBuffer_GetMaxUnsegmentedWrite(GWEN_RINGBUFFER *rb)
Definition ringbuffer.c:128
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition stringlist.c:245
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition stringlist.h:56
uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio)
Definition syncio.c:161
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition syncio.c:97
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition syncio.c:179
GWEN_SYNCIO * GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo)
Definition syncio.c:51
int GWEN_SyncIo_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition syncio.c:147
GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn)
Definition syncio.c:291
GWEN_SYNCIO * GWEN_SyncIo_GetBaseIo(const GWEN_SYNCIO *sio)
Definition syncio.c:224
GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn)
Definition syncio.c:265
void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition syncio.c:188
GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn)
Definition syncio.c:304
int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition syncio.c:317
int GWEN_SyncIo_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition syncio.c:133
GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn)
Definition syncio.c:252
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition syncio.c:109
#define GWEN_SYNCIO_FLAGS_DOSMODE
Definition syncio.h:59
struct GWEN_SYNCIO GWEN_SYNCIO
Definition syncio.h:40
#define GWEN_SYNCIO_FLAGS_TRANSPARENT
Definition syncio.h:55
#define GWEN_SYNCIO_FLAGS_PACKET_END
Definition syncio.h:58
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Connect(GWEN_SYNCIO *sio)
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Write(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
int GWEN_SyncIo_Buffered_ReadLineToBuffer(GWEN_SYNCIO *sio, GWEN_BUFFER *tbuf)
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Disconnect(GWEN_SYNCIO *sio)
void GWENHYWFAR_CB GWEN_SyncIo_Buffered_FreeData(GWEN_UNUSED void *bp, void *p)
GWEN_SYNCIO * GWEN_SyncIo_Buffered_new(GWEN_SYNCIO *baseIo)
int GWEN_SyncIo_Buffered_ReadLinesToStringList(GWEN_SYNCIO *sio, int maxLines, GWEN_STRINGLIST *sl)
int GWENHYWFAR_CB GWEN_SyncIo_Buffered_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
#define GWEN_SYNCIO_BUFFERED_TYPE