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