00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #ifndef STLSOFT_INCL_H_STLSOFT
00064 # include "stlsoft.h"
00065 #endif
00066 #ifndef STLSOFT_INCL_H_STLSOFT_AUTO_BUFFER
00067 # include "stlsoft_auto_buffer.h"
00068 #endif
00069 #ifndef STLSOFT_INCL_H_STLSOFT_PROCESSHEAP_ALLOCATOR
00070 # include "stlsoft_malloc_allocator.h"
00071 #endif
00072 #ifndef STLSOFT_INCL_H_STLSOFT_CHAR_TRAITS
00073 # include "stlsoft_char_traits.h"
00074 #endif
00075 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_ACCESS
00076 # include "stlsoft_string_access.h"
00077 #endif
00078
00079
00080
00081
00082
00083 #ifndef _STLSOFT_NO_NAMESPACE
00084 namespace stlsoft
00085 {
00086 #endif
00087
00088
00089
00092
00097
00098
00099
00100
00101
00103 template< ss_typename_param_k C
00104 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00105 , ss_typename_param_k T = char_traits<C>
00106 , ss_typename_param_k A = malloc_allocator<C>
00107 #else
00108 , ss_typename_param_k T
00109 , ss_typename_param_k A
00110 #endif
00111 >
00112 class basic_environment_block
00113 {
00116 public:
00118 typedef C value_type;
00120 typedef C char_type;
00122 typedef T traits_type;
00124 typedef A allocator_type;
00126 typedef basic_environment_block<C, T, A> class_type;
00128 typedef char_type *pointer;
00130 typedef char_type const *const_pointer;
00132 typedef ss_size_t size_type;
00134
00137 public:
00138 basic_environment_block()
00139 : m_chars(1)
00140 , m_offsets(1)
00141 , m_pointers(0)
00142 {
00143 m_chars[0] = '\0';
00144 m_offsets[0] = 0;
00145 }
00147
00150 public:
00152 void push_back(char_type const *s, size_t cch)
00153 {
00154 stlsoft_assert(NULL != s);
00155 stlsoft_assert(cch >= 3);
00156 stlsoft_assert(NULL != traits_type::find(s, cch, '='));
00157
00158 stlsoft_assert(m_chars.size() > 0);
00159 stlsoft_assert('\0' == m_chars[m_chars.size() - 1]);
00160
00161 const size_type numChars_ = m_chars.size();
00162 const size_type numOffsets_ = m_offsets.size();
00163 const size_type numPointers_ = m_pointers.size();
00164
00165 m_chars.resize(numChars_ + cch + 1);
00166
00167 traits_type::copy(&m_chars[numChars_ - 1], s, cch);
00168 m_chars[numChars_ + cch - 1] = '\0';
00169
00170 m_chars[numChars_ + cch] = '\0';
00171
00172 m_offsets.resize(numOffsets_ + 1);
00173 m_offsets[numOffsets_] = numChars_ + cch;
00174
00175 m_pointers.resize(0);
00176
00177 stlsoft_assert('\0' == m_chars[m_chars.size() - 1]);
00178 }
00179 template <typename S>
00180 void push_back(S const &s)
00181 {
00182 push_back(stlsoft_ns_qual(c_str_ptr)(s), stlsoft_ns_qual(c_str_len)(s));
00183 }
00184 void push_back(char_type const *name, size_t cchName, char_type const *value, size_t cchValue)
00185 {
00186 stlsoft_assert(NULL != name);
00187 stlsoft_assert(NULL != value);
00188 stlsoft_assert(cchName > 0);
00189 stlsoft_assert(cchValue > 0);
00190 stlsoft_assert(NULL == traits_type::find(name, cchName, '='));
00191
00192 stlsoft_assert(m_chars.size() > 0);
00193 stlsoft_assert('\0' == m_chars[m_chars.size() - 1]);
00194
00195 const size_type numChars_ = m_chars.size();
00196 const size_type numOffsets_ = m_offsets.size();
00197 const size_type numPointers_ = m_pointers.size();
00198
00199 m_chars.resize(numChars_ + cchName + 1 + cchValue + 1);
00200
00201
00202 traits_type::copy(&m_chars[numChars_ - 1], name, cchName);
00203 m_chars[numChars_ - 1 + cchName] = '=';
00204 traits_type::copy(&m_chars[numChars_ - 1 + cchName + 1], value, cchValue);
00205 m_chars[numChars_ - 1 + cchName + 1 + cchValue] = '\0';
00206
00207 m_chars[numChars_ + cchName + 1 + cchValue] = '\0';
00208
00209 m_offsets.resize(numOffsets_ + 1);
00210 m_offsets[numOffsets_] = numChars_ + cchName + 1 + cchValue;
00211
00212 m_pointers.resize(0);
00213
00214 stlsoft_assert('\0' == m_chars[m_chars.size() - 1]);
00215 }
00216 template <typename S1, typename S2>
00217 void push_back(S1 const &name, S2 const &value)
00218 {
00219 push_back(stlsoft_ns_qual(c_str_ptr)(name), stlsoft_ns_qual(c_str_len)(name), stlsoft_ns_qual(c_str_ptr)(value), stlsoft_ns_qual(c_str_len)(value));
00220 }
00221
00222 void clear()
00223 {
00224 m_chars.resize(1);
00225 m_offsets.resize(1);
00226 m_pointers.resize(0);
00227
00228 m_chars[0] = '\0';
00229 m_offsets[0] = 0;
00230 }
00232
00235 public:
00236 char_type const *const *base() const
00237 {
00238 if(m_pointers.size() != m_offsets.size())
00239 {
00240 set_pointers();
00241 }
00242
00243 return m_pointers.data();
00244 }
00245 size_type size() const
00246 {
00247 stlsoft_assert(m_offsets.size() >= 1);
00248
00249 return m_offsets.size() - 1;
00250 }
00252
00253
00254 private:
00255 void set_pointers()
00256 {
00257 if(m_pointers.resize(m_offsets.size()))
00258 {
00259 for(size_type i = 0; i < m_offsets.size(); ++i)
00260 {
00261 m_pointers[i] = &m_chars[m_offsets[i]];
00262 }
00263 }
00264 }
00265
00266 void set_pointers() const
00267 {
00268 const_cast<class_type*>(this)->set_pointers();
00269 }
00270
00271
00272 private:
00273 typedef stlsoft_ns_qual(auto_buffer)<char_type, allocator_type, 1024> char_buffer_type;
00274 #if !defined(__STLSOFT_COMPILER_IS_MSVC) || \
00275 _MSC_VER >= 1300
00276 typedef stlsoft_ns_qual(auto_buffer)<size_type, allocator_type::rebind<size_type>::other, 32> offset_buffer_type;
00277 typedef stlsoft_ns_qual(auto_buffer)<const_pointer, allocator_type::rebind<pointer>::other, 32> pointer_buffer_type;
00278 #else
00279 typedef stlsoft_ns_qual(auto_buffer)<size_type, malloc_allocator<size_type>, 32> offset_buffer_type;
00280 typedef stlsoft_ns_qual(auto_buffer)<const_pointer, malloc_allocator<pointer>, 32> pointer_buffer_type;
00281 #endif
00282
00283 char_buffer_type m_chars;
00284 offset_buffer_type m_offsets;
00285 pointer_buffer_type m_pointers;
00286 };
00287
00288
00289
00290
00291
00292 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00293
00295 typedef basic_environment_block<ss_char_a_t> environment_block_a;
00297 typedef basic_environment_block<ss_char_w_t> environment_block_w;
00298
00299 #endif
00300
00301
00302
00303
00304
00305 #ifdef STLSOFT_UNITTEST
00306
00307 namespace unittest
00308 {
00309 ss_bool_t test_stlsoft_environment_block(unittest_reporter *r)
00310 {
00311 using stlsoft::unittest::unittest_initialiser;
00312
00313 ss_bool_t bSuccess = true;
00314
00315 unittest_initialiser init(r, "STLSoft", "environment_block", __FILE__);
00316
00317 return bSuccess;
00318 }
00319
00320 unittest_registrar unittest_stlsoft_environment_block(test_stlsoft_environment_block);
00321
00322 }
00323
00324 #endif
00325
00326
00327
00328
00329
00330
00331
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344