30#define DISABLE_DEBUGLOG
33#include <gwenhywfar/misc.h>
34#include <gwenhywfar/debug.h>
35#include <gwenhywfar/text.h>
56 bf->realBufferSize=size+1;
57 bf->bufferSize=size+1;
58 bf->flags=GWEN_BUFFER_FLAGS_OWNED;
66 bf->realBufferSize=size;
70 bf->flags=GWEN_BUFFER_FLAGS_OWNED;
74 bf->hardLimit=GWEN_BUFFER_DEFAULT_HARDLIMIT;
75 bf->step=GWEN_BUFFER_DYNAMIC_STEP;
83 assert(bf->_refCount);
92 assert(bf->_refCount);
93 if (bf->_refCount==1) {
94 if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
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) {
122 toCopy=bf->bytesUsed+1;
123 if (toCopy>(newbf->bufferSize)) {
124 fprintf(stderr,
"Panic: Too many bytes in buffer");
127 memmove(newbf->ptr, bf->ptr, toCopy);
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;
136 newbf->bookmarks[i]=bf->bookmarks[i];
146 if (!(bf->flags & GWEN_BUFFER_FLAGS_OWNED))
148 if (bf->realPtr!=bf->ptr)
151 bf->flags&=~GWEN_BUFFER_FLAGS_OWNED;
168 memmove(bf->ptr+res, bf->ptr, bf->bytesUsed);
221 return bf->hardLimit;
247 return bf->hardLimit;
248 return bf->bufferSize;
265 if (i>=bf->bufferSize) {
267 "Position %d outside buffer boundaries (%d bytes)",
268 i, (
int)(bf->bufferSize));
280 return bf->bytesUsed;
296 if (bf->bytesUsed+(size+1) > bf->bufferSize) {
313 reserved=bf->ptr-bf->realPtr;
316 nsize=bf->bytesUsed+(size+1)-bf->bufferSize;
318 nsize=(nsize+(bf->step-1));
319 nsize&=~(bf->step-1);
323 nsize+=bf->realBufferSize;
324 if (nsize>bf->hardLimit) {
326 "Size is beyond hard limit (%d>%d)",
327 (
int) nsize, (
int)(bf->hardLimit));
334 bf->bufferSize, nsize);
335 if (bf->realPtr==
NULL) {
350 bf->realPtr=(
char *)p;
351 bf->ptr=bf->realPtr+reserved;
352 bf->realBufferSize=nsize;
353 bf->bufferSize+=noffs;
383 memmove(bf->ptr+bf->bytesUsed, buffer, size);
384 if (bf->pos==bf->bytesUsed)
388 bf->ptr[bf->bytesUsed]=0;
408 if (bf->bytesUsed+1+1 > bf->bufferSize) {
416 bf->ptr[bf->bytesUsed]=c;
417 if (bf->pos == bf->bytesUsed)
420 bf->ptr[++(bf->bytesUsed)]=0;
430 if (bf->pos>=bf->bytesUsed) {
434 return (
unsigned char)(bf->ptr[bf->pos]);
443 if (bf->pos>=bf->bytesUsed) {
447 return (
unsigned char)(bf->ptr[bf->pos++]);
456 if (i+bf->pos>=bf->bufferSize) {
458 "Position %d outside buffer boundaries (%d bytes)\n"
459 "Incrementing anyway",
460 i+bf->pos, bf->bufferSize);
472 if (bf->pos<=bf->bufferSize) {
473 if (bf->pos>bf->bytesUsed) {
476 bf->bytesUsed=bf->pos;
479 bf->ptr[bf->bytesUsed]=0;
484 (
int)(bf->bufferSize));
497 "Position %d outside buffer boundaries (%d bytes)",
498 bf->pos-i, bf->bufferSize);
532 return (bf->bufferSize-(bf->bytesUsed+1));
541 if (bf->pos<bf->bytesUsed)
542 return bf->bytesUsed-bf->pos;
552 return bf->ptr+bf->pos;
560 if (bf->realPtr && bf->realBufferSize) {
561 memset(bf->realPtr, c, bf->realBufferSize);
571 return bf->bookmarks[idx];
581 bf->bookmarks[idx]=v;
590 for (k=0; k<insert; k++)
591 fprintf(stderr,
" ");
592 fprintf(stderr,
"Buffer:\n");
594 for (k=0; k<insert; k++)
595 fprintf(stderr,
" ");
596 fprintf(stderr,
"Pos : %d (%04x)\n", bf->pos, bf->pos);
598 for (k=0; k<insert; k++)
599 fprintf(stderr,
" ");
600 fprintf(stderr,
"Buffer Size : %d\n", bf->bufferSize);
602 for (k=0; k<insert; k++)
603 fprintf(stderr,
" ");
604 fprintf(stderr,
"Hard limit : %d\n", bf->hardLimit);
606 for (k=0; k<insert; k++)
607 fprintf(stderr,
" ");
608 fprintf(stderr,
"Bytes Used : %d\n", bf->bytesUsed);
610 for (k=0; k<insert; k++)
611 fprintf(stderr,
" ");
612 fprintf(stderr,
"Bytes Reserved : %u\n",
613 (uint32_t)(bf->ptr-bf->realPtr));
615 for (k=0; k<insert; k++)
616 fprintf(stderr,
" ");
617 fprintf(stderr,
"Flags : %08x ( ", bf->flags);
618 if (bf->flags & GWEN_BUFFER_FLAGS_OWNED)
619 fprintf(stderr,
"OWNED ");
620 fprintf(stderr,
")\n");
622 for (k=0; k<insert; k++)
623 fprintf(stderr,
" ");
624 fprintf(stderr,
"Mode : %08x ( ", bf->mode);
626 fprintf(stderr,
"DYNAMIC ");
628 fprintf(stderr,
"READONLY ");
630 fprintf(stderr,
"ABORT_ON_MEMFULL ");
631 fprintf(stderr,
")\n");
633 for (k=0; k<insert; k++)
634 fprintf(stderr,
" ");
635 fprintf(stderr,
"Bookmarks :");
637 fprintf(stderr,
" %d", bf->bookmarks[k]);
638 fprintf(stderr,
"\n");
640 if (bf->ptr && bf->bytesUsed) {
641 for (k=0; k<insert; k++)
642 fprintf(stderr,
" ");
643 fprintf(stderr,
"Data:\n");
682 if (bf->pos>=bf->bytesUsed)
685 srcLeft=bf->bytesUsed - bf->pos;
692 memmove(pdst, bf->ptr + bf->pos, j);
729 if (bf->bookmarks[i]>=pos)
730 bf->bookmarks[i]+=offset;
754 if (bf->bytesUsed==0) {
763 bf->ptr[bf->bytesUsed]=0;
767 if ((bf->ptr - bf->realPtr) >= (
int)size) {
771 bf->bufferSize+=size;
783 assert(bf->pos<=bf->bytesUsed);
785 i=bf->bytesUsed-bf->pos;
788 memmove(p+size, p, i);
791 bf->ptr[bf->bytesUsed]=0;
813 if (bf->bytesUsed<size+bf->pos) {
822 bf->bufferSize-=size;
826 p=bf->ptr+bf->pos+size;
827 i=bf->bytesUsed-bf->pos-size;
828 memmove(bf->ptr+bf->pos, p, i);
833 bf->ptr[bf->bytesUsed]=0;
870 "Error replacing %d bytes with %d bytes (%d)",
877 memmove(bf->ptr+bf->pos, buffer, size);
905 memmove(bf->ptr+bf->pos, buffer, size);
961 if (pos>=bf->bufferSize) {
965 if (bf->bytesUsed-pos<l) {
978 if (bf->pos>bf->bytesUsed)
979 bf->pos=bf->bytesUsed;
981 bf->ptr[bf->bytesUsed]=0;
1030 memset(bf->ptr+bf->bytesUsed, c, size);
1031 if (bf->pos==bf->bytesUsed)
1033 bf->bytesUsed+=size;
1035 bf->ptr[bf->bytesUsed]=0;
1062 memset(bf->ptr+bf->pos, c, size);
1089 int maxUnsegmentedWrite;
1098 va_start(list,
fmt);
1099 rv=vsnprintf(p, maxUnsegmentedWrite,
fmt, list);
1105 else if (rv>=maxUnsegmentedWrite) {
1109 rv=vsnprintf(p, maxUnsegmentedWrite,
fmt, list);
1128 const char *openingString,
1129 const char *closingString,
1139 startPos=(ptr-bf->ptr);
1141 startPos+=strlen(openingString);
1142 ptr+=strlen(openingString);
1145 endPos=(ptr-bf->ptr);
1147 endPos+=strlen(closingString);
int GWEN_Buffer_InsertByte(GWEN_BUFFER *bf, char c)
int GWEN_Buffer_DecrementPos(GWEN_BUFFER *bf, uint32_t i)
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
int GWEN_Buffer_AppendArgs(GWEN_BUFFER *bf, const char *fmt,...)
void GWEN_Buffer_SetStep(GWEN_BUFFER *bf, uint32_t step)
int GWEN_Buffer_InsertBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
int GWEN_Buffer_RemoveRoom(GWEN_BUFFER *bf, uint32_t size)
int GWEN_Buffer_ReplaceBytes(GWEN_BUFFER *bf, uint32_t rsize, const char *buffer, uint32_t size)
uint32_t GWEN_Buffer_GetMaxUnsegmentedWrite(GWEN_BUFFER *bf)
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
GWEN_BUFFER * GWEN_Buffer_dup(GWEN_BUFFER *bf)
uint32_t GWEN_Buffer_GetHardLimit(GWEN_BUFFER *bf)
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode)
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert)
void GWEN_Buffer_SetHardLimit(GWEN_BUFFER *bf, uint32_t l)
int GWEN_Buffer_PeekByte(GWEN_BUFFER *bf)
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
int GWEN_Buffer_InsertRoom(GWEN_BUFFER *bf, uint32_t size)
void GWEN_Buffer_OverwriteContent(GWEN_BUFFER *bf, int c)
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
uint32_t GWEN_Buffer_GetMode(GWEN_BUFFER *bf)
int GWEN_Buffer_InsertString(GWEN_BUFFER *bf, const char *buffer)
int GWEN_Buffer_AppendBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
void GWEN_Buffer_Attach(GWEN_BUFFER *bf)
void GWEN_Buffer_free(GWEN_BUFFER *bf)
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
void GWEN_Buffer_SetBookmark(GWEN_BUFFER *bf, unsigned int idx, uint32_t v)
int GWEN_Buffer_ReadBytes(GWEN_BUFFER *bf, char *buffer, uint32_t *size)
int GWEN_Buffer_FillLeftWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
uint32_t GWEN_Buffer_GetBookmark(const GWEN_BUFFER *bf, unsigned int idx)
int GWEN_Buffer_Relinquish(GWEN_BUFFER *bf)
void GWEN_Buffer_AdjustBookmarks(GWEN_BUFFER *bf, uint32_t pos, int offset)
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
int GWEN_Buffer_KeepTextBetweenStrings(GWEN_BUFFER *bf, const char *openingString, const char *closingString, int onlyBetween)
uint32_t GWEN_Buffer_GetSize(const GWEN_BUFFER *bf)
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
uint32_t GWEN_Buffer_GetStep(GWEN_BUFFER *bf)
void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode)
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
int GWENHYWFAR_CB GWEN_Buffer_CacheFn_Attach(void *ptr)
int GWENHYWFAR_CB GWEN_Buffer_CacheFn_Free(void *ptr)
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res)
int GWEN_Buffer_InsertBuffer(GWEN_BUFFER *bf, GWEN_BUFFER *sf)
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
void GWEN_Buffer_SetMode(GWEN_BUFFER *bf, uint32_t mode)
#define GWEN_BUFFER_MAX_BOOKMARKS
#define GWEN_BUFFER_MODE_ABORT_ON_MEMFULL
#define GWEN_BUFFER_MODE_DYNAMIC
#define GWEN_BUFFER_MODE_READONLY
GWENHYWFAR_API const char * fmt
#define GWEN_BUFFER_MODE_DEFAULT
#define DBG_DEBUG(dbg_logger, format, args...)
#define DBG_VERBOUS(dbg_logger, format, args...)
#define DBG_INFO(dbg_logger, format, args...)
#define DBG_ERROR(dbg_logger, format, args...)
#define GWEN_ERROR_MEMORY_FULL
#define GWEN_ERROR_INVALID
#define GWEN_ERROR_BUFFER_OVERFLOW
#define GWEN_ERROR_PERMISSIONS
#define GWEN_ERROR_GENERIC
#define GWEN_ERROR_NOT_FOUND
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
void * GWEN_Memory_realloc(void *oldp, size_t nsize)
void * GWEN_Memory_malloc(size_t wsize)
void GWEN_Memory_dealloc(void *p)
#define GWEN_FREE_OBJECT(varname)
#define GWEN_NEW_OBJECT(typ, varname)
const char * GWEN_Text_StrCaseStr(const char *haystack, const char *needle)
void GWEN_Text_DumpString(const char *s, unsigned int l, unsigned int insert)