HLAfixedRecord.hh

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 // HLAfixedRecord.hh - IEEE 1516.2 compliant datatypes
00003 // Copyright (C) 2008  Petr Gotthard <petr.gotthard@centrum.cz>
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License version 2.1, as published by the Free Software Foundation.
00008 //
00009 // This library 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 GNU
00012 // Lesser General Public License for more details.
00013 //
00014 // $Id: HLAfixedRecord.hh,v 1.2 2008/10/11 09:35:51 gotthardp Exp $
00015 // ----------------------------------------------------------------------------
00016 
00017 #ifndef _HLATYPES_FIXEDRECORD_HH
00018 #define _HLATYPES_FIXEDRECORD_HH
00019 
00020 #include <HLAbuffer.hh>
00021 
00022 namespace libhla {
00023 
00024 /* HLAfixedRecord<
00025  *   HLAfixedField<INDEX1, DATATYPE1,
00026  *   HLAfixedField<INDEX2, DATATYPE2,
00027  *   ...
00028  *   > ... > TYPENAME;
00029  * defines an ordered sequence of DATATYPE entries.
00030  *
00031  * The data can be accessed using the field<INDEX>() function. The INDEX is a logical
00032  * identifier only. The data are stored in the declaration order.
00033  *
00034  * For example:
00035  * +-------------+------------------------------------+----------------+-----------+
00036  * |             | Field                              |                |           |
00037  * | Record name +---------+--------------+-----------+ Encoding       | Semantics |
00038  * |             | Name    | Type         | Semantics |                |           |
00039  * +-------------+---------+--------------+-----------+----------------+-----------+
00040  * |             | FIELD_X | HLAfloat32LE |           |                |           |
00041  * |             +---------+--------------+-----------+                |           |
00042  * | Coordinates | FIELD_Y | HLAfloat32LE |           | HLAfixedRecord |           |
00043  * |             +---------+--------------+-----------+                |           |
00044  * |             | FIELD_Z | HLAfloat32LE |           |                |           |
00045  * +-------------+---------+--------------+-----------+----------------+-----------+
00046  * 
00047  * enum {
00048  *   FIELD_X = 0,
00049  *   FIELD_Y,
00050  *   FIELD_Z
00051  * };
00052  * typedef HLAfixedRecord<
00053  *   HLAfixedField<FIELD_X, HLAfloat32LE,
00054  *   HLAfixedField<FIELD_Y, HLAfloat32LE,
00055  *   HLAfixedField<FIELD_Z, HLAfloat32LE
00056  *   > > > > Coordinates;
00057  * HLAdata<Coordinates> value;
00058  *
00059  * value->field<FIELD_X>() = 3.14;
00060  * value->field<FIELD_Y>() = 6.28;
00061  * value->field<FIELD_Z>() = 9.42;
00062  */
00063 
00065 template<class R, bool hasVariable = R::m_isVariable>
00066 struct HLAfixedRecord;
00067 
00068 template<class R, bool V>
00069 std::ostream& PrintBuffer(std::ostream& stream, HLAfixedRecord<R,V>& buffer)
00070 { return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
00071 
00073 template<class R, int i> struct __FieldAt;
00074 
00075 // Fixed record optimized for fixed-size fields
00076 template<class R>
00077 struct HLAfixedRecord<R, false>
00078 {
00079     template <int i>
00080     typename __FieldAt<R,i>::Type& field() const
00081     { return *(typename __FieldAt<R,i>::Type*)((char*)this + R::field_offsetof(i)); }
00082 
00083     static const size_t emptysizeof()
00084     { return R::emptysizeof(); }
00085 
00086     static const size_t __sizeof()
00087     { return R::__sizeof(); }
00088 
00089     void copy(void* source)
00090     { ((R*)this)->copy(source); }
00091 
00092     static const size_t m_octetBoundary = R::m_octetBoundary;
00093     static const bool m_isVariable = false; // fixed-sized fields
00094 };
00095 
00096 // Generic fixed record, supports variable-size fields
00097 template<class R>
00098 struct HLAfixedRecord<R, true>
00099 {
00100     template <int i>
00101     typename __FieldAt<R,i>::Type& field() const
00102     { return *(typename __FieldAt<R,i>::Type*)((char*)this + ((R*)this)->field_offsetof(i)); }
00103 
00104     static const size_t emptysizeof()
00105     { return R::emptysizeof(); }
00106 
00107     const size_t __sizeof()
00108     { return ((R*)this)->__sizeof(); }
00109 
00110     void copy(void* source)
00111     { ((R*)this)->copy(source); }
00112 
00113     static const size_t m_octetBoundary = R::m_octetBoundary;
00114     static const bool m_isVariable = true; // variable-sized fields
00115 };
00116 
00117 struct HLAfixedEnd;
00118 
00120 // note: <E> must be "int" to enable implicit conversion from/to enum types
00121 template<int E, class M, class N = HLAfixedEnd, bool hasVariable = M::m_isVariable || N::m_isVariable>
00122 struct HLAfixedField;
00123 
00124 // List of fixed-size fields
00125 template<int E, class M, class N>
00126 struct HLAfixedField<E, M, N, false>
00127 {
00128     static const size_t field_offsetof(int d, size_t offs = 0)
00129     {
00130         if (d != E) {
00131             size_t size = M::__sizeof();
00132             size += __padding(offs+size, N::memberBoundary);
00133             return N::field_offsetof(d, offs+size);
00134         }
00135         else
00136             return offs;
00137     }
00138 
00139     static const size_t memberBoundary = M::m_octetBoundary;
00140 
00141     static const size_t emptysizeof(size_t offs = 0)
00142     { return __sizeof(offs); }
00143 
00144     // Padding shall not be added after the last element of the array.
00145     static const size_t __sizeof(size_t offs = 0)
00146     {
00147         size_t size = M::__sizeof();
00148         // if not reached HLAvariantEnd
00149         if (N::memberBoundary) {
00150             size += __padding(offs+size, N::memberBoundary);
00151             return N::__sizeof(offs+size);
00152         }
00153         else
00154             return offs+size;
00155     }
00156 
00157     void copy(void* source, size_t offsD = 0, size_t offsS = 0)
00158     {
00159         ((M*)this)->copy(source);
00160         if (N::memberBoundary) {
00161             offsD += M::__sizeof();
00162             offsD += __padding(offsD, N::memberBoundary);
00163             offsS += M::__sizeof();
00164             offsS += __padding(offsS, N::memberBoundary);
00165             ((N*)((char*)this + M::__sizeof()))->copy((char*)source + M::__sizeof(), offsD, offsS);
00166         }
00167     }
00168 
00169     static const size_t m_octetBoundary = MAX(M::m_octetBoundary, N::m_octetBoundary);
00170     static const bool m_isVariable = false; // fixed-sized fields
00171 };
00172 
00173 // List containg variable-size fields
00174 template<int E, class M, class N>
00175 struct HLAfixedField<E, M, N, true>
00176 {
00177     const size_t field_offsetof(int d, size_t offs = 0) const
00178     {
00179         if (d != E) {
00180             size_t size = ((M*)this)->__sizeof();
00181             size += __padding(offs+size, N::memberBoundary);
00182             return ((N*)((char*)this + size))->field_offsetof(d, offs+size);
00183         }
00184         else
00185             return offs;
00186     }
00187 
00188     static const size_t memberBoundary = M::m_octetBoundary;
00189 
00190     static const size_t emptysizeof(size_t offs = 0)
00191     {
00192         size_t size = M::emptysizeof();
00193         // if not reached HLAvariantEnd
00194         if (N::memberBoundary) {
00195             size += __padding(offs+size, N::memberBoundary);
00196             return N::emptysizeof(offs+size);
00197         }
00198         else
00199             return offs+size;
00200     }
00201 
00202     // Padding shall not be added after the last element of the array.
00203     const size_t __sizeof(size_t offs = 0) const
00204     {
00205       size_t size = ((M*)this)->__sizeof();
00206       // if not reached HLAvariantEnd
00207       if (N::memberBoundary) {
00208           size += __padding(offs+size, N::memberBoundary);
00209           return ((N*)((char*)this + size))->__sizeof(offs+size);
00210       }
00211       else
00212           return offs+size;
00213     }
00214 
00215     void copy(void* source, size_t offsD = 0, size_t offsS = 0)
00216     {
00217         ((M*)this)->copy(source);
00218         if (N::memberBoundary) {
00219             size_t sizeD = ((M*)this)->__sizeof(); // may differ from source size
00220             sizeD += __padding(offsD+sizeD, N::memberBoundary);
00221             size_t sizeS = ((M*)source)->__sizeof();
00222             sizeS += __padding(offsS+sizeS, N::memberBoundary);
00223             ((N*)((char*)this + sizeD))->copy((char*)source + sizeS, offsD+sizeD, offsS+sizeS);
00224         }
00225     }
00226 
00227     static const size_t m_octetBoundary = MAX(M::m_octetBoundary, N::m_octetBoundary);
00228     static const bool m_isVariable = true; // variable-sized fields
00229 };
00230 
00232 struct HLAfixedEnd
00233 {
00234     static const size_t field_offsetof(int d, size_t offs = 0)
00235     { return offs; }
00236 
00237     static const size_t memberBoundary = 0;
00238     static const size_t emptysizeof(size_t offs = 0)
00239     { return offs; }
00240     static const size_t __sizeof(size_t offs = 0)
00241     { return offs; }
00242     void copy(void* source, size_t offsD = 0, size_t offsS = 0)
00243     { /* nop */ }
00244 
00245     static const size_t m_octetBoundary = 0;
00246     static const bool m_isVariable = false;
00247 };
00248 
00249 template<bool C, class Then, class Else>
00250 struct __fixedRecord_if
00251 { typedef Then X; };
00252 
00253 template<class Then, class Else>
00254 struct __fixedRecord_if<false, Then, Else>
00255 { typedef Else X; };
00256 
00257 template<int E, class M, class N, bool V, int d>
00258 struct __FieldAt<HLAfixedField<E, M, N, V>, d>
00259 { typedef typename __fixedRecord_if<d==E, M, typename __FieldAt<N,d>::Type>::X Type; };
00260 
00261 // returned when no HLAfixedField has a given index(i)
00262 template<int d>
00263 struct __FieldAt<HLAfixedEnd, d>
00264 { typedef HLAfixedEnd Type; };
00265 
00266 } // namespace libhla
00267 
00268 #endif // _HLATYPES_FIXEDRECORD_HH
00269 
00270 // $Id: HLAfixedRecord.hh,v 1.2 2008/10/11 09:35:51 gotthardp Exp $
00271 

Generated on Thu Apr 30 15:53:49 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5