/* * i4dstring.cpp -- * * This file provides an implementation of a dynamic string. The * string grows automatically and efficiently as more characters * are appended. * * This facility is modeled after the Tcl_DString feature of Tcl * 8.0.4. * * Copyright (c) 1991-1993 The Regents of the University of California. * Copyright (c) 1994 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "e4graphimpl.h" /* * Constructor: */ e4_DString::e4_DString() : buf(staticSpace) { Reset(); } /* * Destructor: */ e4_DString::~e4_DString() { /* * If the buffer was relocated to a dynamic buffer, free that buffer. */ if (buf != staticSpace) { free(buf); } } /* * Append a string to this DString. */ void e4_DString::Append(const char *str, int slen) { int newlength; char *newbuf; /* * Sanity check -- do nothing if appending NULL. */ if (str == NULL) { return; } /* * If the given length is < 0, it means that we have to compute the * length here. Otherwise we use the given length as the true length. */ if (slen < 0) { slen = strlen(str); } /* * See if there's space in the current buffer. If not, relocate the * current content to a new buffer before appending. */ newlength = slen + length; if (newlength >= spaceAvailable) { spaceAvailable = newlength * 2; newbuf = (char *) memcpy((void *) malloc(spaceAvailable), (const void *) buf, length); if (buf != staticSpace) { free(buf); } buf = newbuf; } /* * Now append the new string to the buffer. Note that the string to copy * is not NULL terminated so we only copy as much as the caller told us. * Also, the string to be appended might contain embedded NULLs and that * prevents use of strcpy or strncpy. */ memcpy((void *) ((char *) buf + length), (const void *) str, slen); buf[newlength] = '\0'; /* * Update the DString. */ length = newlength; } /* * Get a copy of this DString. The memory is expected to be freed by the * caller when done with using it. */ char * e4_DString::GetCopy() const { char *res; if (length <= 0) { return NULL; } res = (char *) memcpy((void *) malloc(length + 1), (const void *) buf, length); res[length] = '\0'; return res; } /* * Get the string from this DString. The memory is owned by the DString. */ char * e4_DString::Get() const { if (length <= 0) { return NULL; } return buf; } /* * Get the length of the string in this DString. */ int e4_DString::Length() const { return length; } /* * Set the length of the string in this DString. If the string is * longer, this truncates the string. If the string is shorter, it * is a no-op. * * Either way return the new length of the string. */ int e4_DString::SetLength(int newlength) { if ((newlength <= length) && (newlength >= 0)) { length = newlength; buf[length] = '\0'; } return length; } /* * Reset this DString to its original state. */ void e4_DString::Reset(void) { /* * Reclaim allocated space, if any. */ if (buf != staticSpace) { free(buf); } /* * Reset to original state. */ buf = staticSpace; length = 0; spaceAvailable = E4_DSTRING_STATIC_SIZE + 1; staticSpace[0] = '\0'; }