bufferedio.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003  -------------------
00004  cvs         : $Id$
00005  begin       : Fri Feb 07 2003
00006  copyright   : (C) 2003 by Martin Preuss
00007  email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
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   /* Extend the assertion: If it fails, print a more verbose error
00171      message to help programmers who are inexperienced with the
00172      BUFFEREDIO. */
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   /* do some fast checks */
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     /* buffer empty, no EOF met, so fill it */
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   /* As an exception, we skip these checks here for performance
00214      reasons. */
00215   /* assert(bt); */
00216   /* assert(bt->readerBuffer); */
00217 
00218   /* do some fast checks */
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     /* buffer empty, no EOF met, so fill it */
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   } /* while */
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     /* partial flush */
00317     bt->writerBufferFlushPos+=i;
00318     return GWEN_ERROR_PARTIAL;
00319   }
00320   else {
00321     /* all bytes written, flush finished */
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   /* flush buffer if needed (only needed if last flush attempt failed) */
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   /* write char to buffer */
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   /* flush buffer if needed */
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   /* now read */
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       /* LF ends every line */
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   } /* while */
00466 
00467   /* add terminating null */
00468   if (s)
00469     buffer[pos]=0;
00470 
00471   /* reading done */
00472   return 0;
00473 }
00474 
00475 
00476 
00477 int GWEN_BufferedIO_ReadLine2Buffer(GWEN_BUFFEREDIO *bt,
00478                                     GWEN_BUFFER *buffer) {
00479   int c;
00480 
00481   /* now read */
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       /* LF ends every line */
00498       break;
00499     }
00500 
00501     if (c!=GWEN_BUFFEREDIO_CR || bt->lineMode==GWEN_LineModeUnix) {
00502       GWEN_Buffer_AppendByte(buffer, (unsigned char)c);
00503     }
00504   } /* while */
00505 
00506   /* reading done */
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   } /* while */
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     /* some data in the buffer, this must be flushed first */
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         /* still some bytes in the buffer, can not write right now */
00614         *bsize=0;
00615         return err;
00616       }
00617     }
00618   }
00619 
00620   /* try to write as many bytes as possible */
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   /* do some fast checks */
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     /* buffer not empty, so read from the buffer first */
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       /* copy as much bytes as needed, advance pointer */
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     /* buffer empty, so read directly from source */
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   } /* while */
00754   GWEN_Gui_ProgressEnd(progressId);
00755 
00756   /* no need to update bsize here, because it already contains the correct
00757    * value */
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   } /* while */
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 

Generated on Thu Aug 20 13:54:37 2009 for gwenhywfar by  doxygen 1.5.9