00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016
00017
00018 #include "io_buffered_p.h"
00019 #include <gwenhywfar/iolayer_be.h>
00020 #include <gwenhywfar/iorequest_be.h>
00021 #include <gwenhywfar/iomanager.h>
00022
00023 #include "i18n_l.h"
00024 #include <gwenhywfar/misc.h>
00025 #include <gwenhywfar/debug.h>
00026 #include <gwenhywfar/gui.h>
00027
00028 #include <assert.h>
00029
00030
00031
00032 GWEN_INHERIT(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED)
00033
00034
00035
00036 GWEN_IO_LAYER *GWEN_Io_LayerBuffered_new(GWEN_IO_LAYER *baseLayer) {
00037 GWEN_IO_LAYER *io;
00038 GWEN_IO_LAYER_BUFFERED *xio;
00039
00040 io=GWEN_Io_Layer_new(GWEN_IO_LAYER_BUFFERED_TYPE, baseLayer);
00041 assert(io);
00042 GWEN_NEW_OBJECT(GWEN_IO_LAYER_BUFFERED, xio);
00043 assert(xio);
00044 GWEN_INHERIT_SETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io, xio, GWEN_Io_LayerBuffered_freeData);
00045
00046 GWEN_Io_Layer_SetWorkOnRequestsFn(io, GWEN_Io_LayerBuffered_WorkOnRequests);
00047 GWEN_Io_Layer_SetAddRequestFn(io, GWEN_Io_LayerBuffered_AddRequest);
00048 GWEN_Io_Layer_SetDelRequestFn(io, GWEN_Io_LayerBuffered_DelRequest);
00049 GWEN_Io_Layer_SetHasWaitingRequestsFn(io, GWEN_Io_LayerBuffered_HasWaitingRequests);
00050
00051
00052 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00053
00054 return io;
00055 }
00056
00057
00058
00059 GWENHYWFAR_CB
00060 void GWEN_Io_LayerBuffered_freeData(void *bp, void *p) {
00061 GWEN_IO_LAYER *io;
00062 GWEN_IO_LAYER_BUFFERED *xio;
00063
00064 io=(GWEN_IO_LAYER*) bp;
00065 assert(io);
00066 xio=(GWEN_IO_LAYER_BUFFERED*) p;
00067 assert(xio);
00068
00069 GWEN_Io_LayerBuffered_AbortInRequests(io, GWEN_ERROR_ABORTED);
00070 GWEN_Io_LayerBuffered_AbortOutRequests(io);
00071
00072 GWEN_RingBuffer_free(xio->readBuffer);
00073 GWEN_RingBuffer_free(xio->writeBuffer);
00074
00075 GWEN_FREE_OBJECT(xio);
00076 }
00077
00078
00079
00080 void GWEN_Io_LayerBuffered_AbortInRequests(GWEN_IO_LAYER *io, int errorCode) {
00081 GWEN_IO_LAYER_BUFFERED *xio;
00082
00083 assert(io);
00084 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00085 assert(xio);
00086
00087 if (xio->readRequestIn) {
00088 GWEN_IO_REQUEST *r;
00089
00090 r=xio->readRequestIn;
00091 xio->readRequestIn=NULL;
00092 DBG_INFO(GWEN_LOGDOMAIN, "Aborting in read request");
00093 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00094 GWEN_Io_Request_free(r);
00095 }
00096 if (xio->writeRequestIn) {
00097 GWEN_IO_REQUEST *r;
00098
00099 r=xio->writeRequestIn;
00100 xio->writeRequestIn=NULL;
00101 DBG_INFO(GWEN_LOGDOMAIN, "Aborting in write request");
00102 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, errorCode);
00103 GWEN_Io_Request_free(r);
00104 }
00105 }
00106
00107
00108
00109 void GWEN_Io_LayerBuffered_AbortOutRequests(GWEN_IO_LAYER *io) {
00110 GWEN_IO_LAYER_BUFFERED *xio;
00111
00112 assert(io);
00113 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00114 assert(xio);
00115
00116 if (xio->readRequestOut) {
00117 GWEN_IO_REQUEST *r;
00118
00119 r=xio->readRequestOut;
00120 GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00121 xio->readRequestOut=NULL;
00122 GWEN_Io_Request_free(r);
00123 }
00124 if (xio->writeRequestIn) {
00125 GWEN_IO_REQUEST *r;
00126
00127 r=xio->writeRequestIn;
00128 GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00129 xio->writeRequestIn=NULL;
00130 GWEN_Io_Request_free(r);
00131 }
00132 }
00133
00134
00135
00136 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerBuffered_WorkOnReadRequest(GWEN_IO_LAYER *io) {
00137 GWEN_IO_LAYER_BUFFERED *xio;
00138 int doneSomething=0;
00139
00140 assert(io);
00141 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00142 assert(xio);
00143
00144 if (xio->readRequestOut) {
00145
00146 if (GWEN_Io_Request_GetStatus(xio->readRequestOut)==GWEN_Io_Request_StatusFinished) {
00147 uint32_t bpos;
00148
00149 doneSomething=1;
00150
00151
00152 bpos=GWEN_Io_Request_GetBufferPos(xio->readRequestOut);
00153 if (bpos==0) {
00154 DBG_INFO(GWEN_LOGDOMAIN, "No bytes read");
00155 }
00156 DBG_VERBOUS(GWEN_LOGDOMAIN, "Read %d bytes into ringbuffer", bpos);
00157 GWEN_RingBuffer_SkipBytesWrite(xio->readBuffer, bpos);
00158
00159
00160 xio->lastReadOutResult=GWEN_Io_Request_GetResultCode(xio->readRequestOut);
00161
00162 GWEN_Io_Request_free(xio->readRequestOut);
00163 xio->readRequestOut=NULL;
00164 }
00165 }
00166
00167 if (xio->readRequestIn) {
00168 uint32_t len;
00169 GWEN_IO_REQUEST *r;
00170 uint32_t rflags;
00171
00172 r=xio->readRequestIn;
00173 if (xio->readBuffer==NULL)
00174 xio->readBuffer=GWEN_RingBuffer_new(GWEN_IO_LAYER_BUFFERED_BUFSIZE);
00175
00176 rflags=GWEN_Io_Request_GetFlags(r);
00177
00178
00179 len=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer);
00180 if (len==0) {
00181
00182 if (xio->lastReadOutResult) {
00183 xio->readRequestIn=NULL;
00184 DBG_INFO(GWEN_LOGDOMAIN, "Aborting in read request (reason: %d)",
00185 xio->lastReadOutResult);
00186 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, xio->lastReadOutResult);
00187 GWEN_Io_Request_free(r);
00188 doneSomething=1;
00189 }
00190 else {
00191 if (xio->readRequestOut==NULL) {
00192 GWEN_IO_REQUEST *br;
00193 int rv;
00194
00195
00196 len=GWEN_RingBuffer_GetMaxUnsegmentedWrite(xio->readBuffer);
00197 assert(len);
00198
00199 br=GWEN_Io_Request_new(GWEN_Io_Request_TypeRead,
00200 (uint8_t*)GWEN_RingBuffer_GetWritePointer(xio->readBuffer), len,
00201 NULL, NULL,
00202 GWEN_Io_Request_GetGuiId(xio->readRequestIn));
00203 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), br);
00204 if (rv) {
00205 GWEN_Io_Request_free(br);
00206 if (rv!=GWEN_ERROR_TRY_AGAIN) {
00207 xio->lastReadOutResult=rv;
00208 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00209 xio->readRequestIn=NULL;
00210 DBG_INFO(GWEN_LOGDOMAIN, "Aborting in read request (reason: %d)",
00211 xio->lastReadOutResult);
00212 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00213 GWEN_Io_Request_free(r);
00214 }
00215 }
00216 else {
00217 xio->readRequestOut=br;
00218 }
00219 doneSomething=1;
00220 }
00221 }
00222 }
00223 else {
00224 const uint8_t *src;
00225
00226
00227 doneSomething=1;
00228
00229 src=(const uint8_t*)GWEN_RingBuffer_GetReadPointer(xio->readBuffer);
00230 if (rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_RAW) {
00231 uint32_t maxBytes;
00232 uint32_t bpos;
00233 uint8_t *dst;
00234
00235
00236 bpos=GWEN_Io_Request_GetBufferPos(r);
00237 dst=GWEN_Io_Request_GetBufferPtr(r)+bpos;
00238 maxBytes=GWEN_Io_Request_GetBufferSize(r)-bpos;
00239 if (maxBytes>len)
00240 maxBytes=len;
00241 if (maxBytes) {
00242 memmove(dst, src, maxBytes);
00243 if (!(rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_PEEK)) {
00244
00245 GWEN_RingBuffer_SkipBytesRead(xio->readBuffer, maxBytes);
00246 }
00247 bpos+=maxBytes;
00248 GWEN_Io_Request_SetBufferPos(r, bpos);
00249 }
00250
00251
00252
00253 if (!(rflags & GWEN_IO_REQUEST_FLAGS_READALL) ||
00254 (rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_PEEK) ||
00255 bpos>=GWEN_Io_Request_GetBufferSize(r)) {
00256
00257 xio->readRequestIn=NULL;
00258 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00259 GWEN_Io_Request_free(r);
00260 }
00261 }
00262 else {
00263 uint32_t maxBytes;
00264 uint32_t bpos;
00265 uint32_t i;
00266 uint8_t *dst;
00267
00268
00269 bpos=GWEN_Io_Request_GetBufferPos(r);
00270 dst=GWEN_Io_Request_GetBufferPtr(r)+bpos;
00271 maxBytes=GWEN_Io_Request_GetBufferSize(r)-bpos;
00272 i=0;
00273
00274 if (rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_PEEK) {
00275
00276 while(i<len && bpos<maxBytes) {
00277 if (*src==10) {
00278 GWEN_Io_Request_AddFlags(r, GWEN_IO_REQUEST_FLAGS_PACKETEND);
00279 GWEN_Io_Request_SetBufferPos(r, bpos);
00280 xio->readRequestIn=NULL;
00281 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00282 GWEN_Io_Request_free(r);
00283 break;
00284 }
00285 else if (*src!=13) {
00286 *(dst++)=*src;
00287 bpos++;
00288 }
00289 i++;
00290 src++;
00291 }
00292 if (xio->readRequestIn && bpos>=GWEN_Io_Request_GetBufferSize(xio->readRequestIn)) {
00293 GWEN_Io_Request_SetBufferPos(r, bpos);
00294 xio->readRequestIn=NULL;
00295 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00296 GWEN_Io_Request_free(r);
00297 }
00298 }
00299 else {
00300 while(i<len && bpos<maxBytes) {
00301 if (*src==10) {
00302 xio->lastReadWasPacketEnd=1;
00303 xio->readLineCount++;
00304 GWEN_Io_Request_AddFlags(r, GWEN_IO_REQUEST_FLAGS_PACKETEND);
00305 GWEN_Io_Request_SetBufferPos(r, bpos);
00306 if (xio->readLinePos==0 &&
00307 (GWEN_Io_Layer_GetFlags(io) & GWEN_IO_REQUEST_BUFFERED_FLAGS_UNTILEMPTYLINE)) {
00308 xio->lastReadOutResult=GWEN_ERROR_EOF;
00309 xio->readLinePos=0;
00310 xio->readRequestIn=NULL;
00311 GWEN_Io_Request_SetBufferPos(r, bpos);
00312 DBG_INFO(GWEN_LOGDOMAIN,
00313 "Aborting in read request (reason: %d)",
00314 xio->lastReadOutResult);
00315 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_EOF);
00316 GWEN_Io_Request_free(r);
00317 }
00318 else {
00319 xio->readLinePos=0;
00320 xio->readRequestIn=NULL;
00321 GWEN_Io_Request_SetBufferPos(r, bpos);
00322 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00323 GWEN_Io_Request_free(r);
00324 }
00325 i++;
00326 break;
00327 }
00328 else if (*src!=13) {
00329 *(dst++)=*src;
00330 bpos++;
00331 }
00332 xio->readLinePos++;
00333 i++;
00334 src++;
00335 }
00336 GWEN_RingBuffer_SkipBytesRead(xio->readBuffer, i);
00337
00338 if (xio->readRequestIn) {
00339 GWEN_Io_Request_SetBufferPos(r, bpos);
00340
00341 if (bpos>=GWEN_Io_Request_GetBufferSize(xio->readRequestIn)) {
00342
00343 xio->lastReadWasPacketEnd=0;
00344 xio->readRequestIn=NULL;
00345 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00346 GWEN_Io_Request_free(r);
00347 }
00348 }
00349 }
00350 }
00351 }
00352 }
00353
00354 if (GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening) {
00355 GWEN_IO_LAYER *newIo;
00356
00357 newIo=GWEN_Io_Layer_GetNextIncomingLayer(GWEN_Io_Layer_GetBaseLayer(io));
00358 if (newIo) {
00359 GWEN_IO_LAYER *newNewIo;
00360 uint32_t fl;
00361
00362 fl=GWEN_Io_Layer_GetFlags(io);
00363 newNewIo=GWEN_Io_LayerBuffered_new(newIo);
00364 GWEN_Io_Layer_AddFlags(newNewIo, GWEN_IO_LAYER_FLAGS_PASSIVE);
00365 GWEN_Io_Layer_AddFlags(newNewIo, fl & 0xffff);
00366 GWEN_Io_Layer_AddIncomingLayer(io, newNewIo);
00367 doneSomething=1;
00368 }
00369 }
00370
00371 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00372 }
00373
00374
00375
00376 int GWEN_Io_LayerBuffered_TryFlush(GWEN_IO_LAYER *io) {
00377 GWEN_IO_LAYER_BUFFERED *xio;
00378
00379 assert(io);
00380 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00381 assert(xio);
00382
00383 if (xio->writeBuffer!=NULL) {
00384 uint32_t len;
00385
00386 len=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->writeBuffer);
00387 if (len!=0) {
00388
00389 if (xio->writeRequestOut==NULL) {
00390 if (xio->lastWriteOutResult)
00391 return xio->lastWriteOutResult;
00392 else {
00393 GWEN_IO_REQUEST *br;
00394 int rv;
00395
00396
00397 len=GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->writeBuffer);
00398 assert(len);
00399
00400 br=GWEN_Io_Request_new(GWEN_Io_Request_TypeWrite,
00401 (uint8_t*)GWEN_RingBuffer_GetReadPointer(xio->writeBuffer), len,
00402 NULL, NULL,
00403 GWEN_Io_Request_GetGuiId(xio->writeRequestIn));
00404 DBG_DEBUG(GWEN_LOGDOMAIN, "Adding write request (%d bytes)", len);
00405 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), br);
00406 if (rv) {
00407 if (rv!=GWEN_ERROR_TRY_AGAIN)
00408 xio->lastWriteOutResult=rv;
00409 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00410 GWEN_Io_Request_free(br);
00411 return rv;
00412 }
00413 else {
00414 xio->writeRequestOut=br;
00415 return 0;
00416 }
00417 }
00418 }
00419 else
00420
00421 return GWEN_ERROR_IN_PROGRESS;
00422 }
00423 }
00424 return GWEN_ERROR_NO_DATA;
00425 }
00426
00427
00428
00429 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerBuffered_WorkOnWriteRequest(GWEN_IO_LAYER *io) {
00430 GWEN_IO_LAYER_BUFFERED *xio;
00431 int doneSomething=0;
00432
00433 assert(io);
00434 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00435 assert(xio);
00436
00437 if (xio->writeRequestOut) {
00438
00439 if (GWEN_Io_Request_GetStatus(xio->writeRequestOut)==GWEN_Io_Request_StatusFinished) {
00440 uint32_t bpos;
00441
00442 doneSomething=1;
00443
00444
00445 bpos=GWEN_Io_Request_GetBufferPos(xio->writeRequestOut);
00446 DBG_VERBOUS(GWEN_LOGDOMAIN, "Written %d bytes into ringbuffer", bpos);
00447 GWEN_RingBuffer_SkipBytesRead(xio->writeBuffer, bpos);
00448
00449
00450 xio->lastWriteOutResult=GWEN_Io_Request_GetResultCode(xio->writeRequestOut);
00451 GWEN_Io_Request_free(xio->writeRequestOut);
00452 xio->writeRequestOut=NULL;
00453 }
00454 }
00455
00456 if (xio->writeRequestIn) {
00457 uint32_t len;
00458 GWEN_IO_REQUEST *r;
00459 uint32_t rflags;
00460
00461 r=xio->writeRequestIn;
00462 if (xio->writeBuffer==NULL)
00463 xio->writeBuffer=GWEN_RingBuffer_new(GWEN_IO_LAYER_BUFFERED_BUFSIZE);
00464
00465 rflags=GWEN_Io_Request_GetFlags(r);
00466
00467 len=GWEN_RingBuffer_GetMaxUnsegmentedWrite(xio->writeBuffer);
00468 if (len==0) {
00469 int rv;
00470
00471
00472 rv=GWEN_Io_LayerBuffered_TryFlush(io);
00473 if (rv==0) {
00474 doneSomething=1;
00475 }
00476 else {
00477 assert(rv!=GWEN_ERROR_NO_DATA);
00478 if (rv!=GWEN_ERROR_TRY_AGAIN &&
00479 rv!=GWEN_ERROR_IN_PROGRESS) {
00480 xio->writeRequestIn=NULL;
00481 DBG_INFO(GWEN_LOGDOMAIN,
00482 "Aborting in write request (reason: %d)",
00483 rv);
00484 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00485 GWEN_Io_Request_free(r);
00486 doneSomething=1;
00487 }
00488 }
00489 }
00490 else {
00491 uint8_t *dst;
00492 uint32_t maxBytes;
00493 uint32_t bpos;
00494 const uint8_t *src;
00495
00496
00497 dst=(uint8_t*)GWEN_RingBuffer_GetWritePointer(xio->writeBuffer);
00498
00499
00500 bpos=GWEN_Io_Request_GetBufferPos(r);
00501 src=GWEN_Io_Request_GetBufferPtr(r)+bpos;
00502 maxBytes=GWEN_Io_Request_GetBufferSize(r)-bpos;
00503 if (maxBytes>len)
00504 maxBytes=len;
00505 if (maxBytes) {
00506 memmove(dst, src, maxBytes);
00507 GWEN_RingBuffer_SkipBytesWrite(xio->writeBuffer, maxBytes);
00508 bpos+=maxBytes;
00509 GWEN_Io_Request_SetBufferPos(r, bpos);
00510 doneSomething=1;
00511 }
00512
00513 if (bpos>=GWEN_Io_Request_GetBufferSize(r)) {
00514 int rv;
00515
00516
00517 if (rflags & GWEN_IO_REQUEST_FLAGS_PACKETEND) {
00518 if (GWEN_Io_Layer_GetFlags(io) & GWEN_IO_LAYER_BUFFERED_FLAGS_DOSMODE)
00519 rflags|=GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE13 | GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE10;
00520 else
00521 rflags|=GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE10;
00522 rflags&=~GWEN_IO_REQUEST_FLAGS_PACKETEND;
00523 GWEN_Io_Request_SetFlags(r, rflags);
00524 doneSomething=1;
00525 }
00526
00527 if (rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE13) {
00528 rv=GWEN_RingBuffer_WriteByte(xio->writeBuffer, 13);
00529 if (rv==0) {
00530 rflags&=~GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE13;
00531 GWEN_Io_Request_SubFlags(r, GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE13);
00532 doneSomething=1;
00533 }
00534 }
00535
00536 if (rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE10) {
00537 rv=GWEN_RingBuffer_WriteByte(xio->writeBuffer, 10);
00538 if (rv==0) {
00539 rflags&=~GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE10;
00540 GWEN_Io_Request_SubFlags(r, GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE10);
00541 doneSomething=1;
00542 }
00543 }
00544 }
00545
00546 if (bpos>=GWEN_Io_Request_GetBufferSize(r) &&
00547 !(rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE13) &&
00548 !(rflags & GWEN_IO_REQUEST_BUFFERED_FLAGS_WRITE10)) {
00549 if (rflags & GWEN_IO_REQUEST_FLAGS_FLUSH) {
00550 int rv;
00551
00552
00553 rv=GWEN_Io_LayerBuffered_TryFlush(io);
00554 if (rv==GWEN_ERROR_NO_DATA) {
00555
00556 xio->writeRequestIn=NULL;
00557 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00558 GWEN_Io_Request_free(r);
00559 doneSomething=1;
00560 }
00561 else if (rv==0) {
00562
00563 doneSomething=1;
00564 }
00565 else if (rv!=GWEN_ERROR_TRY_AGAIN && rv!=GWEN_ERROR_IN_PROGRESS) {
00566 xio->writeRequestIn=NULL;
00567 DBG_INFO(GWEN_LOGDOMAIN,
00568 "Aborting in write request (reason: %d)",
00569 rv);
00570 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, rv);
00571 GWEN_Io_Request_free(r);
00572 doneSomething=1;
00573 }
00574 }
00575 else {
00576 xio->writeRequestIn=NULL;
00577 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00578 GWEN_Io_Request_free(r);
00579 doneSomething=1;
00580 }
00581 }
00582 }
00583 }
00584
00585 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00586 }
00587
00588
00589
00590 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerBuffered_WorkOnRequests(GWEN_IO_LAYER *io) {
00591 GWEN_IO_LAYER_BUFFERED *xio;
00592 int doneSomething=0;
00593
00594 assert(io);
00595 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00596 assert(xio);
00597
00598 DBG_VERBOUS(GWEN_LOGDOMAIN, "LayerBuffered: Working");
00599
00600
00601 if (GWEN_Io_LayerBuffered_WorkOnReadRequest(io)!=GWEN_Io_Layer_WorkResultBlocking)
00602 doneSomething=1;
00603
00604
00605 if (GWEN_Io_LayerBuffered_WorkOnWriteRequest(io)!=GWEN_Io_Layer_WorkResultBlocking)
00606 doneSomething=1;
00607
00608
00609 if (GWEN_Io_Layer_WorkOnRequests(GWEN_Io_Layer_GetBaseLayer(io))!=GWEN_Io_Layer_WorkResultBlocking)
00610 doneSomething=1;
00611
00612 if (GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening) {
00613 GWEN_IO_LAYER *newIo;
00614
00615 newIo=GWEN_Io_Layer_GetNextIncomingLayer(GWEN_Io_Layer_GetBaseLayer(io));
00616 if (newIo) {
00617 GWEN_IO_LAYER *newNewIo;
00618
00619 newNewIo=GWEN_Io_LayerBuffered_new(newIo);
00620 GWEN_Io_Layer_AddIncomingLayer(io, newNewIo);
00621 doneSomething=1;
00622 }
00623 }
00624
00625 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00626 }
00627
00628
00629
00630 int GWEN_Io_LayerBuffered_AddRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00631 GWEN_IO_LAYER_BUFFERED *xio;
00632 GWEN_IO_LAYER_STATUS st;
00633
00634 assert(io);
00635 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00636 assert(xio);
00637
00638 st=GWEN_Io_Layer_GetStatus(io);
00639
00640 switch(GWEN_Io_Request_GetType(r)) {
00641 case GWEN_Io_Request_TypeRead:
00642
00643 if (st!=GWEN_Io_Layer_StatusConnected) {
00644 DBG_INFO(GWEN_LOGDOMAIN, "File is not open");
00645 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00646 return GWEN_ERROR_NOT_OPEN;
00647 }
00648
00649
00650 if (xio->lastReadOutResult &&
00651 (xio->readBuffer &&
00652 GWEN_RingBuffer_GetMaxUnsegmentedRead(xio->readBuffer)==0)) {
00653 DBG_INFO(GWEN_LOGDOMAIN, "Unable to read (%d)", xio->lastReadOutResult);
00654 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, xio->lastReadOutResult);
00655 return xio->lastReadOutResult;
00656 }
00657
00658
00659 if (xio->readRequestIn) {
00660 DBG_INFO(GWEN_LOGDOMAIN, "There already is a read request");
00661 return GWEN_ERROR_TRY_AGAIN;
00662 }
00663
00664
00665 if (!(GWEN_Io_Request_GetFlags(r) && GWEN_IO_REQUEST_BUFFERED_FLAGS_RAW)) {
00666 if (xio->lastReadWasPacketEnd) {
00667
00668
00669
00670 GWEN_Io_Request_AddFlags(r, GWEN_IO_REQUEST_FLAGS_PACKETBEGIN);
00671 xio->lastReadWasPacketEnd=0;
00672 }
00673 }
00674 else
00675
00676
00677 xio->lastReadWasPacketEnd=0;
00678
00679
00680 xio->readRequestIn=r;
00681 GWEN_Io_Request_Attach(xio->readRequestIn);
00682 break;
00683
00684 case GWEN_Io_Request_TypeWrite:
00685
00686 if (st!=GWEN_Io_Layer_StatusConnected) {
00687 DBG_INFO(GWEN_LOGDOMAIN, "File is not open");
00688 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00689 return GWEN_ERROR_NOT_OPEN;
00690 }
00691
00692
00693 if (xio->writeRequestIn) {
00694 DBG_INFO(GWEN_LOGDOMAIN, "There already is a write request");
00695 return GWEN_ERROR_TRY_AGAIN;
00696 }
00697
00698
00699 xio->writeRequestIn=r;
00700 GWEN_Io_Request_Attach(xio->writeRequestIn);
00701 break;
00702
00703 case GWEN_Io_Request_TypeConnect:
00704
00705 if (st!=GWEN_Io_Layer_StatusUnconnected &&
00706 st!=GWEN_Io_Layer_StatusDisconnected) {
00707 DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00708 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00709 return GWEN_ERROR_NOT_OPEN;
00710 }
00711 else {
00712 xio->lastReadOutResult=0;
00713 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00714 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00715 DBG_INFO(GWEN_LOGDOMAIN, "Layer now connected");
00716 }
00717 break;
00718
00719 case GWEN_Io_Request_TypeDisconnect:
00720
00721 if (st!=GWEN_Io_Layer_StatusConnected) {
00722 DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00723 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00724 return GWEN_ERROR_NOT_OPEN;
00725 }
00726 else {
00727
00728 GWEN_Io_LayerBuffered_AbortInRequests(io, GWEN_ERROR_ABORTED);
00729 GWEN_Io_LayerBuffered_AbortOutRequests(io);
00730
00731
00732 GWEN_RingBuffer_free(xio->readBuffer);
00733 xio->readBuffer=NULL;
00734 GWEN_RingBuffer_free(xio->writeBuffer);
00735 xio->writeBuffer=NULL;
00736
00737 xio->lastReadOutResult=0;
00738
00739
00740 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00741 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00742 }
00743 break;
00744
00745 default:
00746 DBG_INFO(GWEN_LOGDOMAIN, "This request type is not supported (%d)", GWEN_Io_Request_GetType(r));
00747 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_SUPPORTED);
00748 return GWEN_ERROR_NOT_SUPPORTED;
00749 }
00750
00751 return 0;
00752 }
00753
00754
00755
00756 int GWEN_Io_LayerBuffered_DelRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00757 GWEN_IO_LAYER_BUFFERED *xio;
00758
00759 assert(io);
00760 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00761 assert(xio);
00762
00763 switch(GWEN_Io_Request_GetType(r)) {
00764 case GWEN_Io_Request_TypeRead:
00765 if (xio->readRequestIn==r) {
00766 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted read request");
00767 xio->readRequestIn=NULL;
00768 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
00769 GWEN_Io_Request_free(r);
00770 }
00771 else {
00772
00773 DBG_INFO(GWEN_LOGDOMAIN, "Read request not registered with this io layer");
00774 return GWEN_ERROR_INVALID;
00775 }
00776 break;
00777
00778 case GWEN_Io_Request_TypeWrite:
00779 if (xio->writeRequestIn==r) {
00780 DBG_DEBUG(GWEN_LOGDOMAIN, "Aborted write request");
00781 xio->writeRequestIn=NULL;
00782 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
00783 GWEN_Io_Request_free(r);
00784 }
00785 else {
00786
00787 DBG_INFO(GWEN_LOGDOMAIN, "Write request not registered with this io layer");
00788 return GWEN_ERROR_INVALID;
00789 }
00790 break;
00791
00792 default:
00793 break;
00794 }
00795
00796 return 0;
00797 }
00798
00799
00800
00801 int GWEN_Io_LayerBuffered_HasWaitingRequests(GWEN_IO_LAYER *io) {
00802 GWEN_IO_LAYER_BUFFERED *xio;
00803
00804 assert(io);
00805 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00806 assert(xio);
00807
00808 if (xio->readRequestIn || xio->writeRequestIn)
00809 return 1;
00810 else
00811 return 0;
00812 }
00813
00814
00815
00816 int GWEN_Io_LayerBuffered_ReadLineToBuffer(GWEN_IO_LAYER *io, GWEN_BUFFER *fbuf, uint32_t guiid, int msecs) {
00817 for (;;) {
00818 GWEN_IO_REQUEST *r;
00819 GWEN_IO_REQUEST_STATUS st;
00820 uint8_t buffer[257];
00821 int rv;
00822
00823 r=GWEN_Io_Request_new(GWEN_Io_Request_TypeRead,
00824 buffer, sizeof(buffer)-1, NULL, NULL, guiid);
00825 rv=GWEN_Io_Layer_AddRequest(io, r);
00826 if (rv<0) {
00827 GWEN_Io_Request_free(r);
00828 if (rv==GWEN_ERROR_EOF) {
00829 return rv;
00830 }
00831 else {
00832 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00833 return rv;
00834 }
00835 }
00836
00837
00838 rv=GWEN_Io_Manager_WaitForRequest(r, msecs);
00839 if (rv<0) {
00840 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00841 GWEN_Io_Request_free(r);
00842 return rv;
00843 }
00844
00845
00846 st=GWEN_Io_Request_GetStatus(r);
00847 if (st!=GWEN_Io_Request_StatusFinished) {
00848 DBG_INFO(GWEN_LOGDOMAIN, "Bad request status (%d)", st);
00849 GWEN_Io_Request_free(r);
00850 return GWEN_ERROR_INTERNAL;
00851 }
00852
00853
00854 rv=GWEN_Io_Request_GetResultCode(r);
00855 if (rv && rv!=GWEN_ERROR_EOF) {
00856 DBG_INFO(GWEN_LOGDOMAIN, "Result of request is an error (%d)", rv);
00857 GWEN_Io_Request_free(r);
00858 return rv;
00859 }
00860
00861 if (GWEN_Io_Request_GetBufferPos(r))
00862 GWEN_Buffer_AppendBytes(fbuf, (const char*)buffer, GWEN_Io_Request_GetBufferPos(r));
00863
00864 if (GWEN_Io_Request_GetFlags(r) & GWEN_IO_REQUEST_FLAGS_PACKETEND) {
00865 GWEN_Io_Request_free(r);
00866 break;
00867 }
00868
00869 GWEN_Io_Request_free(r);
00870 }
00871
00872 return 0;
00873 }
00874
00875
00876
00877 int GWEN_Io_LayerBuffered_WriteLine(GWEN_IO_LAYER *io, const char *buffer, int len, int flush,
00878 uint32_t guiid, int msecs) {
00879 int rv;
00880 uint32_t rflags;
00881
00882 if (len==-1)
00883 len=strlen(buffer);
00884
00885 rflags=GWEN_IO_REQUEST_FLAGS_PACKETEND|GWEN_IO_REQUEST_FLAGS_WRITEALL;
00886 if (flush)
00887 rflags|=GWEN_IO_REQUEST_FLAGS_FLUSH;
00888 rv=GWEN_Io_Layer_WriteBytes(io, (const uint8_t*)buffer, len, rflags, guiid, msecs);
00889 if (rv<0) {
00890 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00891 }
00892
00893 return rv;
00894 }
00895
00896
00897
00898 uint32_t GWEN_Io_LayerBuffered_GetReadLineCount(const GWEN_IO_LAYER *io) {
00899 GWEN_IO_LAYER_BUFFERED *xio;
00900
00901 assert(io);
00902 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00903 assert(xio);
00904
00905 return xio->readLineCount;
00906 }
00907
00908
00909
00910 uint32_t GWEN_Io_LayerBuffered_GetReadLinePos(const GWEN_IO_LAYER *io) {
00911 GWEN_IO_LAYER_BUFFERED *xio;
00912
00913 assert(io);
00914 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00915 assert(xio);
00916
00917 return xio->readLinePos;
00918 }
00919
00920
00921
00922 void GWEN_Io_LayerBuffered_ResetLinePosAndCounter(GWEN_IO_LAYER *io) {
00923 GWEN_IO_LAYER_BUFFERED *xio;
00924
00925 assert(io);
00926 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_BUFFERED, io);
00927 assert(xio);
00928
00929 xio->readLineCount=0;
00930 xio->readLinePos=0;
00931 }
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944