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
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033 #define DISABLE_DEBUGLOG
00034
00035
00036 #include "bufferedio_p.h"
00037 #include "i18n_l.h"
00038 #include <gwenhywfar/misc.h>
00039 #include <gwenhywfar/text.h>
00040 #include <gwenhywfar/gui.h>
00041
00042 #include <stdlib.h>
00043 #ifdef HAVE_UNISTD_H
00044 # include <unistd.h>
00045 #endif
00046 #include <string.h>
00047 #include <errno.h>
00048
00049 #include <gwenhywfar/debug.h>
00050
00051
00052 GWEN_INHERIT_FUNCTIONS(GWEN_BUFFEREDIO)
00053
00054
00055
00056
00057 GWEN_BUFFEREDIO *GWEN_BufferedIO_new(){
00058 GWEN_BUFFEREDIO *bt;
00059
00060 GWEN_NEW_OBJECT(GWEN_BUFFEREDIO, bt);
00061 GWEN_INHERIT_INIT(GWEN_BUFFEREDIO, bt);
00062 bt->lineMode=GWEN_LineModeUnix;
00063 bt->flags=GWEN_BUFFEREDIO_FLAGS_DEFAULT;
00064 return bt;
00065 }
00066
00067
00068
00069 void GWEN_BufferedIO_free(GWEN_BUFFEREDIO *bt){
00070 if (bt) {
00071 GWEN_INHERIT_FINI(GWEN_BUFFEREDIO, bt);
00072 free(bt->readerBuffer);
00073 bt->readerBuffer=0;
00074 free(bt->writerBuffer);
00075 bt->writerBuffer=0;
00076 GWEN_FREE_OBJECT(bt);
00077 }
00078 }
00079
00080
00081
00082 void GWEN_BufferedIO_SetReadBuffer(GWEN_BUFFEREDIO *bt,
00083 char *buffer, int len){
00084 assert(bt);
00085 free(bt->readerBuffer);
00086 bt->readerBuffer=0;
00087 if (buffer==0) {
00088 if (len>0) {
00089 bt->readerBuffer=malloc(len);
00090 assert(bt->readerBuffer);
00091 }
00092 }
00093 else
00094 bt->readerBuffer=buffer;
00095
00096 bt->readerBufferLength=len;
00097 bt->readerBufferFilled=0;
00098 bt->readerBufferPos=0;
00099 }
00100
00101
00102
00103 void GWEN_BufferedIO_SetWriteBuffer(GWEN_BUFFEREDIO *bt, char *buffer, int len){
00104 assert(bt);
00105 free(bt->writerBuffer);
00106 bt->writerBuffer=0;
00107 if (buffer==0) {
00108 if (len>0) {
00109 bt->writerBuffer=malloc(len);
00110 assert(bt->writerBuffer);
00111 }
00112 }
00113 else
00114 bt->writerBuffer=buffer;
00115
00116 bt->writerBufferLength=len;
00117 bt->writerBufferFilled=0;
00118 bt->writerBufferPos=0;
00119 }
00120
00121
00122
00123 int GWEN_BufferedIO_CheckEOF(GWEN_BUFFEREDIO *bt){
00124 return (GWEN_BufferedIO_PeekChar(bt) == GWEN_BUFFEREDIO_CHAR_EOF);
00125 }
00126
00127
00128
00129 int GWEN_BufferedIO__FillReadBuffer(GWEN_BUFFEREDIO *bt){
00130 int err;
00131 int i;
00132
00133 assert(bt->readPtr);
00134 i=bt->readerBufferLength;
00135 err=bt->readPtr(bt,
00136 bt->readerBuffer,
00137 &i,
00138 bt->timeout);
00139 if (err) {
00140 if (err==GWEN_ERROR_NO_DATA) {
00141 DBG_INFO(GWEN_LOGDOMAIN, "Could not fill input buffer, no data");
00142 return GWEN_BUFFEREDIO_CHAR_NO_DATA;
00143 }
00144 else {
00145 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00146 bt->readerError=1;
00147 return GWEN_BUFFEREDIO_CHAR_ERROR;
00148 }
00149 }
00150
00151 bt->readerBufferFilled=i;
00152 bt->readerBufferPos=0;
00153 bt->readerEOF=(i==0);
00154
00155 if (bt->readerEOF) {
00156 DBG_DEBUG(GWEN_LOGDOMAIN, "EOF now met");
00157 return GWEN_BUFFEREDIO_CHAR_EOF;
00158 }
00159
00160 return 0;
00161 }
00162
00163
00164
00165 int GWEN_BufferedIO_PeekChar(GWEN_BUFFEREDIO *bt){
00166 unsigned char c;
00167
00168 assert(bt);
00169
00170
00171
00172
00173 if (!bt->readerBuffer) {
00174 DBG_ERROR(GWEN_LOGDOMAIN,
00175 "BufferedIO has not yet been assigned a reading buffer for reading; probably assign one by GWEN_BufferedIO_SetReadBuffer(bio,0,length).");
00176 assert(bt->readerBuffer);
00177 }
00178
00179
00180 if (bt->readerError) {
00181 DBG_DEBUG(GWEN_LOGDOMAIN, "Error flagged");
00182 return GWEN_BUFFEREDIO_CHAR_ERROR;
00183 }
00184 if (bt->readerEOF) {
00185 DBG_DEBUG(GWEN_LOGDOMAIN, "EOF flagged");
00186 return GWEN_BUFFEREDIO_CHAR_EOF;
00187 }
00188
00189 if (bt->readerBufferPos >= bt->readerBufferFilled) {
00190
00191 int rv=GWEN_BufferedIO__FillReadBuffer(bt);
00192 if (rv)
00193 return rv;
00194 }
00195
00196 c=(bt->readerBuffer[bt->readerBufferPos]);
00197 if (bt->flags & GWEN_BUFFEREDIO_FLAGS_UNTIL_EMPTY_LINE) {
00198 if (c==10 && bt->filteredLinePos==0) {
00199 bt->readerBufferPos++;
00200 bt->lines++;
00201 bt->linePos=0;
00202 return GWEN_BUFFEREDIO_CHAR_EOF;
00203 }
00204 }
00205 return c;
00206 }
00207
00208
00209
00210 int GWEN_BufferedIO_ReadChar(GWEN_BUFFEREDIO *bt){
00211 int i;
00212
00213
00214
00215
00216
00217
00218
00219 if (bt->readerError) {
00220 DBG_DEBUG(GWEN_LOGDOMAIN, "Error flagged");
00221 return GWEN_BUFFEREDIO_CHAR_ERROR;
00222 }
00223 if (bt->readerEOF) {
00224 DBG_DEBUG(GWEN_LOGDOMAIN, "EOF flagged");
00225 return GWEN_BUFFEREDIO_CHAR_EOF;
00226 }
00227
00228 if (bt->readerBufferPos >= bt->readerBufferFilled) {
00229
00230 int rv=GWEN_BufferedIO__FillReadBuffer(bt);
00231 if (rv)
00232 return rv;
00233 }
00234
00235 i=(unsigned char)(bt->readerBuffer[bt->readerBufferPos++]);
00236 if (i==GWEN_BUFFEREDIO_LF) {
00237 bt->lines++;
00238 bt->linePos=0;
00239 if ((bt->flags & GWEN_BUFFEREDIO_FLAGS_UNTIL_EMPTY_LINE) &&
00240 bt->filteredLinePos==0) {
00241 bt->filteredLinePos=0;
00242 DBG_DEBUG(GWEN_LOGDOMAIN, "Empty line, EOF");
00243 return GWEN_BUFFEREDIO_CHAR_EOF;
00244 }
00245 else {
00246 bt->filteredLinePos=0;
00247 }
00248 }
00249 else {
00250 bt->linePos++;
00251 if (i!=GWEN_BUFFEREDIO_CR)
00252 bt->filteredLinePos++;
00253 }
00254 bt->bytesRead++;
00255
00256 return i;
00257 }
00258
00259
00260
00261 int GWEN_BufferedIO_Flush(GWEN_BUFFEREDIO *bt){
00262 int err;
00263 int i;
00264 int written;
00265
00266 assert(bt);
00267 if (bt->writerBufferFilled==0) {
00268 DBG_DEBUG(GWEN_LOGDOMAIN, "WriteBuffer empty, nothing to flush.");
00269 return 0;
00270 }
00271 assert(bt->writerBuffer);
00272 assert(bt->writePtr);
00273 written=bt->writerBufferFlushPos;
00274 DBG_DEBUG(GWEN_LOGDOMAIN, "Flushing %d bytes", bt->writerBufferFilled);
00275 while(written<bt->writerBufferFilled) {
00276 i=bt->writerBufferFilled-written;
00277 err=bt->writePtr(bt,
00278 &(bt->writerBuffer[written]),
00279 &i,
00280 bt->timeout);
00281 if (err)
00282 return err;
00283 written+=i;
00284 }
00285
00286 bt->writerBufferPos=0;
00287 bt->writerBufferFilled=0;
00288 bt->writerBufferFlushPos=0;
00289 return 0;
00290 }
00291
00292
00293
00294 int GWEN_BufferedIO_ShortFlush(GWEN_BUFFEREDIO *bt){
00295 int err;
00296 int i;
00297
00298 assert(bt);
00299 if (bt->writerBufferFilled==0) {
00300 DBG_DEBUG(GWEN_LOGDOMAIN, "WriteBuffer empty, nothing to flush.");
00301 return 0;
00302 }
00303 assert(bt->writerBuffer);
00304 assert(bt->writePtr);
00305 i=bt->writerBufferFilled-bt->writerBufferFlushPos;
00306 DBG_DEBUG(GWEN_LOGDOMAIN, "Flushing %d bytes", i);
00307 err=bt->writePtr(bt,
00308 &(bt->writerBuffer[bt->writerBufferFlushPos]),
00309 &i,
00310 bt->timeout);
00311 if (err) {
00312 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00313 return err;
00314 }
00315 if (i<bt->writerBufferFilled-bt->writerBufferFlushPos) {
00316
00317 bt->writerBufferFlushPos+=i;
00318 return GWEN_ERROR_PARTIAL;
00319 }
00320 else {
00321
00322 bt->writerBufferFlushPos=0;
00323 bt->writerBufferPos=0;
00324 bt->writerBufferFilled=0;
00325 return 0;
00326 }
00327 }
00328
00329
00330
00331 int GWEN_BufferedIO_ReadBufferEmpty(GWEN_BUFFEREDIO *bt) {
00332 assert(bt);
00333 return ((bt->readerBuffer==0) ||
00334 !bt->readerBufferFilled ||
00335 bt->readerBufferPos>=bt->readerBufferFilled);
00336 }
00337
00338
00339
00340 int GWEN_BufferedIO_WriteBufferEmpty(GWEN_BUFFEREDIO *bt) {
00341 assert(bt);
00342 return ((bt->writerBuffer==0) ||
00343 !bt->writerBufferFilled ||
00344 bt->writerBufferPos>=bt->writerBufferFilled);
00345 }
00346
00347
00348
00349 int GWEN_BufferedIO_WriteChar(GWEN_BUFFEREDIO *bt, char c){
00350 assert(bt);
00351 assert(bt->writerBuffer);
00352
00353
00354 if (bt->writerBufferFilled>=bt->writerBufferLength) {
00355 int err;
00356
00357 err=GWEN_BufferedIO_Flush(bt);
00358 if (err) {
00359 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00360 return err;
00361 }
00362 }
00363
00364
00365 bt->writerBuffer[bt->writerBufferPos++]=c;
00366 bt->bytesWritten++;
00367 if (bt->writerBufferPos>bt->writerBufferFilled)
00368 bt->writerBufferFilled=bt->writerBufferPos;
00369 if (c==GWEN_BUFFEREDIO_LF) {
00370 bt->lines++;
00371 bt->linePos=0;
00372 }
00373 else
00374 bt->linePos++;
00375
00376
00377 if (bt->writerBufferFilled>=bt->writerBufferLength) {
00378 int err;
00379
00380 err=GWEN_BufferedIO_Flush(bt);
00381 if (err) {
00382 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00383 return err;
00384 }
00385 }
00386 return 0;
00387 }
00388
00389
00390
00391 int GWEN_BufferedIO_Close(GWEN_BUFFEREDIO *bt){
00392 int err, err2;
00393
00394 assert(bt);
00395 assert(bt->closePtr);
00396 err=GWEN_BufferedIO_Flush(bt);
00397 if (bt->flags & GWEN_BUFFEREDIO_FLAGS_CLOSE)
00398 err2=bt->closePtr(bt);
00399 else
00400 err2=0;
00401
00402 if (err) {
00403 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00404 return err;
00405 }
00406 if (err2) {
00407 DBG_INFO_ERR(GWEN_LOGDOMAIN, err2);
00408 return err2;
00409 }
00410 return 0;
00411 }
00412
00413
00414
00415 int GWEN_BufferedIO_Abandon(GWEN_BUFFEREDIO *bt){
00416 int err;
00417
00418 assert(bt);
00419 assert(bt->closePtr);
00420 err=bt->closePtr(bt);
00421 if (err) {
00422 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00423 return err;
00424 }
00425 return 0;
00426 }
00427
00428
00429
00430 int GWEN_BufferedIO_ReadLine(GWEN_BUFFEREDIO *bt,
00431 char *buffer,
00432 unsigned int s){
00433 int c;
00434 int pos;
00435
00436 assert(s);
00437 pos=0;
00438
00439 while(s>1) {
00440 if (GWEN_BufferedIO_CheckEOF(bt)) {
00441 buffer[pos]=0;
00442 break;
00443 }
00444 c=GWEN_BufferedIO_ReadChar(bt);
00445 if (c==GWEN_BUFFEREDIO_CHAR_NO_DATA) {
00446 DBG_INFO(GWEN_LOGDOMAIN, "No more data for now");
00447 break;
00448 }
00449 if (c<0) {
00450 DBG_ERROR(GWEN_LOGDOMAIN, "Error while reading");
00451 return GWEN_ERROR_READ;
00452 }
00453
00454 if (c==GWEN_BUFFEREDIO_LF) {
00455
00456 buffer[pos]=0;
00457 break;
00458 }
00459
00460 if (c!=GWEN_BUFFEREDIO_CR || bt->lineMode==GWEN_LineModeUnix) {
00461 buffer[pos]=(unsigned char)c;
00462 pos++;
00463 s--;
00464 }
00465 }
00466
00467
00468 if (s)
00469 buffer[pos]=0;
00470
00471
00472 return 0;
00473 }
00474
00475
00476
00477 int GWEN_BufferedIO_ReadLine2Buffer(GWEN_BUFFEREDIO *bt,
00478 GWEN_BUFFER *buffer) {
00479 int c;
00480
00481
00482 while(1) {
00483 if (GWEN_BufferedIO_CheckEOF(bt)) {
00484 break;
00485 }
00486 c=GWEN_BufferedIO_ReadChar(bt);
00487 if (c==GWEN_BUFFEREDIO_CHAR_NO_DATA) {
00488 DBG_INFO(GWEN_LOGDOMAIN, "No more data for now");
00489 break;
00490 }
00491 if (c<0) {
00492 DBG_ERROR(GWEN_LOGDOMAIN, "Error while reading");
00493 return GWEN_ERROR_READ;
00494 }
00495
00496 if (c==GWEN_BUFFEREDIO_LF) {
00497
00498 break;
00499 }
00500
00501 if (c!=GWEN_BUFFEREDIO_CR || bt->lineMode==GWEN_LineModeUnix) {
00502 GWEN_Buffer_AppendByte(buffer, (unsigned char)c);
00503 }
00504 }
00505
00506
00507 return 0;
00508 }
00509
00510
00511
00512 int GWEN_BufferedIO_Write(GWEN_BUFFEREDIO *bt, const char *buffer){
00513 int err;
00514
00515 assert(bt);
00516 assert(buffer);
00517 while(*buffer) {
00518 err=GWEN_BufferedIO_WriteChar(bt, *buffer);
00519 if (err) {
00520 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00521 return err;
00522 }
00523 buffer++;
00524 }
00525 return 0;
00526 }
00527
00528
00529
00530 int GWEN_BufferedIO_WriteLine(GWEN_BUFFEREDIO *bt, const char *buffer){
00531 int err;
00532
00533 assert(bt);
00534 assert(buffer);
00535 err=GWEN_BufferedIO_Write(bt, buffer);
00536 if (err) {
00537 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00538 return err;
00539 }
00540 if (bt->lineMode==GWEN_LineModeDOS) {
00541 err=GWEN_BufferedIO_WriteChar(bt, GWEN_BUFFEREDIO_CR);
00542 if (err) {
00543 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00544 return err;
00545 }
00546 }
00547 err=GWEN_BufferedIO_WriteChar(bt, GWEN_BUFFEREDIO_LF);
00548 if (err) {
00549 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00550 return err;
00551 }
00552
00553 err=GWEN_BufferedIO_Flush(bt);
00554 if (err) {
00555 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00556 return err;
00557 }
00558
00559 return 0;
00560 }
00561
00562
00563
00564 void GWEN_BufferedIO_SetLineMode(GWEN_BUFFEREDIO *dm,
00565 GWEN_BUFFEREDIOLINEMODE lm){
00566 assert(dm);
00567 dm->lineMode=lm;
00568 }
00569
00570
00571
00572 GWEN_BUFFEREDIOLINEMODE GWEN_BufferedIO_GetLineMode(const GWEN_BUFFEREDIO *dm){
00573 assert(dm);
00574 return dm->lineMode;
00575 }
00576
00577
00578
00579 void GWEN_BufferedIO_SetTimeout(GWEN_BUFFEREDIO *dm, int timeout){
00580 assert(dm);
00581 dm->timeout=timeout;
00582 }
00583
00584
00585
00586 int GWEN_BufferedIO_GetTimeout(const GWEN_BUFFEREDIO *dm){
00587 assert(dm);
00588 return dm->timeout;
00589 }
00590
00591
00592
00593 int GWEN_BufferedIO_WriteRaw(GWEN_BUFFEREDIO *bt,
00594 const char *buffer,
00595 unsigned int *bsize){
00596
00597 int err;
00598 int i;
00599
00600 assert(bt);
00601 assert(bsize);
00602 assert(*bsize);
00603
00604 if (bt->writerBufferFilled) {
00605
00606 err=GWEN_BufferedIO_ShortFlush(bt);
00607 if (err) {
00608 if (err!=GWEN_ERROR_PARTIAL) {
00609 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00610 return err;
00611 }
00612 else {
00613
00614 *bsize=0;
00615 return err;
00616 }
00617 }
00618 }
00619
00620
00621 i=*bsize;
00622 err=bt->writePtr(bt,
00623 buffer,
00624 &i,
00625 bt->timeout);
00626 if (err) {
00627 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00628 return err;
00629 }
00630 *bsize=i;
00631 bt->bytesWritten+=i;
00632
00633 return 0;
00634 }
00635
00636
00637
00638 int GWEN_BufferedIO_ReadRaw(GWEN_BUFFEREDIO *bt,
00639 char *buffer,
00640 unsigned int *bsize){
00641 assert(bt);
00642
00643
00644 if (bt->readerError) {
00645 DBG_INFO(GWEN_LOGDOMAIN, "Error flagged");
00646 return GWEN_ERROR_READ;
00647 }
00648 if (bt->readerEOF) {
00649 DBG_INFO(GWEN_LOGDOMAIN, "EOF flagged");
00650 return GWEN_ERROR_EOF;
00651 }
00652
00653 if (bt->readerBufferPos<bt->readerBufferFilled) {
00654
00655 unsigned int i;
00656
00657 i=bt->readerBufferFilled-bt->readerBufferPos;
00658 if (i>*bsize)
00659 i=*bsize;
00660 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading rest from buffer (%d at %d of %d)",
00661 i,bt->readerBufferPos, bt->readerBufferFilled);
00662
00663 if (i) {
00664
00665 memmove(buffer, bt->readerBuffer+bt->readerBufferPos, i);
00666 bt->readerBufferPos+=i;
00667 }
00668 *bsize=i;
00669 DBG_DEBUG(GWEN_LOGDOMAIN, "Read %d bytes from buffer", i);
00670 bt->bytesRead+=i;
00671 return 0;
00672 }
00673 else {
00674
00675 int err;
00676 int i;
00677
00678 DBG_DEBUG(GWEN_LOGDOMAIN, "Reading directly from source");
00679 assert(bt->readPtr);
00680 i=*bsize;
00681 err=bt->readPtr(bt,
00682 buffer,
00683 &i,
00684 bt->timeout);
00685 if (err) {
00686 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00687 bt->readerError=1;
00688 return err;
00689 }
00690 bt->readerEOF=(i==0);
00691 *bsize=i;
00692 bt->bytesRead+=i;
00693 DBG_DEBUG(GWEN_LOGDOMAIN, "Read %d bytes from source", i);
00694 }
00695 if (bt->readerEOF) {
00696 DBG_DEBUG(GWEN_LOGDOMAIN, "EOF now met");
00697 return GWEN_ERROR_EOF;
00698 }
00699 return 0;
00700 }
00701
00702
00703
00704 int GWEN_BufferedIO_ReadRawForced(GWEN_BUFFEREDIO *bt,
00705 char *buffer,
00706 unsigned int *bsize){
00707 int err;
00708 char *lbuffer;
00709 unsigned int lsize;
00710 unsigned int bytesRead;
00711 uint32_t progressId;
00712
00713 lbuffer=buffer;
00714 bytesRead=0;
00715
00716 progressId=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
00717 GWEN_GUI_PROGRESS_ALLOW_EMBED |
00718 GWEN_GUI_PROGRESS_SHOW_PROGRESS |
00719 GWEN_GUI_PROGRESS_SHOW_ABORT,
00720 I18N("Reading from buffered IO..."),
00721 NULL,
00722 *bsize, 0);
00723
00724 while(bytesRead<*bsize) {
00725 err=GWEN_Gui_ProgressAdvance(progressId, bytesRead);
00726 if (err) {
00727 DBG_INFO(GWEN_LOGDOMAIN, "User abort");
00728 *bsize=bytesRead;
00729 GWEN_Gui_ProgressEnd(progressId);
00730 return err;
00731 }
00732 lsize=*bsize-bytesRead;
00733 err=GWEN_BufferedIO_ReadRaw(bt, lbuffer, &lsize);
00734 if (err) {
00735 DBG_INFO_ERR(GWEN_LOGDOMAIN, err);
00736 *bsize=bytesRead;
00737 GWEN_Gui_ProgressEnd(progressId);
00738 return err;
00739 }
00740 if (lsize==0) {
00741 err=GWEN_Gui_ProgressLog(progressId,
00742 GWEN_LoggerLevel_Error,
00743 I18N("Premature end of stream"));
00744 DBG_ERROR(GWEN_LOGDOMAIN, "Premature end of stream");
00745 *bsize=bytesRead;
00746 GWEN_Gui_ProgressEnd(progressId);
00747 if (err==GWEN_ERROR_USER_ABORTED)
00748 return err;
00749 return GWEN_ERROR_PARTIAL;
00750 }
00751 bytesRead+=lsize;
00752 lbuffer+=lsize;
00753 }
00754 GWEN_Gui_ProgressEnd(progressId);
00755
00756
00757
00758 return 0;
00759 }
00760
00761
00762
00763 int GWEN_BufferedIO_WriteRawForced(GWEN_BUFFEREDIO *bt,
00764 const char *buffer,
00765 unsigned int *bsize){
00766 int err;
00767 const char *lbuffer;
00768 unsigned int lsize;
00769 unsigned int bytesWritten;
00770 uint32_t progressId;
00771
00772 lbuffer=buffer;
00773 bytesWritten=0;
00774
00775 progressId=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
00776 GWEN_GUI_PROGRESS_ALLOW_EMBED |
00777 GWEN_GUI_PROGRESS_SHOW_PROGRESS |
00778 GWEN_GUI_PROGRESS_SHOW_ABORT,
00779 I18N("Writing to buffered IO..."),
00780 NULL,
00781 *bsize, 0);
00782 while(bytesWritten<*bsize) {
00783 err=GWEN_Gui_ProgressAdvance(progressId, bytesWritten);
00784 if (err) {
00785 DBG_INFO(GWEN_LOGDOMAIN, "User aborted");
00786 *bsize=bytesWritten;
00787 GWEN_Gui_ProgressEnd(progressId);
00788 return err;
00789 }
00790
00791 lsize=*bsize-bytesWritten;
00792 err=GWEN_BufferedIO_WriteRaw(bt, lbuffer, &lsize);
00793 if (err) {
00794 DBG_ERROR_ERR(GWEN_LOGDOMAIN, err);
00795 GWEN_Gui_ProgressEnd(progressId);
00796 return err;
00797 }
00798 if (lsize==0) {
00799 DBG_ERROR(GWEN_LOGDOMAIN, "Broken pipe");
00800 *bsize=bytesWritten;
00801 GWEN_Gui_ProgressEnd(progressId);
00802 return GWEN_ERROR_PARTIAL;
00803 }
00804 bytesWritten+=lsize;
00805 lbuffer+=lsize;
00806 }
00807 GWEN_Gui_ProgressEnd(progressId);
00808
00809 return 0;
00810
00811 }
00812
00813
00814
00815
00816 uint32_t GWEN_BufferedIO_GetFlags(const GWEN_BUFFEREDIO *bt) {
00817 assert(bt);
00818 return bt->flags;
00819 }
00820
00821
00822
00823 void GWEN_BufferedIO_SetFlags(GWEN_BUFFEREDIO *bt, uint32_t f) {
00824 assert(bt);
00825 bt->flags=f;
00826 }
00827
00828
00829
00830 void GWEN_BufferedIO_AddFlags(GWEN_BUFFEREDIO *bt, uint32_t f) {
00831 assert(bt);
00832 bt->flags|=f;
00833 }
00834
00835
00836
00837 void GWEN_BufferedIO_SubFlags(GWEN_BUFFEREDIO *bt, uint32_t f) {
00838 assert(bt);
00839 bt->flags&=~f;
00840 }
00841
00842
00843
00844 void GWEN_BufferedIO_SetReadFn(GWEN_BUFFEREDIO *dm,
00845 GWEN_BUFFEREDIOREADFN fn){
00846 assert(dm);
00847 dm->readPtr=fn;
00848 }
00849
00850
00851
00852 void GWEN_BufferedIO_SetWriteFn(GWEN_BUFFEREDIO *dm,
00853 GWEN_BUFFEREDIOWRITEFN fn){
00854 assert(dm);
00855 dm->writePtr=fn;
00856 }
00857
00858
00859
00860 void GWEN_BufferedIO_SetCloseFn(GWEN_BUFFEREDIO *dm,
00861 GWEN_BUFFEREDIOCLOSEFN fn){
00862 assert(dm);
00863 dm->closePtr=fn;
00864 }
00865
00866
00867
00868 int GWEN_BufferedIO_GetLines(const GWEN_BUFFEREDIO *dm){
00869 assert(dm);
00870 return dm->lines;
00871 }
00872
00873
00874
00875 int GWEN_BufferedIO_GetLinePos(const GWEN_BUFFEREDIO *dm){
00876 assert(dm);
00877 return dm->linePos;
00878 }
00879
00880
00881
00882 int GWEN_BufferedIO_GetBytesRead(const GWEN_BUFFEREDIO *dm){
00883 assert(dm);
00884 return dm->bytesRead;
00885 }
00886
00887
00888
00889 int GWEN_BufferedIO_GetBytesWritten(const GWEN_BUFFEREDIO *dm){
00890 assert(dm);
00891 return dm->bytesWritten;
00892 }
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904