gwenhywfar  4.3.3
buffer.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Sep 12 2003
3  copyright : (C) 2003-2010 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 #define DISABLE_DEBUGLOG
31 
32 #include "buffer_p.h"
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35 #include <gwenhywfar/text.h>
36 
37 
39  uint32_t size,
40  uint32_t used,
41  int take){
42  GWEN_BUFFER *bf;
43 
45  if (!buffer) {
46  /* allocate buffer */
47  bf->realPtr=(char*)GWEN_Memory_malloc(size+1);
48  assert(bf->realPtr);
49  bf->ptr=bf->realPtr;
50  bf->realBufferSize=size+1;
51  bf->bufferSize=size+1;
52  bf->flags=GWEN_BUFFER_FLAGS_OWNED;
53  bf->bytesUsed=used;
54  bf->ptr[0]=0;
55  }
56  else {
57  /* use existing buffer */
58  bf->realPtr=buffer;
59  bf->ptr=buffer;
60  bf->realBufferSize=size;
61  bf->bufferSize=size;
62  bf->bytesUsed=used;
63  if (take)
64  bf->flags=GWEN_BUFFER_FLAGS_OWNED;
65  }
66 
67  bf->mode=GWEN_BUFFER_MODE_DEFAULT;
68  bf->hardLimit=GWEN_BUFFER_DEFAULT_HARDLIMIT;
69  bf->step=GWEN_BUFFER_DYNAMIC_STEP;
70  return bf;
71 }
72 
73 
74 
76  if (bf) {
77  if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
78  GWEN_Memory_dealloc(bf->realPtr);
79  if (bf->syncIo) {
80  if (bf->flags & GWEN_BUFFER_FLAGS_OWN_SYNCIO)
81  GWEN_SyncIo_free(bf->syncIo);
82  }
83  GWEN_FREE_OBJECT(bf);
84  }
85 }
86 
87 
88 
90  GWEN_BUFFER *newbf;
91  uint32_t i;
92 
94  if (bf->realPtr && bf->realBufferSize) {
95  newbf->realPtr=(char*)GWEN_Memory_malloc(bf->realBufferSize);
96  newbf->ptr=newbf->realPtr+(bf->ptr-bf->realPtr);
97  newbf->realBufferSize=bf->realBufferSize;
98  newbf->bufferSize=bf->bufferSize;
99  newbf->bytesUsed=bf->bytesUsed;
100  if (newbf->bytesUsed) {
101  unsigned int toCopy;
102 
103  toCopy=bf->bytesUsed+1;
104  if (toCopy>(newbf->bufferSize)) {
105  fprintf(stderr, "Panic: Too many bytes in buffer");
106  abort();
107  }
108  memmove(newbf->ptr, bf->ptr, toCopy);
109  }
110  newbf->pos=bf->pos;
111  }
112  newbf->flags=bf->flags | GWEN_BUFFER_FLAGS_OWNED;
113  newbf->mode=bf->mode&GWEN_BUFFER_MODE_COPYMASK;
114  newbf->hardLimit=bf->hardLimit;
115  newbf->step=bf->step;
116  for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++)
117  newbf->bookmarks[i]=bf->bookmarks[i];
118 
119  return newbf;
120 }
121 
122 
123 
125  assert(bf);
126  if (!(bf->flags & GWEN_BUFFER_FLAGS_OWNED))
127  return GWEN_ERROR_INVALID;
128  if (bf->realPtr!=bf->ptr)
129  return GWEN_ERROR_INVALID;
130 
131  bf->flags&=~GWEN_BUFFER_FLAGS_OWNED;
132  return 0;
133 }
134 
135 
136 
137 int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res){
138  assert(bf);
139  if (!res)
140  return 0;
141 
142  if (bf->bytesUsed) {
143  /* we need to move data */
144  if (GWEN_Buffer_AllocRoom(bf, res))
145  return -1;
146 
147  memmove(bf->ptr+res, bf->ptr, bf->bytesUsed);
148  bf->ptr+=res;
149  bf->bufferSize-=res;
150  return 0;
151  }
152  else {
153  /* no data in buffer, so simply move ptrs */
154  if (GWEN_Buffer_AllocRoom(bf, res))
155  return -1;
156 
157  bf->ptr+=res;
158  bf->bufferSize-=res;
159  if (bf->bufferSize)
160  bf->ptr[0]=0;
161  return 0;
162  }
163 }
164 
165 
166 
168  assert(bf);
169  return bf->mode;
170 }
171 
172 
173 
174 void GWEN_Buffer_SetMode(GWEN_BUFFER *bf, uint32_t mode){
175  assert(bf);
176  bf->mode=mode;
177 }
178 
179 
180 void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode){
181  assert(bf);
182  bf->mode|=mode;
183 }
184 
185 
186 void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode){
187  assert(bf);
188  bf->mode&=~mode;
189 }
190 
191 
192 
194  assert(bf);
195  return bf->hardLimit;
196 }
197 
198 
199 
200 void GWEN_Buffer_SetHardLimit(GWEN_BUFFER *bf, uint32_t l){
201  assert(bf);
202  assert(l);
203  bf->hardLimit=l;
204 }
205 
206 
207 
209  assert(bf);
210  return bf->ptr;
211 }
212 
213 
214 
215 uint32_t GWEN_Buffer_GetSize(const GWEN_BUFFER *bf){
216  assert(bf);
217  if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
218  return bf->hardLimit;
219  return bf->bufferSize;
220 }
221 
222 
223 
224 uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf){
225  assert(bf);
226  return bf->pos;
227 }
228 
229 
230 
231 int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i){
232  assert(bf);
233 
234  if (i>=bf->bufferSize) {
235  if (bf->mode & GWEN_BUFFER_MODE_USE_SYNCIO) {
236  bf->pos=i;
237  }
238  else {
240  "Position %d outside buffer boundaries (%d bytes)",
241  i, bf->bufferSize);
243  }
244  }
245  bf->pos=i;
246  return 0;
247 }
248 
249 
250 
252  assert(bf);
253  return bf->bytesUsed;
254 }
255 
256 
257 
258 int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size) {
259  assert(bf);
260  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
261  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
262  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
263  abort();
264  return GWEN_ERROR_PERMISSIONS;
265  }
266  }
267  /*DBG_VERBOUS(GWEN_LOGDOMAIN, "Allocating %d bytes", size);*/
268  /*if (bf->pos+size>bf->bufferSize) {*/
269  if (bf->bytesUsed+(size+1) > bf->bufferSize) {
270  /* need to realloc */
271  uint32_t nsize;
272  uint32_t noffs;
273  uint32_t reserved;
274  void *p;
275 
276  /* check for dynamic mode */
277  if (!(bf->mode & GWEN_BUFFER_MODE_DYNAMIC)) {
278  DBG_ERROR(GWEN_LOGDOMAIN, "Not in dynamic mode");
279  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
280  abort();
281  }
283  }
284 
285  /* calculate reserved bytes (to set ptr later) */
286  reserved=bf->ptr-bf->realPtr;
287  /* this is the raw number of bytes we need */
288  /*nsize=bf->pos+size-bf->bufferSize;*/
289  nsize=bf->bytesUsed+(size+1)-bf->bufferSize;
290  /* round it up */
291  nsize=(nsize+(bf->step-1));
292  nsize&=~(bf->step-1);
293  /* store number of additional bytes to allocate */
294  noffs=nsize;
295  /* add current size to it */
296  nsize+=bf->realBufferSize;
297  if (nsize>bf->hardLimit) {
299  "Size is beyond hard limit (%d>%d)",
300  nsize, bf->hardLimit);
301  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
302  abort();
303  }
305  }
306  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reallocating from %d to %d bytes",
307  bf->bufferSize, nsize);
308  /* we always add a NULL character */
309  if (bf->realPtr==NULL) {
310  p=GWEN_Memory_malloc(nsize+1);
311  }
312  else {
313  p=GWEN_Memory_realloc(bf->realPtr, nsize+1);
314  }
315  if (!p) {
316  DBG_ERROR(GWEN_LOGDOMAIN, "Realloc failed.");
317  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
318  abort();
319  }
320  return GWEN_ERROR_MEMORY_FULL;
321  }
322 
323  /* store new size and pointer */
324  bf->realPtr=p;
325  bf->ptr=bf->realPtr+reserved;
326  bf->realBufferSize=nsize;
327  bf->bufferSize+=noffs;
328  }
329 
330  return 0;
331 }
332 
333 
334 
336  const char *buffer,
337  uint32_t size){
338  int rv;
339 
340  assert(bf);
341 
342  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
343  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
344  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
345  abort();
346  return GWEN_ERROR_PERMISSIONS;
347  }
348  }
349 
350  rv=GWEN_Buffer_AllocRoom(bf, size+1);
351  if (rv<0) {
352  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
353  return rv;
354  }
355  /* if (bf->pos+size>bf->bufferSize) { */
356  if (bf->bytesUsed+size>bf->bufferSize) {
357  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
358  /*bf->pos, size,*/
359  bf->bytesUsed, size+1,
360  bf->bufferSize);
362  }
363 
364  memmove(bf->ptr+bf->bytesUsed, buffer, size);
365  /*bf->pos+=size;*/
366  if (bf->pos==bf->bytesUsed)
367  bf->pos+=size;
368  bf->bytesUsed+=size;
369  /* append a NULL to allow using the buffer as ASCIIZ string */
370  bf->ptr[bf->bytesUsed]=0;
371  return 0;
372 }
373 
374 
375 
377  int rv;
378 
379  assert(bf);
380 
381  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
382  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
383  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
384  abort();
385  return GWEN_ERROR_PERMISSIONS;
386  }
387  }
388 
389  if (bf->bytesUsed+1+1 > bf->bufferSize) {
390  rv=GWEN_Buffer_AllocRoom(bf, 1+1);
391  if (rv<0) {
392  DBG_DEBUG(GWEN_LOGDOMAIN, "here");
393  return rv;
394  }
395  }
396 
397  bf->ptr[bf->bytesUsed]=c;
398  if (bf->pos == bf->bytesUsed)
399  bf->pos++;
400  /* append a NULL to allow using the buffer as ASCIIZ string */
401  bf->ptr[++(bf->bytesUsed)]=0;
402  return 0;
403 }
404 
405 
406 
408  if (bf->syncIo) {
409  uint32_t toread;
410  int rv;
411 
412  toread=bf->pos-bf->bytesUsed+1;
413  if (GWEN_Buffer_AllocRoom(bf, toread+1)) {
414  DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
415  return GWEN_ERROR_GENERIC;
416  }
417  rv=GWEN_SyncIo_ReadForced(bf->syncIo,
418  (uint8_t*) (bf->ptr+bf->bytesUsed),
419  toread);
420  if (rv<0) {
421  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
422  return rv;
423  }
424  else if (rv==0) {
425  DBG_INFO(GWEN_LOGDOMAIN, "EOF met");
426  return GWEN_ERROR_EOF;
427  }
428 
429  bf->bytesUsed+=rv;
430  }
431  else {
433  "End of used area reached and no SYNCIO (%d bytes)",
434  bf->pos);
435  return GWEN_ERROR_EOF;
436  }
437  return 0;
438 }
439 
440 
441 
443  assert(bf);
444  if (bf->mode & GWEN_BUFFER_MODE_USE_SYNCIO)
446  else {
448  "End of used area reached (%d bytes)", bf->pos);
449  return GWEN_ERROR_EOF;
450  }
451 }
452 
453 
454 
456  assert(bf);
457 
458  if (bf->pos>=bf->bytesUsed) {
459  int rv;
460 
462  if (rv<0) {
463  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
464  return rv;
465  }
466  }
467 
468  return (unsigned char) (bf->ptr[bf->pos]);
469 }
470 
471 
472 
474  assert(bf);
475 
476  if (bf->pos>=bf->bytesUsed) {
477  int rv;
478 
480  if (rv<0) {
481  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
482  return rv;
483  }
484  }
485 
486  return (unsigned char) (bf->ptr[bf->pos++]);
487 }
488 
489 
490 
492  assert(bf);
493 
494  if (i+bf->pos>=bf->bufferSize) {
495  if (!(bf->mode & GWEN_BUFFER_MODE_USE_SYNCIO)) {
497  "Position %d outside buffer boundaries (%d bytes)\n"
498  "Incrementing anyway",
499  i+bf->pos, bf->bufferSize);
500  }
501  }
502 
503  bf->pos+=i;
504  return 0;
505 }
506 
507 
508 
510  assert(bf);
511  if (bf->pos<=bf->bufferSize) {
512  if (bf->pos>bf->bytesUsed) {
513  DBG_DEBUG(GWEN_LOGDOMAIN, "Adjusted buffer (uses now %d bytes)",
514  bf->pos);
515  bf->bytesUsed=bf->pos;
516  }
517  /* append a NULL to allow using the buffer as ASCIIZ string */
518  bf->ptr[bf->bytesUsed]=0;
519  return 0;
520  }
521  else {
522  DBG_ERROR(GWEN_LOGDOMAIN, "Pointer outside buffer size (%d bytes)",
523  bf->bufferSize);
525  }
526 }
527 
528 
529 
531  assert(bf);
532 
533  if (bf->pos<i) {
535  "Position %d outside buffer boundaries (%d bytes)",
536  bf->pos-i, bf->bufferSize);
538  }
539  bf->pos-=i;
540  return 0;
541 }
542 
543 
544 
546 
547  assert(bf);
548  assert(sf);
549 
550  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
551  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
552  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
553  abort();
554  return GWEN_ERROR_PERMISSIONS;
555  }
556  }
557 
558  if (sf->bytesUsed)
559  return GWEN_Buffer_AppendBytes(bf, sf->ptr, sf->bytesUsed);
560  return 0;
561 }
562 
563 
564 
566  assert(bf);
567 
568  return (bf->bufferSize-bf->bytesUsed);
569 }
570 
571 
572 
574  assert(bf);
575 
576  if (bf->pos<bf->bytesUsed)
577  return bf->bytesUsed-bf->pos;
578  else
579  return 0;
580 }
581 
582 
583 
585  assert(bf);
586  return bf->ptr+bf->pos;
587 }
588 
589 
590 
591 uint32_t GWEN_Buffer_GetBookmark(const GWEN_BUFFER *bf, unsigned int idx){
592  assert(bf);
593  assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
594  return bf->bookmarks[idx];
595 }
596 
597 
598 
599 void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx,
600  uint32_t v){
601  assert(bf);
602  assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
603  bf->bookmarks[idx]=v;
604 }
605 
606 
607 
608 void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert) {
609  uint32_t k;
610 
611  for (k=0; k<insert; k++)
612  fprintf(stderr, " ");
613  fprintf(stderr, "Buffer:\n");
614 
615  for (k=0; k<insert; k++)
616  fprintf(stderr, " ");
617  fprintf(stderr, "Pos : %d (%04x)\n", bf->pos, bf->pos);
618 
619  for (k=0; k<insert; k++)
620  fprintf(stderr, " ");
621  fprintf(stderr, "Buffer Size : %d\n", bf->bufferSize);
622 
623  for (k=0; k<insert; k++)
624  fprintf(stderr, " ");
625  fprintf(stderr, "Hard limit : %d\n", bf->hardLimit);
626 
627  for (k=0; k<insert; k++)
628  fprintf(stderr, " ");
629  fprintf(stderr, "Bytes Used : %d\n", bf->bytesUsed);
630 
631  for (k=0; k<insert; k++)
632  fprintf(stderr, " ");
633  fprintf(stderr, "Bytes Reserved : %u\n",
634  (uint32_t)(bf->ptr-bf->realPtr));
635 
636  for (k=0; k<insert; k++)
637  fprintf(stderr, " ");
638  fprintf(stderr, "Flags : %08x ( ", bf->flags);
639  if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
640  fprintf(stderr, "OWNED ");
641  fprintf(stderr, ")\n");
642 
643  for (k=0; k<insert; k++)
644  fprintf(stderr, " ");
645  fprintf(stderr, "Mode : %08x ( ", bf->mode);
646  if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
647  fprintf(stderr, "DYNAMIC ");
648  if (bf->mode & GWEN_BUFFER_MODE_READONLY)
649  fprintf(stderr, "READONLY ");
650  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL)
651  fprintf(stderr, "ABORT_ON_MEMFULL ");
652  fprintf(stderr, ")\n");
653 
654  for (k=0; k<insert; k++)
655  fprintf(stderr, " ");
656  fprintf(stderr, "Bookmarks :");
657  for (k=0; k<GWEN_BUFFER_MAX_BOOKMARKS; k++)
658  fprintf(stderr, " %d", bf->bookmarks[k]);
659  fprintf(stderr, "\n");
660 
661  if (bf->ptr && bf->bytesUsed) {
662  for (k=0; k<insert; k++)
663  fprintf(stderr, " ");
664  fprintf(stderr, "Data:\n");
665  GWEN_Text_DumpString(bf->ptr, bf->bytesUsed, insert+1);
666  }
667 }
668 
669 
670 
672  assert(bf);
673  bf->pos=0;
674  bf->bytesUsed=0;
675  bf->ptr[0]=0;
676 }
677 
678 
679 
681  assert(bf);
682  bf->pos=0;
683 }
684 
685 
686 
687 int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf, char *buffer, uint32_t *size){
688  /* optimized for speed */
689  uint32_t i;
690  char *pdst;
691 
692  DBG_VERBOUS(GWEN_LOGDOMAIN, "About to copy up to %d bytes", *size);
693  i=0;
694  pdst=buffer;
695 
696  while(i<*size) {
697  int j;
698  int srcLeft;
699 
700  if (bf->pos>=bf->bytesUsed) {
701  if (GWEN_Buffer__FillBuffer(bf)) {
702  DBG_DEBUG(GWEN_LOGDOMAIN, "Could not fill buffer, but that's ok");
703  break;
704  }
705  }
706 
707  srcLeft=bf->bytesUsed - bf->pos;
708  if (srcLeft==0)
709  break;
710  j=(*size)-i;
711  if (j>srcLeft)
712  j=srcLeft;
713  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copying %d bytes", j);
714  memmove(pdst, bf->ptr + bf->pos, j);
715  pdst+=j;
716  i+=j;
717  bf->pos+=j;
718  } /* while */
719 
720  *size=i;
721  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copied %d bytes", *size);
722  return 0;
723 }
724 
725 
726 
728  assert(bf);
729  return bf->step;
730 }
731 
732 
733 
734 void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step){
735  assert(bf);
736  bf->step=step;
737 }
738 
739 
740 
742  uint32_t pos,
743  int offset) {
744  uint32_t i;
745 
746  assert(bf);
747  for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++) {
748  if (bf->bookmarks[i]>=pos)
749  bf->bookmarks[i]+=offset;
750  } /* for */
751 }
752 
753 
754 
756  uint32_t size){
757  char *p;
758  int i;
759  int rv;
760 
761  assert(bf);
762 
763  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
764  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
765  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
766  abort();
767  return GWEN_ERROR_PERMISSIONS;
768  }
769  }
770 
771  if (bf->pos==0) {
772  if (bf->bytesUsed==0) {
773  /* no bytes used, simply return */
774  rv=GWEN_Buffer_AllocRoom(bf, size);
775  if (rv) {
776  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
777  return rv;
778  }
779  bf->bytesUsed+=size;
780  /* append "0" behind buffer */
781  bf->ptr[bf->bytesUsed]=0;
782  return 0;
783  }
784  else {
785  if ( (bf->ptr - bf->realPtr) >= (int)size ) {
786  /* simply occupy the reserved space */
787  bf->ptr-=size;
788  bf->bytesUsed+=size;
789  bf->bufferSize+=size;
790  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
791  return 0;
792  }
793  }
794  }
795 
796  rv=GWEN_Buffer_AllocRoom(bf, size);
797  if (rv<0) {
798  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
799  return rv;
800  }
801  if (bf->pos+size>bf->bufferSize) {
802  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
803  bf->pos, size,
804  bf->bufferSize);
806  }
807  p=bf->ptr+bf->pos;
808  i=bf->bytesUsed-bf->pos;
809  if (i>0)
810  /* move current data at pos out of the way */
811  memmove(p+size, p, i);
812  bf->bytesUsed+=size;
813  /* append "0" behind buffer */
814  bf->ptr[bf->bytesUsed]=0;
815  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
816  return 0;
817 }
818 
819 
820 
821 int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size){
822  char *p;
823  int i;
824 
825  assert(bf);
826 
827  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
828  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
829  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
830  abort();
831  return GWEN_ERROR_PERMISSIONS;
832  }
833  }
834 
835  if (bf->pos==0) {
836  if (bf->bytesUsed<size) {
837  /* can't remove bytes we don't have */
838  return GWEN_ERROR_INVALID;
839  }
840  /* simply add to reserved space */
841  bf->ptr+=size;
842  bf->bytesUsed-=size;
843  bf->bufferSize-=size;
844  }
845  else {
846  if (bf->bytesUsed+size<(bf->bytesUsed)) {
847  /* can't remove more bytes than we have */
848  return GWEN_ERROR_INVALID;
849  }
850 
851  /* we need to get the rest closer */
852  p=bf->ptr+bf->pos+size;
853  i=bf->bytesUsed-bf->pos-size;
854  memmove(bf->ptr+bf->pos, p, i);
855  bf->bytesUsed+=size;
856  }
857 
858  /* append "0" behind buffer */
859  bf->ptr[bf->bytesUsed]=0;
860  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, -((int)size));
861 
862  return 0;
863 }
864 
865 
866 
868  uint32_t rsize,
869  const char *buffer,
870  uint32_t size){
871  int32_t d;
872  int rv;
873 
874  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
875  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
876  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
877  abort();
878  return GWEN_ERROR_PERMISSIONS;
879  }
880  }
881 
882  /* either insert or remove bytes */
883  d=size-rsize;
884  if (d<0) {
885  rv=GWEN_Buffer_RemoveRoom(bf, -d);
886  }
887  else if (d>0) {
888  rv=GWEN_Buffer_InsertRoom(bf, d);
889  }
890  else
891  /* nothing to adjust if sizes are the same */
892  rv=0;
893  if (rv) {
895  "Error replacing %d bytes with %d bytes (%d)",
896  rsize, size, rv);
897  return rv;
898  }
899 
900  /* write new bytes */
901  if (size)
902  memmove(bf->ptr+bf->pos, buffer, size);
903  return 0;
904 }
905 
906 
907 
909  const char *buffer,
910  uint32_t size){
911  int rv;
912 
913  assert(bf);
914  assert(buffer);
915 
916  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
917  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
918  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
919  abort();
920  return GWEN_ERROR_PERMISSIONS;
921  }
922  }
923 
924  rv=GWEN_Buffer_InsertRoom(bf, size);
925  if (rv<0) {
926  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
927  return rv;
928  }
929  memmove(bf->ptr+bf->pos, buffer, size);
930  return 0;
931 }
932 
933 
934 
936  int rv;
937 
938  assert(bf);
939 
940  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
941  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
942  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
943  abort();
944  return GWEN_ERROR_PERMISSIONS;
945  }
946  }
947 
948  rv=GWEN_Buffer_InsertRoom(bf, 1);
949  if (rv<0) {
950  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
951  return rv;
952  }
953  bf->ptr[bf->pos]=c;
954  return 0;
955 }
956 
957 
958 
960  GWEN_BUFFER *sf){
961  assert(bf);
962  assert(sf);
963 
964  return GWEN_Buffer_InsertBytes(bf, sf->ptr, sf->bytesUsed);
965 }
966 
967 
968 
970  uint32_t pos,
971  uint32_t l) {
972 
973  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
974  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
975  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
976  abort();
977  return GWEN_ERROR_PERMISSIONS;
978  }
979  }
980 
981  if (pos>=bf->bufferSize) {
982  DBG_ERROR(GWEN_LOGDOMAIN, "Position outside buffer");
983  return -1;
984  }
985  bf->ptr+=pos;
986  bf->bufferSize-=pos;
987  bf->pos-=pos;
988  if (bf->bytesUsed-pos<l) {
989  DBG_INFO(GWEN_LOGDOMAIN, "Invalid length");
990  return -1;
991  }
992  bf->bytesUsed=l;
993  GWEN_Buffer_AdjustBookmarks(bf, pos, -pos);
994  /* adjust position after possible truncation */
995  if (bf->pos>bf->bytesUsed)
996  bf->pos=bf->bytesUsed;
997 
998  bf->ptr[bf->bytesUsed]=0;
999 
1000  return 0;
1001 }
1002 
1003 
1004 
1006  const char *buffer){
1007  assert(bf);
1008  assert(buffer);
1009  return GWEN_Buffer_AppendBytes(bf, buffer, strlen(buffer));
1010 }
1011 
1012 
1013 
1015  const char *buffer){
1016  assert(bf);
1017  assert(buffer);
1018  return GWEN_Buffer_InsertBytes(bf, buffer, strlen(buffer));
1019 }
1020 
1021 
1022 
1024  GWEN_SYNCIO *sio,
1025  int take) {
1026  assert(bf);
1027  if (bf->syncIo) {
1028  if (bf->flags & GWEN_BUFFER_FLAGS_OWN_SYNCIO) {
1029  GWEN_SyncIo_free(bf->syncIo);
1030  }
1031  }
1032  if (take)
1033  bf->flags|=GWEN_BUFFER_FLAGS_OWN_SYNCIO;
1034  else
1035  bf->flags&=~GWEN_BUFFER_FLAGS_OWN_SYNCIO;
1036  bf->syncIo=sio;
1037 }
1038 
1039 
1040 
1042  unsigned char c,
1043  uint32_t size){
1044  int rv;
1045 
1046  assert(bf);
1047 
1048  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
1049  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
1050  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
1051  abort();
1052  return GWEN_ERROR_PERMISSIONS;
1053  }
1054  }
1055 
1056  rv=GWEN_Buffer_AllocRoom(bf, size+1);
1057  if (rv<0) {
1058  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
1059  return rv;
1060  }
1061  /* if (bf->pos+size>bf->bufferSize) { */
1062  if (bf->bytesUsed+size>bf->bufferSize) {
1063  DBG_ERROR(GWEN_LOGDOMAIN, "Buffer full (%d [%d] of %d bytes)",
1064  bf->bytesUsed, size+1,
1065  bf->bufferSize);
1067  }
1068  memset(bf->ptr+bf->bytesUsed, c, size);
1069  if (bf->pos==bf->bytesUsed)
1070  bf->pos+=size;
1071  bf->bytesUsed+=size;
1072  /* append a NULL to allow using the buffer as ASCIIZ string */
1073  bf->ptr[bf->bytesUsed]=0;
1074  return 0;
1075 }
1076 
1077 
1078 
1080  unsigned char c,
1081  uint32_t size){
1082  int rv;
1083 
1084  assert(bf);
1085 
1086  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
1087  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
1088  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
1089  abort();
1090  return GWEN_ERROR_PERMISSIONS;
1091  }
1092  }
1093 
1094  rv=GWEN_Buffer_InsertRoom(bf, size);
1095  if (rv<0) {
1096  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1097  return -1;
1098  }
1099  memset(bf->ptr+bf->pos, c, size);
1100  return 0;
1101 }
1102 
1103 
1104 
1105 
1106 
1107 
1108