StringBuffer.cc

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #include <stdlib.h>
00019 
00020 #include "StringBuffer.h"
00021 #include "StringUtils.h"
00022 
00023 #include "ExpandableBuffer.h"
00024 #include "io/IOClient.h"
00025 
00026 namespace oasys {
00027 
00028 StringBuffer::StringBuffer(size_t initsz, const char* initstr)
00029     : buf_(0), own_buf_(true)
00030 {
00031     buf_ = new ExpandableBuffer();
00032     ASSERT(buf_ != 0);
00033 
00034     ASSERT(initsz != 0);
00035     buf_->reserve(initsz);
00036 
00037     if (initstr) {
00038         append(initstr);
00039     }
00040 }
00041     
00042 StringBuffer::StringBuffer(const char* fmt, ...)
00043     : buf_(0), own_buf_(true)
00044 {
00045     buf_ = new ExpandableBuffer();
00046     ASSERT(buf_);
00047     buf_->reserve(256);
00048 
00049     if (fmt != 0) 
00050     {
00051         STRINGBUFFER_VAPPENDF(*this, fmt);
00052     }
00053 }
00054 
00055 StringBuffer::StringBuffer(ExpandableBuffer* buffer, bool own_buf)
00056     : buf_(buffer), own_buf_(own_buf)
00057 {
00058     ASSERT(buf_ != 0);
00059     buf_->reserve(256);
00060 }
00061 
00062 StringBuffer::~StringBuffer()
00063 {
00064     if (own_buf_)
00065         delete_z(buf_);
00066 }
00067 
00068 const char*
00069 StringBuffer::c_str() const
00070 {
00071     // we make sure there's a null terminator but don't bump up len_
00072     // to count it, just like std::string
00073     if (buf_->len() == 0 || (*buf_->at(buf_->len() - 1) != '\0'))
00074     {
00075         if (buf_->nfree() == 0) {
00076             buf_->reserve(buf_->len() + 1);
00077         }
00078         
00079         *buf_->end() = '\0';
00080     }
00081     
00082     return data();
00083 }
00084 
00085 size_t
00086 StringBuffer::append(const char* str, size_t len)
00087 {
00088     if (len == 0) {
00089         len = strlen(str);
00090 
00091         // might be a zero length string after all
00092         if (len == 0) {
00093             return 0;
00094         }
00095     }
00096     
00097     // len is not past the end of str
00098     ASSERT(len <= strlen(str));
00099 
00100     buf_->reserve(buf_->len() + len);
00101     memcpy(buf_->end(), str, len);
00102     buf_->set_len(buf_->len() + len);
00103     
00104     return len;
00105 }
00106 
00107 size_t
00108 StringBuffer::append(char c)
00109 {
00110     buf_->reserve(buf_->len() + 1);
00111     *buf_->end() = c;
00112     buf_->set_len(buf_->len() + 1);
00113 
00114     return 1;
00115 }
00116 
00117 size_t
00118 StringBuffer::append_int(u_int32_t val, int base)
00119 {
00120     char tmp[16];
00121     size_t len = fast_ultoa(val, base, &tmp[15]);
00122 
00123     ASSERT(len < 16);
00124     
00125     buf_->reserve(buf_->len() + len);
00126     memcpy(buf_->end(), &tmp[16 - len], len);
00127     buf_->set_len(buf_->len() + len);
00128 
00129     return len;
00130 }
00131 
00132 size_t
00133 StringBuffer::append_int(u_int64_t val, int base)
00134 {
00135     char tmp[16];
00136     size_t len = fast_ultoa(val, base, &tmp[15]);
00137 
00138     ASSERT(len < 16);
00139     
00140     buf_->reserve(buf_->len() + len);
00141     memcpy(buf_->end(), &tmp[16 - len], len);
00142     buf_->set_len(buf_->len() + len);
00143 
00144     return len;
00145 }
00146 
00147 size_t
00148 StringBuffer::vappendf(const char* fmt, size_t* lenp, va_list ap)
00149 {
00150     if (buf_->nfree() < (*lenp + 1))
00151     {
00152         ASSERT(buf_->buf_len() != 0);
00153         buf_->reserve(std::max(*lenp + 1, buf_->buf_len() * 2));
00154         ASSERT(buf_->nfree() >= (*lenp + 1));
00155     }
00156 
00157     int ret = vsnprintf(buf_->end(), buf_->nfree(), fmt, ap);
00158 
00159     // Note that we don't support old glibc implementations that
00160     // return -1 from vsnprintf when the output is truncated, but
00161     // depend on vsnprintf returning the length that the formatted
00162     // string would have been
00163     ASSERT(ret >= 0);
00164 
00165     *lenp = std::min(ret, (int)buf_->nfree());
00166     buf_->set_len(buf_->len() + *lenp);
00167         
00168     return ret;
00169 }
00170 
00171 size_t
00172 StringBuffer::appendf(const char* fmt, ...)
00173 {
00174     size_t oldlen = buf_->len();
00175     STRINGBUFFER_VAPPENDF(*this, fmt);
00176     return buf_->len() - oldlen;
00177 }
00178 
00179 } // namespace oasys

Generated on Thu Jun 7 16:56:52 2007 for DTN Reference Implementation by  doxygen 1.5.1