StringBuffer.h

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 #ifndef _OASYS_STRING_BUFFER_H_
00019 #define _OASYS_STRING_BUFFER_H_
00020 
00021 #include <algorithm>
00022 
00023 #include "../debug/Log.h"       // for PRINTFLIKE macro
00024 #include "ScratchBuffer.h"
00025 
00026 namespace oasys {
00027 
00028 class ExpandableBuffer;
00029 
00038 class StringBuffer {
00039 public:
00044     StringBuffer(size_t initsz = 256, const char* initstr = 0);
00045 
00047     StringBuffer(const char* fmt, ...) PRINTFLIKE(2, 3);
00048 
00050     StringBuffer(ExpandableBuffer* buffer, bool own_buf);
00052         
00053     ~StringBuffer();
00054 
00058     ExpandableBuffer* expandable_buf() { return buf_; }
00059 
00063     const char* data() const { return buf_->raw_buf(); }
00064 
00068     char* data() { return buf_->raw_buf(); }
00069 
00074     size_t length() const { return buf_->len(); }
00075 
00079     const char* c_str() const;
00080 
00088     size_t append(const char* str, size_t len = 0);
00089 
00096     size_t append(const std::string& str)
00097     {
00098         return append(str.data(), str.length());
00099     }
00100 
00107     size_t append(char c);
00108 
00115     size_t appendf(const char* fmt, ...) PRINTFLIKE(2, 3);
00116 
00135     size_t vappendf(const char* fmt, size_t* lenp, va_list ap);
00136     
00142     size_t append_int(u_int32_t val, int base);
00143 
00149     size_t append_int(u_int64_t val, int base);
00150 
00154     void trim(size_t cnt)
00155     {
00156         ASSERT(buf_->len() >= cnt);
00157         buf_->set_len(buf_->len() - cnt);
00158     }
00159 
00163     void set_length(size_t len)
00164     {
00165         ASSERT(buf_->buf_len() >= len);
00166         buf_->set_len(len);
00167     }
00168 
00169 private:
00170     mutable ExpandableBuffer* buf_;
00171     bool    own_buf_;
00172 };
00173 
00179 #define STRINGBUFFER_VAPPENDF(_stringbuf, _fmt)                              \
00180     do {                                                        \
00181         size_t ret;                                             \
00182         size_t len = 0;                                         \
00183                                                                 \
00184         /* call once optimistically with no known length */     \
00185         {                                                       \
00186             va_list ap;                                         \
00187             va_start(ap, _fmt);                                 \
00188             ret = (_stringbuf).vappendf(_fmt, &len, ap);        \
00189             va_end(ap);                                         \
00190         }                                                       \
00191                                                                 \
00192         /* call again with the known length */                  \
00193         if (ret >= len)                                         \
00194         {                                                       \
00195             (_stringbuf).trim(len);                             \
00196             len = ret;                                          \
00197             va_list ap;                                         \
00198             va_start(ap, _fmt);                                 \
00199             ret = (_stringbuf).vappendf(_fmt, &len, ap);        \
00200             va_end(ap);                                         \
00201         }                                                       \
00202                                                                 \
00203         ASSERT(ret == len);                                     \
00204     } while (0)
00205 
00214 template<size_t _sz>
00215 class StaticStringBuffer : public StringBuffer {
00216 public:
00220     StaticStringBuffer()
00221         : StringBuffer(new ScratchBuffer<char*, _sz>(), true) {}
00222     
00228     StaticStringBuffer(const char* fmt, ...) PRINTFLIKE(2, 3);
00229 };
00230 
00231 template <size_t _sz>
00232 StaticStringBuffer<_sz>::StaticStringBuffer(const char* fmt, ...)
00233     : StringBuffer(new ScratchBuffer<char*, _sz>(), true)
00234 {
00235     if (fmt != 0) 
00236     {
00237         STRINGBUFFER_VAPPENDF(*this, fmt);
00238     }
00239 }
00240 
00241 
00242 } // namespace oasys
00243 
00244 #endif /* _OASYS_STRING_BUFFER_H_ */

Generated on Sat Sep 8 08:36:18 2007 for DTN Reference Implementation by  doxygen 1.5.3