gwenhywfar  5.1.2
buffer.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Fri Sep 12 2003
3  copyright : (C) 2020 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 {
43  GWEN_BUFFER *bf;
44 
46  bf->_refCount=1;
47  if (!buffer) {
48  /* allocate buffer */
49  bf->realPtr=(char *)GWEN_Memory_malloc(size?(size+1):0);
50  assert(bf->realPtr);
51  bf->ptr=bf->realPtr;
52  bf->realBufferSize=size+1;
53  bf->bufferSize=size+1;
54  bf->flags=GWEN_BUFFER_FLAGS_OWNED;
55  bf->bytesUsed=used;
56  bf->ptr[0]=0;
57  }
58  else {
59  /* use existing buffer */
60  bf->realPtr=buffer;
61  bf->ptr=buffer;
62  bf->realBufferSize=size;
63  bf->bufferSize=size;
64  bf->bytesUsed=used;
65  if (take)
66  bf->flags=GWEN_BUFFER_FLAGS_OWNED;
67  }
68 
69  bf->mode=GWEN_BUFFER_MODE_DEFAULT;
70  bf->hardLimit=GWEN_BUFFER_DEFAULT_HARDLIMIT;
71  bf->step=GWEN_BUFFER_DYNAMIC_STEP;
72  return bf;
73 }
74 
75 
76 
78 {
79  assert(bf->_refCount);
80  bf->_refCount++;
81 }
82 
83 
84 
86 {
87  if (bf) {
88  assert(bf->_refCount);
89  if (bf->_refCount==1) {
90  if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
91  GWEN_Memory_dealloc(bf->realPtr);
92  GWEN_FREE_OBJECT(bf);
93  }
94  else
95  bf->_refCount--;
96  }
97 }
98 
99 
100 
102 {
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)?(bf->realBufferSize+1):0);
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 {
141  assert(bf);
142  if (!(bf->flags & GWEN_BUFFER_FLAGS_OWNED))
143  return GWEN_ERROR_INVALID;
144  if (bf->realPtr!=bf->ptr)
145  return GWEN_ERROR_INVALID;
146 
147  bf->flags&=~GWEN_BUFFER_FLAGS_OWNED;
148  return 0;
149 }
150 
151 
152 
153 int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res)
154 {
155  assert(bf);
156  if (!res)
157  return 0;
158 
159  if (bf->bytesUsed) {
160  /* we need to move data */
161  if (GWEN_Buffer_AllocRoom(bf, res))
162  return -1;
163 
164  memmove(bf->ptr+res, bf->ptr, bf->bytesUsed);
165  bf->ptr+=res;
166  bf->bufferSize-=res;
167  return 0;
168  }
169  else {
170  /* no data in buffer, so simply move ptrs */
171  if (GWEN_Buffer_AllocRoom(bf, res))
172  return -1;
173 
174  bf->ptr+=res;
175  bf->bufferSize-=res;
176  if (bf->bufferSize)
177  bf->ptr[0]=0;
178  return 0;
179  }
180 }
181 
182 
183 
185 {
186  assert(bf);
187  return bf->mode;
188 }
189 
190 
191 
192 void GWEN_Buffer_SetMode(GWEN_BUFFER *bf, uint32_t mode)
193 {
194  assert(bf);
195  bf->mode=mode;
196 }
197 
198 
199 void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode)
200 {
201  assert(bf);
202  bf->mode|=mode;
203 }
204 
205 
206 void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode)
207 {
208  assert(bf);
209  bf->mode&=~mode;
210 }
211 
212 
213 
215 {
216  assert(bf);
217  return bf->hardLimit;
218 }
219 
220 
221 
223 {
224  assert(bf);
225  assert(l);
226  bf->hardLimit=l;
227 }
228 
229 
230 
232 {
233  assert(bf);
234  return bf->ptr;
235 }
236 
237 
238 
239 uint32_t GWEN_Buffer_GetSize(const GWEN_BUFFER *bf)
240 {
241  assert(bf);
242  if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
243  return bf->hardLimit;
244  return bf->bufferSize;
245 }
246 
247 
248 
249 uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
250 {
251  assert(bf);
252  return bf->pos;
253 }
254 
255 
256 
257 int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
258 {
259  assert(bf);
260 
261  if (i>=bf->bufferSize) {
263  "Position %d outside buffer boundaries (%d bytes)",
264  i, (int)(bf->bufferSize));
266  }
267  bf->pos=i;
268  return 0;
269 }
270 
271 
272 
274 {
275  assert(bf);
276  return bf->bytesUsed;
277 }
278 
279 
280 
281 int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
282 {
283  assert(bf);
284  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
285  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
286  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
287  abort();
288  }
289  return GWEN_ERROR_PERMISSIONS;
290  }
291  /*DBG_VERBOUS(GWEN_LOGDOMAIN, "Allocating %d bytes", size);*/
292  if (bf->bytesUsed+(size+1) > bf->bufferSize) {
293  /* need to realloc */
294  uint32_t nsize;
295  uint32_t noffs;
296  uint32_t reserved;
297  void *p;
298 
299  /* check for dynamic mode */
300  if (!(bf->mode & GWEN_BUFFER_MODE_DYNAMIC)) {
301  DBG_ERROR(GWEN_LOGDOMAIN, "Not in dynamic mode");
302  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
303  abort();
304  }
306  }
307 
308  /* calculate reserved bytes (to set ptr later) */
309  reserved=bf->ptr-bf->realPtr;
310  /* this is the raw number of bytes we need (we always add a NULL
311  * character) */
312  nsize=bf->bytesUsed+(size+1)-bf->bufferSize;
313  /* round it up */
314  nsize=(nsize+(bf->step-1));
315  nsize&=~(bf->step-1);
316  /* store number of additional bytes to allocate */
317  noffs=nsize;
318  /* add current size to it */
319  nsize+=bf->realBufferSize;
320  if (nsize>bf->hardLimit) {
322  "Size is beyond hard limit (%d>%d)",
323  (int) nsize, (int)(bf->hardLimit));
324  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
325  abort();
326  }
328  }
329  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reallocating from %d to %d bytes",
330  bf->bufferSize, nsize);
331  if (bf->realPtr==NULL) {
332  p=GWEN_Memory_malloc(nsize?(nsize+1):0);
333  }
334  else {
335  p=GWEN_Memory_realloc(bf->realPtr, nsize?(nsize+1):0);
336  }
337  if (!p) {
338  DBG_ERROR(GWEN_LOGDOMAIN, "Realloc failed.");
339  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
340  abort();
341  }
342  return GWEN_ERROR_MEMORY_FULL;
343  }
344 
345  /* store new size and pointer */
346  bf->realPtr=(char *)p;
347  bf->ptr=bf->realPtr+reserved;
348  bf->realBufferSize=nsize;
349  bf->bufferSize+=noffs;
350  }
351 
352  return 0;
353 }
354 
355 
356 
358  const char *buffer,
359  uint32_t size)
360 {
361  int rv;
362 
363  assert(bf);
364 
365  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
366  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
367  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
368  abort();
369  }
370  return GWEN_ERROR_PERMISSIONS;
371  }
372 
373  rv=GWEN_Buffer_AllocRoom(bf, size+1);
374  if (rv<0) {
375  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
376  return rv;
377  }
378 
379  memmove(bf->ptr+bf->bytesUsed, buffer, size);
380  if (bf->pos==bf->bytesUsed)
381  bf->pos+=size;
382  bf->bytesUsed+=size;
383  /* append a NULL to allow using the buffer as ASCIIZ string */
384  bf->ptr[bf->bytesUsed]=0;
385  return 0;
386 }
387 
388 
389 
391 {
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  }
401  return GWEN_ERROR_PERMISSIONS;
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 {
424  assert(bf);
425 
426  if (bf->pos>=bf->bytesUsed) {
427  return GWEN_ERROR_EOF;
428  }
429 
430  return (unsigned char)(bf->ptr[bf->pos]);
431 }
432 
433 
434 
436 {
437  assert(bf);
438 
439  if (bf->pos>=bf->bytesUsed) {
440  return GWEN_ERROR_EOF;
441  }
442 
443  return (unsigned char)(bf->ptr[bf->pos++]);
444 }
445 
446 
447 
449 {
450  assert(bf);
451 
452  if (i+bf->pos>=bf->bufferSize) {
454  "Position %d outside buffer boundaries (%d bytes)\n"
455  "Incrementing anyway",
456  i+bf->pos, bf->bufferSize);
457  }
458 
459  bf->pos+=i;
460  return 0;
461 }
462 
463 
464 
466 {
467  assert(bf);
468  if (bf->pos<=bf->bufferSize) {
469  if (bf->pos>bf->bytesUsed) {
470  DBG_DEBUG(GWEN_LOGDOMAIN, "Adjusted buffer (uses now %d bytes)",
471  bf->pos);
472  bf->bytesUsed=bf->pos;
473  }
474  /* append a NULL to allow using the buffer as ASCIIZ string */
475  bf->ptr[bf->bytesUsed]=0; /* TODO: This has to be checked (is it okay to add a byte here?)! */
476  return 0;
477  }
478  else {
479  DBG_ERROR(GWEN_LOGDOMAIN, "Pointer outside buffer size (%d bytes)",
480  (int)(bf->bufferSize));
482  }
483 }
484 
485 
486 
488 {
489  assert(bf);
490 
491  if (bf->pos<i) {
493  "Position %d outside buffer boundaries (%d bytes)",
494  bf->pos-i, bf->bufferSize);
496  }
497  bf->pos-=i;
498  return 0;
499 }
500 
501 
502 
504 {
505 
506  assert(bf);
507  assert(sf);
508 
509  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
510  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
511  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
512  abort();
513  }
514  return GWEN_ERROR_PERMISSIONS;
515  }
516 
517  if (sf->bytesUsed)
518  return GWEN_Buffer_AppendBytes(bf, sf->ptr, sf->bytesUsed);
519  return 0;
520 }
521 
522 
523 
525 {
526  assert(bf);
527 
528  return (bf->bufferSize-(bf->bytesUsed+1));
529 }
530 
531 
532 
534 {
535  assert(bf);
536 
537  if (bf->pos<bf->bytesUsed)
538  return bf->bytesUsed-bf->pos;
539  else
540  return 0;
541 }
542 
543 
544 
546 {
547  assert(bf);
548  return bf->ptr+bf->pos;
549 }
550 
551 
552 
554 {
555  assert(bf);
556  if (bf->realPtr && bf->realBufferSize) {
557  memset(bf->realPtr, c, bf->realBufferSize);
558  }
559 }
560 
561 
562 
563 uint32_t GWEN_Buffer_GetBookmark(const GWEN_BUFFER *bf, unsigned int idx)
564 {
565  assert(bf);
566  assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
567  return bf->bookmarks[idx];
568 }
569 
570 
571 
572 void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx,
573  uint32_t v)
574 {
575  assert(bf);
576  assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
577  bf->bookmarks[idx]=v;
578 }
579 
580 
581 
582 void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert)
583 {
584  uint32_t k;
585 
586  for (k=0; k<insert; k++)
587  fprintf(stderr, " ");
588  fprintf(stderr, "Buffer:\n");
589 
590  for (k=0; k<insert; k++)
591  fprintf(stderr, " ");
592  fprintf(stderr, "Pos : %d (%04x)\n", bf->pos, bf->pos);
593 
594  for (k=0; k<insert; k++)
595  fprintf(stderr, " ");
596  fprintf(stderr, "Buffer Size : %d\n", bf->bufferSize);
597 
598  for (k=0; k<insert; k++)
599  fprintf(stderr, " ");
600  fprintf(stderr, "Hard limit : %d\n", bf->hardLimit);
601 
602  for (k=0; k<insert; k++)
603  fprintf(stderr, " ");
604  fprintf(stderr, "Bytes Used : %d\n", bf->bytesUsed);
605 
606  for (k=0; k<insert; k++)
607  fprintf(stderr, " ");
608  fprintf(stderr, "Bytes Reserved : %u\n",
609  (uint32_t)(bf->ptr-bf->realPtr));
610 
611  for (k=0; k<insert; k++)
612  fprintf(stderr, " ");
613  fprintf(stderr, "Flags : %08x ( ", bf->flags);
614  if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
615  fprintf(stderr, "OWNED ");
616  fprintf(stderr, ")\n");
617 
618  for (k=0; k<insert; k++)
619  fprintf(stderr, " ");
620  fprintf(stderr, "Mode : %08x ( ", bf->mode);
621  if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
622  fprintf(stderr, "DYNAMIC ");
623  if (bf->mode & GWEN_BUFFER_MODE_READONLY)
624  fprintf(stderr, "READONLY ");
625  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL)
626  fprintf(stderr, "ABORT_ON_MEMFULL ");
627  fprintf(stderr, ")\n");
628 
629  for (k=0; k<insert; k++)
630  fprintf(stderr, " ");
631  fprintf(stderr, "Bookmarks :");
632  for (k=0; k<GWEN_BUFFER_MAX_BOOKMARKS; k++)
633  fprintf(stderr, " %d", bf->bookmarks[k]);
634  fprintf(stderr, "\n");
635 
636  if (bf->ptr && bf->bytesUsed) {
637  for (k=0; k<insert; k++)
638  fprintf(stderr, " ");
639  fprintf(stderr, "Data:\n");
640  GWEN_Text_DumpString(bf->ptr, bf->bytesUsed, insert+1);
641  }
642 }
643 
644 
645 
647 {
648  assert(bf);
649  bf->pos=0;
650  bf->bytesUsed=0;
651  bf->ptr[0]=0;
652 }
653 
654 
655 
657 {
658  assert(bf);
659  bf->pos=0;
660 }
661 
662 
663 
664 int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf, char *buffer, uint32_t *size)
665 {
666  /* optimized for speed */
667  uint32_t i;
668  char *pdst;
669 
670  DBG_VERBOUS(GWEN_LOGDOMAIN, "About to copy up to %d bytes", *size);
671  i=0;
672  pdst=buffer;
673 
674  while (i<*size) {
675  int j;
676  int srcLeft;
677 
678  if (bf->pos>=bf->bytesUsed)
679  break;
680 
681  srcLeft=bf->bytesUsed - bf->pos;
682  if (srcLeft==0)
683  break;
684  j=(*size)-i;
685  if (j>srcLeft)
686  j=srcLeft;
687  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copying %d bytes", j);
688  memmove(pdst, bf->ptr + bf->pos, j);
689  pdst+=j;
690  i+=j;
691  bf->pos+=j;
692  } /* while */
693 
694  *size=i;
695  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copied %d bytes", *size);
696  return 0;
697 }
698 
699 
700 
702 {
703  assert(bf);
704  return bf->step;
705 }
706 
707 
708 
709 void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step)
710 {
711  assert(bf);
712  bf->step=step;
713 }
714 
715 
716 
718  uint32_t pos,
719  int offset)
720 {
721  uint32_t i;
722 
723  assert(bf);
724  for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++) {
725  if (bf->bookmarks[i]>=pos)
726  bf->bookmarks[i]+=offset;
727  } /* for */
728 }
729 
730 
731 
733  uint32_t size)
734 {
735  char *p;
736  int i;
737  int rv;
738 
739  assert(bf);
740 
741  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
742  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
743  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
744  abort();
745  }
746  return GWEN_ERROR_PERMISSIONS;
747  }
748 
749  if (bf->pos==0) {
750  if (bf->bytesUsed==0) {
751  /* no bytes used, simply return */
752  rv=GWEN_Buffer_AllocRoom(bf, size);
753  if (rv) {
754  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
755  return rv;
756  }
757  bf->bytesUsed+=size;
758  /* append "0" behind buffer */
759  bf->ptr[bf->bytesUsed]=0;
760  return 0;
761  }
762  else {
763  if ((bf->ptr - bf->realPtr) >= (int)size) {
764  /* simply occupy the reserved space */
765  bf->ptr-=size;
766  bf->bytesUsed+=size;
767  bf->bufferSize+=size;
768  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
769  return 0;
770  }
771  }
772  }
773 
774  rv=GWEN_Buffer_AllocRoom(bf, size);
775  if (rv<0) {
776  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
777  return rv;
778  }
779  assert(bf->pos<=bf->bytesUsed);
780  p=bf->ptr+bf->pos;
781  i=bf->bytesUsed-bf->pos;
782  if (i>0)
783  /* move current data at pos out of the way */
784  memmove(p+size, p, i);
785  bf->bytesUsed+=size;
786  /* append "0" behind buffer */
787  bf->ptr[bf->bytesUsed]=0;
788  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
789  return 0;
790 }
791 
792 
793 
794 int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size)
795 {
796  char *p;
797  int i;
798 
799  assert(bf);
800 
801  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
802  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
803  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
804  abort();
805  }
806  return GWEN_ERROR_PERMISSIONS;
807  }
808 
809  if (bf->bytesUsed<size+bf->pos) {
810  /* can't remove more bytes than we have */
811  return GWEN_ERROR_INVALID;
812  }
813 
814  if (bf->pos==0) {
815  /* simply add to reserved space */
816  bf->ptr+=size;
817  bf->bytesUsed-=size;
818  bf->bufferSize-=size;
819  }
820  else {
821  /* we need to get the rest closer */
822  p=bf->ptr+bf->pos+size;
823  i=bf->bytesUsed-bf->pos-size;
824  memmove(bf->ptr+bf->pos, p, i);
825  bf->bytesUsed-=size;
826  }
827 
828  /* append "0" behind buffer */
829  bf->ptr[bf->bytesUsed]=0;
830  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, -((int)size));
831 
832  return 0;
833 }
834 
835 
836 
838  uint32_t rsize,
839  const char *buffer,
840  uint32_t size)
841 {
842  int32_t d;
843  int rv;
844 
845  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
846  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
847  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
848  abort();
849  }
850  return GWEN_ERROR_PERMISSIONS;
851  }
852 
853  /* either insert or remove bytes */
854  d=size-rsize;
855  if (d<0) {
856  rv=GWEN_Buffer_RemoveRoom(bf, -d);
857  }
858  else if (d>0) {
859  rv=GWEN_Buffer_InsertRoom(bf, d);
860  }
861  else
862  /* nothing to adjust if sizes are the same */
863  rv=0;
864  if (rv) {
866  "Error replacing %d bytes with %d bytes (%d)",
867  rsize, size, rv);
868  return rv;
869  }
870 
871  /* write new bytes */
872  if (size)
873  memmove(bf->ptr+bf->pos, buffer, size);
874  return 0;
875 }
876 
877 
878 
880  const char *buffer,
881  uint32_t size)
882 {
883  int rv;
884 
885  assert(bf);
886  assert(buffer);
887 
888  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
889  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
890  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
891  abort();
892  }
893  return GWEN_ERROR_PERMISSIONS;
894  }
895 
896  rv=GWEN_Buffer_InsertRoom(bf, size);
897  if (rv<0) {
898  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
899  return rv;
900  }
901  memmove(bf->ptr+bf->pos, buffer, size);
902  return 0;
903 }
904 
905 
906 
908 {
909  int rv;
910 
911  assert(bf);
912 
913  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
914  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
915  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
916  abort();
917  }
918  return GWEN_ERROR_PERMISSIONS;
919  }
920 
921  rv=GWEN_Buffer_InsertRoom(bf, 1);
922  if (rv<0) {
923  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
924  return rv;
925  }
926  bf->ptr[bf->pos]=c;
927  return 0;
928 }
929 
930 
931 
933  GWEN_BUFFER *sf)
934 {
935  assert(bf);
936  assert(sf);
937 
938  return GWEN_Buffer_InsertBytes(bf, sf->ptr, sf->bytesUsed);
939 }
940 
941 
942 
944  uint32_t pos,
945  uint32_t l)
946 {
947  int offset;
948 
949  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
950  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
951  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
952  abort();
953  }
954  return GWEN_ERROR_PERMISSIONS;
955  }
956 
957  if (pos>=bf->bufferSize) {
958  DBG_ERROR(GWEN_LOGDOMAIN, "Position outside buffer");
959  return -1;
960  }
961  if (bf->bytesUsed-pos<l) {
962  DBG_INFO(GWEN_LOGDOMAIN, "Invalid length");
963  return -1;
964  }
965  bf->ptr+=pos;
966  bf->bufferSize-=pos;
967  if (bf->pos>pos)
968  offset=pos;
969  else
970  offset=bf->pos;
971  bf->pos-=offset;
972  bf->bytesUsed=l;
973  /* adjust position after possible truncation */
974  if (bf->pos>bf->bytesUsed)
975  bf->pos=bf->bytesUsed;
976 
977  bf->ptr[bf->bytesUsed]=0;
978  GWEN_Buffer_AdjustBookmarks(bf, offset, -offset);
979 
980  return 0;
981 }
982 
983 
984 
986  const char *buffer)
987 {
988  assert(bf);
989  assert(buffer);
990  return GWEN_Buffer_AppendBytes(bf, buffer, strlen(buffer));
991 }
992 
993 
994 
996  const char *buffer)
997 {
998  assert(bf);
999  assert(buffer);
1000  return GWEN_Buffer_InsertBytes(bf, buffer, strlen(buffer));
1001 }
1002 
1003 
1004 
1006  unsigned char c,
1007  uint32_t size)
1008 {
1009  int rv;
1010 
1011  assert(bf);
1012 
1013  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
1014  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
1015  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
1016  abort();
1017  }
1018  return GWEN_ERROR_PERMISSIONS;
1019  }
1020 
1021  rv=GWEN_Buffer_AllocRoom(bf, size+1);
1022  if (rv<0) {
1023  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
1024  return rv;
1025  }
1026  memset(bf->ptr+bf->bytesUsed, c, size);
1027  if (bf->pos==bf->bytesUsed)
1028  bf->pos+=size;
1029  bf->bytesUsed+=size;
1030  /* append a NULL to allow using the buffer as ASCIIZ string */
1031  bf->ptr[bf->bytesUsed]=0;
1032  return 0;
1033 }
1034 
1035 
1036 
1038  unsigned char c,
1039  uint32_t size)
1040 {
1041  int rv;
1042 
1043  assert(bf);
1044 
1045  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
1046  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
1047  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
1048  abort();
1049  }
1050  return GWEN_ERROR_PERMISSIONS;
1051  }
1052 
1053  rv=GWEN_Buffer_InsertRoom(bf, size);
1054  if (rv<0) {
1055  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1056  return -1;
1057  }
1058  memset(bf->ptr+bf->pos, c, size);
1059  return 0;
1060 }
1061 
1062 
1063 
1065 {
1067  return 0;
1068 }
1069 
1070 
1071 
1073 {
1074  GWEN_Buffer_free((GWEN_BUFFER *) ptr);
1075  return 0;
1076 }
1077 
1078 
1079 
1080 
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
Definition: buffer.c:533
int GWEN_Buffer_FillLeftWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition: buffer.c:1037
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:231
int GWEN_Buffer_InsertString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:995
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:281
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
Definition: buffer.c:524
#define GWEN_ERROR_INVALID
Definition: error.h:67
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:273
void GWEN_Buffer_SetHardLimit(GWEN_BUFFER *bf, uint32_t l)
Definition: buffer.c:222
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition: text.c:1283
void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step)
Definition: buffer.c:709
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void GWEN_Memory_dealloc(void *p)
Definition: memory.c:69
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:217
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:465
#define GWEN_LOGDOMAIN
Definition: logger.h:35
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition: buffer.c:249
int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition: buffer.c:1005
int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res)
Definition: buffer.c:153
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
#define GWEN_ERROR_BUFFER_OVERFLOW
Definition: error.h:79
int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:794
void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert)
Definition: buffer.c:582
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:545
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:646
int GWENHYWFAR_CB GWEN_Buffer_CacheFn_Free(void *ptr)
Definition: buffer.c:1072
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:448
void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx, uint32_t v)
Definition: buffer.c:572
void GWEN_Buffer_AdjustBookmarks(GWEN_BUFFER *bf, uint32_t pos, int offset)
Definition: buffer.c:717
int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf)
Definition: buffer.c:422
uint32_t GWEN_Buffer_GetBookmark(const GWEN_BUFFER *bf, unsigned int idx)
Definition: buffer.c:563
void GWEN_Buffer_Attach(GWEN_BUFFER *bf)
Definition: buffer.c:77
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
uint32_t GWEN_Buffer_GetSize(const GWEN_BUFFER *bf)
Definition: buffer.c:239
void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:206
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:209
int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition: buffer.c:503
int GWEN_Buffer_InsertByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:907
int GWENHYWFAR_CB GWEN_Buffer_CacheFn_Attach(void *ptr)
Definition: buffer.c:1064
void * GWEN_Memory_malloc(size_t wsize)
Definition: memory.c:39
#define GWEN_BUFFER_MODE_DYNAMIC
Definition: buffer.h:66
void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:199
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:390
#define GWEN_ERROR_PERMISSIONS
Definition: error.h:126
int GWEN_Buffer_Relinquish(GWEN_BUFFER *bf)
Definition: buffer.c:139
GWEN_BUFFER * GWEN_Buffer_dup(GWEN_BUFFER *bf)
Definition: buffer.c:101
int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:487
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:85
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:943
void GWEN_Buffer_SetMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:192
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
uint32_t GWEN_Buffer_GetStep(GWEN_BUFFER *bf)
Definition: buffer.c:701
#define GWEN_ERROR_EOF
Definition: error.h:96
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:257
#define GWEN_BUFFER_MODE_ABORT_ON_MEMFULL
Definition: buffer.h:67
#define GWEN_BUFFER_MAX_BOOKMARKS
Definition: buffer.h:64
int GWEN_Buffer_InsertBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition: buffer.c:932
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
uint32_t GWEN_Buffer_GetMode(GWEN_BUFFER *bf)
Definition: buffer.c:184
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
Definition: buffer.c:435
#define GWEN_BUFFER_MODE_READONLY
Definition: buffer.h:68
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:357
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
Definition: buffer.c:656
void * GWEN_Memory_realloc(void *oldp, size_t nsize)
Definition: memory.c:59
int GWEN_Buffer_InsertRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:732
int GWEN_Buffer_InsertBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:879
uint32_t GWEN_Buffer_GetHardLimit(GWEN_BUFFER *bf)
Definition: buffer.c:214
int GWEN_Buffer_ReplaceBytes(GWEN_BUFFER *bf, uint32_t rsize, const char *buffer, uint32_t size)
Definition: buffer.c:837
int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf, char *buffer, uint32_t *size)
Definition: buffer.c:664
#define GWEN_ERROR_MEMORY_FULL
Definition: error.h:77
#define GWEN_BUFFER_MODE_DEFAULT
Definition: buffer.h:70
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:985
void GWEN_Buffer_OverwriteContent(GWEN_BUFFER *bf, int c)
Definition: buffer.c:553