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