00001 #ifndef GLIM_BUFSTR_T_HPP_
00002 #define GLIM_BUFSTR_T_HPP_
00003
00004
00005
00006
00007 #include <stdexcept>
00008 #include <limits>
00009 #include <utility>
00010 #include <string>
00011 #include "config.h"
00012 #if defined HAS_stpncpy
00013 # include <string.h>
00014 #endif
00015 #include "c_func.hpp"
00016
00017 namespace glim {
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 template <int SIZE, bool THROW = true>
00029 struct bufstr_t {
00030
00031
00032
00033
00034 char buf[SIZE+1];
00035
00036 int len;
00037
00038
00039
00040
00041 bufstr_t(): len(0) {}
00042
00043
00044
00045
00046
00047 char* c() {
00048 buf[len] = 0;
00049 return buf;
00050 }
00051
00052
00053
00054
00055
00056 char* c_str() {
00057 buf[len] = 0;
00058 return buf;
00059 }
00060
00061
00062
00063
00064
00065 char* end() const {
00066 return (char*) buf + len;
00067 }
00068
00069
00070
00071
00072
00073 std::pair<char const*, int> pair() const {
00074 return std::pair<char const*, int> (buf, len);
00075 }
00076
00077
00078
00079
00080 bufstr_t& reset() {
00081 len = 0;
00082 return *this;
00083 }
00084
00085
00086
00087
00088 template <int C_SIZE, bool C_THROW>
00089 bufstr_t& operator << (const bufstr_t<C_SIZE, C_THROW>& ab) {
00090 return appendString(ab.buf, ab.len); }
00091
00092
00093
00094
00095 bufstr_t& operator << (std::pair<char const*, int> str) {
00096 return appendString(str.first, str.second); }
00097
00098
00099
00100
00101 bufstr_t& operator << (char const* cs) {
00102 return appendString(cs); }
00103
00104
00105 bufstr_t& operator << (const std::string& str) {
00106 return appendString (str.c_str(), str.length()); }
00107
00108
00109
00110
00111 template <typename INT>
00112 bufstr_t& appendInt (INT integer) {
00113 if (SIZE - len < std::numeric_limits<INT>::digits10 + 2) {
00114 if (THROW) throw std::out_of_range("bufstr_t");
00115 else return *this;
00116 }
00117 char* end = buf + len;
00118 len += glim::itoa(end, integer) - end;
00119 return *this; }
00120
00121
00122
00123
00124 bufstr_t& appendString (char const* str, int strLen) {
00125 if (strLen > 0) {
00126 if (strLen + len > SIZE) {
00127 if (THROW) throw std::out_of_range("bufstr_t");
00128 else return *this;
00129 } else {
00130 memcpy(buf+len, str, strLen);
00131 len += strLen;
00132 } }
00133 return *this; }
00134
00135
00136
00137
00138 bufstr_t& appendString (char const* cs) {
00139 if (cs) {
00140 char* end = buf + len;
00141 #if defined HAS_stpncpy
00142 len += ::stpncpy(end, cs, SIZE - len) - end;
00143 #else
00144 len += glim::stpncpy(end, cs, SIZE - len) - end;
00145 #endif
00146 if(THROW && len == SIZE) throw std::out_of_range("bufstr_t");
00147 }
00148 return *this; }
00149
00150
00151 bufstr_t& appendString (const std::string& str) {
00152 return appendString (str.c_str(), str.length()); }
00153
00154
00155 bufstr_t& operator << (int integer) {
00156 return appendInt(integer); }
00157
00158
00159 bufstr_t& operator << (long long integer) {
00160 return appendInt(integer); }
00161
00162
00163
00164
00165 bufstr_t& operator << (char ch) {
00166 if (len >= SIZE) {
00167 if (THROW) throw std::out_of_range("bufstr_t");
00168 else return *this;
00169 }
00170 buf[len++] = ch;
00171 return *this;
00172 }
00173 };
00174
00175 }
00176
00177 #endif // GLIM_BUFSTR_T_HPP_