gwenhywfar
4.3.3
|
00001 /*************************************************************************** 00002 begin : Fri Sep 12 2003 00003 copyright : (C) 2003-2010 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00021 * MA 02111-1307 USA * 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 /* allocate buffer */ 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 /* use existing buffer */ 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 /* we need to move data */ 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 /* no data in buffer, so simply move ptrs */ 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 /*DBG_VERBOUS(GWEN_LOGDOMAIN, "Allocating %d bytes", size);*/ 00268 /*if (bf->pos+size>bf->bufferSize) {*/ 00269 if (bf->bytesUsed+(size+1) > bf->bufferSize) { 00270 /* need to realloc */ 00271 uint32_t nsize; 00272 uint32_t noffs; 00273 uint32_t reserved; 00274 void *p; 00275 00276 /* check for dynamic mode */ 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 /* calculate reserved bytes (to set ptr later) */ 00286 reserved=bf->ptr-bf->realPtr; 00287 /* this is the raw number of bytes we need */ 00288 /*nsize=bf->pos+size-bf->bufferSize;*/ 00289 nsize=bf->bytesUsed+(size+1)-bf->bufferSize; 00290 /* round it up */ 00291 nsize=(nsize+(bf->step-1)); 00292 nsize&=~(bf->step-1); 00293 /* store number of additional bytes to allocate */ 00294 noffs=nsize; 00295 /* add current size to it */ 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 /* we always add a NULL character */ 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 /* store new size and pointer */ 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 /* if (bf->pos+size>bf->bufferSize) { */ 00356 if (bf->bytesUsed+size>bf->bufferSize) { 00357 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)", 00358 /*bf->pos, size,*/ 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 /*bf->pos+=size;*/ 00366 if (bf->pos==bf->bytesUsed) 00367 bf->pos+=size; 00368 bf->bytesUsed+=size; 00369 /* append a NULL to allow using the buffer as ASCIIZ string */ 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 /* append a NULL to allow using the buffer as ASCIIZ string */ 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 /* append a NULL to allow using the buffer as ASCIIZ string */ 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 /* optimized for speed */ 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 } /* while */ 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 } /* for */ 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 /* no bytes used, simply return */ 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 /* append "0" behind buffer */ 00781 bf->ptr[bf->bytesUsed]=0; 00782 return 0; 00783 } 00784 else { 00785 if ( (bf->ptr - bf->realPtr) >= (int)size ) { 00786 /* simply occupy the reserved space */ 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 /* move current data at pos out of the way */ 00811 memmove(p+size, p, i); 00812 bf->bytesUsed+=size; 00813 /* append "0" behind buffer */ 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 /* can't remove bytes we don't have */ 00838 return GWEN_ERROR_INVALID; 00839 } 00840 /* simply add to reserved space */ 00841 bf->ptr+=size; 00842 bf->bytesUsed-=size; 00843 bf->bufferSize-=size; 00844 } 00845 else { 00846 if (bf->bytesUsed+size<(bf->bytesUsed)) { 00847 /* can't remove more bytes than we have */ 00848 return GWEN_ERROR_INVALID; 00849 } 00850 00851 /* we need to get the rest closer */ 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 /* append "0" behind buffer */ 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 /* either insert or remove bytes */ 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 /* nothing to adjust if sizes are the same */ 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 /* write new bytes */ 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 /* adjust position after possible truncation */ 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 /* if (bf->pos+size>bf->bufferSize) { */ 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 /* append a NULL to allow using the buffer as ASCIIZ string */ 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