/*------------------------------------------------------------------------- D Y N S T R I N G Implementation file for a dynamic string object. Usage and copyright: see dynstring.h Mark Koennecke, March 1998 -----------------------------------------------------------------------------*/ #include #include #include #include #include "dynstring.h" #define DYNMAGIC 27031998 /*--------------------------------------------------------------------------*/ typedef struct __DynString { int iMAGIC; char *pBuffer; int iTextLen; int iBufferSize; int iResize; } DynString; /*--------------------------------------------------------------------------*/ pDynString CreateDynString(int iInitial, int iResize) { pDynString pNew = NULL; if (iInitial <= 0) iInitial = 512; if (iResize <= 0) iResize = 512; /* new memory */ pNew = (pDynString) malloc(sizeof(DynString)); if (!pNew) { return NULL; } memset(pNew, 0, sizeof(DynString)); pNew->pBuffer = (char *) malloc(iInitial * sizeof(char)); if (!pNew->pBuffer) { free(pNew); return NULL; } memset(pNew->pBuffer, 0, iInitial * sizeof(char)); /* initialise the rest */ pNew->iMAGIC = DYNMAGIC; pNew->iBufferSize = iInitial; pNew->iResize = iResize; pNew->iTextLen = 0; return pNew; } /*--------------------------------------------------------------------------*/ static int Resize(pDynString self, int iRequested) { char *pNewBuffer; int iNewSize; if (iRequested < self->iBufferSize) { return 1; } /* get new data space */ iNewSize = iRequested + self->iResize; pNewBuffer = (char *) malloc(iNewSize * sizeof(char)); if (!pNewBuffer) { return 0; } memset(pNewBuffer, 0, iNewSize); /* copy data */ memcpy(pNewBuffer, self->pBuffer, self->iTextLen); /* swap things around */ if (self->pBuffer) { free(self->pBuffer); } self->pBuffer = pNewBuffer; self->iBufferSize = iNewSize; return 1; } /*--------------------------------------------------------------------------*/ int DynStringCapacity(pDynString self, int length) { if(self->iBufferSize < length){ return Resize(self,length); } else { return 1; } } /*--------------------------------------------------------------------------*/ void DeleteDynString(pDynString self) { assert(self); assert(self->iMAGIC == DYNMAGIC); if (self->pBuffer) free(self->pBuffer); self->iMAGIC = 0; free(self); } /*--------------------------------------------------------------------------*/ int DynStringClear(pDynString self) { assert(self); assert(self->iMAGIC == DYNMAGIC); self->iTextLen = 0; memset(self->pBuffer, 0, self->iBufferSize); return 1; } /*-------------------------------------------------------------------------*/ int DynStringCopy(pDynString self, char *pText) { int iRequested, iRet; assert(self); assert(self->iMAGIC == DYNMAGIC); if(pText == 0){ return 0; } iRequested = strlen(pText); if (iRequested >= self->iBufferSize) { iRet = Resize(self, iRequested); if (!iRet) { return 0; } } else { /* safety: remove rubbish */ memset(self->pBuffer, 0, self->iBufferSize * sizeof(char)); } strcpy(self->pBuffer, pText); self->iTextLen = iRequested; return 1; } /*--------------------------------------------------------------------------*/ int DynStringConcat(pDynString self, char *pText) { int iRequested, iRet; assert(self); assert(self->iMAGIC == DYNMAGIC); iRequested = strlen(pText) + self->iTextLen; if (iRequested >= self->iBufferSize) { iRet = Resize(self, iRequested); if (!iRet) { return 0; } } strcpy(self->pBuffer + self->iTextLen, pText); self->iTextLen = iRequested; return 1; } /*--------------------------------------------------------------------------*/ int DynStringConcatLine(pDynString self, char *pText) { DynStringConcat(self,pText); return DynStringConcatChar(self,'\n'); } /*--------------------------------------------------------------------------*/ int DynStringConcatChar(pDynString self, char c) { int iRequested, iRet; assert(self); assert(self->iMAGIC == DYNMAGIC); iRequested = self->iTextLen + 1; if (iRequested >= self->iBufferSize) { iRet = Resize(self, iRequested); if (!iRet) { return 0; } } self->pBuffer[self->iTextLen] = c; self->iTextLen++; return 1; } /*---------------------------------------------------------------------------*/ int DynStringConcatBytes(pDynString self, char *data, int datalen) { int iRequested, iRet; assert(self); assert(self->iMAGIC == DYNMAGIC); iRequested = self->iTextLen + datalen; if (iRequested >= self->iBufferSize) { iRet = Resize(self, iRequested); if (!iRet) { return 0; } } memcpy(self->pBuffer + self->iTextLen,data,datalen); self->iTextLen += datalen; return 1; } /*---------------------------------------------------------------------------*/ int DynStringInsert(pDynString self, char *pText, int iPos) { int iRequested, iRet, iPush, iRest; assert(self); assert(self->iMAGIC == DYNMAGIC); /* provide space */ iPush = strlen(pText); iRequested = self->iTextLen + iPush; if (iRequested >= self->iBufferSize) { iRet = Resize(self, iRequested); if (!iRet) { return 0; } } if (iPos >= self->iTextLen) { iPos = self->iTextLen; } else { if (iPos < 0) { iPos = 0; } memmove(&self->pBuffer[iPos + iPush], &self->pBuffer[iPos], self->iTextLen + 1 - iPos); } memcpy(&self->pBuffer[iPos], pText, iPush); self->iTextLen = iRequested; return 1; } /*--------------------------------------------------------------------------*/ int DynStringReplace(pDynString self, char *pText, int iPos) { int iRequested, iRet; assert(self); assert(self->iMAGIC == DYNMAGIC); iRequested = strlen(pText) + iPos; if (iRequested >= self->iBufferSize) { iRet = Resize(self, iRequested); if (!iRet) { return 0; } } memcpy(&self->pBuffer[iPos], pText, strlen(pText) * sizeof(char)); if (iRequested > self->iTextLen) { self->iTextLen = iRequested; } return 1; } /*---------------------------------------------------------------------------*/ char *GetCharArray(pDynString self) { assert(self); assert(self->iMAGIC == DYNMAGIC); return self->pBuffer; } /*---------------------------------------------------------------------------*/ int GetDynStringLength(pDynString self) { assert(self); assert(self->iMAGIC == DYNMAGIC); return self->iTextLen; } /*---------------------------------------------------------------------------*/ int DynStringBackspace(pDynString self) { assert(self); assert(self->iMAGIC == DYNMAGIC); if (self->iTextLen > 0) { self->pBuffer[self->iTextLen - 1] = '\0'; self->iTextLen--; } return 1; } /*---------------------------------------------------------------------------*/ int DynStringShorten(pDynString self, int length) { assert(self); assert(self->iMAGIC == DYNMAGIC); if (length >= self->iTextLen || length < 0) { return 0; } self->iTextLen = length; self->pBuffer[length] = '\0'; return 1; } /*---------------------------------------------------------------------------*/ char *Dyn2Cstring(pDynString self) { char *result; assert(self); assert(self->iMAGIC == DYNMAGIC); result = self->pBuffer; free(self); return result; }