debian/libbit-dev/usr/include/bit-0.3/bit/fieldbuffer.h

00001 /***************************************************************************
00002 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
00003 *   rvinyard@cs.nmsu.edu                                                  *
00004 *                                                                         *
00005 *   This program is free software; you can redistribute it and/or modify  *
00006 *   it under the terms of the GNU Lesser General Public License as        *
00007 *   published by the Free Software Foundation version 2.1.                *
00008 *                                                                         *
00009 *   This program is distributed in the hope that it will be useful,       *
00010 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012 *   GNU General Public License for more details.                          *
00013 *                                                                         *
00014 *   You should have received a copy of the GNU Lesser General Public      *
00015 *   License along with this library; if not, write to the                 *
00016 *   Free Software Foundation, Inc.,                                       *
00017 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
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::pointer 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     // TODO finish this section for all allowed types
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   // TODO finish this section for string conversions
00158   // probably need to check that length%8 == 0 or throw
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     // TODO finish this section for all allowed types
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

Generated on Tue Mar 13 20:00:01 2007 by  doxygen 1.5.1