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