Str.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:19k
- /* $Id: Str.c++,v 1.6 2009/10/07 15:36:26 faxguy Exp $ */
- /*
- * Copyright (c) 1990-1996 Sam Leffler
- * Copyright (c) 1991-1996 Silicon Graphics, Inc.
- * HylaFAX is a trademark of Silicon Graphics
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- #include "Str.h"
- #include <stdlib.h>
- #include <ctype.h>
- #include <stdarg.h>
- #include <errno.h>
- #define DEFAULT_FORMAT_BUFFER 4096
- char fxStr::emptyString = ' ';
- fxStr fxStr::null = "";
- fxStr::fxStr(u_int l)
- {
- isutf8 = false;
- slength = l+1;
- if (l>0) {
- data = (char*) malloc(slength);
- memset(data,0,slength);
- } else
- data = &emptyString;
- }
- fxStr::fxStr(const char *s)
- {
- isutf8 = false;
- u_int l = strlen(s)+1;
- if (l>1) {
- data = (char*) malloc(l);
- memcpy(data,s,l);
- } else {
- data = &emptyString;
- }
- slength = l;
- }
- fxStr::fxStr(const char *s, u_int len)
- {
- isutf8 = false;
- if (len>0) {
- data = (char*) malloc(len+1);
- memcpy(data,s,len);
- data[len] = 0;
- } else
- data = &emptyString;
- slength = len+1;
- }
- fxStr::fxStr(const fxStr& s)
- {
- isutf8 = s.isutf8;
- slength = s.slength;
- if (slength > 1) {
- data = (char*) malloc(slength);
- memcpy(data,s.data,slength);
- } else {
- data = &emptyString;
- }
- }
- fxStr::fxStr(const fxTempStr& t)
- {
- isutf8 = t.isutf8;
- slength = t.slength;
- if (t.slength>1) {
- data = (char*) malloc(slength);
- memcpy(data,t.data,slength);
- } else {
- data = &emptyString;
- }
- }
- fxStr::fxStr(int a, const char * format)
- {
- fxStr s = fxStr::format((format) ? format : "%d", a);
- slength = s.slength;
- isutf8 = s.isutf8;
- if (slength > 1) {
- data = (char*) malloc(slength);
- memcpy(data, s.data, slength);
- } else {
- data = &emptyString;
- }
- }
- fxStr::fxStr(long a, const char * format)
- {
- fxStr s = fxStr::format((format) ? format : "%ld", a);
- slength = s.slength;
- isutf8 = s.isutf8;
- if (slength > 1) {
- data = (char*) malloc(slength);
- memcpy(data, s.data, slength);
- } else {
- data = &emptyString;
- }
- }
- fxStr::fxStr(float a, const char * format)
- {
- fxStr s = fxStr::format((format) ? format : "%g", a);
- slength = s.slength;
- isutf8 = s.isutf8;
- if (slength > 1) {
- data = (char*) malloc(slength);
- memcpy(data, s.data, slength);
- } else {
- data = &emptyString;
- }
- }
- fxStr::fxStr(double a, const char * format)
- {
- fxStr s = fxStr::format((format) ? format : "%lg", a);
- slength = s.slength;
- isutf8 = s.isutf8;
- if (slength > 1) {
- data = (char*) malloc(slength);
- memcpy(data, s.data, slength);
- } else {
- data = &emptyString;
- }
- }
- fxStr::~fxStr()
- {
- assert(data);
- if (data != &emptyString) free(data);
- }
- fxStr
- fxStr::format(const char* fmt ...)
- {
- int size = DEFAULT_FORMAT_BUFFER;
- fxStr s;
- va_list ap;
- va_start(ap, fmt);
- s.data = (char*)malloc(size);
- int len = vsnprintf(s.data, size, fmt, ap);
- va_end(ap);
- while (len < 0 || len >= size) {
- if (len < 0 && errno != 0)
- return s;
- if (len >= size) {
- size = len + 1;
- } else {
- size *= 2;
- }
- s.data = (char*)realloc(s.data, size);
- va_start(ap, fmt);
- len = vsnprintf(s.data, size, fmt, ap);
- va_end(ap);
- }
- if (size > len + 1) {
- s.data = (char*) realloc(s.data, len + 1);
- }
- s.slength = len + 1;
- return s; //XXX this is return by value which is inefficient
- }
- fxStr
- fxStr::vformat(const char* fmt, va_list ap)
- {
- int size = DEFAULT_FORMAT_BUFFER;
- fxStr s;
- char* tmp = NULL;
- int len = 0;
- do
- {
- if (len)
- size *= 2;
- tmp = (char*)realloc(tmp, size);
- va_list ac;
- va_copy(ac, ap);
- len = vsnprintf(tmp, size, fmt, ac);
- va_end(ac);
- fxAssert(len >= 0, "Str::vformat() error in vsnprintf");
- } while (len > size);
- if (size > len + 1) {
- tmp = (char*) realloc(tmp, len + 1);
- }
- s.data = tmp;
- s.slength = len + 1;
- return s; //XXX this is return by value which is inefficient
- }
- fxStr fxStr::extract(u_int start, u_int chars) const
- {
- fxAssert(start+chars<slength, "Str::extract: Invalid range");
- return fxStr(data+start,chars);
- }
- fxStr fxStr::head(u_int chars) const
- {
- fxAssert(chars<slength, "Str::head: Invalid size");
- return fxStr(data,chars);
- }
- fxStr fxStr::tail(u_int chars) const
- {
- fxAssert(chars<slength, "Str::tail: Invalid size");
- return fxStr(data+slength-chars-1,chars);
- }
- void fxStr::lowercase(u_int posn, u_int chars)
- {
- if (!chars) chars = slength-1-posn;
- fxAssert(posn+chars<slength, "Str::lowercase: Invalid range");
- while (chars--) {
- #if defined(hpux) || defined(__hpux) || defined(__hpux__)
- /*
- * HPUX (10.x at least) is seriously busted. According
- * to the manual page, when compiling in ANSI C mode tolower
- * is defined as a macro that expands to a function that
- * is undefined. It is necessary to #undef tolower before
- * using it! (sigh)
- */
- #ifdef tolower
- #undef tolower
- #endif
- data[posn] = tolower(data[posn]);
- #elif defined(_tolower)
- char c = data[posn];
- if (isupper(c))
- data[posn] = _tolower(c);
- #else
- data[posn] = tolower(data[posn]);
- #endif
- posn++;
- }
- }
- void fxStr::raisecase(u_int posn, u_int chars)
- {
- if (!chars) chars = slength-1-posn;
- fxAssert(posn+chars<slength, "Str::raisecase: Invalid range");
- while (chars--) {
- #ifdef hpux // HPUX bogosity; see above
- #ifdef toupper
- #undef toupper
- #endif
- data[posn] = toupper(data[posn]);
- #elif defined(_toupper)
- char c = data[posn];
- if (islower(c))
- data[posn] = _toupper(c);
- #else
- data[posn] = toupper(data[posn]);
- #endif
- posn++;
- }
- }
- /*
- * Although T.32 6.1.1 and T.31 6.1 may lead a DCE to not
- * distinguish between lower case and upper case, many DCEs
- * actually support lower case characters in quoted strings.
- * Thus, we don't rasecase quoted strings.
- */
- void fxStr::raiseatcmd(u_int posn, u_int chars)
- {
- if (!chars) chars = slength-1-posn;
- fxAssert(posn+chars<slength, "Str::raiseatcmd: Invalid range");
- bool quoted = false;
- while (chars--) {
- #ifdef hpux // HPUX bogosity; see above
- #ifdef toupper
- #undef toupper
- #endif
- if (!quoted)
- data[posn] = toupper(data[posn]);
- #elif defined(_toupper)
- char c = data[posn];
- if (islower(c) && !quoted)
- data[posn] = _toupper(c);
- #else
- if (!quoted)
- data[posn] = toupper(data[posn]);
- #endif
- if (data[posn] == '"')
- quoted = !quoted;
- posn++;
- }
- }
- fxStr fxStr::copy() const
- {
- return fxStr(data,slength-1);
- }
- void fxStr::remove(u_int start, u_int chars)
- {
- fxAssert(start+chars<slength,"Str::remove: Invalid range");
- long move = slength-start-chars; // we always move at least 1
- assert(move > 0);
- if (slength - chars <= 1) {
- resizeInternal(0);
- slength = 1;
- } else {
- memmove(data+start, data+start+chars, (u_int)move);
- slength -= chars;
- }
- }
- fxStr fxStr::cut(u_int start, u_int chars)
- {
- fxAssert(start+chars<slength,"Str::cut: Invalid range");
- fxStr a(data+start, chars);
- remove(start, chars);
- return a;
- }
- void fxStr::insert(const char * v, u_int posn, u_int len)
- {
- if (!len) len = strlen(v);
- if (!len) return;
- fxAssert(posn<slength, "Str::insert: Invalid index");
- u_int move = slength - posn;
- u_int nl = slength + len;
- resizeInternal(nl);
- /*
- * When move is one we are always moving