dstring.c.svn-base
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 337 行
SVN-BASE
337 行
/**************************************************************************** * * Dynamic strings ****************************************************************************//* * tcl.h -- * * This header file describes the externally-visible facilities * of the Tcl interpreter. * * Copyright (c) 1987-1994 The Regents of the University of California. * Copyright (c) 1994-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39 */#include "dstring.h"#include <stdarg.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include "str_strsafe.h"/* *---------------------------------------------------------------------- * * DStringInit -- * * Initializes a dynamic string, discarding any previous contents * of the string (DStringFree should have been called already * if the dynamic string was previously in use). * * Results: * None. * * Side effects: * The dynamic string is initialized to be empty. * *---------------------------------------------------------------------- */voidDStringInit(DString* pDs){ pDs->pString = pDs->staticSpace; pDs->length = 0; pDs->spaceAvl = kDstringStaticSize; pDs->staticSpace[0] = 0;}/* *---------------------------------------------------------------------- * * DStringAppend -- * * Append more characters to the current value of a dynamic string. * * Results: * The return value is a pointer to the dynamic string's new value. * * Side effects: * Length bytes from string (or all of string if length is less * than zero) are added to the current value of the string. Memory * gets reallocated if needed to accomodate the string's new size. * *---------------------------------------------------------------------- */char *DStringAppend(DString *pDs, const char* string, int length){ int newSize; char* newString; char* dst; const char* end; if (length < 0) { length = strlen(string); } newSize = length + pDs->length; /* * Allocate a larger buffer for the string if the current one isn't * large enough. Allocate extra space in the new buffer so that there * will be room to grow before we have to allocate again. */ if (newSize >= pDs->spaceAvl) { pDs->spaceAvl = newSize*2; newString = (char *) malloc((unsigned) pDs->spaceAvl); memcpy((void *)newString, (void *) pDs->pString, (size_t) pDs->length); if (pDs->pString != pDs->staticSpace) { free(pDs->pString); } pDs->pString = newString; } /* * Copy the new string into the buffer at the end of the old * one. */ for (dst = pDs->pString + pDs->length, end = string+length; string < end; string++, dst++) { *dst = *string; } *dst = 0; pDs->length += length; return pDs->pString;}/* *---------------------------------------------------------------------- * * DStringSetLength -- * * Change the length of a dynamic string. This can cause the * string to either grow or shrink, depending on the value of * length. * * Results: * None. * * Side effects: * The length of pDsis changed to length and a null byte is * stored at that position in the string. If length is larger * than the space allocated for pDs, then a panic occurs. * *---------------------------------------------------------------------- */voidDStringSetLength(DString* pDs, int length){ if (length < 0) { length = 0; } if (length >= pDs->spaceAvl) { char *newString; pDs->spaceAvl = length+1; newString = (char *) malloc((unsigned) pDs->spaceAvl); /* * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string * to a larger buffer, since there may be embedded NULLs in the * string in some cases. */ memcpy((void *) newString, (void*) pDs->pString, (size_t) pDs->length); if (pDs->pString != pDs->staticSpace) { free(pDs->pString); } pDs->pString = newString; } pDs->length = length; pDs->pString[length] = 0;}/* *---------------------------------------------------------------------- * * DStringFree -- * * Frees up any memory allocated for the dynamic string and * reinitializes the string to an empty state. * * Results: * None. * * Side effects: * The previous contents of the dynamic string are lost, and * the new value is an empty string. * *---------------------------------------------------------------------- */voidDStringFree(DString* pDs){ if (pDs->pString != pDs->staticSpace) { free(pDs->pString); } pDs->pString = pDs->staticSpace; pDs->length = 0; pDs->spaceAvl = kDstringStaticSize; pDs->staticSpace[0] = 0;}/* * DStringSprintf -- * * Append a formatted string to a dstring */voidDStringSprintf(DString* pDs, const char* pFormat, ...){#ifdef _WIN32 va_list args; char message[256]; char * buf; size_t bufCchSize; buf = &(message[0]); bufCchSize = sizeof(message); va_start(args, pFormat);# ifndef DISABLE_STRSAFE for (;;) { /* TODO: this only works on windows with recent C library */ HRESULT hr = StringCchVPrintfA(buf, bufCchSize, pFormat, args); if (S_OK == hr) break; if (STRSAFE_E_INSUFFICIENT_BUFFER != hr) { /* any error other than buffer not big enough: a) should not happen b) means we give up */ goto Error; } /* we have to make the buffer bigger. The algorithm used to calculate the new size is arbitrary (aka. educated guess) */ if (buf != &(message[0])) free(buf); if (bufCchSize < 4*1024) bufCchSize += bufCchSize; else bufCchSize += 1024; buf = (char *)malloc(bufCchSize*sizeof(char)); if (NULL == buf) goto Error; }# else /* strsafe is disabled */ { int len = vsnprintf(buf, bufCchSize, pFormat, args); if(len >= bufCchSize) { bufCchSize = len + 1; buf = (char *)malloc(bufCchSize*sizeof(char)); if (NULL == buf) goto Error; len = vsnprintf(buf, bufCchSize, pFormat, args); } if(len < 0) goto Error; }# endif va_end(args); DStringAppend(pDs, buf, -1);Error: if (buf != &(message[0])) free((void*)buf); return;#else va_list args; char* pBuffer; int len; va_start(args, pFormat); len = vasprintf(&pBuffer, pFormat, args); DStringAppend(pDs, pBuffer, len); free(pBuffer); va_end(args);#endif}/**************************************************************************** * DStringAppendLowerCase -- * * Append text to a dstring lowercased */char*DStringAppendLowerCase(DString* pDs, const char* string, int length){ int newSize; char* newString; char* dst; const char* end; if (length < 0) { length = strlen(string); } newSize = length + pDs->length; /* * Allocate a larger buffer for the string if the current one isn't * large enough. Allocate extra space in the new buffer so that there * will be room to grow before we have to allocate again. */ if (newSize >= pDs->spaceAvl) { pDs->spaceAvl = newSize*2; newString = (char *) malloc((unsigned) pDs->spaceAvl); memcpy((void *)newString, (void *) pDs->pString, (size_t) pDs->length); if (pDs->pString != pDs->staticSpace) { free(pDs->pString); } pDs->pString = newString; } /* * Copy the new string into the buffer at the end of the old * one. */ for (dst = pDs->pString + pDs->length, end = string+length; string < end; string++, dst++) { *dst = tolower(*string); } *dst = 0; pDs->length += length; return pDs->pString;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?