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