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 #include "base/list.hpp"
00029 #include "base/vector.hpp"
00030 #include "base/common.hpp"
00031 #include "base/date.h"
00032 #include "base/string.hpp"
00033 #include "base/memory.hpp"
00034 #include "base/numeric.h"
00035
00036 BEGIN_TERIMBER_NAMESPACE
00037 #pragma pack(4)
00038
00040 terimber_xml_value
00041 parse_value(vt_types type, const char* x, size_t length, byte_allocator* _allocator)
00042 {
00043 sb2_t ss;
00044 ub2_t us;
00045 terimber_xml_value dest;
00046 memset(&dest, 0, sizeof(terimber_xml_value));
00047 if (!x) return dest;
00048
00049 size_t len = (length == os_minus_one) ? str_template::strlen(x) : length;
00050 switch(type)
00051 {
00052 case vt_empty:
00053 case vt_null:
00054 break;
00055 case vt_bool:
00056 dest.boolVal = (!str_template::strcmp(x, "true", len) || !str_template::strcmp(x, "1", len));
00057 break;
00058 case vt_sb1:
00059 str_template::strscan(x, len, "%hd", &ss);
00060 dest.cVal = (sb1_t)ss;
00061 break;
00062 case vt_ub1:
00063 str_template::strscan(x, len, "%hu", &us);
00064 dest.bVal = (ub1_t)us;
00065 break;
00066 case vt_sb2:
00067 str_template::strscan(x, len, "%hd", &dest.iVal);
00068 break;
00069 case vt_ub2:
00070 str_template::strscan(x, len, "%hu", &dest.uiVal);
00071 break;
00072 case vt_sb4:
00073 str_template::strscan(x, len, "%ld", &dest.lVal);
00074 break;
00075 case vt_ub4:
00076 str_template::strscan(x, len, "%lu", &dest.ulVal);
00077 break;
00078 case vt_float:
00079 str_template::strscan(x, len, "%f", &dest.fltVal);
00080 break;
00081 case vt_double:
00082 {
00083 #ifdef OS_64BIT
00084 str_template::strscan(x, len, "%lf", &dest.dblVal);
00085 #else
00086 check_pointer(_allocator);
00087 double* dummy = (double*)check_pointer(_allocator->allocate(sizeof(double)));
00088 str_template::strscan(x, len, "%lf", dummy);
00089 dest.dblVal = dummy;
00090 #endif
00091 }
00092 break;
00093 case vt_date:
00094 {
00095 date date_dummy(x, len);
00096 #ifdef OS_64BIT
00097 dest.intVal = date_dummy;
00098 #else
00099 check_pointer(_allocator);
00100 sb8_t* dummy = (sb8_t*)check_pointer(_allocator->allocate(sizeof(sb8_t)));
00101 *dummy = date_dummy;
00102 dest.intVal = dummy;
00103 #endif
00104 }
00105 break;
00106 case vt_guid:
00107 {
00108 check_pointer(_allocator);
00109 guid_t* dummy = (guid_t*)check_pointer(_allocator->allocate(sizeof(guid_t)));
00110 string_to_guid(*dummy, x);
00111 dest.guidVal = dummy;
00112 }
00113 break;
00114 case vt_sb8:
00115 {
00116 #ifdef OS_64BIT
00117 str_template::strscan(x, len, I64d, &dest.intVal);
00118 #else
00119 check_pointer(_allocator);
00120 sb8_t* dummy = (sb8_t*)check_pointer(_allocator->allocate(sizeof(sb8_t)));
00121 str_template::strscan(x, len, I64d, dummy);
00122 dest.intVal = dummy;
00123 #endif
00124 }
00125 break;
00126 case vt_ub8:
00127 {
00128 #ifdef OS_64BIT
00129 str_template::strscan(x, len, I64u, &dest.uintVal);
00130 #else
00131 check_pointer(_allocator);
00132 ub8_t* dummy = (ub8_t*)check_pointer(_allocator->allocate(sizeof(ub8_t)));
00133 str_template::strscan(x, len, I64u, dummy);
00134 dest.uintVal = dummy;
00135 #endif
00136 }
00137 break;
00138 case vt_binary:
00139 {
00140 check_pointer(_allocator);
00141 ub1_t* dummy = (ub1_t*)check_pointer(_allocator->allocate(len / 2 + sizeof(ub4_t)));
00142 hex_to_binary(dummy, x, len);
00143 dest.bufVal = dummy;
00144 }
00145 break;
00146 case vt_decimal:
00147 case vt_numeric:
00148 {
00149 check_pointer(_allocator);
00150 numeric num(x, len, _ch_period);
00151 ub1_t* dummy = (ub1_t*)check_pointer(_allocator->allocate(num.orcl_len()));
00152 num.persist_orcl(dummy);
00153 dest.bufVal = dummy;
00154 }
00155 break;
00156 case vt_string:
00157 {
00158 check_pointer(_allocator);
00159 dest.strVal = (const char*)str_template::strcpy((char*)check_pointer(_allocator->allocate(len + 1)), x, len);
00160 }
00161 break;
00162 case vt_wstring:
00163 {
00164 check_pointer(_allocator);
00165 dest.wstrVal = str_template::multibyte_to_unicode( *_allocator, (const char*)x, len);
00166 }
00167 break;
00168 default:
00169 assert(false);
00170 break;
00171 }
00172
00173 return dest;
00174 }
00175
00176 const char*
00177 persist_value(vt_types type, const terimber_xml_value& x, byte_allocator* allocator_)
00178 {
00179 char* dest = 0;
00180 assert(allocator_);
00181 switch(type)
00182 {
00183 case vt_empty:
00184 case vt_null:
00185 break;
00186 case vt_bool:
00187 dest = (char*)check_pointer(allocator_->allocate(2));
00188 dest[0] = x.boolVal ? _ch1 : _ch0;
00189 dest[1] = 0;
00190 break;
00191 case vt_sb1:
00192 dest = (char*)check_pointer(allocator_->allocate(8));
00193 str_template::strprint(dest, 64, "%hd", (sb2_t)x.cVal);
00194 break;
00195 case vt_ub1:
00196 dest = (char*)check_pointer(allocator_->allocate(8));
00197 str_template::strprint(dest, 64, "%hu", (ub2_t)x.bVal);
00198 break;
00199 case vt_sb2:
00200 dest = (char*)check_pointer(allocator_->allocate(64));
00201 str_template::strprint(dest, 64, "%hd", x.iVal);
00202 break;
00203 case vt_ub2:
00204 dest = (char*)check_pointer(allocator_->allocate(64));
00205 str_template::strprint(dest, 64, "%hu", x.uiVal);
00206 break;
00207 case vt_sb4:
00208 dest = (char*)check_pointer(allocator_->allocate(64));
00209 str_template::strprint(dest, 64, "%ld", x.lVal);
00210 break;
00211 case vt_ub4:
00212 dest = (char*)check_pointer(allocator_->allocate(64));
00213 str_template::strprint(dest, 64, "%lu", x.ulVal);
00214 break;
00215 case vt_float:
00216 dest = (char*)check_pointer(allocator_->allocate(64));
00217 str_template::strprint(dest, 64, "%f", (double)x.fltVal);
00218 break;
00219 case vt_double:
00220 if (x.dblVal)
00221 {
00222 dest = (char*)check_pointer(allocator_->allocate(64));
00223 str_template::strprint(dest, 64, "%f",
00224 #ifdef OS_64BIT
00225 x.dblVal
00226 #else
00227 *x.dblVal
00228 #endif
00229 );
00230 }
00231 break;
00232 case vt_date:
00233 if (x.dblVal)
00234 {
00235 dest = (char*)check_pointer(allocator_->allocate(64));
00236 date date_dummy(
00237 #ifdef OS_64BIT
00238 x.intVal
00239 #else
00240 *x.intVal
00241 #endif
00242
00243 );
00244 date_dummy.get_date(dest);
00245 }
00246 break;
00247 case vt_guid:
00248 if (x.guidVal)
00249 {
00250 dest = (char*)check_pointer(allocator_->allocate(sizeof(guid_t) * 2 + 1));
00251 guid_to_string(dest, *x.guidVal);
00252 }
00253 break;
00254 case vt_sb8:
00255 if (x.intVal)
00256 {
00257 dest = (char*)check_pointer(allocator_->allocate(64));
00258 str_template::strprint(dest, 64, I64d,
00259 #ifdef OS_64BIT
00260 x.intVal
00261 #else
00262 *x.intVal
00263 #endif
00264 );
00265 }
00266 break;
00267 case vt_ub8:
00268 if (x.uintVal)
00269 {
00270 dest = (char*)check_pointer(allocator_->allocate(64));
00271 str_template::strprint(dest, 64, I64u,
00272 #ifdef OS_64BIT
00273 x.uintVal
00274 #else
00275 *x.uintVal
00276 #endif
00277 );
00278 }
00279 break;
00280 case vt_binary:
00281 if (x.bufVal)
00282 {
00283 dest = (char*)check_pointer(allocator_->allocate(*(ub4_t*)x.bufVal * 2));
00284 binary_to_hex(dest, x.bufVal);
00285 }
00286 break;
00287 case vt_decimal:
00288 case vt_numeric:
00289 if (x.bufVal)
00290 {
00291 numeric num;
00292 num.parse_orcl(x.bufVal);
00293 dest = (char*)check_pointer(allocator_->allocate(num.precision() + 4));
00294 num.format(dest, _ch_period);
00295 }
00296 break;
00297 case vt_string:
00298 dest = (char*)x.strVal;
00299 break;
00300 case vt_wstring:
00301 if (x.wstrVal)
00302 {
00303 dest = (char*)str_template::unicode_to_multibyte( *allocator_, x.wstrVal);
00304 }
00305 break;
00306 default:
00307 assert(false);
00308 break;
00309 }
00310
00311 return dest;
00312 }
00313
00316 paged_buffer::paged_buffer(byte_allocator& data_allocator, byte_allocator& tmp_allocator, size_t xml_size) :
00317 _data_allocator(data_allocator), _tmp_allocator(tmp_allocator), _size(xml_size), _pos(0)
00318 {
00319 _ptr = _primary = (ub1_t*)_data_allocator.allocate(_size + 1);
00320 }
00321
00322 paged_buffer::~paged_buffer()
00323 {
00324 }
00325
00326 const char*
00327 paged_buffer::_persist()
00328 {
00329 size_t total_len = size();
00330 char* retVal = 0;
00331 if (total_len && (retVal = (char*)_tmp_allocator.allocate(total_len + 1)))
00332 {
00333 retVal[total_len] = 0;
00334
00335 memcpy(retVal, _primary, _size);
00336 size_t shift = _size;
00337
00338 for (paged_store_t::iterator iter = _buffer.begin(); iter != _buffer.end(); ++iter)
00339 {
00340 size_t len = (&*iter != &_buffer.back()) ? _size : _pos;
00341 memcpy(retVal + shift, iter->begin(), len);
00342 shift += len;
00343 }
00344 }
00345
00346 return retVal;
00347 }
00348
00349 const ub1_t*
00350 paged_buffer::_persist(size_t& size_)
00351 {
00352 size_t total_len = size();
00353 size_ = total_len;
00354 ub1_t* retVal = 0;
00355 if (total_len && (retVal = (ub1_t*)_tmp_allocator.allocate(total_len)))
00356 {
00357 retVal[total_len] = 0;
00358
00359 memcpy(retVal, _primary, _size);
00360 size_t shift = _size;
00361 for (paged_store_t::iterator iter = _buffer.begin(); iter != _buffer.end(); ++iter)
00362 {
00363 size_t len = (&*iter != &_buffer.back()) ? _size : _pos;
00364 memcpy(retVal + shift, iter->begin(), len);
00365 shift += len;
00366 }
00367 }
00368
00369 return retVal;
00370 }
00371
00372
00373 void
00374 paged_buffer::add_page()
00375 {
00376
00377 paged_vector_t vec;
00378 _buffer.push_back(_tmp_allocator, vec);
00379 paged_vector_t& entry = _buffer.back();
00380 entry.resize(_tmp_allocator, _size + 1);
00381 _ptr = entry.begin();
00382 _pos = 0;
00383 }
00384
00386 #pragma pack()
00387 END_TERIMBER_NAMESPACE