certi-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[certi-cvs] certi/libHLA HLAtypesIEEE1516.hh hlaomtdif2cpp.py


From: certi-cvs
Subject: [certi-cvs] certi/libHLA HLAtypesIEEE1516.hh hlaomtdif2cpp.py
Date: Sat, 02 Aug 2008 11:44:12 +0000

CVSROOT:        /sources/certi
Module name:    certi
Changes by:     Petr Gotthard <gotthardp>       08/08/02 11:44:12

Modified files:
        libHLA         : HLAtypesIEEE1516.hh hlaomtdif2cpp.py 

Log message:
        New feature: Support for HLAvariantRecord.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAtypesIEEE1516.hh?cvsroot=certi&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/hlaomtdif2cpp.py?cvsroot=certi&r1=1.1&r2=1.2

Patches:
Index: HLAtypesIEEE1516.hh
===================================================================
RCS file: /sources/certi/certi/libHLA/HLAtypesIEEE1516.hh,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- HLAtypesIEEE1516.hh 17 Jul 2008 16:03:53 -0000      1.2
+++ HLAtypesIEEE1516.hh 2 Aug 2008 11:44:12 -0000       1.3
@@ -11,12 +11,16 @@
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// $Id: HLAtypesIEEE1516.hh,v 1.2 2008/07/17 16:03:53 gotthardp Exp $
+// $Id: HLAtypesIEEE1516.hh,v 1.3 2008/08/02 11:44:12 gotthardp Exp $
 // ----------------------------------------------------------------------------
 
 #ifndef _HLATYPES_IEEE1516_HH
 #define _HLATYPES_IEEE1516_HH
 
+#if defined(_WIN32)
+#pragma warning(disable:4503) // suppress warning C4503: decorated name length 
exceeded
+#endif
+
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
@@ -71,19 +75,22 @@
     size_t mCapacity;
     // no automatic free() and realloc() for user allocated memory
     bool mUserAllocated;
+    // parameters used during dynamic resizing
+    const void* mShakeThat;
+    int mShakeValue;
 
     __HLAbuffer(size_t capacity)
-     : mUserAllocated(false)
+     : mUserAllocated(false), mShakeThat(NULL)
     {
         // exponential growth: capacity *= 1.5
         mCapacity = (size_t)(capacity*1.5);
-        mBegin = (char*)malloc(mCapacity);
+        mBegin = (char*)calloc(1, mCapacity);
         // store "this" to a global table
         gBuffers[mBegin + mCapacity] = this;
     }
 
     __HLAbuffer(void *begin, size_t capacity)
-      : mBegin((char*)begin), mCapacity(capacity), mUserAllocated(true)
+      : mBegin((char*)begin), mCapacity(capacity), mUserAllocated(true), 
mShakeThat(NULL)
     {
         // store "this" to a global table
         gBuffers[mBegin + mCapacity] = this;
@@ -97,6 +104,20 @@
         gBuffers.erase(__buffer_iterator(mBegin));
     }
 
+    void __exchange_buffers(__HLAbuffer& newBuffer)
+    {
+        char* oldBegin = mBegin;
+        size_t oldCapacity = mCapacity;
+
+        mBegin = newBuffer.mBegin;
+        mCapacity = newBuffer.mCapacity;
+        gBuffers[mBegin + mCapacity] = this; // update
+
+        newBuffer.mBegin = oldBegin;
+        newBuffer.mCapacity = oldCapacity;
+        gBuffers[oldBegin + oldCapacity] = &newBuffer; // update
+    }
+
     static BufferList::iterator __buffer_iterator(const void* __this)
     {
         // find the first pointer not less than "this", what is the end() 
pointer
@@ -109,52 +130,31 @@
     static __HLAbuffer& __buffer(const void* __this)
     { return *(__buffer_iterator(__this)->second); }
 
-    //! Resize the data buffer, shifts the data at [offset, __sizeof()] by 
"shift"
-    void resize_buffer(size_t offset, long shift)
-    {
-        size_t buffer_size = size();
-
-        if (shift > 0) {
-            // check buffer overflow
-            if (buffer_size+shift > mCapacity) {
-                if (!mUserAllocated) {
-                    // remove old "this" from the global table
-                    gBuffers.erase(__buffer_iterator(mBegin));
-                    // exponential growth: capacity *= 1.5
-                    mCapacity = (size_t)((buffer_size+shift)*1.5);
-                    mBegin = (char*)realloc(mBegin, mCapacity);
-                    // store new "this" to a global table
-                    gBuffers[mBegin + mCapacity] = this;
-                }
-                else
-                    throw std::length_error("HLAdata: data buffer overflow");
-            }
-
-            char* ptr = (char*)mBegin + offset;
-            memmove(ptr+shift, ptr, mBegin+buffer_size-ptr);
-            // clean the buffer for new members
-            memset(ptr, '\0', shift);
-        }
-        else if (shift < 0) {
-            char* ptr = (char*)mBegin + offset;
-            memmove(ptr+shift, ptr, mBegin+buffer_size-ptr);
-        }
-    }
-
+#ifndef NDEBUG
     static void __check_memory(const void* __this, size_t size)
     {
         const __HLAbuffer& buffer = __buffer(__this);
         if ((char*)__this + size > (char*)buffer.mBegin + buffer.mCapacity)
             throw std::length_error("HLAdata: data buffer overflow");
     }
+#endif
 
     virtual const size_t size() const = 0;
+    virtual void __shake(const void* __that, int value, long resize) = 0;
+
+    static void shake(const void* __that, int value, long resize)
+    { __buffer(__that).__shake(__that, value, resize); }
 
     const char* data() const
     { return mBegin; }
 
     std::ostream& print(std::ostream& stream)
-    { return __print_buffer(stream, mBegin, size()); }
+    {
+#ifndef NDEBUG
+        __check_memory(mBegin, size());
+#endif
+        return __print_buffer(stream, mBegin, size());
+    }
 };
 
 template<class T>
@@ -162,13 +162,9 @@
 {
 public:
   //! Create new buffer
-  HLAdata()
-   : __HLAbuffer(T::empty_sizeof())
-  {
-      // clean the member data structures
-      // unused bytes are not cleaned, mCapacity > T::empty_sizeof()
-      memset(mBegin, '\0', T::empty_sizeof());
-  }
+    HLAdata(size_t capacity = T::emptysizeof())
+      : __HLAbuffer(capacity)
+    { }
 
   //! Create buffer from existing data
   HLAdata(void *begin, size_t capacity)
@@ -187,6 +183,33 @@
 
   virtual const size_t size() const
   { return ((T*)mBegin)->__sizeof(); }
+
+    //! Shake the buffer
+    /* Resizing the variable-size elements may have significant impact on 
padding
+     * of other elements. This function changes a <value> of <__that> element
+     * and updates the padding through the whole buffer.
+     */
+    virtual void __shake(const void* __that, int value, long resize)
+    {
+        HLAdata<T> newData(size()+resize);
+
+        // copy the data to the temporary buffer, while changing a <value> of 
<__that>
+        newData.mShakeThat = __that;
+        newData.mShakeValue = value;
+        // create copy of the data
+        ((T*)newData.mBegin)->copy(mBegin);
+
+        if (mUserAllocated)
+        {
+            if (newData.size() < mCapacity)
+                // copy data back to the original buffer
+                memcpy(mBegin, newData.mBegin, newData.size());
+            else
+                throw std::length_error("HLAdata: data buffer overflow");
+        }
+        else
+            __exchange_buffers(newData);
+    }
 };
 
 //! Swap <i> bytes of the <T> type
@@ -235,9 +258,13 @@
 struct __swap<T,2>
 {
     inline const T operator()(const T& x) const {
-        uint16_t result =
+        union {
+            uint16_t u16;
+            T x;
+        } result;
+        result.u16 =
             (*(uint16_t*)&x<<8 | *(uint16_t*)&x>>8);
-        return *(T*)&result;
+        return result.x;
     }
 };
 
@@ -245,11 +272,15 @@
 struct __swap<T,4>
 {
     inline const T operator()(const T& x) const {
-        uint32_t result =
+        union {
+            uint32_t u32;
+            T x;
+        } result;
+        result.u32 =
             (*(uint32_t*)&x<<24 | *(uint32_t*)&x>>24 |
             (*(uint32_t*)&x & 0x0000ff00UL)<<8 |
             (*(uint32_t*)&x & 0x00ff0000UL)>>8);
-        return *(T*)&result;
+        return result.x;
     }
 };
 
@@ -257,7 +288,11 @@
 struct __swap<T,8>
 {
     inline const T operator()(const T& x) const {
-        uint64_t result =
+        union {
+            uint64_t u64;
+            T x;
+        } result;
+        result.u64 =
             (*(uint64_t*)&x<<56 | *(uint64_t*)&x>>56 |
             (*(uint64_t*)&x & 0x000000000000ff00ULL)<<40 |
             (*(uint64_t*)&x & 0x0000000000ff0000ULL)<<24 |
@@ -265,7 +300,7 @@
             (*(uint64_t*)&x & 0x000000ff00000000ULL)>> 8 |
             (*(uint64_t*)&x & 0x0000ff0000000000ULL)>>24 |
             (*(uint64_t*)&x & 0x00ff000000000000ULL)>>40);
-        return *(T*)&result;
+        return result.x;
     }
 };
 
@@ -291,23 +326,35 @@
 {
     HLAbasicType& operator = (const T& data)
     {
+#ifndef NDEBUG
         __HLAbuffer::__check_memory(this, __sizeof());
+#endif
         *(S*)this = E<S>()(data);
         return *this;
     }
 
     operator T() const
     {
+#ifndef NDEBUG
         __HLAbuffer::__check_memory(this, __sizeof());
+#endif
         return E<S>()(*(S*)this);
     }
 
-    static const size_t empty_sizeof()
+    static const size_t emptysizeof()
     { return __sizeof(); }
 
     static const size_t __sizeof()
     { return sizeof(S); }
 
+    void copy(void* source)
+    {
+#ifndef NDEBUG
+        __HLAbuffer::__check_memory(this, __sizeof());
+#endif
+        memcpy((char*)this, source, __sizeof());
+    }
+
     static const size_t m_octetBoundary = sizeof(S);
     static const bool m_isVariable = false;
 };
@@ -339,6 +386,7 @@
  */
 typedef HLAbasicType<unsigned short, uint16_t, BigEndian> Unsignedinteger16BE;
 typedef HLAbasicType<unsigned long, uint32_t, BigEndian> Unsignedinteger32BE;
+typedef HLAbasicType<unsigned long, uint64_t, BigEndian> Unsignedinteger64BE;
 
 //! HLA enumerated type, enumeration <E> with representation <R>.
 /*!
@@ -347,13 +395,25 @@
  *
  * The data can be accessed in an usual way.
  *
+ * Some models may use one enumerated value in multiple enumerations. To avoid
+ * name collisions it's recommended to put the ENUMERATION in an individual 
namespace.
+ *
  * For example:
- * enum __HLAboolean
- * {
+ * +------------+----------------+------------+--------+-----------+
+ * | Name       | Representation | Enumerator | Values | Semantics |
+ * +------------+----------------+------------+--------+-----------+
+ * |            |                | HLAfalse   | 0      |           |
+ * | HLAboolean | HLAinteger32BE +------------+--------+-----------+
+ * |            |                | HLAfalse   | 1      |           |
+ * +------------+----------------+------------+--------+-----------+
+ * 
+ * namespace __HLAboolean {
+ * enum __enum {
  *   HLAfalse = 0,
  *   HLAtrue = 1
  * };
- * typedef HLAenumeratedType<__HLAboolean, HLAinteger32BE> HLAboolean;
+ * }
+ * typedef HLAenumeratedType<__HLAboolean::__enum, HLAinteger32BE> HLAboolean;
  * HLAdata<HLAboolean> value;
  *
  * value = HLAtrue;
@@ -367,15 +427,30 @@
         return *this;
     }
 
+    HLAenumeratedType& operator = (const int& data)
+    {
+        *(R*)this = data;
+        return *this;
+    }
+
     operator E() const
+    {
+        int result = *(R*)this;
+        return (E)result;
+    }
+
+    operator int() const
     { return *(R*)this; }
 
-    static const size_t empty_sizeof()
-    { return R::empty_sizeof(); }
+    static const size_t emptysizeof()
+    { return R::emptysizeof(); }
 
     static const size_t __sizeof()
     { return R::__sizeof(); }
 
+    void copy(void* source)
+    { ((R*)this)->copy(source); }
+
     static const size_t m_octetBoundary = R::m_octetBoundary;
     static const bool m_isVariable = false;
 };
@@ -398,6 +473,12 @@
  * The data can be accessed in an usual way.
  *
  * For example:
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | Name        | Element type   | Cardinality | Encoding        | Semantics |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | Coordinates | HLAinteger32BE | 3           | HLAfixedArray   |           |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ *
  * typedef HLAfixedArray<HLAinteger32BE,3> Coordinates;
  * HLAdata<Coordinates> value;
  *
@@ -429,13 +510,23 @@
         return *(M*)((char*)this + offset(i));
     }
 
-    static const size_t empty_sizeof()
+    static const size_t emptysizeof()
     { return __sizeof(); }
 
     // Padding shall not be added after the last element of the array.
     static const size_t __sizeof()
     { return offset(N-1) + M::__sizeof(); }
 
+    void copy(void* source)
+    {
+        size_t offs = 0;
+        // copy all elements of the structure
+        for (size_t i = 0; i < N; i++) {
+            ((M*)((char*)this + offs))->copy((char*)source + offs);
+            offs += M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary);
+        }
+    }
+
     static const size_t m_octetBoundary = M::m_octetBoundary;
     static const bool m_isVariable = false; // fixed-size array of fixed-size 
elements
 };
@@ -465,16 +556,36 @@
         return *(M*)((char*)this + offset(i));
     }
 
-    static const size_t empty_sizeof()
-    { return N*M::empty_sizeof(); }
+    static const size_t emptysizeof()
+    {
+        size_t size = N*M::emptysizeof();
+        // padding shall not be added after the last element of the array
+        if(N > 1)
+            size += (N-1)*__padding(M::emptysizeof(), M::m_octetBoundary);
+        return size;
+    }
 
-    // Padding shall not be added after the last element of the array.
     const size_t __sizeof() const
     {
         size_t offs = offset(N-1);
         return offs + ((M*)((char*)this + offs))->__sizeof();
     }
 
+    void copy(void* source)
+    {
+        size_t offsD = 0;
+        size_t offsS = 0;
+        // copy all elements of the structure, the elements may be 
variable-sized
+        for (size_t i = 0; i < N; i++) {
+            ((M*)((char*)this + offsD))->copy((char*)source + offsS);
+
+            offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ 
from source size
+            offsD += __padding(offsD, M::m_octetBoundary);
+            offsS += ((M*)((char*)source + offsS))->__sizeof();
+            offsS += __padding(offsS, M::m_octetBoundary);
+        }
+    }
+
     static const size_t m_octetBoundary = M::m_octetBoundary;
     static const bool m_isVariable = true; // variable-sized elements
 };
@@ -488,6 +599,12 @@
  * when the size() is changed.
  *
  * For example:
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | Name        | Element type   | Cardinality | Encoding        | Semantics |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | List        | HLAinteger32BE | Dynamic     | HLAvaribleArray |           |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ *
  * typedef HLAvariableArray<HLAinteger32BE> List;
  * HLAdata<List> value;
  *
@@ -513,30 +630,19 @@
     HLAinteger32BE& size() const
     { return (HLAinteger32BE&)*this; }
 
-    //! Set array size, with memory management (identical for both 
HLAvariableArray)
+    //! Set array size, with memory management
     void set_size(long i)
     {
-        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
-        // the data following this structure that need to be shifted
-        size_t offset = (char*)this - buffer.mBegin;
-        size_t my_sizeof = __sizeof();
-
-        const void* result = this;
-        if (i > size()) { // enlarge
-            buffer.resize_buffer(offset+my_sizeof, (i - 
(long)size())*(long)M::empty_sizeof());
-            result = buffer.mBegin+offset;
-            // resize_buffer may invoke realloc(), so "this" pointer changes
-            *(HLAinteger32BE*)result = i;
-        }
-        else if (i < size()) { // shrink
-            size() = i;
-            buffer.resize_buffer(offset+my_sizeof, 
(long)__sizeof()-(long)my_sizeof);
-            result = buffer.mBegin+offset;
-        }
+        if (i == size())
+            return; // no change
+
+        // as changing the array size may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, i,
+            (i-size())*(long)(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)));
     }
 
     static const size_t offset(long i)
-    { return empty_sizeof() + i*(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)); }
+    { return emptysizeof() + i*(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)); }
 
     M& operator[](long i) const
     {
@@ -545,7 +651,7 @@
         return *(M*)((char*)this + offset(i));
     }
 
-    static const size_t empty_sizeof()
+    static const size_t emptysizeof()
     { return HLAinteger32BE::__sizeof() + 
__padding(HLAinteger32BE::__sizeof(), M::m_octetBoundary); }
 
     // Padding shall not be added after the last element of the array.
@@ -554,7 +660,30 @@
         if (size() > 0)
             return offset(size()-1) + M::__sizeof();
         else
-            return empty_sizeof();
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        int N = *(HLAinteger32BE*)source;
+        int toCopy;
+
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(HLAinteger32BE*)this = buffer.mShakeValue;
+            toCopy = std::min(N, buffer.mShakeValue); // number of elements to 
copy
+        }
+        else {
+            *(HLAinteger32BE*)this = N;
+            toCopy = N; // copy all elements
+        }
+
+        size_t offs = emptysizeof();
+        // copy all elements of the structure, the elements may be 
variable-sized
+        for (int i = 0; i < toCopy; i++) {
+            ((M*)((char*)this + offs))->copy((char*)source + offs);
+            offs += M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary);
+        }
     }
 
     static const size_t m_octetBoundary =
@@ -574,31 +703,20 @@
     HLAinteger32BE& size() const
     { return (HLAinteger32BE&)*this; }
 
-    //! Set array size, with memory management (identical for both 
HLAvariableArray)
+    //! Set array size, with memory management
     void set_size(long i)
     {
-        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
-        // the data following this structure that need to be shifted
-        size_t offset = (char*)this - buffer.mBegin;
-        size_t my_sizeof = __sizeof();
-
-        const void* result = this;
-        if (i > size()) { // enlarge
-            buffer.resize_buffer(offset+my_sizeof, (i - 
(long)size())*(long)M::empty_sizeof());
-            result = buffer.mBegin+offset;
-            // resize_buffer may invoke realloc(), so "this" pointer changes
-            *(HLAinteger32BE*)result = i;
-        }
-        else if (i < size()) { // shrink
-            size() = i;
-            buffer.resize_buffer(offset+my_sizeof, 
(long)__sizeof()-(long)my_sizeof);
-            result = buffer.mBegin+offset;
-        }
+        if (i == size())
+            return; // no change
+
+        // as changing the array size may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, i,
+            (i-size())*(long)(M::emptysizeof() + __padding(M::emptysizeof(), 
M::m_octetBoundary)));
     }
 
     const size_t offset(long i) const
     {
-        size_t offs = empty_sizeof();
+        size_t offs = emptysizeof();
         // count every member, the elements may be variable-sized
         for (long j=0; j<i; j++) {
             offs += ((M*)((char*)this + offs))->__sizeof();
@@ -614,7 +732,7 @@
         return *(M*)((char*)this + offset(i));
     }
 
-    static const size_t empty_sizeof()
+    static const size_t emptysizeof()
     { return HLAinteger32BE::__sizeof() + 
__padding(HLAinteger32BE::__sizeof(), M::m_octetBoundary); }
 
     // Padding shall not be added after the last element of the array.
@@ -625,7 +743,35 @@
             return offs + ((M*)((char*)this + offs))->__sizeof();
         }
         else
-            return empty_sizeof();
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        int N = *(HLAinteger32BE*)source;
+        int toCopy;
+
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(HLAinteger32BE*)this = buffer.mShakeValue;
+            toCopy = std::min(N, buffer.mShakeValue); // number of elements to 
copy
+        }
+        else {
+            *(HLAinteger32BE*)this = N;
+            toCopy = N; // copy all elements
+        }
+
+        size_t offsD = emptysizeof();
+        size_t offsS = emptysizeof();
+        // copy all elements of the structure, the elements may be 
variable-sized
+        for (int i = 0; i < toCopy; i++) {
+            ((M*)((char*)this + offsD))->copy((char*)source + offsS);
+
+            offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ 
from source size
+            offsD += __padding(offsD, M::m_octetBoundary);
+            offsS += ((M*)((char*)source + offsS))->__sizeof();
+            offsS += __padding(offsS, M::m_octetBoundary);
+        }
     }
 
     static const size_t m_octetBoundary =
@@ -633,54 +779,116 @@
     static const bool m_isVariable = true; // variable-size array of 
variable-size elements
 };
 
-//! Fixed record field of type <M>, followed by HLAfixedRecord <N>
+//! Fixed record of fields <R>
 /*!
- * HLAfixedRecord<DATATYPE,
- *   HLAfixedRecord<DATATYPE,
- *   ...,
- *   HLAfixedRecordEnd> ... > TYPENAME;
+ * HLAfixedRecord<
+ *   HLAfixedField<INDEX1, DATATYPE1,
+ *   HLAfixedField<INDEX2, DATATYPE2,
+ *   ...
+ *   > ... > TYPENAME;
  * defines an ordered sequence of DATATYPE entries.
  *
- * The data can be accessed using the field<INDEX>() function, where the INDEX
- * is a zero-based order of the field being accessed.
+ * The data can be accessed using the field<INDEX>() function. The INDEX is a 
logical
+ * identifier only. The data are stored in the declaration order.
  *
  * For example:
+ * 
+-------------+------------------------------------+----------------+-----------+
+ * |             | Field                              |                |       
    |
+ * | Record name +---------+--------------+-----------+ Encoding       | 
Semantics |
+ * |             | Name    | Type         | Semantics |                |       
    |
+ * 
+-------------+---------+--------------+-----------+----------------+-----------+
+ * |             | FIELD_X | HLAfloat32LE |           |                |       
    |
+ * |             +---------+--------------+-----------+                |       
    |
+ * | Coordinates | FIELD_X | HLAfloat32LE |           | HLAfixedRecord |       
    |
+ * |             +---------+--------------+-----------+                |       
    |
+ * |             | FIELD_X | HLAfloat32LE |           |                |       
    |
+ * 
+-------------+---------+--------------+-----------+----------------+-----------+
+ * 
  * enum {
  *   FIELD_X = 0,
  *   FIELD_Y,
  *   FIELD_Z
  * };
- * typedef
- *   HLAfixedRecord<HLAfloat23LE,
- *   HLAfixedRecord<HLAfloat32LE,
- *   HLAfixedRecord<HLAfloat32LE,
- *   HLAfixedRecordEnd> > > Coordinates;
+ * typedef HLAfixedRecord<
+ *   HLAfixedField<FIELD_X, HLAfloat32LE,
+ *   HLAfixedField<FIELD_Y, HLAfloat32LE,
+ *   HLAfixedField<FIELD_Z, HLAfloat32LE
+ *   > > > > Coordinates;
  * HLAdata<Coordinates> value;
  *
  * value->field<FIELD_X>() = 3.14;
  * value->field<FIELD_Y>() = 6.28;
  * value->field<FIELD_Z>() = 9.42;
  */
-template<class M, class N, bool hasVariable = M::m_isVariable || 
N::m_isVariable>
+template<class R, bool hasVariable = R::m_isVariable>
 struct HLAfixedRecord;
 
-template<class M, class N, bool V>
-std::ostream& PrintBuffer(std::ostream& stream, HLAfixedRecord<M,N,V>& buffer)
+template<class R, bool V>
+std::ostream& PrintBuffer(std::ostream& stream, HLAfixedRecord<R,V>& buffer)
 { return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
 
-//! Returns <i>th field of the HLAfixedRecord <L>
-template<class R, unsigned i> struct __FieldAt;
+//! Returns <i>th field of the HLAfixedField <L>
+template<class R, int i> struct __FieldAt;
 
 // Fixed record optimized for fixed-size fields
-template<class M, class N>
-struct HLAfixedRecord<M, N, false>
+template<class R>
+struct HLAfixedRecord<R, false>
+{
+    template <int i>
+    typename __FieldAt<R,i>::Type& field() const
+    { return *(typename __FieldAt<R,i>::Type*)((char*)this + 
R::field_offsetof(i)); }
+
+    static const size_t emptysizeof()
+    { return R::emptysizeof(); }
+
+    static const size_t __sizeof()
+    { return R::__sizeof(); }
+
+    void copy(void* source)
+    { ((R*)this)->copy(source); }
+
+    static const size_t m_octetBoundary = R::m_octetBoundary;
+    static const bool m_isVariable = false; // fixed-sized fields
+};
+
+// Generic fixed record, supports variable-size fields
+template<class R>
+struct HLAfixedRecord<R, true>
 {
-    static const size_t offset(size_t i, size_t offs = 0)
+    template <int i>
+    typename __FieldAt<R,i>::Type& field() const
+    { return *(typename __FieldAt<R,i>::Type*)((char*)this + 
((R*)this)->field_offsetof(i)); }
+
+    static const size_t emptysizeof()
+    { return R::emptysizeof(); }
+
+    const size_t __sizeof()
+    { return ((R*)this)->__sizeof(); }
+
+    void copy(void* source)
+    { ((R*)this)->copy(source); }
+
+    static const size_t m_octetBoundary = R::m_octetBoundary;
+    static const bool m_isVariable = true; // variable-sized fields
+};
+
+struct HLAfixedEnd;
+
+//! Record at index <E>, field of type <M>, followed by HLAfixedField <N>
+// note: <E> must be "int" to enable implicit conversion from/to enum types
+template<int E, class M, class N = HLAfixedEnd, bool hasVariable = 
M::m_isVariable || N::m_isVariable>
+struct HLAfixedField;
+
+// List of fixed-size fields
+template<int E, class M, class N>
+struct HLAfixedField<E, M, N, false>
+{
+    static const size_t field_offsetof(int d, size_t offs = 0)
     {
-        if (i > 0) {
+        if (d != E) {
             size_t size = M::__sizeof();
             size += __padding(offs+size, N::memberBoundary);
-            return N::offset(i-1, offs+size);
+            return N::field_offsetof(d, offs+size);
         }
         else
             return offs;
@@ -688,18 +896,14 @@
 
     static const size_t memberBoundary = M::m_octetBoundary;
 
-    template <unsigned i>
-    typename __FieldAt<HLAfixedRecord<M,N>,i>::Type& field() const
-    { return *(typename __FieldAt<HLAfixedRecord<M,N>,i>::Type*)((char*)this + 
offset(i)); }
-
-    static const size_t empty_sizeof()
-    { return __sizeof(); }
+    static const size_t emptysizeof(size_t offs = 0)
+    { return __sizeof(offs); }
 
     // Padding shall not be added after the last element of the array.
     static const size_t __sizeof(size_t offs = 0)
     {
         size_t size = M::__sizeof();
-        // if not reached HLAfixedRecordEnd
+        // if not reached HLAvariantEnd
         if (N::memberBoundary) {
             size += __padding(offs+size, N::memberBoundary);
             return N::__sizeof(offs+size);
@@ -708,20 +912,32 @@
             return offs+size;
     }
 
+    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
+    {
+        ((M*)this)->copy(source);
+        if (N::memberBoundary) {
+            offsD += M::__sizeof();
+            offsD += __padding(offsD, N::memberBoundary);
+            offsS += M::__sizeof();
+            offsS += __padding(offsS, N::memberBoundary);
+            ((N*)((char*)this + M::__sizeof()))->copy((char*)source + 
M::__sizeof(), offsD, offsS);
+        }
+    }
+
     static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
     static const bool m_isVariable = false; // fixed-sized fields
 };
 
-// Generic fixed record, supports variable-size fields
-template<class M, class N>
-struct HLAfixedRecord<M, N, true>
+// List containg variable-size fields
+template<int E, class M, class N>
+struct HLAfixedField<E, M, N, true>
 {
-    const size_t offset(size_t i, size_t offs = 0) const
+    const size_t field_offsetof(int d, size_t offs = 0) const
     {
-        if (i > 0) {
+        if (d != E) {
             size_t size = ((M*)this)->__sizeof();
             size += __padding(offs+size, N::memberBoundary);
-            return ((N*)((char*)this + size))->offset(i-1, offs+size);
+            return ((N*)((char*)this + size))->field_offsetof(d, offs+size);
         }
         else
             return offs;
@@ -729,17 +945,13 @@
 
     static const size_t memberBoundary = M::m_octetBoundary;
 
-    template <unsigned i>
-    typename __FieldAt<HLAfixedRecord<M,N,true>,i>::Type& field() const
-    { return *(typename 
__FieldAt<HLAfixedRecord<M,N,true>,i>::Type*)((char*)this + offset(i)); }
-
-    static const size_t empty_sizeof(size_t offs = 0)
+    static const size_t emptysizeof(size_t offs = 0)
     {
-        size_t size = M::empty_sizeof();
-        // if not reached HLAfixedRecordEnd
+        size_t size = M::emptysizeof();
+        // if not reached HLAvariantEnd
         if (N::memberBoundary) {
             size += __padding(offs+size, N::memberBoundary);
-            return N::empty_sizeof(offs+size);
+            return N::emptysizeof(offs+size);
         }
         else
             return offs+size;
@@ -749,7 +961,7 @@
     const size_t __sizeof(size_t offs = 0) const
     {
       size_t size = ((M*)this)->__sizeof();
-      // if not reached HLAfixedRecordEnd
+      // if not reached HLAvariantEnd
       if (N::memberBoundary) {
           size += __padding(offs+size, N::memberBoundary);
           return ((N*)((char*)this + size))->__sizeof(offs+size);
@@ -758,37 +970,420 @@
           return offs+size;
     }
 
+    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
+    {
+        ((M*)this)->copy(source);
+        if (N::memberBoundary) {
+            size_t sizeD = ((M*)this)->__sizeof(); // may differ from source 
size
+            sizeD += __padding(offsD+sizeD, N::memberBoundary);
+            size_t sizeS = ((M*)source)->__sizeof();
+            sizeS += __padding(offsS+sizeS, N::memberBoundary);
+            ((N*)((char*)this + sizeD))->copy((char*)source + sizeS, 
offsD+sizeD, offsS+sizeS);
+        }
+    }
+
     static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
     static const bool m_isVariable = true; // variable-sized fields
 };
 
 //! Defines a last field in the fixed record
-struct HLAfixedRecordEnd
+struct HLAfixedEnd
 {
-    static const size_t offset(size_t i, size_t offs = 0)
+    static const size_t field_offsetof(int d, size_t offs = 0)
     { return offs; }
 
     static const size_t memberBoundary = 0;
-    static const size_t empty_sizeof(size_t offs = 0)
+    static const size_t emptysizeof(size_t offs = 0)
     { return offs; }
     static const size_t __sizeof(size_t offs = 0)
     { return offs; }
+    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
+    { /* nop */ }
+
+    static const size_t m_octetBoundary = 0;
+    static const bool m_isVariable = false;
+};
+
+template<bool C, class T, class E>
+struct __if
+{ typedef T X; };
+
+template<class T, class E>
+struct __if<false, T, E>
+{ typedef E X; };
+
+template<int E, class M, class N, bool V, int d>
+struct __FieldAt<HLAfixedField<E, M, N, V>, d>
+{ typedef typename __if<d==E, M, typename __FieldAt<N,d>::Type>::X Type; }; 
+
+// returned when no HLAfixedField has a given index(i)
+template<int d>
+struct __FieldAt<HLAfixedEnd, d>
+{ typedef HLAfixedEnd Type; };
+
+//! Variant record of discriminant <D> at index <E> and alternatives <R>
+/*!
+ * HLAvariantRecord<
+ *   INDEX, DATATYPE,
+ *   HLAvariantField<ENUMERATORS1, INDEX1, DATATYPE1,
+ *   HLAvariantField<ENUMERATORS2, INDEX2, DATATYPE2,
+ *   ...
+ *   > ... > TYPENAME;
+ * defines an ordered sequence of DATATYPE entries.
+ *
+ * The data can be accessed using the field<INDEX>() function. The INDEX is a 
logical
+ * identifier only. 
+ * The first field is a discriminant. It is followed by an alternative whose
+ * ENUMERATORS match the discriminant value.
+ *
+ * For example:
+ * 
+-------------+-------------------------------+------------------------------------+------------------+-----------+
+ * |             | Discriminant                  | Alternative                 
       |                  |           |
+ * | Record name 
+------+-----------+------------+---------+--------------+-----------+ Encoding 
        | Semantics |
+ * |             | Name | Type      | Enumerator | Name    | Type         | 
Semantics |                  |           |
+ * 
+-------------+------+-----------+------------+---------+--------------+-----------+------------------+-----------+
+ * |             |      |           | AXIS_X     | FIELD_X | HLAfloat32LE |    
       |                  |           |
+ * | Coordinates | TYPE | TypesEnum 
+------------+---------+--------------+-----------+ HLAvariantRecord |          
 |
+ * |             |      |           | AXIS_Y     | FIELD_Y | HLAfloat32LE |    
       |                  |           |
+ * 
+-------------+------+-----------+------------+---------+--------------+-----------+------------------+-----------+
+ * 
+ * namespace __Fields {
+ * enum __enum {
+ *   TYPE = 0,
+ *   FIELD_X = 101,
+ *   FIELD_Y = 102
+ * };
+ * }
+ * typedef HLAenumeratedType<__Fields::__enum, HLAinteger32BE> Fields;
+ * typedef HLAvariantRecord<
+ *   __Fields::TYPE, TypesEnum,
+ *   HLAvariantField<HLAsetValue<AXIS_X>, __Fields::FIELD_X, HLAfloat32LE,
+ *   HLAvariantField<HLAsetValue<AXIS_Y>, __Fields::FIELD_Y, HLAfloat32LE
+ *   > > > Coordinates;
+ * HLAdata<Coordinates> value;
+ *
+ * value->set_discriminant(AXIS_X);
+ * value->field<__Fields::FIELD_X>() = 3.14;
+ */
+template<int DE, class DM, class R, bool hasVariable = R::m_isVariable>
+struct HLAvariantRecord;
+
+template<int DE, class DM, class R, bool V>
+std::ostream& PrintBuffer(std::ostream& stream, HLAvariantRecord<DE,DM,R,V>& 
buffer)
+{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
+
+//! Returns the discriminant, or a <i>th field of the HLAvariantField <R>
+template<int DE, class DM, class R, int e>
+struct __DiscriminantOrFieldAt;
+
+// Variant record optimized for fixed-size fields
+template<int DE, class DM, class R>
+struct HLAvariantRecord<DE, DM, R, false>
+{
+    //! Get/Set the discriminant, without memory management
+    /* This function assumes no data are stored in the buffer after this array.
+     * You may want to use set_discriminant() instead.
+     */
+    DM& discriminant() const
+    { return *(DM*)this; }
+
+    //! Set the discriminant, with memory management
+    void set_discriminant(int d)
+    {
+        if (d == (int)discriminant())
+            return; // no change
+
+        // as changing the discriminant may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, d, (long)R::field_emptysizeof(d));
+    }
+
+    template <int e>
+    typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type& field() const
+    {
+        // return the discriminant
+        if (e == DE)
+            return *(typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type*)this;
+
+        if (e != R::get_field(discriminant()))
+            throw std::out_of_range("HLAvariantRecord: wrong discriminant");
+        // return one of the alternatives
+        return *(typename 
__DiscriminantOrFieldAt<DE,DM,R,e>::Type*)((char*)this + emptysizeof());
+    }
+
+    static const size_t emptysizeof()
+    { return DM::__sizeof() + __padding(DM::__sizeof(), R::m_octetBoundary); }
+
+    const size_t __sizeof() const
+    {
+        if (R::has_field(discriminant()))
+            return emptysizeof() + R::field_sizeof(discriminant());
+        else
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(DM*)this = buffer.mShakeValue;
+            // switching variant: content is removed
+        }
+        else {
+            int d = *(DM*)source;
+            // not switching variant: copy the content
+            *(DM*)this = d;
+            ((R*)this)->copy(d, (char*)source + emptysizeof());
+        }
+    }
+
+    static const size_t m_octetBoundary = MAX(DM::m_octetBoundary, 
R::m_octetBoundary);
+    static const bool m_isVariable = true; // variant record of fixed-size 
fields
+};
+
+// Generic variant record, supports variable-size fields
+template<int DE, class DM, class R>
+struct HLAvariantRecord<DE, DM, R, true>
+{
+    //! Get/Set the discriminant, without memory management
+    /* This function assumes no data are stored in the buffer after this array.
+     * You may want to use set_discriminant() instead.
+     */
+    DM& discriminant() const
+    { return *(DM*)this; }
+
+    //! Set the discriminant, with memory management
+    void set_discriminant(int d)
+    {
+        if (d == (int)discriminant())
+            return; // no change
+
+        // as changing the discriminant may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, d, (long)R::field_emptysizeof(d));
+    }
+
+    template <int e>
+    typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type& field() const
+    {
+        // return the discriminant
+        if (e == DE)
+            return *(typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type*)this;
+
+        if (e != R::get_field(discriminant()))
+            throw std::out_of_range("HLAvariantRecord: wrong discriminant");
+        // return one of the alternatives
+        return *(typename 
__DiscriminantOrFieldAt<DE,DM,R,e>::Type*)((char*)this + emptysizeof());
+    }
+
+    static const size_t emptysizeof()
+    { return DM::__sizeof() + __padding(DM::__sizeof(), R::m_octetBoundary); }
+
+    const size_t __sizeof() const
+    {
+        if (R::has_field(discriminant()))
+            return emptysizeof() + ((R*)((char*)this + 
emptysizeof()))->field_sizeof(discriminant());
+        else
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(DM*)this = buffer.mShakeValue;
+            // switching variant: content is removed
+        }
+        else {
+            int d = *(DM*)source;
+            // not switching variant: copy the content
+            *(DM*)this = d;
+            ((R*)this)->copy(d, (char*)source + emptysizeof());
+        }
+    }
+
+    static const size_t m_octetBoundary = MAX(DM::m_octetBoundary, 
R::m_octetBoundary);
+    static const bool m_isVariable = true; // variant record of variable-sized 
fields
+};
+
+struct HLAsetEnd;
+
+//! Defines a value in an enumerator list; to be used with HLAvariantField
+template<int e, class N = HLAsetEnd>
+struct HLAsetValue
+{
+    static int includes(int i)
+    {
+        if (i == e)
+            return 1;
+        else
+            return N::includes(i);
+    }
+};
+
+//! Defines a range in an enumerator list
+template<int e1, int e2, class N = HLAsetEnd>
+struct HLAsetRange
+{
+    static int includes(int i)
+    {
+        if (e1 <= i && i <= e2)
+            return 1;
+        else
+            return N::includes(i);
+    }
+};
+
+//! Defines the "HLAother" symbol in an enumerator list
+template<class N = HLAsetEnd>
+struct HLAsetOther
+{
+    static int includes(int i)
+    { return 1; }
+};
+
+//! Defines the end of an enumerator list
+struct HLAsetEnd
+{
+    static int includes(int i)
+    { return 0; }
+};
+
+struct HLAvariantEnd;
+
+//! Record at index <E>, field of type <M>, followed by HLAvariantField <N>
+// note: <E> must be "int" to enable implicit conversion from/to enum types
+template<class D, int E, class M, class N = HLAvariantEnd, bool hasVariable = 
M::m_isVariable || N::m_isVariable>
+struct HLAvariantField;
+
+// List of fixed-size fields
+template<class D, int E, class M, class N>
+struct HLAvariantField<D, E, M, N, false>
+{
+    static bool has_field(int d)
+    {
+        if (D::includes(d))
+          return true; // found
+        else
+          return N::has_field(d); // continue searching
+    }
+
+    static int get_field(int d)
+    {
+        if (D::includes(d))
+            return E;
+        else
+            return N::get_field(d);
+    }
+
+    static const size_t field_emptysizeof(int e)
+    {
+        if (e == E)
+            return M::emptysizeof();
+        else
+            return N::field_emptysizeof(e);
+    }
+
+    static const size_t field_sizeof(int e)
+    {
+        if (e == E)
+            return M::__sizeof();
+        else
+            return N::field_sizeof(e);
+    }
+
+    void copy(int e, void* source)
+    {
+        if (e == E)
+            return ((M*)this)->copy(source);
+        else
+            return ((N*)this)->copy(e, source);
+    }
+
+    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
+    static const bool m_isVariable = false; // fixed-sized fields
+};
+
+// List containg variable-size fields
+template<class D, int E, class M, class N>
+struct HLAvariantField<D, E, M, N, true>
+{
+    static bool has_field(int d)
+    {
+        if (D::includes(d))
+          return true; // found
+        else
+          return N::has_field(d); // continue searching
+    }
+
+    static int get_field(int d)
+    {
+        if (D::includes(d))
+            return E;
+        else
+            return N::get_field(d);
+    }
+
+    static const size_t field_emptysizeof(int e)
+    {
+        if (e == E)
+            return M::emptysizeof();
+        else
+            return N::field_emptysizeof(e);
+    }
+
+    const size_t field_sizeof(int e) const
+    {
+        if (e == E)
+            return ((M*)this)->__sizeof();
+        else
+            return ((N*)this)->field_sizeof(e);
+    }
+
+    void copy(int e, void* source)
+    {
+        if (e == E)
+            return ((M*)this)->copy(source);
+        else
+            return ((N*)this)->copy(e, source);
+    }
+
+    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
+    static const bool m_isVariable = true; // variable-sized fields
+};
+
+//! Defines a last field in the fixed record
+struct HLAvariantEnd
+{
+    static bool has_field(int d)
+    { return false; }
+    static int get_field(int d)
+    { throw std::out_of_range("HLAvariantRecord: unknown discriminant"); }
+    static const size_t field_emptysizeof(int e)
+    { return 0; }
+    static const size_t field_sizeof(int e)
+    { return 0; }
+    void copy(int e, void* source)
+    { /* nop */ }
 
     static const size_t m_octetBoundary = 0;
     static const bool m_isVariable = false;
 };
 
-template<class M, class N, bool V, unsigned i>
-struct __FieldAt<HLAfixedRecord<M, N, V>,i>
-{ typedef typename __FieldAt<N,i-1>::Type Type; };
-
-template <class M, class N, bool V>
-struct __FieldAt<HLAfixedRecord<M, N, V>,0>
-{ typedef M Type; };
+template<int DE, class DM, class R, int e>
+struct __DiscriminantOrFieldAt
+{ typedef typename __if<e==DE, DM, typename __FieldAt<R,e>::Type>::X Type; }; 
+
+template<class D, int E, class M, class N, bool V, int e>
+struct __FieldAt<HLAvariantField<D,E,M,N,V>, e>
+{ typedef typename __if<e==E, M, typename __FieldAt<N,e>::Type>::X Type; }; 
+
+// returned when no HLAvariantField has a given index(i)
+template<int e>
+struct __FieldAt<HLAvariantEnd, e>
+{ typedef HLAvariantEnd Type; };
 
 } // namespace libhla
 
 #endif // _HLATYPES_IEEE1516_HH
 
-// $Id: HLAtypesIEEE1516.hh,v 1.2 2008/07/17 16:03:53 gotthardp Exp $
+// $Id: HLAtypesIEEE1516.hh,v 1.3 2008/08/02 11:44:12 gotthardp Exp $
 

Index: hlaomtdif2cpp.py
===================================================================
RCS file: /sources/certi/certi/libHLA/hlaomtdif2cpp.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- hlaomtdif2cpp.py    17 Jul 2008 16:03:53 -0000      1.1
+++ hlaomtdif2cpp.py    2 Aug 2008 11:44:12 -0000       1.2
@@ -13,7 +13,7 @@
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ## Lesser General Public License for more details.
 ##
-## $Id: hlaomtdif2cpp.py,v 1.1 2008/07/17 16:03:53 gotthardp Exp $
+## $Id: hlaomtdif2cpp.py,v 1.2 2008/08/02 11:44:12 gotthardp Exp $
 ## ----------------------------------------------------------------------------
 
 import getopt, sys
@@ -68,9 +68,79 @@
   formatter.addComment(text)
   formatter.finish()
 
-class CodeGenerator(xml.sax.handler.ContentHandler):
-#  def __init__(self):
+def identifier(text):
+  return re.sub('[-]', '_', text)
 
+# custom exception to stop the SAX parser
+class SAXDone(Exception):
+  pass
+
+KnownBasicTypes = (
+  "HLAinteger16BE", "HLAinteger32BE", "HLAinteger64BE",
+  "HLAfloat32BE", "HLAfloat64BE", "HLAoctetPairBE",
+  "HLAinteger16LE", "HLAinteger32LE", "HLAinteger64LE",
+  "HLAfloat32LE", "HLAfloat64LE", "HLAoctetPairLE",
+  "HLAoctet",
+  "Unsignedinteger16BE", "Unsignedinteger32BE", "Unsignedinteger64BE")
+
+KnownArrayEncodings = (
+  "HLAfixedArray", "HLAvariableArray")
+
+class DependencyChecker(xml.sax.handler.ContentHandler):
+  def __init__(self, deps):
+    pass
+
+  def warning(self, string):
+    sys.stderr.write("Warning: [line " + str(parser.getLineNumber()) + "] " + 
string + "\n")
+
+  def startElement(self, name, attributes):
+    if name == "basicData":
+      self.typeName = attributes["name"]
+      if self.typeName in deps:
+        return self.warning("Duplicite type " + self.typeName)
+      if self.typeName not in KnownBasicTypes:
+        return self.warning("Unknown basic type " + self.typeName)
+      deps[self.typeName] = set()
+
+    elif name == "simpleData":
+      self.typeName = attributes["name"]
+      if self.typeName in deps:
+        return self.warning("Duplicite type " + self.typeName)
+      deps[self.typeName] = set([attributes["representation"]])
+
+    elif name == "enumeratedData":
+      self.typeName = attributes["name"]
+      if self.typeName in deps:
+        return self.warning("Duplicite type " + self.typeName)
+      deps[self.typeName] = set([attributes["representation"]])
+
+    elif name == "arrayData":
+      self.typeName = attributes["name"]
+      if self.typeName in deps:
+        return self.warning("Duplicite type " + self.typeName)
+      if attributes["encoding"] not in KnownArrayEncodings:
+        return self.warning(self.typeName + " uses unknown arrayData encoding 
" + attributes["encoding"])
+      deps[attributes["name"]] = set([attributes["dataType"]])
+
+    elif name == "fixedRecordData":
+      self.typeName = attributes["name"]
+      if self.typeName in deps:
+        return self.warning("Duplicite type " + self.typeName)
+      deps[self.typeName] = set()
+
+    elif name == "field":
+      deps[self.typeName].add(attributes["dataType"])
+
+    elif name == "variantRecordData":
+      self.typeName = attributes["name"]
+      if self.typeName in deps:
+        return self.warning("Duplicite type " + self.typeName)
+      deps[self.typeName] = set([attributes["dataType"]])
+
+    elif name == "alternative":
+      deps[self.typeName].add(attributes["dataType"])
+
+class HeaderGenerator(xml.sax.handler.ContentHandler):
   def startElement(self, name, attributes):
     if name == "objectModel":
       print "#line", parser.getLineNumber(), "\"" + input + "\""
@@ -95,81 +165,182 @@
       formatter.addComment("E-mail: " + attributes["pocEmail"])
       formatter.finish();
       print
+      raise SAXDone
+
+class TypeGenerator(xml.sax.handler.ContentHandler):
+  def __init__(self, deps, done):
+    self.inEnum = False
+    self.inRecord = False
+
+  def warning(self, string):
+    sys.stderr.write("Warning: [line " + str(parser.getLineNumber()) + "] " + 
string + "\n")
+
+  def startElement(self, name, attributes):
+    if name == "basicData":
+      self.typeName = attributes["name"]
+      if self.typeName in done or self.typeName not in deps or 
len(deps[self.typeName]-done) > 0:
+        return
+
+      done.add(self.typeName)
+
+    elif name == "simpleData":
+      self.typeName = attributes["name"]
+      if self.typeName in done or self.typeName not in deps or 
len(deps[self.typeName]-done) > 0:
+        return
 
-    if name == "simpleData":
       print "#line", parser.getLineNumber(), "\"" + input + "\""
       self.buffer = ""
       printComment(attributes["semantics"])
-      print "typedef " + attributes["representation"] + " " + 
attributes["name"] + ";"
+      print "typedef " + attributes["representation"] + " " + 
attributes["name"] + ";\n"
+
+      done.add(self.typeName)
 
     elif name == "enumeratedData":
+      self.typeName = attributes["name"]
+      if self.typeName in done or self.typeName not in deps or 
len(deps[self.typeName]-done) > 0:
+        return
+
+      self.inEnum = True
       print "#line", parser.getLineNumber(), "\"" + input + "\""
-      self.enumCounter = 0
+      self.generatedEnums = set()
       self.enumRepresentation = attributes["representation"]
-      self.enumName = attributes["name"]
       printComment(attributes["semantics"])
       # The enumerations must be isolated from other enumerations in an 
individual namespace
       print "namespace __" + attributes["name"] + " {"
       print "enum __enum {",
 
     elif name == "enumerator":
-      if self.enumCounter > 0:
+      if not self.inEnum:
+        return
+      if attributes["name"] in self.generatedEnums:
+        self.warning("Duplicate enumerator " + attributes["name"] + " in " + 
self.typeName)
+        return
+
+      if len(self.generatedEnums) > 0:
         print ",",
-      self.enumCounter += 1
-      sys.stdout.write("\n  " + attributes["name"] + " = " + 
attributes["values"])
+      sys.stdout.write("\n")
+      self.generatedEnums.add(attributes["name"])
+#     print "#line", parser.getLineNumber(), "\"" + input + "\""
+      sys.stdout.write("  " + identifier(attributes["name"]) + " = " + 
attributes["values"])
 
     elif name == "arrayData":
+      self.typeName = attributes["name"]
+      if self.typeName in done or self.typeName not in deps or 
len(deps[self.typeName]-done) > 0:
+        return
+
       print "#line", parser.getLineNumber(), "\"" + input + "\""
       printComment(attributes["semantics"])
       if attributes["encoding"] == "HLAfixedArray":
-        print "typedef HLAfixedArray<" + attributes["dataType"] + ", " + 
attributes["cardinality"] + "> " + attributes["name"] + ";"
+        print "typedef HLAfixedArray<" + attributes["dataType"] + ", " + 
attributes["cardinality"] + "> " + identifier(attributes["name"]) + ";\n"
 
       elif attributes["encoding"] == "HLAvariableArray":
-        print "typedef HLAvariableArray<" + attributes["dataType"] + "> " + 
attributes["name"] + ";"
+        print "typedef HLAvariableArray<" + attributes["dataType"] + "> " + 
identifier(attributes["name"]) + ";\n"
+
+      done.add(self.typeName)
 
     elif name == "fixedRecordData":
+      self.typeName = attributes["name"]
+      if self.typeName in done or self.typeName not in deps or 
len(deps[self.typeName]-done) > 0:
+        return
+
+      self.inRecord = True
       print "#line", parser.getLineNumber(), "\"" + input + "\""
       printComment(attributes["semantics"])
       # The enumerations must be isolated from other enumerations in an 
individual namespace
       print "namespace __" + attributes["name"] + " {"
       print "enum __enum {"
-      self.recordName = attributes["name"]
       self.recordFields = []
 
     elif name == "field":
+      if not self.inRecord:
+        return
+
       if len(self.recordFields) > 0:
         sys.stdout.write(",\n")
+#     print "#line", parser.getLineNumber(), "\"" + input + "\""
       printComment(attributes["semantics"], 2)
-      sys.stdout.write("  " + attributes["name"])
+      sys.stdout.write("  " + identifier(attributes["name"]))
       if len(self.recordFields) == 0:
         sys.stdout.write(" = 0")
       tupple = (attributes["dataType"], attributes["name"])
       self.recordFields.append(tupple)
 
-#  def characters(self, data):
+    elif name == "variantRecordData":
+      self.typeName = attributes["name"]
+      if self.typeName in done or self.typeName not in deps or 
len(deps[self.typeName]-done) > 0:
+        return
 
-  def endElement(self, name):
-    if name == "simpleDataTypes":
-      print "\n",
+      self.inRecord = True
+      print "#line", parser.getLineNumber(), "\"" + input + "\""
+      printComment(attributes["semantics"])
+      # The enumerations must be isolated from other enumerations in an 
individual namespace
+      print "namespace __" + attributes["name"] + " {"
+      print "enum __enum {"
+      sys.stdout.write("  " + attributes["discriminant"] + " = 0")
+      self.variantName = attributes["discriminant"]
+      self.variantType = attributes["dataType"]
+      self.recordFields = []
+
+    elif name == "alternative":
+      if not self.inRecord:
+        return
 
+      sys.stdout.write(",\n")
+#     print "#line", parser.getLineNumber(), "\"" + input + "\""
+      printComment(attributes["semantics"], 2)
+      sys.stdout.write("  " + identifier(attributes["name"]))
+      tupple = (attributes["dataType"], attributes["enumerator"], 
attributes["name"])
+      self.recordFields.append(tupple)
+
+  def endElement(self, name):
     if name == "enumeratedData":
+      if not self.inEnum:
+        return
+
       print "\n};"
       print "}"
-      print "typedef HLAenumeratedType<__" + self.enumName + "::__enum, " + 
self.enumRepresentation + "> " + self.enumName + ";\n"
+      print "typedef HLAenumeratedType<__" + self.typeName + "::__enum, " + 
self.enumRepresentation + "> " + self.typeName + ";\n"
 
-    if name == "arrayDataTypes":
-      print "\n",
+      done.add(self.typeName)
+      self.inEnum = False
 
     elif name == "fixedRecordData":
+      if not self.inRecord:
+        return
+
       print "\n};"
       print "}"
-      print "typedef"
+      print "typedef HLAfixedRecord<"
+      for index, field in enumerate(self.recordFields):
+        if index > 0:
+          sys.stdout.write(",\n")
+        sys.stdout.write("  HLAfixedField<__" + self.typeName + "::" + 
identifier(field[1]) + ", " + field[0])
+      sys.stdout.write("\n  ")
+      for field in self.recordFields:
+        sys.stdout.write("> ")
+      print "> " + self.typeName + ";\n"
+
+      done.add(self.typeName)
+      self.inRecord = False
+
+    elif name == "variantRecordData":
+      if not self.inRecord:
+        return
+
+      print "\n};"
+      print "}"
+      print "typedef HLAvariantRecord<"
+      sys.stdout.write("  __" + self.typeName + "::" + self.variantName + ", " 
+ self.variantType)
       for field in self.recordFields:
-        print "  HLAfixedRecord<" + field[0] + ", // " + field[1]
-      sys.stdout.write("  HLAfixedRecordEnd")
+        sys.stdout.write(",\n  HLAvariantField<HLAsetValue<__" + 
self.variantType + "::" + field[1] + ">")
+        sys.stdout.write(",\n    __" + self.typeName + "::" + 
identifier(field[2]) + ", " + field[0])
+      sys.stdout.write("\n  ")
       for field in self.recordFields:
         sys.stdout.write("> ")
-      print self.recordName + ";\n"
+      print "> " + self.typeName + ";\n"
+
+      done.add(self.typeName)
+      self.inRecord = False
 
 try:
   opts, args = getopt.getopt(sys.argv[1:], "i:h", ["help", "output="])
@@ -202,13 +373,39 @@
 print "#include <HLAtypesIEEE1516.hh>\n"
 print "namespace libhla {\n"
 
+done = set()
+
+deps = {}
 parser = xml.sax.make_parser()
-handler = CodeGenerator()
+
+handler = DependencyChecker(deps)
 parser.setContentHandler(handler)
 parser.parse(input)
 
+handler = HeaderGenerator()
+parser.setContentHandler(handler)
+try:
+  parser.parse(input)
+except SAXDone: pass
+
+while True:
+  initiallyDone = len(done)
+
+  handler = TypeGenerator(deps, done)
+  parser.setContentHandler(handler)
+  parser.parse(input)
+
+  if len(done) == initiallyDone:
+    break
+
+for datatype in set(deps.keys())-done:
+  sys.stderr.write("Warning: " + datatype + " depends on unknown type(s)")
+  for dep in deps[datatype]-done:
+    sys.stderr.write(" " + dep)
+  sys.stderr.write("\n")
+
 print "} // namespace libhla"
 print
 print "#endif // " + modulename
 
-# $Id: hlaomtdif2cpp.py,v 1.1 2008/07/17 16:03:53 gotthardp Exp $
+# $Id: hlaomtdif2cpp.py,v 1.2 2008/08/02 11:44:12 gotthardp Exp $




reply via email to

[Prev in Thread] Current Thread [Next in Thread]