00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028
00029 #define DISABLE_DEBUGLOG
00030
00031
00032 #include "syncio_p.h"
00033 #include "syncio_file.h"
00034 #include "syncio_buffered.h"
00035
00036 #include <gwenhywfar/misc.h>
00037 #include <gwenhywfar/debug.h>
00038
00039 #include <assert.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042
00043
00044
00045 GWEN_INHERIT_FUNCTIONS(GWEN_SYNCIO)
00046 GWEN_LIST_FUNCTIONS(GWEN_SYNCIO, GWEN_SyncIo)
00047
00048
00049
00050
00051 GWEN_SYNCIO *GWEN_SyncIo_new(const char *typeName, GWEN_SYNCIO *baseIo) {
00052 GWEN_SYNCIO *sio;
00053
00054 assert(typeName);
00055 GWEN_NEW_OBJECT(GWEN_SYNCIO, sio);
00056 sio->refCount=1;
00057 GWEN_INHERIT_INIT(GWEN_SYNCIO, sio);
00058 GWEN_LIST_INIT(GWEN_SYNCIO, sio);
00059
00060 sio->typeName=strdup(typeName);
00061 sio->baseIo=baseIo;
00062
00063 return sio;
00064 }
00065
00066
00067
00068 void GWEN_SyncIo_Attach(GWEN_SYNCIO *sio) {
00069 assert(sio);
00070 assert(sio->refCount);
00071 sio->refCount++;
00072 }
00073
00074
00075
00076 void GWEN_SyncIo_free(GWEN_SYNCIO *sio) {
00077 if (sio) {
00078 assert(sio->refCount);
00079 if (sio->refCount==1) {
00080 GWEN_LIST_FINI(GWEN_SYNCIO, sio);
00081 GWEN_INHERIT_FINI(GWEN_SYNCIO, sio);
00082 GWEN_SyncIo_free(sio->baseIo);
00083 free(sio->typeName);
00084 sio->refCount=0;
00085 GWEN_FREE_OBJECT(sio);
00086 }
00087 else
00088 sio->refCount--;
00089 }
00090 }
00091
00092
00093
00094 int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio) {
00095 assert(sio);
00096 assert(sio->refCount);
00097 if (sio->connectFn)
00098 return sio->connectFn(sio);
00099 else
00100 return 0;
00101 }
00102
00103
00104
00105 int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio) {
00106 assert(sio);
00107 assert(sio->refCount);
00108 if (sio->disconnectFn)
00109 return sio->disconnectFn(sio);
00110 else
00111 return 0;
00112 }
00113
00114
00115
00116 int GWEN_SyncIo_Flush(GWEN_SYNCIO *sio) {
00117 assert(sio);
00118 assert(sio->refCount);
00119 if (sio->flushFn)
00120 return sio->flushFn(sio);
00121 else
00122 return 0;
00123 }
00124
00125
00126
00127 int GWEN_SyncIo_Read(GWEN_SYNCIO *sio,
00128 uint8_t *buffer,
00129 uint32_t size) {
00130 assert(sio);
00131 assert(sio->refCount);
00132 if (sio->readFn)
00133 return sio->readFn(sio, buffer, size);
00134 else
00135 return GWEN_ERROR_EOF;
00136 }
00137
00138
00139
00140 int GWEN_SyncIo_Write(GWEN_SYNCIO *sio,
00141 const uint8_t *buffer,
00142 uint32_t size) {
00143 assert(sio);
00144 assert(sio->refCount);
00145 if (sio->writeFn)
00146 return sio->writeFn(sio, buffer, size);
00147 else
00148 return GWEN_ERROR_BROKEN_PIPE;
00149 }
00150
00151
00152
00153 uint32_t GWEN_SyncIo_GetFlags(const GWEN_SYNCIO *sio) {
00154 assert(sio);
00155 assert(sio->refCount);
00156 return sio->flags;
00157 }
00158
00159
00160
00161 void GWEN_SyncIo_SetFlags(GWEN_SYNCIO *sio, uint32_t fl) {
00162 assert(sio);
00163 assert(sio->refCount);
00164 sio->flags=fl;
00165 }
00166
00167
00168
00169 void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl) {
00170 assert(sio);
00171 assert(sio->refCount);
00172 sio->flags|=fl;
00173 }
00174
00175
00176
00177 void GWEN_SyncIo_SubFlags(GWEN_SYNCIO *sio, uint32_t fl) {
00178 assert(sio);
00179 assert(sio->refCount);
00180 sio->flags&=~fl;
00181 }
00182
00183
00184
00185 GWEN_SYNCIO_STATUS GWEN_SyncIo_GetStatus(const GWEN_SYNCIO *sio) {
00186 assert(sio);
00187 assert(sio->refCount);
00188 return sio->status;
00189 }
00190
00191
00192
00193 void GWEN_SyncIo_SetStatus(GWEN_SYNCIO *sio, GWEN_SYNCIO_STATUS st) {
00194 assert(sio);
00195 assert(sio->refCount);
00196 sio->status=st;
00197 }
00198
00199
00200
00201 const char *GWEN_SyncIo_GetTypeName(const GWEN_SYNCIO *sio) {
00202 assert(sio);
00203 assert(sio->refCount);
00204 return sio->typeName;
00205 }
00206
00207
00208
00209 GWEN_SYNCIO *GWEN_SyncIo_GetBaseIo(const GWEN_SYNCIO *sio) {
00210 assert(sio);
00211 assert(sio->refCount);
00212 return sio->baseIo;
00213 }
00214
00215
00216
00217 GWEN_SYNCIO *GWEN_SyncIo_GetBaseIoByTypeName(const GWEN_SYNCIO *sio, const char *typeName) {
00218 GWEN_SYNCIO *baseIo;
00219
00220 assert(sio);
00221 assert(sio->refCount);
00222
00223 baseIo=sio->baseIo;
00224 while(baseIo) {
00225 if (baseIo->typeName && strcasecmp(baseIo->typeName, typeName)==0)
00226 return baseIo;
00227 baseIo=baseIo->baseIo;
00228 }
00229
00230 return NULL;
00231 }
00232
00233
00234
00235 GWEN_SYNCIO_CONNECT_FN GWEN_SyncIo_SetConnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_CONNECT_FN fn) {
00236 GWEN_SYNCIO_CONNECT_FN of;
00237
00238 assert(sio);
00239 assert(sio->refCount);
00240 of=sio->connectFn;
00241 sio->connectFn=fn;
00242 return of;
00243 }
00244
00245
00246
00247 GWEN_SYNCIO_DISCONNECT_FN GWEN_SyncIo_SetDisconnectFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_DISCONNECT_FN fn) {
00248 GWEN_SYNCIO_DISCONNECT_FN of;
00249
00250 assert(sio);
00251 assert(sio->refCount);
00252 of=sio->disconnectFn;
00253 sio->disconnectFn=fn;
00254 return of;
00255 }
00256
00257
00258
00259 GWEN_SYNCIO_FLUSH_FN GWEN_SyncIo_SetFlushFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_FLUSH_FN fn) {
00260 GWEN_SYNCIO_FLUSH_FN of;
00261
00262 assert(sio);
00263 assert(sio->refCount);
00264 of=sio->flushFn;
00265 sio->flushFn=fn;
00266 return of;
00267 }
00268
00269
00270
00271 GWEN_SYNCIO_READ_FN GWEN_SyncIo_SetReadFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_READ_FN fn) {
00272 GWEN_SYNCIO_READ_FN of;
00273
00274 assert(sio);
00275 assert(sio->refCount);
00276 of=sio->readFn;
00277 sio->readFn=fn;
00278 return of;
00279 }
00280
00281
00282
00283 GWEN_SYNCIO_WRITE_FN GWEN_SyncIo_SetWriteFn(GWEN_SYNCIO *sio, GWEN_SYNCIO_WRITE_FN fn) {
00284 GWEN_SYNCIO_WRITE_FN of;
00285
00286 assert(sio);
00287 assert(sio->refCount);
00288 of=sio->writeFn;
00289 sio->writeFn=fn;
00290 return of;
00291 }
00292
00293
00294
00295 int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio,
00296 const uint8_t *buffer,
00297 uint32_t size) {
00298 if (size==0) {
00299 int rv;
00300
00301 do {
00302 rv=GWEN_SyncIo_Write(sio, buffer, size);
00303 } while (rv==GWEN_ERROR_INTERRUPTED);
00304 if (rv<0) {
00305 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00306 return rv;
00307 }
00308 return 0;
00309 }
00310 else {
00311 uint32_t todo;
00312
00313 todo=size;
00314 while(todo) {
00315 int rv;
00316
00317 do {
00318 rv=GWEN_SyncIo_Write(sio, buffer, todo);
00319 } while (rv==GWEN_ERROR_INTERRUPTED);
00320
00321 if (rv<0) {
00322 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00323 return rv;
00324 }
00325 todo-=rv;
00326 buffer+=rv;
00327 }
00328
00329 return size;
00330 }
00331 }
00332
00333
00334
00335 int GWEN_SyncIo_ReadForced(GWEN_SYNCIO *sio,
00336 uint8_t *buffer,
00337 uint32_t size) {
00338 uint32_t todo;
00339
00340 todo=size;
00341 while(todo) {
00342 int rv;
00343
00344 do {
00345 rv=GWEN_SyncIo_Read(sio, buffer, todo);
00346 } while (rv==GWEN_ERROR_INTERRUPTED);
00347
00348 if (rv<0) {
00349 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00350 return rv;
00351 }
00352 else if (rv==0) {
00353 DBG_ERROR(GWEN_LOGDOMAIN, "EOF met");
00354 return GWEN_ERROR_EOF;
00355 }
00356 todo-=rv;
00357 buffer+=rv;
00358 }
00359
00360 return size;
00361 }
00362
00363
00364
00365 int GWEN_SyncIo_WriteString(GWEN_SYNCIO *sio, const char *s) {
00366 int rv;
00367
00368 rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) s, s?strlen(s):0);
00369 if (rv<0) {
00370 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00371 return rv;
00372 }
00373
00374 return 0;
00375 }
00376
00377
00378
00379 int GWEN_SyncIo_WriteLine(GWEN_SYNCIO *sio, const char *s) {
00380 int rv;
00381
00382 rv=GWEN_SyncIo_WriteString(sio, s);
00383 if (rv<0) {
00384 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00385 return rv;
00386 }
00387
00388 if (GWEN_SyncIo_GetFlags(sio) & GWEN_SYNCIO_FLAGS_DOSMODE)
00389 rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) "\r\n", 2);
00390 else
00391 rv=GWEN_SyncIo_WriteForced(sio, (const uint8_t*) "\n", 1);
00392 if (rv<0) {
00393 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00394 return rv;
00395 }
00396
00397 return 0;
00398 }
00399
00400
00401
00402 int GWEN_SyncIo_WriteChar(GWEN_SYNCIO *sio, char s) {
00403 return GWEN_SyncIo_WriteForced(sio, (const uint8_t*) &s, 1);
00404 }
00405
00406
00407
00408 int GWEN_SyncIo_Helper_ReadFileToStringList(const char *fname,
00409 int maxLines,
00410 GWEN_STRINGLIST *sl) {
00411 GWEN_SYNCIO *sio;
00412 GWEN_SYNCIO *baseSio;
00413 int rv;
00414
00415
00416 baseSio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
00417 GWEN_SyncIo_SetFlags(baseSio, GWEN_SYNCIO_FILE_FLAGS_READ);
00418 sio=GWEN_SyncIo_Buffered_new(baseSio);
00419
00420 rv=GWEN_SyncIo_Connect(sio);
00421 if (rv<0) {
00422 DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fname?fname:"<no filename>");
00423 GWEN_SyncIo_free(sio);
00424 return rv;
00425 }
00426
00427
00428 rv=GWEN_SyncIo_Buffered_ReadLinesToStringList(sio, maxLines, sl);
00429 if (rv<0) {
00430 DBG_INFO(GWEN_LOGDOMAIN, "Could not open file [%s]", fname?fname:"<no filename>");
00431 GWEN_SyncIo_Disconnect(sio);
00432 GWEN_SyncIo_free(sio);
00433 return rv;
00434 }
00435
00436
00437 GWEN_SyncIo_Disconnect(sio);
00438 GWEN_SyncIo_free(sio);
00439 return 0;
00440 }
00441
00442
00443