gwenhywfar  4.99.8beta
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?(size+1):0);
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)?(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  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  }
280  return GWEN_ERROR_PERMISSIONS;
281  }
282  /*DBG_VERBOUS(GWEN_LOGDOMAIN, "Allocating %d bytes", size);*/
283  if (bf->bytesUsed+(size+1) > bf->bufferSize) {
284  /* need to realloc */
285  uint32_t nsize;
286  uint32_t noffs;
287  uint32_t reserved;
288  void *p;
289 
290  /* check for dynamic mode */
291  if (!(bf->mode & GWEN_BUFFER_MODE_DYNAMIC)) {
292  DBG_ERROR(GWEN_LOGDOMAIN, "Not in dynamic mode");
293  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
294  abort();
295  }
297  }
298 
299  /* calculate reserved bytes (to set ptr later) */
300  reserved=bf->ptr-bf->realPtr;
301  /* this is the raw number of bytes we need (we always add a NULL
302  * character) */
303  nsize=bf->bytesUsed+(size+1)-bf->bufferSize;
304  /* round it up */
305  nsize=(nsize+(bf->step-1));
306  nsize&=~(bf->step-1);
307  /* store number of additional bytes to allocate */
308  noffs=nsize;
309  /* add current size to it */
310  nsize+=bf->realBufferSize;
311  if (nsize>bf->hardLimit) {
313  "Size is beyond hard limit (%d>%d)",
314  nsize, bf->hardLimit);
315  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
316  abort();
317  }
319  }
320  DBG_VERBOUS(GWEN_LOGDOMAIN, "Reallocating from %d to %d bytes",
321  bf->bufferSize, nsize);
322  if (bf->realPtr==NULL) {
323  p=GWEN_Memory_malloc(nsize?(nsize+1):0);
324  }
325  else {
326  p=GWEN_Memory_realloc(bf->realPtr, nsize?(nsize+1):0);
327  }
328  if (!p) {
329  DBG_ERROR(GWEN_LOGDOMAIN, "Realloc failed.");
330  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
331  abort();
332  }
333  return GWEN_ERROR_MEMORY_FULL;
334  }
335 
336  /* store new size and pointer */
337  bf->realPtr=p;
338  bf->ptr=bf->realPtr+reserved;
339  bf->realBufferSize=nsize;
340  bf->bufferSize+=noffs;
341  }
342 
343  return 0;
344 }
345 
346 
347 
349  const char *buffer,
350  uint32_t size) {
351  int rv;
352 
353  assert(bf);
354 
355  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
356  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
357  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
358  abort();
359  }
360  return GWEN_ERROR_PERMISSIONS;
361  }
362 
363  rv=GWEN_Buffer_AllocRoom(bf, size+1);
364  if (rv<0) {
365  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
366  return rv;
367  }
368 
369  memmove(bf->ptr+bf->bytesUsed, buffer, size);
370  if (bf->pos==bf->bytesUsed)
371  bf->pos+=size;
372  bf->bytesUsed+=size;
373  /* append a NULL to allow using the buffer as ASCIIZ string */
374  bf->ptr[bf->bytesUsed]=0;
375  return 0;
376 }
377 
378 
379 
381  int rv;
382 
383  assert(bf);
384 
385  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
386  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
387  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
388  abort();
389  }
390  return GWEN_ERROR_PERMISSIONS;
391  }
392 
393  if (bf->bytesUsed+1+1 > bf->bufferSize) {
394  rv=GWEN_Buffer_AllocRoom(bf, 1+1);
395  if (rv<0) {
396  DBG_DEBUG(GWEN_LOGDOMAIN, "here");
397  return rv;
398  }
399  }
400 
401  bf->ptr[bf->bytesUsed]=c;
402  if (bf->pos == bf->bytesUsed)
403  bf->pos++;
404  /* append a NULL to allow using the buffer as ASCIIZ string */
405  bf->ptr[++(bf->bytesUsed)]=0;
406  return 0;
407 }
408 
409 
410 
412  if (bf->syncIo) {
413  uint32_t toread;
414  int rv;
415 
416  toread=bf->pos-bf->bytesUsed+1;
417  if (GWEN_Buffer_AllocRoom(bf, toread+1)) {
418  DBG_INFO(GWEN_LOGDOMAIN, "Buffer too small");
419  return GWEN_ERROR_GENERIC;
420  }
421  rv=GWEN_SyncIo_ReadForced(bf->syncIo,
422  (uint8_t*) (bf->ptr+bf->bytesUsed),
423  toread);
424  if (rv<0) {
425  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
426  return rv;
427  }
428  else if (rv==0) {
429  DBG_INFO(GWEN_LOGDOMAIN, "EOF met");
430  return GWEN_ERROR_EOF;
431  }
432 
433  bf->bytesUsed+=rv;
434  }
435  else {
437  "End of used area reached and no SYNCIO (%d bytes)",
438  bf->pos);
439  return GWEN_ERROR_EOF;
440  }
441  return 0;
442 }
443 
444 
445 
447  assert(bf);
448  if (bf->mode & GWEN_BUFFER_MODE_USE_SYNCIO)
450  else {
452  "End of used area reached (%d bytes)", bf->pos);
453  return GWEN_ERROR_EOF;
454  }
455 }
456 
457 
458 
460  assert(bf);
461 
462  if (bf->pos>=bf->bytesUsed) {
463  int rv;
464 
466  if (rv<0) {
467  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
468  return rv;
469  }
470  }
471 
472  return (unsigned char) (bf->ptr[bf->pos]);
473 }
474 
475 
476 
478  assert(bf);
479 
480  if (bf->pos>=bf->bytesUsed) {
481  int rv;
482 
484  if (rv<0) {
485  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
486  return rv;
487  }
488  }
489 
490  return (unsigned char) (bf->ptr[bf->pos++]);
491 }
492 
493 
494 
495 int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i) {
496  assert(bf);
497 
498  if (i+bf->pos>=bf->bufferSize) {
499  if (!(bf->mode & GWEN_BUFFER_MODE_USE_SYNCIO)) {
501  "Position %d outside buffer boundaries (%d bytes)\n"
502  "Incrementing anyway",
503  i+bf->pos, bf->bufferSize);
504  }
505  }
506 
507  bf->pos+=i;
508  return 0;
509 }
510 
511 
512 
514  assert(bf);
515  if (bf->pos<=bf->bufferSize) {
516  if (bf->pos>bf->bytesUsed) {
517  DBG_DEBUG(GWEN_LOGDOMAIN, "Adjusted buffer (uses now %d bytes)",
518  bf->pos);
519  bf->bytesUsed=bf->pos;
520  }
521  /* append a NULL to allow using the buffer as ASCIIZ string */
522  bf->ptr[bf->bytesUsed]=0; /* TODO: This has to be checked (is it okay to add a byte here?)! */
523  return 0;
524  }
525  else {
526  DBG_ERROR(GWEN_LOGDOMAIN, "Pointer outside buffer size (%d bytes)",
527  bf->bufferSize);
529  }
530 }
531 
532 
533 
534 int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i) {
535  assert(bf);
536 
537  if (bf->pos<i) {
539  "Position %d outside buffer boundaries (%d bytes)",
540  bf->pos-i, bf->bufferSize);
542  }
543  bf->pos-=i;
544  return 0;
545 }
546 
547 
548 
550 
551  assert(bf);
552  assert(sf);
553 
554  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
555  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
556  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
557  abort();
558  }
559  return GWEN_ERROR_PERMISSIONS;
560  }
561 
562  if (sf->bytesUsed)
563  return GWEN_Buffer_AppendBytes(bf, sf->ptr, sf->bytesUsed);
564  return 0;
565 }
566 
567 
568 
570  assert(bf);
571 
572  return (bf->bufferSize-(bf->bytesUsed+1));
573 }
574 
575 
576 
578  assert(bf);
579 
580  if (bf->pos<bf->bytesUsed)
581  return bf->bytesUsed-bf->pos;
582  else
583  return 0;
584 }
585 
586 
587 
589  assert(bf);
590  return bf->ptr+bf->pos;
591 }
592 
593 
594 
596  assert(bf);
597  if (bf->realPtr && bf->realBufferSize) {
598  memset(bf->realPtr, c, bf->realBufferSize);
599  }
600 }
601 
602 
603 
604 uint32_t GWEN_Buffer_GetBookmark(const GWEN_BUFFER *bf, unsigned int idx) {
605  assert(bf);
606  assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
607  return bf->bookmarks[idx];
608 }
609 
610 
611 
612 void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx,
613  uint32_t v) {
614  assert(bf);
615  assert(idx<GWEN_BUFFER_MAX_BOOKMARKS);
616  bf->bookmarks[idx]=v;
617 }
618 
619 
620 
621 void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert) {
622  uint32_t k;
623 
624  for (k=0; k<insert; k++)
625  fprintf(stderr, " ");
626  fprintf(stderr, "Buffer:\n");
627 
628  for (k=0; k<insert; k++)
629  fprintf(stderr, " ");
630  fprintf(stderr, "Pos : %d (%04x)\n", bf->pos, bf->pos);
631 
632  for (k=0; k<insert; k++)
633  fprintf(stderr, " ");
634  fprintf(stderr, "Buffer Size : %d\n", bf->bufferSize);
635 
636  for (k=0; k<insert; k++)
637  fprintf(stderr, " ");
638  fprintf(stderr, "Hard limit : %d\n", bf->hardLimit);
639 
640  for (k=0; k<insert; k++)
641  fprintf(stderr, " ");
642  fprintf(stderr, "Bytes Used : %d\n", bf->bytesUsed);
643 
644  for (k=0; k<insert; k++)
645  fprintf(stderr, " ");
646  fprintf(stderr, "Bytes Reserved : %u\n",
647  (uint32_t)(bf->ptr-bf->realPtr));
648 
649  for (k=0; k<insert; k++)
650  fprintf(stderr, " ");
651  fprintf(stderr, "Flags : %08x ( ", bf->flags);
652  if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
653  fprintf(stderr, "OWNED ");
654  fprintf(stderr, ")\n");
655 
656  for (k=0; k<insert; k++)
657  fprintf(stderr, " ");
658  fprintf(stderr, "Mode : %08x ( ", bf->mode);
659  if (bf->mode & GWEN_BUFFER_MODE_DYNAMIC)
660  fprintf(stderr, "DYNAMIC ");
661  if (bf->mode & GWEN_BUFFER_MODE_READONLY)
662  fprintf(stderr, "READONLY ");
663  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL)
664  fprintf(stderr, "ABORT_ON_MEMFULL ");
665  fprintf(stderr, ")\n");
666 
667  for (k=0; k<insert; k++)
668  fprintf(stderr, " ");
669  fprintf(stderr, "Bookmarks :");
670  for (k=0; k<GWEN_BUFFER_MAX_BOOKMARKS; k++)
671  fprintf(stderr, " %d", bf->bookmarks[k]);
672  fprintf(stderr, "\n");
673 
674  if (bf->ptr && bf->bytesUsed) {
675  for (k=0; k<insert; k++)
676  fprintf(stderr, " ");
677  fprintf(stderr, "Data:\n");
678  GWEN_Text_DumpString(bf->ptr, bf->bytesUsed, insert+1);
679  }
680 }
681 
682 
683 
685  assert(bf);
686  bf->pos=0;
687  bf->bytesUsed=0;
688  bf->ptr[0]=0;
689 }
690 
691 
692 
694  assert(bf);
695  bf->pos=0;
696 }
697 
698 
699 
700 int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf, char *buffer, uint32_t *size) {
701  /* optimized for speed */
702  uint32_t i;
703  char *pdst;
704 
705  DBG_VERBOUS(GWEN_LOGDOMAIN, "About to copy up to %d bytes", *size);
706  i=0;
707  pdst=buffer;
708 
709  while(i<*size) {
710  int j;
711  int srcLeft;
712 
713  if (bf->pos>=bf->bytesUsed) {
714  if (GWEN_Buffer__FillBuffer(bf)) {
715  DBG_DEBUG(GWEN_LOGDOMAIN, "Could not fill buffer, but that's ok");
716  break;
717  }
718  }
719 
720  srcLeft=bf->bytesUsed - bf->pos;
721  if (srcLeft==0)
722  break;
723  j=(*size)-i;
724  if (j>srcLeft)
725  j=srcLeft;
726  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copying %d bytes", j);
727  memmove(pdst, bf->ptr + bf->pos, j);
728  pdst+=j;
729  i+=j;
730  bf->pos+=j;
731  } /* while */
732 
733  *size=i;
734  DBG_VERBOUS(GWEN_LOGDOMAIN, "Copied %d bytes", *size);
735  return 0;
736 }
737 
738 
739 
741  assert(bf);
742  return bf->step;
743 }
744 
745 
746 
747 void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step) {
748  assert(bf);
749  bf->step=step;
750 }
751 
752 
753 
755  uint32_t pos,
756  int offset) {
757  uint32_t i;
758 
759  assert(bf);
760  for (i=0; i<GWEN_BUFFER_MAX_BOOKMARKS; i++) {
761  if (bf->bookmarks[i]>=pos)
762  bf->bookmarks[i]+=offset;
763  } /* for */
764 }
765 
766 
767 
769  uint32_t size) {
770  char *p;
771  int i;
772  int rv;
773 
774  assert(bf);
775 
776  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
777  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
778  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
779  abort();
780  }
781  return GWEN_ERROR_PERMISSIONS;
782  }
783 
784  if (bf->pos==0) {
785  if (bf->bytesUsed==0) {
786  /* no bytes used, simply return */
787  rv=GWEN_Buffer_AllocRoom(bf, size);
788  if (rv) {
789  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
790  return rv;
791  }
792  bf->bytesUsed+=size;
793  /* append "0" behind buffer */
794  bf->ptr[bf->bytesUsed]=0;
795  return 0;
796  }
797  else {
798  if ( (bf->ptr - bf->realPtr) >= (int)size ) {
799  /* simply occupy the reserved space */
800  bf->ptr-=size;
801  bf->bytesUsed+=size;
802  bf->bufferSize+=size;
803  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
804  return 0;
805  }
806  }
807  }
808 
809  rv=GWEN_Buffer_AllocRoom(bf, size);
810  if (rv<0) {
811  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
812  return rv;
813  }
814  assert(bf->pos<=bf->bytesUsed);
815  p=bf->ptr+bf->pos;
816  i=bf->bytesUsed-bf->pos;
817  if (i>0)
818  /* move current data at pos out of the way */
819  memmove(p+size, p, i);
820  bf->bytesUsed+=size;
821  /* append "0" behind buffer */
822  bf->ptr[bf->bytesUsed]=0;
823  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, size);
824  return 0;
825 }
826 
827 
828 
829 int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size) {
830  char *p;
831  int i;
832 
833  assert(bf);
834 
835  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
836  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
837  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
838  abort();
839  }
840  return GWEN_ERROR_PERMISSIONS;
841  }
842 
843  if (bf->bytesUsed<size+bf->pos) {
844  /* can't remove more bytes than we have */
845  return GWEN_ERROR_INVALID;
846  }
847 
848  if (bf->pos==0) {
849  /* simply add to reserved space */
850  bf->ptr+=size;
851  bf->bytesUsed-=size;
852  bf->bufferSize-=size;
853  }
854  else {
855  /* we need to get the rest closer */
856  p=bf->ptr+bf->pos+size;
857  i=bf->bytesUsed-bf->pos-size;
858  memmove(bf->ptr+bf->pos, p, i);
859  bf->bytesUsed-=size;
860  }
861 
862  /* append "0" behind buffer */
863  bf->ptr[bf->bytesUsed]=0;
864  GWEN_Buffer_AdjustBookmarks(bf, bf->pos, -((int)size));
865 
866  return 0;
867 }
868 
869 
870 
872  uint32_t rsize,
873  const char *buffer,
874  uint32_t size) {
875  int32_t d;
876  int rv;
877 
878  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
879  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
880  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
881  abort();
882  }
883  return GWEN_ERROR_PERMISSIONS;
884  }
885 
886  /* either insert or remove bytes */
887  d=size-rsize;
888  if (d<0) {
889  rv=GWEN_Buffer_RemoveRoom(bf, -d);
890  }
891  else if (d>0) {
892  rv=GWEN_Buffer_InsertRoom(bf, d);
893  }
894  else
895  /* nothing to adjust if sizes are the same */
896  rv=0;
897  if (rv) {
899  "Error replacing %d bytes with %d bytes (%d)",
900  rsize, size, rv);
901  return rv;
902  }
903 
904  /* write new bytes */
905  if (size)
906  memmove(bf->ptr+bf->pos, buffer, size);
907  return 0;
908 }
909 
910 
911 
913  const char *buffer,
914  uint32_t size) {
915  int rv;
916 
917  assert(bf);
918  assert(buffer);
919 
920  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
921  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
922  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
923  abort();
924  }
925  return GWEN_ERROR_PERMISSIONS;
926  }
927 
928  rv=GWEN_Buffer_InsertRoom(bf, size);
929  if (rv<0) {
930  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
931  return rv;
932  }
933  memmove(bf->ptr+bf->pos, buffer, size);
934  return 0;
935 }
936 
937 
938 
940  int rv;
941 
942  assert(bf);
943 
944  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
945  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
946  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
947  abort();
948  }
949  return GWEN_ERROR_PERMISSIONS;
950  }
951 
952  rv=GWEN_Buffer_InsertRoom(bf, 1);
953  if (rv<0) {
954  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
955  return rv;
956  }
957  bf->ptr[bf->pos]=c;
958  return 0;
959 }
960 
961 
962 
964  GWEN_BUFFER *sf) {
965  assert(bf);
966  assert(sf);
967 
968  return GWEN_Buffer_InsertBytes(bf, sf->ptr, sf->bytesUsed);
969 }
970 
971 
972 
974  uint32_t pos,
975  uint32_t l) {
976  int offset;
977 
978  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
979  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
980  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
981  abort();
982  }
983  return GWEN_ERROR_PERMISSIONS;
984  }
985 
986  if (pos>=bf->bufferSize) {
987  DBG_ERROR(GWEN_LOGDOMAIN, "Position outside buffer");
988  return -1;
989  }
990  if (bf->bytesUsed-pos<l) {
991  DBG_INFO(GWEN_LOGDOMAIN, "Invalid length");
992  return -1;
993  }
994  bf->ptr+=pos;
995  bf->bufferSize-=pos;
996  if (bf->pos>pos)
997  offset=pos;
998  else
999  offset=bf->pos;
1000  bf->pos-=offset;
1001  bf->bytesUsed=l;
1002  /* adjust position after possible truncation */
1003  if (bf->pos>bf->bytesUsed)
1004  bf->pos=bf->bytesUsed;
1005 
1006  bf->ptr[bf->bytesUsed]=0;
1007  GWEN_Buffer_AdjustBookmarks(bf, offset, -offset);
1008 
1009  return 0;
1010 }
1011 
1012 
1013 
1015  const char *buffer) {
1016  assert(bf);
1017  assert(buffer);
1018  return GWEN_Buffer_AppendBytes(bf, buffer, strlen(buffer));
1019 }
1020 
1021 
1022 
1024  const char *buffer) {
1025  assert(bf);
1026  assert(buffer);
1027  return GWEN_Buffer_InsertBytes(bf, buffer, strlen(buffer));
1028 }
1029 
1030 
1031 
1033  GWEN_SYNCIO *sio,
1034  int take) {
1035  assert(bf);
1036  if (bf->syncIo) {
1037  if (bf->flags & GWEN_BUFFER_FLAGS_OWN_SYNCIO) {
1038  GWEN_SyncIo_free(bf->syncIo);
1039  }
1040  }
1041  if (take)
1042  bf->flags|=GWEN_BUFFER_FLAGS_OWN_SYNCIO;
1043  else
1044  bf->flags&=~GWEN_BUFFER_FLAGS_OWN_SYNCIO;
1045  bf->syncIo=sio;
1046 }
1047 
1048 
1049 
1051  unsigned char c,
1052  uint32_t size) {
1053  int rv;
1054 
1055  assert(bf);
1056 
1057  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
1058  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
1059  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
1060  abort();
1061  }
1062  return GWEN_ERROR_PERMISSIONS;
1063  }
1064 
1065  rv=GWEN_Buffer_AllocRoom(bf, size+1);
1066  if (rv<0) {
1067  DBG_DEBUG(GWEN_LOGDOMAIN, "called from here");
1068  return rv;
1069  }
1070  memset(bf->ptr+bf->bytesUsed, c, size);
1071  if (bf->pos==bf->bytesUsed)
1072  bf->pos+=size;
1073  bf->bytesUsed+=size;
1074  /* append a NULL to allow using the buffer as ASCIIZ string */
1075  bf->ptr[bf->bytesUsed]=0;
1076  return 0;
1077 }
1078 
1079 
1080 
1082  unsigned char c,
1083  uint32_t size) {
1084  int rv;
1085 
1086  assert(bf);
1087 
1088  if (bf->mode & GWEN_BUFFER_MODE_READONLY) {
1089  DBG_ERROR(GWEN_LOGDOMAIN, "Read-only mode");
1090  if (bf->mode & GWEN_BUFFER_MODE_ABORT_ON_MEMFULL) {
1091  abort();
1092  }
1093  return GWEN_ERROR_PERMISSIONS;
1094  }
1095 
1096  rv=GWEN_Buffer_InsertRoom(bf, size);
1097  if (rv<0) {
1098  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1099  return -1;
1100  }
1101  memset(bf->ptr+bf->pos, c, size);
1102  return 0;
1103 }
1104 
1105 
1106 
1109  return 0;
1110 }
1111 
1112 
1113 
1115  GWEN_Buffer_free((GWEN_BUFFER*) ptr);
1116  return 0;
1117 }
1118 
1119 
1120 
1121 
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
Definition: buffer.c:577
int GWEN_Buffer_FillLeftWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition: buffer.c:1081
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
int GWEN_Buffer_InsertString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1023
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:273
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
Definition: buffer.c:569
#define GWEN_ERROR_INVALID
Definition: error.h:67
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:266
void GWEN_Buffer_SetHardLimit(GWEN_BUFFER *bf, uint32_t l)
Definition: buffer.c:215
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)
Definition: text.c:1235
void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step)
Definition: buffer.c:747
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:92
#define NULL
Definition: binreloc.c:290
void GWEN_Memory_dealloc(void *p)
Definition: memory.c:472
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:200
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:513
#define GWEN_LOGDOMAIN
Definition: logger.h:35
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition: buffer.c:239
int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition: buffer.c:1050
int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res)
Definition: buffer.c:152
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:829
void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert)
Definition: buffer.c:621
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:588
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:684
int GWENHYWFAR_CB GWEN_Buffer_CacheFn_Free(void *ptr)
Definition: buffer.c:1114
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:495
void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx, uint32_t v)
Definition: buffer.c:612
void GWEN_Buffer_AdjustBookmarks(GWEN_BUFFER *bf, uint32_t pos, int offset)
Definition: buffer.c:754
int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf)
Definition: buffer.c:459
uint32_t GWEN_Buffer_GetBookmark(const GWEN_BUFFER *bf, unsigned int idx)
Definition: buffer.c:604
void GWEN_Buffer_Attach(GWEN_BUFFER *bf)
Definition: buffer.c:76
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:86
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
uint32_t GWEN_Buffer_GetSize(const GWEN_BUFFER *bf)
Definition: buffer.c:230
int GWEN_Buffer__FillBuffer_SyncIo(GWEN_BUFFER *bf)
Definition: buffer.c:411
void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:201
void GWEN_Buffer_SetSourceSyncIo(GWEN_BUFFER *bf, GWEN_SYNCIO *sio, int take)
Definition: buffer.c:1032
#define GWENHYWFAR_CB
Definition: gwenhywfarapi.h:89
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:192
int GWEN_Buffer__FillBuffer(GWEN_BUFFER *bf)
Definition: buffer.c:446
int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition: buffer.c:549
int GWEN_Buffer_InsertByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:939
int GWENHYWFAR_CB GWEN_Buffer_CacheFn_Attach(void *ptr)
Definition: buffer.c:1107
int GWEN_SyncIo_ReadForced(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:337
void * GWEN_Memory_malloc(size_t wsize)
Definition: memory.c:385
#define GWEN_ERROR_GENERIC
Definition: error.h:62
#define GWEN_BUFFER_MODE_DYNAMIC
Definition: buffer.h:69
void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:195
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:380
#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:102
int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:534
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:76
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:973
void GWEN_Buffer_SetMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:189
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
uint32_t GWEN_Buffer_GetStep(GWEN_BUFFER *bf)
Definition: buffer.c:740
#define GWEN_ERROR_EOF
Definition: error.h:96
#define GWEN_BUFFER_MODE_USE_SYNCIO
Definition: buffer.h:71
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:246
#define GWEN_BUFFER_MODE_ABORT_ON_MEMFULL
Definition: buffer.h:70
#define GWEN_BUFFER_MAX_BOOKMARKS
Definition: buffer.h:67
int GWEN_Buffer_InsertBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
Definition: buffer.c:963
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:164
uint32_t GWEN_Buffer_GetMode(GWEN_BUFFER *bf)
Definition: buffer.c:182
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
Definition: buffer.c:477
#define GWEN_BUFFER_MODE_READONLY
Definition: buffer.h:72
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:348
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
Definition: buffer.c:693
void * GWEN_Memory_realloc(void *oldp, size_t nsize)
Definition: memory.c:433
int GWEN_Buffer_InsertRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:768
int GWEN_Buffer_InsertBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:912
uint32_t GWEN_Buffer_GetHardLimit(GWEN_BUFFER *bf)
Definition: buffer.c:208
int GWEN_Buffer_ReplaceBytes(GWEN_BUFFER *bf, uint32_t rsize, const char *buffer, uint32_t size)
Definition: buffer.c:871
int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf, char *buffer, uint32_t *size)
Definition: buffer.c:700
#define GWEN_ERROR_MEMORY_FULL
Definition: error.h:77
#define GWEN_BUFFER_MODE_DEFAULT
Definition: buffer.h:74
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1014
void GWEN_Buffer_OverwriteContent(GWEN_BUFFER *bf, int c)
Definition: buffer.c:595