00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BITFIELDBUFFER_H
00020 #define BITFIELDBUFFER_H
00021
00022 #include <bit/fieldbase.h>
00023 #include <bit/data.h>
00024
00025 #include <sstream>
00026
00027 namespace bit
00028 {
00029
00030 class RecordBuffer;
00031
00032
00040 class FieldBuffer
00041 {
00042 public:
00043
00044 FieldBuffer(RecordBuffer& b, FieldBase::pointer f);
00045
00046 virtual ~FieldBuffer();
00047
00048 const std::string& xml();
00049
00050 FieldBuffer field(size_t index) throw (exception::invalid_index);
00051
00052 FieldBuffer field(std::string index) throw (exception::invalid_index);
00053
00054 FieldBuffer operator[](size_t index) throw (exception::invalid_index);
00055
00056 FieldBuffer operator[](std::string index) throw (exception::invalid_index);
00057
00058 template <typename T>
00059 operator T();
00060
00064 Data data();
00065
00066 bool unpack(void* mem, size_t mem_octets);
00067
00068 template <typename T>
00069 bool unpack(T& val);
00070
00071 bool pack(const void* mem, size_t mem_octets);
00072 bool pack(const void* mem, size_t mem_octets, size_t n);
00073
00074 template <typename T>
00075 bool pack(const T& val);
00076 template <typename T>
00077 FieldBuffer& operator=(const T& t);
00078
00079 FieldBase::pointer field();
00080 RecordBuffer& buffer();
00081
00082 protected:
00083 RecordBuffer& m_buffer;
00084 FieldBase::pointer m_field;
00085 std::string m_xml;
00086
00091 bool unpack_uint64(uint64_t& ui64 );
00092
00093 bool unpack_float(float& f);
00094 bool unpack_double(double& d);
00095
00100 bool pack_uint64(uint64_t data);
00101 bool pack_float(float f);
00102 bool pack_double(double d);
00103
00104 };
00105
00106 template <typename T>
00107 inline
00108 FieldBuffer::operator T()
00109 {
00110 T t;
00111 unpack(t);
00112 return t;
00113 }
00114
00115 template <typename T>
00116 inline
00117 bool FieldBuffer::unpack(T& val)
00118 {
00119 bool b;
00120 float f;
00121 double d;
00122 uint64_t ui64;
00123 size_t length;
00124
00125
00126 switch ( m_field->type().type() )
00127 {
00128 case TYPE_INTEGER:
00129 b = unpack_uint64(ui64);
00130 val = static_cast<uint64_t>(ui64);
00131 return b;
00132
00133 case TYPE_FLOATING:
00134 length = m_field->length(BITS);
00135 if ( ! (length == 64 || length == 32 ) )
00136 throw exception::type::floating_point_length();
00137 if (length == 64)
00138 {
00139 b = unpack_double(d);
00140 val = static_cast<T>(d);
00141 }
00142 else
00143 {
00144 b = unpack_float(f);
00145 val = static_cast<T>(f);
00146 }
00147 return b;
00148 case TYPE_NONE:
00149 case TYPE_ASCII:
00150 case TYPE_UTF8:
00151 case TYPE_BCD:
00152 break;
00153 }
00154 return unpack(&val, sizeof(T));
00155 }
00156
00157
00158
00159 template <>
00160 inline
00161 bool FieldBuffer::unpack(std::string& val)
00162 {
00163 double d;
00164 float f;
00165 uint64_t ui64;
00166 size_t length;
00167 std::ostringstream sout;
00168
00169
00170 switch ( m_field->type().type() )
00171 {
00172 case TYPE_INTEGER:
00173 if ( unpack_uint64(ui64) )
00174 {
00175 sout << ui64;
00176 val = sout.str();
00177 return true;
00178 }
00179 else
00180 return false;
00181
00182 case TYPE_FLOATING:
00183 length = m_field->length(BITS);
00184 if ( ! (length == 64 || length == 32 ) )
00185 throw exception::type::floating_point_length();
00186 if (length == 64)
00187 {
00188 if ( unpack_double(d) )
00189 {
00190 sout << d;
00191 val = sout.str();
00192 return true;
00193 }
00194 else
00195 return false;
00196 }
00197 else
00198 {
00199 if ( unpack_float(f) )
00200 {
00201 sout << f;
00202 val = sout.str();
00203 return true;
00204 }
00205 else
00206 return false;
00207 }
00208 default:
00209 return false;
00210 }
00211 return false;
00212 }
00213
00214 template <typename T>
00215 inline
00216 bool FieldBuffer::pack(const T& val)
00217 {
00218 uint64_t ui64;
00219 double d;
00220 float f;
00221 size_t length;
00222
00223 switch ( m_field->type().type() )
00224 {
00225 case TYPE_INTEGER:
00226 ui64 = val;
00227 return pack_uint64(ui64);
00228
00229 case TYPE_FLOATING:
00230 length = m_field->length(BITS);
00231 if ( ! (length == 64 || length == 32 ) )
00232 throw exception::type::floating_point_length();
00233 if (length == 64)
00234 {
00235 d = static_cast<double>(val);
00236 return pack_double(d);
00237 }
00238 else
00239 {
00240 f = static_cast<float>(val);
00241 return pack_float(f);
00242 }
00243 case TYPE_NONE:
00244 case TYPE_ASCII:
00245 case TYPE_UTF8:
00246 case TYPE_BCD:
00247 break;
00248 }
00249
00250 return pack(&val, sizeof(T));
00251 }
00252
00253 template <>
00254 inline
00255 bool FieldBuffer::pack(const std::string& val)
00256 {
00257 uint64_t ui64;
00258 double d;
00259 float f;
00260 size_t length;
00261 std::istringstream sin(val);
00262
00263 switch ( m_field->type().type() )
00264 {
00265 case TYPE_INTEGER:
00266 sin >> ui64;
00267 return pack_uint64(ui64);
00268
00269 case TYPE_FLOATING:
00270 length = m_field->length(BITS);
00271 if ( ! (length == 64 || length == 32 ) )
00272 throw exception::type::floating_point_length();
00273 if (length == 64)
00274 {
00275 sin >> d;
00276 return pack_double(d);
00277 }
00278 else
00279 {
00280 sin >> f;
00281 return pack_float(f);
00282 }
00283 default:
00284 return false;
00285 }
00286
00287 return false;
00288 }
00289
00290 template <typename T>
00291 inline
00292 FieldBuffer& FieldBuffer::operator=(const T& t)
00293 {
00294 pack(t);
00295 return *this;
00296 }
00297
00298
00299 }
00300
00301 #endif