# HLAfixedArray.hh

Go to the documentation of this file.

    00001 // ----------------------------------------------------------------------------
    00002 // HLAfixedArray.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: HLAfixedArray.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
    00015 // ----------------------------------------------------------------------------
    00016
    00017 #ifndef _HLATYPES_FIXEDARRAY_HH
    00018 #define _HLATYPES_FIXEDARRAY_HH
    00019
    00020 #include <stdexcept>
    00021
    00022 namespace libhla {
    00023
    00024 /* HLAfixedArray<DATATYPE, NUMBER>
    00025  * defines a fixed array of NUMBER elements of type DATATYPE.
    00026  *
    00027  * The data can be accessed in an usual way.
    00028  *
    00029  * For example:
    00030  * +-------------+----------------+-------------+-----------------+-----------+
    00031  * | Name        | Element type   | Cardinality | Encoding        | Semantics |
    00032  * +-------------+----------------+-------------+-----------------+-----------+
    00033  * | Coordinates | HLAinteger32BE | 3           | HLAfixedArray   |           |
    00034  * +-------------+----------------+-------------+-----------------+-----------+
    00035  *
    00036  * typedef HLAfixedArray<HLAinteger32BE,3> Coordinates;
    00037  * HLAdata<Coordinates> value;
    00038  *
    00039  * (*value)[0] = 100;
    00040  * (*value)[1] = 200;
    00041  */
    00042
    00044 template<class M, int N, bool hasVariable = M::m_isVariable>
    00045 struct HLAfixedArray;
    00046
    00047 template<class M, int N, bool hasVariable>
    00048 std::ostream& PrintBuffer(std::ostream& stream, HLAfixedArray<M,N,hasVariable>& buffer)
    00049 { return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
    00050
    00051 // Fixed array optimized for fixed-size elements
    00052 // note: this is the most efficient data type
    00053 template<class M, int N>
    00054 struct HLAfixedArray<M, N, false>
    00055 {
    00056     static const size_t size()
    00057     { return N; }
    00058
    00059     static const size_t offset(long i)
    00060     { return i*(M::__sizeof() + __padding(M::__sizeof(), M::m_octetBoundary)); }
    00061
    00062     M& operator[](long i) const
    00063     {
    00064         if (i < 0 || i >= (long)size())
    00065             throw std::out_of_range("HLAfixedArray: index out of range");
    00066         return *(M*)((char*)this + offset(i));
    00067     }
    00068
    00069     static const size_t emptysizeof()
    00070     { return __sizeof(); }
    00071
    00072     // Padding shall not be added after the last element of the array.
    00073     static const size_t __sizeof()
    00074     { return offset(N-1) + M::__sizeof(); }
    00075
    00076     void copy(void* source)
    00077     {
    00078         size_t offs = 0;
    00079         // copy all elements of the structure
    00080         for (size_t i = 0; i < N; i++) {
    00081             ((M*)((char*)this + offs))->copy((char*)source + offs);
    00082             offs += M::__sizeof() + __padding(M::__sizeof(), M::m_octetBoundary);
    00083         }
    00084     }
    00085
    00086     static const size_t m_octetBoundary = M::m_octetBoundary;
    00087     static const bool m_isVariable = false; // fixed-size array of fixed-size elements
    00088 };
    00089
    00090 // Generic fixed array, supports variable-size elements
    00091 template<class M, int N>
    00092 struct HLAfixedArray<M, N, true>
    00093 {
    00094     static const size_t size()
    00095     { return N; }
    00096
    00097     const size_t offset(long i) const
    00098     {
    00099         size_t offs = 0;
    00100         // count every member, the elements may be variable-sized
    00101         for (long j=0; j<i; j++) {
    00102             offs += ((M*)((char*)this + offs))->__sizeof();
    00103             offs += __padding(offs, M::m_octetBoundary);
    00104         }
    00105         return offs;
    00106     }
    00107
    00108     M& operator[](long i) const
    00109     {
    00110         if (i >= size())
    00111             throw std::out_of_range("HLAfixedArray: index out of range");
    00112         return *(M*)((char*)this + offset(i));
    00113     }
    00114
    00115     static const size_t emptysizeof()
    00116     {
    00117         size_t size = N*M::emptysizeof();
    00118         // padding shall not be added after the last element of the array
    00119         if(N > 1)
    00120             size += (N-1)*__padding(M::emptysizeof(), M::m_octetBoundary);
    00121         return size;
    00122     }
    00123
    00124     const size_t __sizeof() const
    00125     {
    00126         size_t offs = offset(N-1);
    00127         return offs + ((M*)((char*)this + offs))->__sizeof();
    00128     }
    00129
    00130     void copy(void* source)
    00131     {
    00132         size_t offsD = 0;
    00133         size_t offsS = 0;
    00134         // copy all elements of the structure, the elements may be variable-sized
    00135         for (size_t i = 0; i < N; i++) {
    00136             ((M*)((char*)this + offsD))->copy((char*)source + offsS);
    00137
    00138             offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ from source size
    00139             offsD += __padding(offsD, M::m_octetBoundary);
    00140             offsS += ((M*)((char*)source + offsS))->__sizeof();
    00141             offsS += __padding(offsS, M::m_octetBoundary);
    00142         }
    00143     }
    00144
    00145     static const size_t m_octetBoundary = M::m_octetBoundary;
    00146     static const bool m_isVariable = true; // variable-sized elements
    00147 };
    00148
    00149 } // namespace libhla
    00150
    00151 #endif // _HLATYPES_FIXEDARRAY_HH
    00152
    00153 // $Id: HLAfixedArray.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
    00154