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 FieldBuffer operator[](size_t index) throw (error::invalid_index);
00049
00050 FieldBuffer operator[](std::string index) throw (error::invalid_index);
00051
00052 template <typename T>
00053 operator T();
00054
00058 Data data();
00059
00060 bool unpack(void* mem, size_t mem_octets);
00061
00062 template <typename T>
00063 bool unpack(T& val);
00064
00065 bool pack(const void* mem, size_t mem_octets);
00066 bool pack(const void* mem, size_t mem_octets, size_t n);
00067
00068 template <typename T>
00069 bool pack(const T& val);
00070 template <typename T>
00071 FieldBuffer& operator=(const T& t);
00072
00073 FieldBase::pointer field();
00074 RecordBuffer& buffer();
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 protected:
00085 RecordBuffer& m_buffer;
00086 FieldBase::pointer m_field;
00087
00092 bool unpack_uint64(uint64_t& ui64 );
00093
00094 bool unpack_float(float& f);
00095 bool unpack_double(double& d);
00096
00101 bool pack_uint64(uint64_t data);
00102 bool pack_float(float f);
00103 bool pack_double(double d);
00104
00105 };
00106
00107 template <typename T>
00108 inline
00109 FieldBuffer::operator T()
00110 {
00111 T t;
00112 unpack(t);
00113 return t;
00114 }
00115
00116 template <typename T>
00117 inline
00118 bool FieldBuffer::unpack(T& val)
00119 {
00120 bool b;
00121 float f;
00122 double d;
00123 uint64_t ui64;
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 size_t length = m_field->length(BITS);
00135 if ( ! (length == 64 || length == 32 ) )
00136 throw error::type::floating_point_length();
00137 if (length == 64)
00138 {
00139 b = unpack_double(d);
00140 val = static_cast<T>(d);
00141 return b;
00142 }
00143 else
00144 {
00145 b = unpack_float(f);
00146 val = static_cast<T>(f);
00147 return b;
00148 }
00149 }
00150 return unpack(&val, sizeof(T));
00151 }
00152
00153
00154
00155 template <>
00156 inline
00157 bool FieldBuffer::unpack(std::string& val)
00158 {
00159 double d;
00160 float f;
00161 uint64_t ui64;
00162 size_t length;
00163 std::ostringstream sout;
00164
00165
00166 switch ( m_field->type().type() )
00167 {
00168 case TYPE_INTEGER:
00169 if ( unpack_uint64(ui64) )
00170 {
00171 sout << ui64;
00172 val = sout.str();
00173 return true;
00174 }
00175 else
00176 return false;
00177
00178 case TYPE_FLOATING:
00179 length = m_field->length(BITS);
00180 if ( ! (length == 64 || length == 32 ) )
00181 throw error::type::floating_point_length();
00182 if (length == 64)
00183 {
00184 if ( unpack_double(d) )
00185 {
00186 sout << d;
00187 val = sout.str();
00188 return true;
00189 }
00190 else
00191 return false;
00192 }
00193 else
00194 {
00195 if ( unpack_float(f) )
00196 {
00197 sout << f;
00198 val = sout.str();
00199 return true;
00200 }
00201 else
00202 return false;
00203 }
00204 default:
00205 return false;
00206 }
00207 return false;
00208 }
00209
00210 template <typename T>
00211 inline
00212 bool FieldBuffer::pack(const T& val)
00213 {
00214 uint64_t ui64;
00215 double d;
00216 float f;
00217
00218 switch ( m_field->type().type() )
00219 {
00220 case TYPE_INTEGER:
00221 ui64 = val;
00222 return pack_uint64(ui64);
00223
00224 case TYPE_FLOATING:
00225 size_t length = m_field->length(BITS);
00226 if ( ! (length == 64 || length == 32 ) )
00227 throw error::type::floating_point_length();
00228 if (length == 64)
00229 {
00230 d = static_cast<double>(val);
00231 return pack_double(d);
00232 }
00233 else
00234 {
00235 f = static_cast<float>(val);
00236 return pack_float(f);
00237 }
00238 }
00239
00240 return pack(&val, sizeof(T));
00241 }
00242
00243 template <>
00244 inline
00245 bool FieldBuffer::pack(const std::string& val)
00246 {
00247 uint64_t ui64;
00248 double d;
00249 float f;
00250 size_t length;
00251 std::istringstream sin(val);
00252
00253 switch ( m_field->type().type() )
00254 {
00255 case TYPE_INTEGER:
00256 sin >> ui64;
00257 return pack_uint64(ui64);
00258
00259 case TYPE_FLOATING:
00260 length = m_field->length(BITS);
00261 if ( ! (length == 64 || length == 32 ) )
00262 throw error::type::floating_point_length();
00263 if (length == 64)
00264 {
00265 sin >> d;
00266 return pack_double(d);
00267 }
00268 else
00269 {
00270 sin >> f;
00271 return pack_float(f);
00272 }
00273 default:
00274 return false;
00275 }
00276
00277 return false;
00278 }
00279
00280 template <typename T>
00281 inline
00282 FieldBuffer& FieldBuffer::operator=(const T& t)
00283 {
00284 pack(t);
00285 return *this;
00286 }
00287
00288
00289 }
00290
00291 #endif