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 (GWEN_UNLIKELY(bf->bytesUsed+1+1 > bf->bufferSize)) {
00385 if (GWEN_UNLIKELY(GWEN_Buffer_AllocRoom(bf, 1+1))) {
00386 DBG_DEBUG(GWEN_LOGDOMAIN, "here");
00387 return 1;
00388 }
00389 }
00390
00391 bf->ptr[bf->bytesUsed]=c;
00392 if (GWEN_LIKELY(bf->pos == bf->bytesUsed))
00393 bf->pos++;
00394
00395 bf->ptr[++(bf->bytesUsed)]=0;
00396 return 0;
00397 }
00398
00399
00400
00401 int GWEN_Buffer__FillBuffer_Bio(GWEN_BUFFER *bf){
00402 if (bf->bio) {
00403 unsigned int toread;
00404 int gerr;
00405
00406 if (GWEN_BufferedIO_CheckEOF(bf->bio)) {
00407 DBG_INFO(GWEN_LOGDOMAIN, "End of data stream reached");
00408 return GWEN_ERROR_EOF;
00409 }
00410 toread=bf->pos-bf->bytesUsed+1;
00411 if (GWEN_Buffer_AllocRoom(bf, toread+1)) {
00412 DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00413 return -1;
00414 }
00415 gerr=GWEN_BufferedIO_ReadRawForced(bf->bio,
00416 bf->ptr+bf->bytesUsed,
00417 &toread);
00418 if (gerr) {
00419 DBG_INFO_ERR(GWEN_LOGDOMAIN, gerr);
00420 return -1;
00421 }
00422 bf->bytesUsed+=toread;
00423 }
00424 else {
00425 DBG_DEBUG(GWEN_LOGDOMAIN,
00426 "End of used area reached and no BIO (%d bytes)",
00427 bf->pos);
00428 return GWEN_ERROR_EOF;
00429 }
00430 return 0;
00431 }
00432
00433
00434
00435 int GWEN_Buffer__FillBuffer_IoLayer(GWEN_BUFFER *bf){
00436 if (bf->ioLayer) {
00437 unsigned int toread;
00438 int rv;
00439
00440 toread=bf->pos-bf->bytesUsed+1;
00441 if (GWEN_Buffer_AllocRoom(bf, toread+1)) {
00442 DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
00443 return -1;
00444 }
00445
00446 rv=GWEN_Io_Layer_ReadBytes(bf->ioLayer,
00447 (uint8_t*)bf->ptr+bf->bytesUsed,
00448 toread,
00449 GWEN_IO_REQUEST_FLAGS_READALL,
00450 0, 30000);
00451 if (rv<(int)toread) {
00452 if (rv<0) {
00453 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00454 return rv;
00455 }
00456 else {
00457 DBG_INFO(GWEN_LOGDOMAIN, "EOF met");
00458
00459 bf->bytesUsed+=toread;
00460 return GWEN_ERROR_EOF;
00461 }
00462 }
00463 bf->bytesUsed+=toread;
00464 return 0;
00465 }
00466 else {
00467 DBG_DEBUG(GWEN_LOGDOMAIN,
00468 "End of used area reached and no BIO (%d bytes)",
00469 bf->pos);
00470 return GWEN_ERROR_EOF;
00471 }
00472 }
00473
00474
00475
00476 int GWEN_Buffer__FillBuffer(GWEN_BUFFER *bf){
00477 assert(bf);
00478 if (bf->mode & GWEN_BUFFER_MODE_USE_BIO)
00479 return GWEN_Buffer__FillBuffer_Bio(bf);
00480 else if (bf->mode & GWEN_BUFFER_MODE_USE_IO)
00481 return GWEN_Buffer__FillBuffer_IoLayer(bf);
00482 else {
00483 DBG_DEBUG(GWEN_LOGDOMAIN,
00484 "End of used area reached (%d bytes)", bf->pos);
00485 return GWEN_ERROR_EOF;
00486 }
00487 }
00488
00489
00490
00491 int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf){
00492 assert(bf);
00493
00494 if (bf->pos>=bf->bytesUsed) {
00495 if (GWEN_Buffer__FillBuffer(bf))
00496 return -1;
00497 }
00498
00499 return (unsigned char) (bf->ptr[bf->pos]);
00500 }
00501
00502
00503
00504 int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf){
00505 assert(bf);
00506
00507 if (bf->pos>=bf->bytesUsed) {
00508 if (GWEN_Buffer__FillBuffer(bf))
00509 return -1;
00510 }
00511
00512 return (unsigned char) (bf->ptr[bf->pos++]);
00513 }
00514
00515
00516
00517 int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i){
00518 assert(bf);
00519
00520 if (i+bf->pos>=bf->bufferSize) {
00521 if (!(bf->mode & GWEN_BUFFER_MODE_USE_BIO)) {
00522 DBG_DEBUG(GWEN_LOGDOMAIN,
00523 "Position %d outside buffer boundaries (%d bytes)\n"
00524 "Incrementing anyway",
00525 i+bf->pos, bf->bufferSize);
00526 }
00527 }
00528
00529 bf->pos+=i;
00530 return 0;
00531 }
00532
00533
00534
00535 int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf){
00536 assert(bf);
00537 if (bf->pos<=bf->bufferSize) {
00538 if (bf->pos>bf->bytesUsed) {
00539 DBG_DEBUG(GWEN_LOGDOMAIN, "Adjusted buffer (uses now %d bytes)",
00540 bf->pos);
00541 bf->bytesUsed=bf->pos;
00542 }
00543
00544 bf->ptr[bf->bytesUsed]=0;
00545 return 0;
00546 }
00547 else {
00548 DBG_ERROR(GWEN_LOGDOMAIN, "Pointer outside buffer size (%d bytes)",
00549 bf->bufferSize);
00550 return 1;
00551 }
00552 }
00553
00554
00555
00556 int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i){
00557 assert(bf);
00558
00559 if (bf->pos<i) {
00560 DBG_ERROR(GWEN_LOGDOMAIN,
00561 "Position %d outside buffer boundaries (%d bytes)",
00562 bf->pos-i, bf->bufferSize);
00563 return 1;
00564 }
00565 bf->pos-=i;
00566 return 0;
00567 }
00568
00569
00570
00571 int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf,
00572 GWEN_BUFFER *sf){
00573 assert(bf);
00574 assert(sf);
00575 if (sf->bytesUsed)
00576 return GWEN_Buffer_AppendBytes(bf, sf->ptr, sf->bytesUsed);
00577 return 0;
00578 }
00579
00580
00581
00582 uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf){
00583 assert(bf);
00584
00585 return (bf->bufferSize-bf->bytesUsed);
00586 }
00587
00588
00589
00590 uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf){
00591 assert(bf);
00592
00593 if (bf->pos<bf->bytesUsed)
00594 return bf->bytesUsed-bf->pos;
00595 else
00596 return 0;
00597 }
00598
00599
00600
00601 char *GWEN_Buffer_GetPosPointer(GWEN_BUFFER *bf){
00602 assert(bf);
00603 return bf->ptr+bf->pos;
00604 }
00605
00606
00607
00608 uint32_t GWEN_Buffer_GetBookmark(GWEN_BUFFER *bf, unsigned int idx){
00609 assert(bf);
00610 assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
00611 return bf->bookmarks[idx];
00612 }
00613
00614
00615
00616 void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx,
00617 uint32_t v){
00618 assert(bf);
00619 assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
00620 bf->bookmarks[idx]=v;
00621 }
00622
00623
00624
00625 void GWEN_Buffer_Dump(GWEN_BUFFER *bf, FILE *f, unsigned int insert) {
00626 uint32_t k;
00627
00628 for (k=0; k<insert; k++)
00629 fprintf(f, " ");
00630 fprintf(f, "Buffer:\n");
00631
00632 for (k=0; k<insert; k++)
00633 fprintf(f, " ");
00634 fprintf(f, "Pos : %d (%04x)\n", bf->pos, bf->pos);
00635
00636 for (k=0; k<insert; k++)
00637 fprintf(f, " ");
00638 fprintf(f, "Buffer Size : %d\n", bf->bufferSize);
00639
00640 for (k=0; k<insert; k++)
00641 fprintf(f, " ");
00642 fprintf(f, "Hard limit : %d\n", bf->hardLimit);
00643
00644 for (k=0; k<insert; k++)
00645 fprintf(f, " ");
00646 fprintf(f, "Bytes Used : %d\n", bf->bytesUsed);
00647
00648 for (k=0; k<insert; k++)
00649 fprintf(f, " ");
00650 fprintf(f, "Bytes Reserved : %u\n",
00651 (uint32_t)(bf->ptr-bf->realPtr));
00652
00653 for (k=0; k<insert; k++)
00654 fprintf(f, " ");
00655 fprintf(f, "Flags : %08x ( ", bf->flags);
00656 if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
00657 fprintf(f, "OWNED ");
00658 fprintf(f, ")\n");
00659
00660 for (k=0; k<insert; k++)
00661 fprintf(f, " ");
00662 fprintf(f, "Mode : %08x ( ", bf->mode);
00663 if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
00664 fprintf(f, "DYNAMIC ");
00665 if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL)
00666 fprintf(f, "ABORT_ON_MEMFULL ");
00667 fprintf(f, ")\n");
00668
00669 for (k=0; k<insert; k++)
00670 fprintf(f, " ");
00671 fprintf(f, "Bookmarks :");
00672 for (k=0; k<GWEN_BUFFER_MAX_BOOKMARKS; k++)
00673 fprintf(f, " %d", bf->bookmarks[k]);
00674 fprintf(f, "\n");
00675
00676 if (bf->ptr && bf->bytesUsed) {
00677 for (k=0; k<insert; k++)
00678 fprintf(f, " ");
00679 fprintf(f, "Data:\n");
00680 GWEN_Text_DumpString(bf->ptr, bf->bytesUsed, f, insert+1);
00681 }
00682 }
00683
00684
00685
00686 void GWEN_Buffer_Reset(GWEN_BUFFER *bf){
00687 assert(bf);
00688 bf->pos=0;
00689 bf->bytesUsed=0;
00690 bf->ptr[0]=0;
00691 }
00692
00693
00694
00695 void GWEN_Buffer_Rewind(GWEN_BUFFER *bf){
00696 assert(bf);
00697 bf->pos=0;
00698 }
00699
00700
00701
00702 int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf,
00703 char *buffer,
00704 uint32_t *size){
00705 #if 0
00706
00707 uint32_t i;
00708 int c;
00709
00710 i=0;
00711
00712 while(i<*size) {
00713 c=GWEN_Buffer_ReadByte(bf);
00714 if (c==-1)
00715 break;
00716 buffer[i]=c;
00717 i++;
00718 }
00719
00720 *size=i;
00721 return 0;
00722
00723 #else
00724
00725 uint32_t i;
00726 char *pdst;
00727
00728 DBG_VERBOUS(GWEN_LOGDOMAIN, "About to copy up to %d bytes", *size);
00729 i=0;
00730 pdst=buffer;
00731
00732 while(i<*size) {
00733 int j;
00734 int srcLeft;
00735
00736 if (bf->pos>=bf->bytesUsed) {
00737 if (GWEN_Buffer__FillBuffer(bf)) {
00738 DBG_DEBUG(GWEN_LOGDOMAIN, "Could not fill buffer, but that's ok");
00739 break;
00740 }
00741 }
00742
00743 srcLeft=bf->bytesUsed - bf->pos;
00744 if (srcLeft==0)
00745 break;
00746 j=(*size)-i;
00747 if (j>srcLeft)
00748 j=srcLeft;
00749 DBG_VERBOUS(GWEN_LOGDOMAIN, "Copying %d bytes", j);
00750 memmove(pdst, bf->ptr + bf->pos, j);
00751 pdst+=j;
00752 i+=j;
00753 bf->pos+=j;
00754 }
00755
00756 *size=i;
00757 DBG_VERBOUS(GWEN_LOGDOMAIN, "Copied %d bytes", *size);
00758 return 0;
00759 #endif
00760 }
00761
00762
00763
00764 uint32_t GWEN_Buffer_GetStep(GWEN_BUFFER *bf){
00765 assert(bf);
00766 return bf->step;
00767 }
00768
00769
00770
00771 void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step){
00772 assert(bf);
00773 bf->step=step;
00774 }
00775
00776
00777
00778 void GWEN_Buffer_AdjustBookmarks(GWEN_BUFFER *bf,
00779 uint32_t pos,
00780 int offset) {
00781 uint32_t i;
00782
00783 assert(bf);
00784 for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++) {
00785 if (bf->bookmarks[i]>=pos)
00786 bf->bookmarks[i]+=offset;
00787 }
00788 }
00789
00790
00791
00792 int GWEN_Buffer_InsertRoom(GWEN_BUFFER *bf,
00793 uint32_t size){
00794 char *p;
00795 int i;
00796
00797 assert(bf);
00798
00799 if (bf->pos==0) {
00800 if (bf->bytesUsed==0) {
00801 int rv;
00802
00803
00804 rv=GWEN_Buffer_AllocRoom(bf, size);
00805 if (rv) {
00806 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
00807 return rv;
00808 }
00809 bf->bytesUsed+=size;
00810
00811 bf->ptr[bf->bytesUsed]=0;
00812 return 0;
00813 }
00814 else {
00815 if ( (bf->ptr - bf->realPtr) >= (int)size ) {
00816
00817 bf->ptr-=size;
00818 bf->bytesUsed+=size;
00819 bf->bufferSize+=size;
00820 GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
00821 return 0;
00822 }
00823 }
00824 }
00825
00826 if (GWEN_Buffer_AllocRoom(bf, size)) {
00827 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
00828 return 1;
00829 }
00830 if (bf->pos+size>bf->bufferSize) {
00831 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
00832 bf->pos, size,
00833 bf->bufferSize);
00834 return -1;
00835 }
00836 p=bf->ptr+bf->pos;
00837 i=bf->bytesUsed-bf->pos;
00838 if (i>0)
00839
00840 memmove(p+size, p, i);
00841 bf->bytesUsed+=size;
00842
00843 bf->ptr[bf->bytesUsed]=0;
00844 GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
00845 return 0;
00846 }
00847
00848
00849
00850 int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size){
00851 char *p;
00852 int i;
00853
00854 assert(bf);
00855
00856 if (bf->pos==0) {
00857 if (bf->bytesUsed<size) {
00858
00859 return GWEN_ERROR_INVALID;
00860 }
00861
00862 bf->ptr+=size;
00863 bf->bytesUsed-=size;
00864 bf->bufferSize-=size;
00865 }
00866 else {
00867 if (bf->bytesUsed+size<(bf->bytesUsed)) {
00868
00869 return GWEN_ERROR_INVALID;
00870 }
00871
00872
00873 p=bf->ptr+bf->pos+size;
00874 i=bf->bytesUsed-bf->pos-size;
00875 memmove(bf->ptr+bf->pos, p, i);
00876 bf->bytesUsed+=size;
00877 }
00878
00879
00880 bf->ptr[bf->bytesUsed]=0;
00881 GWEN_Buffer_AdjustBookmarks(bf, bf->pos, -((int)size));
00882
00883 return 0;
00884 }
00885
00886
00887
00888 int GWEN_Buffer_ReplaceBytes(GWEN_BUFFER *bf,
00889 uint32_t rsize,
00890 const char *buffer,
00891 uint32_t size){
00892 int32_t d;
00893 int rv;
00894
00895
00896 d=size-rsize;
00897 if (d<0) {
00898 rv=GWEN_Buffer_RemoveRoom(bf, -d);
00899 }
00900 else if (d>0) {
00901 rv=GWEN_Buffer_InsertRoom(bf, d);
00902 }
00903 else
00904
00905 rv=0;
00906 if (rv) {
00907 DBG_ERROR(GWEN_LOGDOMAIN,
00908 "Error replacing %d bytes with %d bytes (%d)",
00909 rsize, size, rv);
00910 return rv;
00911 }
00912
00913
00914 if (size)
00915 memmove(bf->ptr+bf->pos, buffer, size);
00916 return 0;
00917 }
00918
00919
00920
00921 int GWEN_Buffer_InsertBytes(GWEN_BUFFER *bf,
00922 const char *buffer,
00923 uint32_t size){
00924 assert(bf);
00925 assert(buffer);
00926
00927 if (GWEN_Buffer_InsertRoom(bf, size)) {
00928 return -1;
00929 }
00930 memmove(bf->ptr+bf->pos, buffer, size);
00931 return 0;
00932 }
00933
00934
00935
00936 int GWEN_Buffer_InsertByte(GWEN_BUFFER *bf, char c){
00937 assert(bf);
00938
00939 if (GWEN_Buffer_InsertRoom(bf, 1)) {
00940 return -1;
00941 }
00942 bf->ptr[bf->pos]=c;
00943 return 0;
00944 }
00945
00946
00947
00948 int GWEN_Buffer_InsertBuffer(GWEN_BUFFER *bf,
00949 GWEN_BUFFER *sf){
00950 assert(bf);
00951 assert(sf);
00952
00953 return GWEN_Buffer_InsertBytes(bf, sf->ptr, sf->bytesUsed);
00954 }
00955
00956
00957
00958 int GWEN_Buffer_Crop(GWEN_BUFFER *bf,
00959 uint32_t pos,
00960 uint32_t l) {
00961 if (pos>=bf->bufferSize) {
00962 DBG_ERROR(GWEN_LOGDOMAIN, "Position outside buffer");
00963 return -1;
00964 }
00965 bf->ptr+=pos;
00966 bf->bufferSize-=pos;
00967 bf->pos-=pos;
00968 if (bf->bytesUsed-pos<l) {
00969 DBG_INFO(GWEN_LOGDOMAIN, "Invalid length");
00970 return -1;
00971 }
00972 bf->bytesUsed=l;
00973 GWEN_Buffer_AdjustBookmarks(bf, pos, -pos);
00974
00975 if (bf->pos>bf->bytesUsed)
00976 bf->pos=bf->bytesUsed;
00977
00978 bf->ptr[bf->bytesUsed]=0;
00979
00980 return 0;
00981 }
00982
00983
00984
00985 int GWEN_Buffer_AppendString(GWEN_BUFFER *bf,
00986 const char *buffer){
00987 assert(bf);
00988 assert(buffer);
00989 return GWEN_Buffer_AppendBytes(bf, buffer, strlen(buffer));
00990 }
00991
00992
00993
00994 int GWEN_Buffer_InsertString(GWEN_BUFFER *bf,
00995 const char *buffer){
00996 assert(bf);
00997 assert(buffer);
00998 return GWEN_Buffer_InsertBytes(bf, buffer, strlen(buffer));
00999 }
01000
01001
01002
01003 void GWEN_Buffer_SetSourceBIO(GWEN_BUFFER *bf,
01004 GWEN_BUFFEREDIO *bio,
01005 int take){
01006 assert(bf);
01007 if (bf->bio) {
01008 if (bf->flags & GWEN_BUFFER_FLAGS_OWN_BIO) {
01009 GWEN_BufferedIO_free(bf->bio);
01010 }
01011 }
01012 if (take)
01013 bf->flags|=GWEN_BUFFER_FLAGS_OWN_BIO;
01014 else
01015 bf->flags&=~GWEN_BUFFER_FLAGS_OWN_BIO;
01016 bf->bio=bio;
01017 }
01018
01019
01020
01021 void GWEN_Buffer_SetSourceIoLayer(GWEN_BUFFER *bf,
01022 GWEN_IO_LAYER *io,
01023 int take) {
01024 assert(bf);
01025 if (bf->ioLayer) {
01026 if (bf->flags & GWEN_BUFFER_FLAGS_OWN_IO) {
01027 GWEN_Io_Layer_free(bf->ioLayer);
01028 }
01029 }
01030 if (take)
01031 bf->flags|=GWEN_BUFFER_FLAGS_OWN_IO;
01032 else
01033 bf->flags&=~GWEN_BUFFER_FLAGS_OWN_IO;
01034 bf->ioLayer=io;
01035 }
01036
01037
01038
01039 int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf,
01040 unsigned char c,
01041 uint32_t size){
01042 assert(bf);
01043 if (GWEN_Buffer_AllocRoom(bf, size+1)) {
01044 DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
01045 return 1;
01046 }
01047
01048 if (bf->bytesUsed+size>bf->bufferSize) {
01049 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
01050 bf->bytesUsed, size+1,
01051 bf->bufferSize);
01052 return 1;
01053 }
01054 memset(bf->ptr+bf->bytesUsed, c, size);
01055 if (bf->pos==bf->bytesUsed)
01056 bf->pos+=size;
01057 bf->bytesUsed+=size;
01058
01059 bf->ptr[bf->bytesUsed]=0;
01060 return 0;
01061 }
01062
01063
01064
01065 int GWEN_Buffer_FillLeftWithBytes(GWEN_BUFFER *bf,
01066 unsigned char c,
01067 uint32_t size){
01068 assert(bf);
01069
01070 if (GWEN_Buffer_InsertRoom(bf, size)) {
01071 return -1;
01072 }
01073 memset(bf->ptr+bf->pos, c, size);
01074 return 0;
01075 }
01076
01077
01078
01079
01080
01081
01082