123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /*
- ** 2012-04-27
- **
- ** The author disclaims copyright to this source code. In place of
- ** a legal notice, here is a blessing:
- **
- ** May you do good and not evil.
- ** May you find forgiveness for yourself and forgive others.
- ** May you share freely, never taking more than you give.
- **
- *************************************************************************
- **
- ** Dynamic string functions.
- */
- #include "lsmInt.h"
- /*
- ** Turn bulk and uninitialized memory into an LsmString object
- */
- void lsmStringInit(LsmString *pStr, lsm_env *pEnv){
- memset(pStr, 0, sizeof(pStr[0]));
- pStr->pEnv = pEnv;
- }
- /*
- ** Increase the memory allocated for holding the string. Realloc as needed.
- **
- ** If a memory allocation error occurs, set pStr->n to -1 and free the existing
- ** allocation. If a prior memory allocation has occurred, this routine is a
- ** no-op.
- */
- int lsmStringExtend(LsmString *pStr, int nNew){
- assert( nNew>0 );
- if( pStr->n<0 ) return LSM_NOMEM;
- if( pStr->n + nNew >= pStr->nAlloc ){
- int nAlloc = pStr->n + nNew + 100;
- char *zNew = lsmRealloc(pStr->pEnv, pStr->z, nAlloc);
- if( zNew==0 ){
- lsmFree(pStr->pEnv, pStr->z);
- nAlloc = 0;
- pStr->n = -1;
- }
- pStr->nAlloc = nAlloc;
- pStr->z = zNew;
- }
- return (pStr->z ? LSM_OK : LSM_NOMEM_BKPT);
- }
- /*
- ** Clear an LsmString object, releasing any allocated memory that it holds.
- ** This also clears the error indication (if any).
- */
- void lsmStringClear(LsmString *pStr){
- lsmFree(pStr->pEnv, pStr->z);
- lsmStringInit(pStr, pStr->pEnv);
- }
- /*
- ** Append N bytes of text to the end of an LsmString object. If
- ** N is negative, append the entire string.
- **
- ** If the string is in an error state, this routine is a no-op.
- */
- int lsmStringAppend(LsmString *pStr, const char *z, int N){
- int rc;
- if( N<0 ) N = (int)strlen(z);
- rc = lsmStringExtend(pStr, N+1);
- if( pStr->nAlloc ){
- memcpy(pStr->z+pStr->n, z, N+1);
- pStr->n += N;
- }
- return rc;
- }
- int lsmStringBinAppend(LsmString *pStr, const u8 *a, int n){
- int rc;
- rc = lsmStringExtend(pStr, n);
- if( pStr->nAlloc ){
- memcpy(pStr->z+pStr->n, a, n);
- pStr->n += n;
- }
- return rc;
- }
- /*
- ** Append printf-formatted content to an LsmString.
- */
- void lsmStringVAppendf(
- LsmString *pStr,
- const char *zFormat,
- va_list ap1,
- va_list ap2
- ){
- #if (!defined(__STDC_VERSION__) || (__STDC_VERSION__<199901L)) && \
- !defined(__APPLE__)
- extern int vsnprintf(char *str, size_t size, const char *format, va_list ap)
- /* Compatibility crutch for C89 compilation mode. sqlite3_vsnprintf()
- does not work identically and causes test failures if used here.
- For the time being we are assuming that the target has vsnprintf(),
- but that is not guaranteed to be the case for pure C89 platforms.
- */;
- #endif
- int nWrite;
- int nAvail;
- nAvail = pStr->nAlloc - pStr->n;
- nWrite = vsnprintf(pStr->z + pStr->n, nAvail, zFormat, ap1);
- if( nWrite>=nAvail ){
- lsmStringExtend(pStr, nWrite+1);
- if( pStr->nAlloc==0 ) return;
- nWrite = vsnprintf(pStr->z + pStr->n, nWrite+1, zFormat, ap2);
- }
- pStr->n += nWrite;
- pStr->z[pStr->n] = 0;
- }
- void lsmStringAppendf(LsmString *pStr, const char *zFormat, ...){
- va_list ap, ap2;
- va_start(ap, zFormat);
- va_start(ap2, zFormat);
- lsmStringVAppendf(pStr, zFormat, ap, ap2);
- va_end(ap);
- va_end(ap2);
- }
- int lsmStrlen(const char *zName){
- int nRet = 0;
- while( zName[nRet] ) nRet++;
- return nRet;
- }
- /*
- ** Write into memory obtained from lsm_malloc().
- */
- char *lsmMallocPrintf(lsm_env *pEnv, const char *zFormat, ...){
- LsmString s;
- va_list ap, ap2;
- lsmStringInit(&s, pEnv);
- va_start(ap, zFormat);
- va_start(ap2, zFormat);
- lsmStringVAppendf(&s, zFormat, ap, ap2);
- va_end(ap);
- va_end(ap2);
- if( s.n<0 ) return 0;
- return (char *)lsmReallocOrFree(pEnv, s.z, s.n+1);
- }
|