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 #include "buffer_p.h"
00036 #include <gwenhywfar/misc.h>
00037 #include <gwenhywfar/debug.h>
00038 #include <gwenhywfar/text.h>
00039
00040
00041 GWEN_BUFFER *GWEN_Buffer_new(char *buffer,
00042 uint32_t size,
00043 uint32_t used,
00044 int take){
00045 GWEN_BUFFER *bf;
00046
00047 GWEN_NEW_OBJECT(GWEN_BUFFER, bf);
00048 if (!buffer) {
00049
00050 if (size) {
00051 bf->realPtr=(char*)GWEN_Memory_malloc(size+1);
00052 assert(bf->realPtr);
00053 bf->ptr=bf->realPtr;
00054 bf->realBufferSize=size+1;
00055 bf->bufferSize=size+1;
00056 bf->flags=GWEN_BUFFER_FLAGS_OWNED;
00057 bf->bytesUsed=used;
00058 bf->ptr[0]=0;
00059 }
00060 }
00061 else {
00062
00063 bf->realPtr=buffer;
00064 bf->ptr=buffer;
00065 bf->realBufferSize=size;
00066 bf->bufferSize=size;
00067 bf->bytesUsed=used;
00068 if (take)
00069 bf->flags=GWEN_BUFFER_FLAGS_OWNED;
00070 }
00071
00072 bf->mode=GWEN_BUFFER_MODE_DEFAULT;
00073 bf->hardLimit=GWEN_BUFFER_DEFAULT_HARDLIMIT;
00074 bf->step=GWEN_BUFFER_DYNAMIC_STEP;
00075 return bf;
00076 }
00077
00078
00079
00080 void GWEN_Buffer_free(GWEN_BUFFER *bf){
00081 if (bf) {
00082 if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
00083 GWEN_Memory_dealloc(bf->realPtr);
00084 if (bf->bio) {
00085 if (bf->flags & GWEN_BUFFER_FLAGS_OWN_BIO) {
00086 GWEN_BufferedIO_free(bf->bio);
00087 }
00088 }
00089 GWEN_FREE_OBJECT(bf);
00090 }
00091 }
00092
00093
00094
00095 GWEN_BUFFER *GWEN_Buffer_dup(GWEN_BUFFER *bf) {
00096 GWEN_BUFFER *newbf;
00097 uint32_t i;
00098
00099 GWEN_NEW_OBJECT(GWEN_BUFFER, newbf);
00100 if (bf->realPtr && bf->realBufferSize) {
00101 newbf->realPtr=(char*)GWEN_Memory_malloc(bf->realBufferSize);
00102 newbf->ptr=newbf->realPtr+(bf->ptr-bf->realPtr);
00103 newbf->realBufferSize=bf->realBufferSize;
00104 newbf->bufferSize=bf->bufferSize;
00105 newbf->bytesUsed=bf->bytesUsed;
00106 if (newbf->bytesUsed) {
00107 unsigned int toCopy;
00108
00109 toCopy=bf->bytesUsed+1;
00110 if (toCopy>(newbf->bufferSize)) {
00111 fprintf(stderr, "Panic: Too many bytes in buffer");
00112 abort();
00113 }
00114 memmove(newbf->ptr, bf->ptr, toCopy);
00115 }
00116 newbf->pos=bf->pos;
00117 }
00118 newbf->flags=bf->flags | GWEN_BUFFER_FLAGS_OWNED;
00119 newbf->mode=bf->mode&GWEN_BUFFER_MODE_COPYMASK;
00120 newbf->hardLimit=bf->hardLimit;
00121 newbf->step=bf->step;
00122 for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++)
00123 newbf->bookmarks[i]=bf->bookmarks[i];
00124
00125 return newbf;
00126 }
00127
00128
00129
00130 int GWEN_Buffer_Relinquish(GWEN_BUFFER *bf) {
00131 assert(bf);
00132 if (!(bf->flags & GWEN_BUFFER_FLAGS_OWNED))
00133 return GWEN_ERROR_INVALID;
00134 if (bf->realPtr!=bf->ptr)
00135 return GWEN_ERROR_INVALID;
00136
00137 bf->flags&=~GWEN_BUFFER_FLAGS_OWNED;
00138 return 0;
00139 }
00140
00141
00142
00143 int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res){
00144 assert(bf);
00145 if (!res)
00146 return 0;
00147
00148 if (bf->bytesUsed) {
00149
00150 if (GWEN_Buffer_AllocRoom(bf, res))
00151 return -1;
00152
00153 memmove(bf->ptr+res, bf->ptr, bf->bytesUsed);
00154 bf->ptr+=res;
00155 bf->bufferSize-=res;
00156 return 0;
00157 }
00158 else {
00159
00160 if (GWEN_Buffer_AllocRoom(bf, res))
00161 return -1;
00162
00163 bf->ptr+=res;
00164 bf->bufferSize-=res;
00165 if (bf->bufferSize)
00166 bf->ptr[0]=0;
00167 return 0;
00168 }
00169 }
00170
00171
00172
00173 uint32_t GWEN_Buffer_GetMode(GWEN_BUFFER *bf){
00174 assert(bf);
00175 return bf->mode;
00176 }
00177
00178
00179
00180 void GWEN_Buffer_SetMode(GWEN_BUFFER *bf, uint32_t mode){
00181 assert(bf);
00182 bf->mode=mode;
00183 }
00184
00185
00186 void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode){
00187 assert(bf);
00188 bf->mode|=mode;
00189 }
00190
00191
00192 void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode){
00193 assert(bf);
00194 bf->mode&=~mode;
00195 }
00196
00197
00198
00199 uint32_t GWEN_Buffer_GetHardLimit(GWEN_BUFFER *bf){
00200 assert(bf);
00201 return bf->hardLimit;
00202 }
00203
00204
00205
00206 void GWEN_Buffer_SetHardLimit(GWEN_BUFFER *bf, uint32_t l){
00207 assert(bf);
00208 assert(l);
00209 bf->hardLimit=l;
00210 }
00211
00212
00213
00214 char *GWEN_Buffer_GetStart(GWEN_BUFFER *bf){
00215 assert(bf);
00216 return bf->ptr;
00217 }
00218
00219
00220
00221 uint32_t GWEN_Buffer_GetSize(GWEN_BUFFER *bf){
00222 assert(bf);
00223 if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
00224 return bf->hardLimit;
00225 return bf->bufferSize;
00226 }
00227
00228
00229
00230 uint32_t GWEN_Buffer_GetPos(GWEN_BUFFER *bf){
00231 assert(bf);
00232 return bf->pos;
00233 }
00234
00235
00236
00237 int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i){
00238 assert(bf);
00239
00240 if (i>=bf->bufferSize) {
00241 if ((bf->mode & GWEN_BUFFER_MODE_USE_BIO) ||
00242 (bf->mode & GWEN_BUFFER_MODE_USE_IO)) {
00243 bf->pos=i;
00244 }
00245 else {
00246 DBG_ERROR(GWEN_LOGDOMAIN,
00247 "Position %d outside buffer boundaries (%d bytes)",
00248 i, bf->bufferSize);
00249 return -1;
00250 }
00251 }
00252 bf->pos=i;
00253 return 0;
00254 }
00255
00256
00257
00258 uint32_t GWEN_Buffer_GetUsedBytes(GWEN_BUFFER *bf){
00259 assert(bf);
00260 return bf->bytesUsed;
00261 }
00262
00263
00264
00265 int GWEN_Buffer_SetUsedBytes(GWEN_BUFFER *bf, uint32_t i){
00266 assert(bf);
00267
00268 DBG_WARN(GWEN_LOGDOMAIN,
00269 "GWEN_Buffer_SetUsedBytes: Deprecated, "
00270 "please use GWEN_Buffer_Crop instead.");
00271 if (i>bf->bufferSize) {
00272 DBG_ERROR(GWEN_LOGDOMAIN, "Bytes used>buffer size (%d>%d bytes)",
00273 i, bf->bufferSize);
00274 return 1;
00275 }
00276 bf->bytesUsed=i;
00277 return 0;
00278 }
00279
00280
00281
00282 int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size) {
00283 assert(bf);
00284
00285
00286 if (bf->bytesUsed+(size+1) > bf->bufferSize) {
00287
00288 uint32_t nsize;
00289 uint32_t noffs;
00290 uint32_t reserved;
00291 void *p;
00292
00293
00294 if (!(bf->mode & GWEN_BUFFER_MODE_DYNAMIC)) {
00295 DBG_ERROR(GWEN_LOGDOMAIN, "Not in dynamic mode");
00296 if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
00297 abort();
00298 }
00299 return 1;
00300 }
00301
00302
00303 reserved=bf->ptr-bf->realPtr;
00304
00305
00306 nsize=bf->bytesUsed+(size+1)-bf->bufferSize;
00307
00308 nsize=(nsize+(bf->step-1));
00309 nsize&=~(bf->step-1);
00310
00311 noffs=nsize;
00312
00313 nsize+=bf->realBufferSize;
00314 if (nsize>bf->hardLimit) {
00315 DBG_ERROR(GWEN_LOGDOMAIN,
00316 "Size is beyond hard limit (%d>%d)",
00317 nsize, bf->hardLimit);
00318 if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
00319 abort();
00320 }
00321 return 1;
00322 }
00323 DBG_VERBOUS(GWEN_LOGDOMAIN, "Reallocating from %d to %d bytes",
00324 bf->bufferSize, nsize);
00325
00326 if (bf->realPtr==NULL) {
00327 p=GWEN_Memory_malloc(nsize+1);
00328 }
00329 else {
00330 p=GWEN_Memory_realloc(bf->realPtr, nsize+1);
00331 }
00332 if (!p) {
00333 DBG_ERROR(GWEN_LOGDOMAIN, "Realloc failed.");
00334 if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
00335 abort();
00336 }
00337 return 1;
00338 }
00339
00340
00341 bf->realPtr=p;
00342 bf->ptr=bf->realPtr+reserved;
00343 bf->realBufferSize=nsize;
00344 bf->bufferSize+=noffs;
00345 }
00346
00347 return 0;
00348 }
00349
00350
00351
00352 int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf,
00353 const char *buffer,
00354 uint32_t size){
00355 assert(bf);
00356 if (GWEN_Buffer_AllocRoom(bf, size+1)) {
00357 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
00358 return 1;
00359 }
00360
00361 if (bf->bytesUsed+size>bf->bufferSize) {
00362 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
00363
00364 bf->bytesUsed, size+1,
00365 bf->bufferSize);
00366 return 1;
00367 }
00368
00369 memmove(bf->ptr+bf->bytesUsed, buffer, size);
00370
00371 if (bf->pos==bf->bytesUsed)
00372 bf->pos+=size;
00373 bf->bytesUsed+=size;
00374
00375 bf->ptr[bf->bytesUsed]=0;
00376 return 0;
00377 }
00378
00379
00380
00381 int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c){
00382 assert(bf);
00383
00384 if ((bf->bytesUsed+1+1 > bf->bufferSize) &&
00385 GWEN_Buffer_AllocRoom(bf, 1+1)) {
00386 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
00387 return 1;
00388 }
00389
00390 bf->ptr[bf->bytesUsed]=c;
00391 if (bf->pos == bf->bytesUsed)
00392 bf->pos++;
00393
00394 bf->ptr[++(bf->bytesUsed)]=0;
00395 return 0;
00396 }
00397
00398
00399
00400 int GWEN_Buffer__FillBuffer_Bio(GWEN_BUFFER *bf){
00401 if (bf->bio) {
00402 unsigned int toread;
00403 int gerr;
00404
00405 if (GWEN_BufferedIO_CheckEOF(bf->bio)) {
00406 DBG_INFO(GWEN_LOGDOMAIN, "End of data stream reached");
00407 return GWEN_ERROR_EOF;
00408 }
00409 toread=bf->pos-bf->bytesUsed+1;
00410 if (GWEN_Buffer_AllocRoom(bf, toread+1)) {
00411 DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00412 return -1;
00413 }
00414 gerr=GWEN_BufferedIO_ReadRawForced(bf->bio,
00415 bf->ptr+bf->bytesUsed,
00416 &toread);
00417 if (gerr) {
00418 DBG_INFO_ERR(GWEN_LOGDOMAIN, gerr);
00419 return -1;
00420 }
00421 bf->bytesUsed+=toread;
00422 }
00423 else {
00424 DBG_DEBUG(GWEN_LOGDOMAIN,
00425 "End of used area reached and no BIO (%d bytes)",
00426 bf->pos);
00427 return GWEN_ERROR_EOF;
00428 }
00429 return 0;
00430 }
00431
00432
00433
00434 int GWEN_Buffer__FillBuffer_IoLayer(GWEN_BUFFER *bf){
00435 if (bf->ioLayer) {
00436 unsigned int toread;
00437 int rv;
00438
00439 toread=bf->pos-bf->bytesUsed+1;
00440 if (GWEN_Buffer_AllocRoom(bf, toread+1)) {
00441 DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00442 return -1;
00443 }
00444
00445 rv=GWEN_Io_Layer_ReadBytes(bf->ioLayer,
00446 (uint8_t*)bf->ptr+bf->bytesUsed,
00447 toread,
00448 GWEN_IO_REQUEST_FLAGS_READALL,
00449 0, 30000);
00450 if (rv<toread) {
00451 if (rv<0) {
00452 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00453 return rv;
00454 }
00455 else {
00456 DBG_INFO(GWEN_LOGDOMAIN, "EOF met");
00457
00458 bf->bytesUsed+=toread;
00459 return GWEN_ERROR_EOF;
00460 }
00461 }
00462 bf->bytesUsed+=toread;
00463 return 0;
00464 }
00465 else {
00466 DBG_DEBUG(GWEN_LOGDOMAIN,
00467 "End of used area reached and no BIO (%d bytes)",
00468 bf->pos);
00469 return GWEN_ERROR_EOF;
00470 }
00471 }
00472
00473
00474
00475 int GWEN_Buffer__FillBuffer(GWEN_BUFFER *bf){
00476 assert(bf);
00477 if (bf->mode & GWEN_BUFFER_MODE_USE_BIO)
00478 return GWEN_Buffer__FillBuffer_Bio(bf);
00479 else if (bf->mode & GWEN_BUFFER_MODE_USE_IO)
00480 return GWEN_Buffer__FillBuffer_IoLayer(bf);
00481 else {
00482 DBG_DEBUG(GWEN_LOGDOMAIN,
00483 "End of used area reached (%d bytes)", bf->pos);
00484 return GWEN_ERROR_EOF;
00485 }
00486 }
00487
00488
00489
00490 int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf){
00491 assert(bf);
00492
00493 if (bf->pos>=bf->bytesUsed) {
00494 if (GWEN_Buffer__FillBuffer(bf))
00495 return -1;
00496 }
00497
00498 return (unsigned char) (bf->ptr[bf->pos]);
00499 }
00500
00501
00502
00503 int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf){
00504 assert(bf);
00505
00506 if (bf->pos>=bf->bytesUsed) {
00507 if (GWEN_Buffer__FillBuffer(bf))
00508 return -1;
00509 }
00510
00511 return (unsigned char) (bf->ptr[bf->pos++]);
00512 }
00513
00514
00515
00516 int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i){
00517 assert(bf);
00518
00519 if (i+bf->pos>=bf->bufferSize) {
00520 if (!(bf->mode & GWEN_BUFFER_MODE_USE_BIO)) {
00521 DBG_DEBUG(GWEN_LOGDOMAIN,
00522 "Position %d outside buffer boundaries (%d bytes)\n"
00523 "Incrementing anyway",
00524 i+bf->pos, bf->bufferSize);
00525 }
00526 }
00527
00528 bf->pos+=i;
00529 return 0;
00530 }
00531
00532
00533
00534 int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf){
00535 assert(bf);
00536 if (bf->pos<=bf->bufferSize) {
00537 if (bf->pos>bf->bytesUsed) {
00538 DBG_DEBUG(GWEN_LOGDOMAIN, "Adjusted buffer (uses now %d bytes)",
00539 bf->pos);
00540 bf->bytesUsed=bf->pos;
00541 }
00542
00543 bf->ptr[bf->bytesUsed]=0;
00544 return 0;
00545 }
00546 else {
00547 DBG_ERROR(GWEN_LOGDOMAIN, "Pointer outside buffer size (%d bytes)",
00548 bf->bufferSize);
00549 return 1;
00550 }
00551 }
00552
00553
00554
00555 int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i){
00556 assert(bf);
00557
00558 if (bf->pos<i) {
00559 DBG_ERROR(GWEN_LOGDOMAIN,
00560 "Position %d outside buffer boundaries (%d bytes)",
00561 bf->pos-i, bf->bufferSize);
00562 return 1;
00563 }
00564 bf->pos-=i;
00565 return 0;
00566 }
00567
00568
00569
00570 int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf,
00571 GWEN_BUFFER *sf){
00572 assert(bf);
00573 assert(sf);
00574 if (sf->bytesUsed)
00575 return GWEN_Buffer_AppendBytes(bf, sf->ptr, sf->bytesUsed);
00576 return 0;
00577 }
00578
00579
00580
00581 uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf){
00582 assert(bf);
00583
00584 return (bf->bufferSize-bf->bytesUsed);
00585 }
00586
00587
00588
00589 uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf){
00590 assert(bf);
00591
00592 if (bf->pos<bf->bytesUsed)
00593 return bf->bytesUsed-bf->pos;
00594 else
00595 return 0;
00596 }
00597
00598
00599
00600 char *GWEN_Buffer_GetPosPointer(GWEN_BUFFER *bf){
00601 assert(bf);
00602 return bf->ptr+bf->pos;
00603 }
00604
00605
00606
00607 uint32_t GWEN_Buffer_GetBookmark(GWEN_BUFFER *bf, unsigned int idx){
00608 assert(bf);
00609 assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
00610 return bf->bookmarks[idx];
00611 }
00612
00613
00614
00615 void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx,
00616 uint32_t v){
00617 assert(bf);
00618 assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
00619 bf->bookmarks[idx]=v;
00620 }
00621
00622
00623
00624 void GWEN_Buffer_Dump(GWEN_BUFFER *bf, FILE *f, unsigned int insert) {
00625 uint32_t k;
00626
00627 for (k=0; k<insert; k++)
00628 fprintf(f, " ");
00629 fprintf(f, "Buffer:\n");
00630
00631 for (k=0; k<insert; k++)
00632 fprintf(f, " ");
00633 fprintf(f, "Pos : %d (%04x)\n", bf->pos, bf->pos);
00634
00635 for (k=0; k<insert; k++)
00636 fprintf(f, " ");
00637 fprintf(f, "Buffer Size : %d\n", bf->bufferSize);
00638
00639 for (k=0; k<insert; k++)
00640 fprintf(f, " ");
00641 fprintf(f, "Hard limit : %d\n", bf->hardLimit);
00642
00643 for (k=0; k<insert; k++)
00644 fprintf(f, " ");
00645 fprintf(f, "Bytes Used : %d\n", bf->bytesUsed);
00646
00647 for (k=0; k<insert; k++)
00648 fprintf(f, " ");
00649 fprintf(f, "Bytes Reserved : %u\n",
00650 (uint32_t)(bf->ptr-bf->realPtr));
00651
00652 for (k=0; k<insert; k++)
00653 fprintf(f, " ");
00654 fprintf(f, "Flags : %08x ( ", bf->flags);
00655 if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
00656 fprintf(f, "OWNED ");
00657 fprintf(f, ")\n");
00658
00659 for (k=0; k<insert; k++)
00660 fprintf(f, " ");
00661 fprintf(f, "Mode : %08x ( ", bf->mode);
00662 if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
00663 fprintf(f, "DYNAMIC ");
00664 if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL)
00665 fprintf(f, "ABORT_ON_MEMFULL ");
00666 fprintf(f, ")\n");
00667
00668 for (k=0; k<insert; k++)
00669 fprintf(f, " ");
00670 fprintf(f, "Bookmarks :");
00671 for (k=0; k<GWEN_BUFFER_MAX_BOOKMARKS; k++)
00672 fprintf(f, " %d", bf->bookmarks[k]);
00673 fprintf(f, "\n");
00674
00675 if (bf->ptr && bf->bytesUsed) {
00676 for (k=0; k<insert; k++)
00677 fprintf(f, " ");
00678 fprintf(f, "Data:\n");
00679 GWEN_Text_DumpString(bf->ptr, bf->bytesUsed, f, insert+1);
00680 }
00681 }
00682
00683
00684
00685 void GWEN_Buffer_Reset(GWEN_BUFFER *bf){
00686 assert(bf);
00687 bf->pos=0;
00688 bf->bytesUsed=0;
00689 bf->ptr[0]=0;
00690 }
00691
00692
00693
00694 void GWEN_Buffer_Rewind(GWEN_BUFFER *bf){
00695 assert(bf);
00696 bf->pos=0;
00697 }
00698
00699
00700
00701 int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf,
00702 char *buffer,
00703 uint32_t *size){
00704 #if 0
00705
00706 uint32_t i;
00707 int c;
00708
00709 i=0;
00710
00711 while(i<*size) {
00712 c=GWEN_Buffer_ReadByte(bf);
00713 if (c==-1)
00714 break;
00715 buffer[i]=c;
00716 i++;
00717 }
00718
00719 *size=i;
00720 return 0;
00721
00722 #else
00723
00724 uint32_t i;
00725 char *pdst;
00726
00727 DBG_VERBOUS(GWEN_LOGDOMAIN, "About to copy up to %d bytes", *size);
00728 i=0;
00729 pdst=buffer;
00730
00731 while(i<*size) {
00732 int j;
00733 int srcLeft;
00734
00735 if (bf->pos>=bf->bytesUsed) {
00736 if (GWEN_Buffer__FillBuffer(bf)) {
00737 DBG_DEBUG(GWEN_LOGDOMAIN, "Could not fill buffer, but that's ok");
00738 break;
00739 }
00740 }
00741
00742 srcLeft=bf->bytesUsed - bf->pos;
00743 if (srcLeft==0)
00744 break;
00745 j=(*size)-i;
00746 if (j>srcLeft)
00747 j=srcLeft;
00748 DBG_VERBOUS(GWEN_LOGDOMAIN, "Copying %d bytes", j);
00749 memmove(pdst, bf->ptr + bf->pos, j);
00750 pdst+=j;
00751 i+=j;
00752 bf->pos+=j;
00753 }
00754
00755 *size=i;
00756 DBG_VERBOUS(GWEN_LOGDOMAIN, "Copied %d bytes", *size);
00757 return 0;
00758 #endif
00759 }
00760
00761
00762
00763 uint32_t GWEN_Buffer_GetStep(GWEN_BUFFER *bf){
00764 assert(bf);
00765 return bf->step;
00766 }
00767
00768
00769
00770 void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step){
00771 assert(bf);
00772 bf->step=step;
00773 }
00774
00775
00776
00777 void GWEN_Buffer_AdjustBookmarks(GWEN_BUFFER *bf,
00778 uint32_t pos,
00779 int offset) {
00780 uint32_t i;
00781
00782 assert(bf);
00783 for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++) {
00784 if (bf->bookmarks[i]>=pos)
00785 bf->bookmarks[i]+=offset;
00786 }
00787 }
00788
00789
00790
00791 int GWEN_Buffer_InsertRoom(GWEN_BUFFER *bf,
00792 uint32_t size){
00793 char *p;
00794 int i;
00795
00796 assert(bf);
00797
00798 if (bf->pos==0) {
00799 if (bf->bytesUsed==0) {
00800 int rv;
00801
00802
00803 rv=GWEN_Buffer_AllocRoom(bf, size);
00804 if (rv) {
00805 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
00806 return rv;
00807 }
00808 bf->bytesUsed+=size;
00809
00810 bf->ptr[bf->bytesUsed]=0;
00811 return 0;
00812 }
00813 else {
00814 if ( (bf->ptr - bf->realPtr) >= (int)size ) {
00815
00816 bf->ptr-=size;
00817 bf->bytesUsed+=size;
00818 bf->bufferSize+=size;
00819 GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
00820 return 0;
00821 }
00822 }
00823 }
00824
00825 if (GWEN_Buffer_AllocRoom(bf, size)) {
00826 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
00827 return 1;
00828 }
00829 if (bf->pos+size>bf->bufferSize) {
00830 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
00831 bf->pos, size,
00832 bf->bufferSize);
00833 return -1;
00834 }
00835 p=bf->ptr+bf->pos;
00836 i=bf->bytesUsed-bf->pos;
00837 if (i>0)
00838
00839 memmove(p+size, p, i);
00840 bf->bytesUsed+=size;
00841
00842 bf->ptr[bf->bytesUsed]=0;
00843 GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
00844 return 0;
00845 }
00846
00847
00848
00849 int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size){
00850 char *p;
00851 int i;
00852
00853 assert(bf);
00854
00855 if (bf->pos==0) {
00856 if (bf->bytesUsed<size) {
00857
00858 return GWEN_ERROR_INVALID;
00859 }
00860
00861 bf->ptr+=size;
00862 bf->bytesUsed-=size;
00863 bf->bufferSize-=size;
00864 }
00865 else {
00866 if (bf->bytesUsed+size<(bf->bytesUsed)) {
00867
00868 return GWEN_ERROR_INVALID;
00869 }
00870
00871
00872 p=bf->ptr+bf->pos+size;
00873 i=bf->bytesUsed-bf->pos-size;
00874 memmove(bf->ptr+bf->pos, p, i);
00875 bf->bytesUsed+=size;
00876 }
00877
00878
00879 bf->ptr[bf->bytesUsed]=0;
00880 GWEN_Buffer_AdjustBookmarks(bf, bf->pos, -((int)size));
00881
00882 return 0;
00883 }
00884
00885
00886
00887 int GWEN_Buffer_ReplaceBytes(GWEN_BUFFER *bf,
00888 uint32_t rsize,
00889 const char *buffer,
00890 uint32_t size){
00891 int32_t d;
00892 int rv;
00893
00894
00895 d=size-rsize;
00896 if (d<0) {
00897 rv=GWEN_Buffer_RemoveRoom(bf, -d);
00898 }
00899 else if (d>0) {
00900 rv=GWEN_Buffer_InsertRoom(bf, d);
00901 }
00902 else
00903
00904 rv=0;
00905 if (rv) {
00906 DBG_ERROR(GWEN_LOGDOMAIN,
00907 "Error replacing %d bytes with %d bytes (%d)",
00908 rsize, size, rv);
00909 return rv;
00910 }
00911
00912
00913 if (size)
00914 memmove(bf->ptr+bf->pos, buffer, size);
00915 return 0;
00916 }
00917
00918
00919
00920 int GWEN_Buffer_InsertBytes(GWEN_BUFFER *bf,
00921 const char *buffer,
00922 uint32_t size){
00923 assert(bf);
00924 assert(buffer);
00925
00926 if (GWEN_Buffer_InsertRoom(bf, size)) {
00927 return -1;
00928 }
00929 memmove(bf->ptr+bf->pos, buffer, size);
00930 return 0;
00931 }
00932
00933
00934
00935 int GWEN_Buffer_InsertByte(GWEN_BUFFER *bf, char c){
00936 assert(bf);
00937
00938 if (GWEN_Buffer_InsertRoom(bf, 1)) {
00939 return -1;
00940 }
00941 bf->ptr[bf->pos]=c;
00942 return 0;
00943 }
00944
00945
00946
00947 int GWEN_Buffer_InsertBuffer(GWEN_BUFFER *bf,
00948 GWEN_BUFFER *sf){
00949 assert(bf);
00950 assert(sf);
00951
00952 return GWEN_Buffer_InsertBytes(bf, sf->ptr, sf->bytesUsed);
00953 }
00954
00955
00956
00957 int GWEN_Buffer_Crop(GWEN_BUFFER *bf,
00958 uint32_t pos,
00959 uint32_t l) {
00960 if (pos>=bf->bufferSize) {
00961 DBG_ERROR(GWEN_LOGDOMAIN, "Position outside buffer");
00962 return -1;
00963 }
00964 bf->ptr+=pos;
00965 bf->bufferSize-=pos;
00966 bf->pos-=pos;
00967 if (bf->bytesUsed-pos<l) {
00968 DBG_INFO(GWEN_LOGDOMAIN, "Invalid length");
00969 return -1;
00970 }
00971 bf->bytesUsed=l;
00972 GWEN_Buffer_AdjustBookmarks(bf, pos, -pos);
00973
00974 if (bf->pos>bf->bytesUsed)
00975 bf->pos=bf->bytesUsed;
00976
00977 bf->ptr[bf->bytesUsed]=0;
00978
00979 return 0;
00980 }
00981
00982
00983
00984 int GWEN_Buffer_AppendString(GWEN_BUFFER *bf,
00985 const char *buffer){
00986 assert(bf);
00987 assert(buffer);
00988 return GWEN_Buffer_AppendBytes(bf, buffer, strlen(buffer));
00989 }
00990
00991
00992
00993 int GWEN_Buffer_InsertString(GWEN_BUFFER *bf,
00994 const char *buffer){
00995 assert(bf);
00996 assert(buffer);
00997 return GWEN_Buffer_InsertBytes(bf, buffer, strlen(buffer));
00998 }
00999
01000
01001
01002 void GWEN_Buffer_SetSourceBIO(GWEN_BUFFER *bf,
01003 GWEN_BUFFEREDIO *bio,
01004 int take){
01005 assert(bf);
01006 if (bf->bio) {
01007 if (bf->flags & GWEN_BUFFER_FLAGS_OWN_BIO) {
01008 GWEN_BufferedIO_free(bf->bio);
01009 }
01010 }
01011 if (take)
01012 bf->flags|=GWEN_BUFFER_FLAGS_OWN_BIO;
01013 else
01014 bf->flags&=~GWEN_BUFFER_FLAGS_OWN_BIO;
01015 bf->bio=bio;
01016 }
01017
01018
01019
01020 void GWEN_Buffer_SetSourceIoLayer(GWEN_BUFFER *bf,
01021 GWEN_IO_LAYER *io,
01022 int take) {
01023 assert(bf);
01024 if (bf->ioLayer) {
01025 if (bf->flags & GWEN_BUFFER_FLAGS_OWN_IO) {
01026 GWEN_Io_Layer_free(bf->ioLayer);
01027 }
01028 }
01029 if (take)
01030 bf->flags|=GWEN_BUFFER_FLAGS_OWN_IO;
01031 else
01032 bf->flags&=~GWEN_BUFFER_FLAGS_OWN_IO;
01033 bf->ioLayer=io;
01034 }
01035
01036
01037
01038 int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf,
01039 unsigned char c,
01040 uint32_t size){
01041 assert(bf);
01042 if (GWEN_Buffer_AllocRoom(bf, size+1)) {
01043 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
01044 return 1;
01045 }
01046
01047 if (bf->bytesUsed+size>bf->bufferSize) {
01048 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
01049 bf->bytesUsed, size+1,
01050 bf->bufferSize);
01051 return 1;
01052 }
01053 memset(bf->ptr+bf->bytesUsed, c, size);
01054 if (bf->pos==bf->bytesUsed)
01055 bf->pos+=size;
01056 bf->bytesUsed+=size;
01057
01058 bf->ptr[bf->bytesUsed]=0;
01059 return 0;
01060 }
01061
01062
01063
01064 int GWEN_Buffer_FillLeftWithBytes(GWEN_BUFFER *bf,
01065 unsigned char c,
01066 uint32_t size){
01067 assert(bf);
01068
01069 if (GWEN_Buffer_InsertRoom(bf, size)) {
01070 return -1;
01071 }
01072 memset(bf->ptr+bf->pos, c, size);
01073 return 0;
01074 }
01075
01076
01077
01078
01079
01080
01081