certi-cvs
[Top][All Lists]
Advanced

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

certi libCERTI/CMakeLists.txt libCERTI/MessageB...


From: certi-cvs
Subject: certi libCERTI/CMakeLists.txt libCERTI/MessageB...
Date: Thu, 14 Feb 2008 15:29:58 +0000

CVSROOT:        /sources/certi
Module name:    certi
Changes by:     Eric NOULARD <erk>      08/02/14 15:29:58

Modified files:
        libCERTI       : CMakeLists.txt MessageBody.cc 
        test/utility   : CertiUtilTests.cc 
        include        : certi.hh 
Added files:
        libCERTI       : MessageBuffer.cc MessageBuffer.hh 

Log message:
        First set of functions for heterogeneity handling

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/certi/libCERTI/CMakeLists.txt?cvsroot=certi&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/certi/libCERTI/MessageBody.cc?cvsroot=certi&r1=3.15&r2=3.16
http://cvs.savannah.gnu.org/viewcvs/certi/libCERTI/MessageBuffer.cc?cvsroot=certi&rev=3.1
http://cvs.savannah.gnu.org/viewcvs/certi/libCERTI/MessageBuffer.hh?cvsroot=certi&rev=3.1
http://cvs.savannah.gnu.org/viewcvs/certi/test/utility/CertiUtilTests.cc?cvsroot=certi&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/certi/include/certi.hh?cvsroot=certi&r1=3.24&r2=3.25

Patches:
Index: libCERTI/CMakeLists.txt
===================================================================
RCS file: /sources/certi/certi/libCERTI/CMakeLists.txt,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- libCERTI/CMakeLists.txt     12 Dec 2007 08:20:35 -0000      1.10
+++ libCERTI/CMakeLists.txt     14 Feb 2008 15:29:58 -0000      1.11
@@ -65,29 +65,17 @@
 )
 
 SET(CERTI_SUPPORT_SRCS
-AuditFile.cc
-AuditLine.cc
-BasicMessage.cc
+AuditFile.cc AuditFile.hh
+AuditLine.cc AuditLine.hh
+BasicMessage.cc BasicMessage.hh
 Clock.cc Clock.hh
-MessageBody.cc
-Message.cc
-Message_R.cc
-Message_W.cc
-NetworkMessage.cc
-NetworkMessage_RW.cc
-Exception.cc
-XmlParser.cc
-PrettyDebug.cc
-PrettyDebEx.cc
-AuditFile.hh
-AuditLine.hh
-BasicMessage.hh
-MessageBody.hh
-Message.hh
-NetworkMessage.hh
-Exception.hh
-XmlParser.hh
-PrettyDebug.hh
+MessageBody.cc MessageBody.hh
+MessageBuffer.cc MessageBuffer.hh
+Message.cc Message_R.cc Message_W.cc Message.hh
+NetworkMessage.cc NetworkMessage_RW.cc NetworkMessage.hh
+Exception.cc Exception.hh
+XmlParser.cc XmlParser.hh
+PrettyDebug.cc PrettyDebEx.cc PrettyDebug.hh
 )
 
 IF (HAVE_POSIX_CLOCK)

Index: libCERTI/MessageBody.cc
===================================================================
RCS file: /sources/certi/certi/libCERTI/MessageBody.cc,v
retrieving revision 3.15
retrieving revision 3.16
diff -u -b -r3.15 -r3.16
--- libCERTI/MessageBody.cc     11 Dec 2007 16:44:20 -0000      3.15
+++ libCERTI/MessageBody.cc     14 Feb 2008 15:29:58 -0000      3.16
@@ -17,7 +17,7 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 // USA
 //
-// $Id: MessageBody.cc,v 3.15 2007/12/11 16:44:20 rousse Exp $
+// $Id: MessageBody.cc,v 3.16 2008/02/14 15:29:58 erk Exp $
 // ----------------------------------------------------------------------------
 
 
@@ -122,7 +122,7 @@
 MessageBody &MessageBody::operator<<(unsigned long val)
 {
 assert(val <= 4294967295U);
-#ifdef BIG_INDIAN
+#ifdef HOST_IS_BIG_ENDIAN
        buffer[wPtr++]= (char)(0x000000FF & (val >> 24));
        buffer[wPtr++]= (char)(0x000000FF & (val >> 16));
        buffer[wPtr++]= (char)(0x000000FF & (val >>  8));
@@ -140,7 +140,7 @@
 MessageBody &MessageBody::operator<<(unsigned short val)
 {
 //assert(val <= 4294967295U);
-#ifdef BIG_INDIAN
+#ifdef HOST_IS_BIG_ENDIAN
        buffer[wPtr++]= (char)0x000000FF & (val >>  8);
        buffer[wPtr++]= (char)0x000000FF & val;
 #else
@@ -154,7 +154,7 @@
 // ----------------------------------------------------------------------------
 const MessageBody &MessageBody::operator>>(unsigned long &val)
 {
-#ifdef BIG_INDIAN
+#ifdef HOST_IS_BIG_ENDIAN
        val = (unsigned long) (buffer[rPtr++] << 24);
        val|= (unsigned long) (buffer[rPtr++] << 16);
        val|= (unsigned long) (buffer[rPtr++] <<  8);
@@ -170,7 +170,7 @@
 
 const MessageBody &MessageBody::operator>>(unsigned short &val)
 {
-#ifdef BIG_INDIAN
+#ifdef HOST_IS_BIG_ENDIAN
        val = (unsigned short) (buffer[rPtr++] <<  8);
        val|= (unsigned short) buffer[rPtr++];
 #else
@@ -182,4 +182,4 @@
 
 } // certi
 
-// $Id: MessageBody.cc,v 3.15 2007/12/11 16:44:20 rousse Exp $
+// $Id: MessageBody.cc,v 3.16 2008/02/14 15:29:58 erk Exp $

Index: test/utility/CertiUtilTests.cc
===================================================================
RCS file: /sources/certi/certi/test/utility/CertiUtilTests.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- test/utility/CertiUtilTests.cc      30 Jul 2007 07:30:22 -0000      1.2
+++ test/utility/CertiUtilTests.cc      14 Feb 2008 15:29:58 -0000      1.3
@@ -28,6 +28,8 @@
 
 #include "config.h"
 #include "PrettyDebug.hh"
+#include "MessageBuffer.hh"
+#include <cassert>
 
 #include "Clock.hh"
 void clockTests(certi::Clock& aClock) {
@@ -49,6 +51,68 @@
 #include "PosixClock.hh"
 #endif
 
+void messageBufferTests(certi::MessageBuffer& MsgBuf) {
+       const char*   str = "bouhlala";
+       uint8_t  u8   =  232;
+       int8_t   i8   = -125;
+       uint16_t u16  = 0xFFAA;
+       int16_t  i16  = -576;
+       uint32_t u32  = 0xFFAAEEBB;
+       int32_t  i32  = -9999;
+       uint64_t u64  = 0xFFEEDDCC;
+       int64_t  i64  = -1000000000;
+       float    f32  = 3.1415927;
+       double   d64  = 2.7182818;
+       char*    vstr = NULL;   
+       uint8_t  vu8   = 0;
+       int8_t   vi8   = 0;
+       uint16_t vu16  = 0;
+       int16_t  vi16  = 0;
+       uint32_t vu32  = 0;
+       int32_t  vi32  = 0;
+       uint64_t vu64  = 0;
+       int64_t  vi64  = 0;
+       float    vf32  = 0.0;
+       double   vd64  = 0.0;   
+       cout << "Testing MessageBuffer class BEGIN..."<<endl;
+       cout << "    Default MessageBuffer MaxSize               ="<< 
MsgBuf.maxSize() <<endl;
+       cout << "    Current (initially void) MessageBuffer size ="<< 
MsgBuf.size()<<endl;
+       cout << "    Encoding to buffer..." <<endl;
+       cout << "    bytes string = " << str << endl;
+       MsgBuf.write_uint32(strlen(str)+1);
+       MsgBuf.write_bytes(str,strlen(str)+1);
+       MsgBuf.write_uint8(u8);
+       MsgBuf.write_uint16(u16);
+       MsgBuf.write_uint32(u32);
+       MsgBuf.write_uint64(u64);
+       MsgBuf.write_int8(i8);
+       MsgBuf.write_int16(i16);
+       MsgBuf.write_int32(i32);
+       MsgBuf.write_int64(i64);
+       MsgBuf.write_float(f32);
+       MsgBuf.write_double(d64);
+       cout << "    Current MessageBuffer size                  = "<< 
MsgBuf.size()<<endl;
+       cout << "    Decoding from buffer..." <<endl;
+       MsgBuf.read_uint32(&vu32);
+       vstr = new char[vu32];
+       memset(vstr,'\0',vu32);
+       MsgBuf.read_bytes(vstr,vu32);
+       cout << "    bytes string = " << vstr << endl; 
assert(0==strcmp(str,vstr));
+       MsgBuf.read_uint8(&vu8); assert(vu8==u8);
+       MsgBuf.read_uint16(&vu16); assert(vu16==u16);
+       MsgBuf.read_uint32(&vu32); assert(vu32==u32);
+       MsgBuf.read_uint64(&vu64); assert(vu64==u64);
+       MsgBuf.read_int8(&vi8); assert(vi8==i8);
+       MsgBuf.read_int16(&vi16); assert(vi16==i16);
+       MsgBuf.read_int32(&vi32); assert(vi32==i32);
+       MsgBuf.read_int64(&vi64); assert(vi64==i64);
+       MsgBuf.read_float(&vf32); assert(vf32==f32);
+       MsgBuf.read_double(&vd64); assert(vd64==d64);
+    cout << "    All encoded/decoded values are equal." << endl;
+    
+       cout << "Testing MessageBuffer class END."<<endl;
+} /* end of messageBufferTests */
+
 
 int
 main(int argc, char **argv)
@@ -59,8 +123,18 @@
 #ifdef HAVE_TSC_CLOCK  
        certi::TSCClock   tscClk;
 #endif
+       certi::MessageBuffer MsgBuf;
        
        cout << "CERTI Utility Tests->BEGIN..."<< endl ;
+
+       cout << "    Host is " << 
+#ifdef HOST_IS_BIG_ENDIAN
+         "Big Endian"
+#else
+         "Little Endian"
+#endif
+            << endl;   
+    messageBufferTests(MsgBuf);
 #ifdef HAVE_TSC_CLOCK
     clockTests(tscClk);
 #endif

Index: include/certi.hh
===================================================================
RCS file: /sources/certi/certi/include/certi.hh,v
retrieving revision 3.24
retrieving revision 3.25
diff -u -b -r3.24 -r3.25
--- include/certi.hh    24 Jan 2008 16:15:56 -0000      3.24
+++ include/certi.hh    14 Feb 2008 15:29:58 -0000      3.25
@@ -16,7 +16,7 @@
 // License along with this program ; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 //
-// $Id: certi.hh,v 3.24 2008/01/24 16:15:56 rousse Exp $
+// $Id: certi.hh,v 3.25 2008/02/14 15:29:58 erk Exp $
 // ----------------------------------------------------------------------------
 
 #ifndef CERTI_HH_INCLUDED
@@ -41,20 +41,43 @@
     typedef u_long                             in_addr_t;
     typedef unsigned short             in_port_t;
     #ifdef _MSC_VER
+        typedef unsigned __int64        uint64_t;
+        typedef __int64                         int64_t;
         typedef unsigned __int32       uint32_t;
         typedef __int32                                int32_t;
         typedef unsigned __int16       uint16_t;
         typedef __int16                                int16_t;
         typedef unsigned __int8        uint8_t;
         typedef __int8                         int8_t;
+        #ifdef _M_X64 
+           #define  CERTI_INT64_CONSTANT(val)  (val##L)
+           #define  CERTI_INT64_FORMAT         "l"
+        #else
+           #define  CERTI_INT64_CONSTANT(val)  (val##LL)
+           #define  CERTI_INT64_FORMAT         "ll"
+        #endif
+    #else
+       #ifdef __x86_64__
+          #define  CERTI_INT64_CONSTANT(val)  (val##L)
+          #define  CERTI_INT64_FORMAT         "l"
+       #else
+          #define  CERTI_INT64_CONSTANT(val)  (val##LL)
+          #define  CERTI_INT64_FORMAT         "ll"
+       #endif
     #endif
 #else
        #define STAT_FUNCTION           stat
        #define STAT_STRUCT                     struct stat
+    #ifdef __x86_64__
+       #define  CERTI_INT64_CONSTANT(val)  (val##L)
+       #define  CERTI_INT64_FORMAT         "l"
+    #else
+       #define  CERTI_INT64_CONSTANT(val)  (val##LL)
+       #define  CERTI_INT64_FORMAT         "ll"
+    #endif
 #endif
 
 #include "RTI.hh"
-//#include <vector>
        
 /**
  * @defgroup libCERTI The CERTI library.
@@ -324,6 +347,37 @@
 // Note: Currently, no option is suppported by our default GSSAPI mechanism.
 #define HLA_GSS_FLAGS 0
 
+
+/* 
+ * Basic bit swapping functions
+ */
+#define CERTI_UINT16_SWAP_BYTES(val)   ((uint16_t) ( \
+    (((uint16_t) (val) & (uint16_t) 0x00ffU) << 8) |  \
+    (((uint16_t) (val) & (uint16_t) 0xff00U) >> 8)))
+
+#define CERTI_UINT32_SWAP_BYTES(val)   ((uint32_t) (     \
+    (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \
+    (((uint32_t) (val) & (uint32_t) 0x0000ff00U) <<  8) | \
+    (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >>  8) | \
+    (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))
+
+#define CERTI_UINT64_SWAP_BYTES(val)   ((uint64_t) (                   \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x00000000000000ffU)) << 56) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x000000000000ff00U)) << 40) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x0000000000ff0000U)) << 24) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x00000000ff000000U)) <<  8) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x000000ff00000000U)) >>  8) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x0000ff0000000000U)) >> 24) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0x00ff000000000000U)) >> 40) |  \
+      (((uint64_t) (val) &                                             \
+       (uint64_t) CERTI_INT64_CONSTANT(0xff00000000000000U)) >> 56)))
 #endif // CERTI_HH_INCLUDED
 
-// $Id: certi.hh,v 3.24 2008/01/24 16:15:56 rousse Exp $
+// $Id: certi.hh,v 3.25 2008/02/14 15:29:58 erk Exp $

Index: libCERTI/MessageBuffer.cc
===================================================================
RCS file: libCERTI/MessageBuffer.cc
diff -N libCERTI/MessageBuffer.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libCERTI/MessageBuffer.cc   14 Feb 2008 15:29:58 -0000      3.1
@@ -0,0 +1,323 @@
+// ----------------------------------------------------------------------------
+// CERTI - HLA RunTime Infrastructure
+// Copyright (C) 2002-2005 ONERA
+//
+// This program is free software ; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation ; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY ; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program ; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//
+// ----------------------------------------------------------------------------
+
+#include "MessageBuffer.hh"
+#include <cassert>
+#include <sstream>
+
+namespace certi {
+
+void MessageBuffer::initialize() {
+       buffer = NULL;
+       bufferMaxSize = DEFAULT_MESSAGE_BUFFER_SIZE;
+       bufferHasMyEndianness = true;
+       writeOffset = 0;
+       readOffset = 0;
+} /* end of MessageBuffer::initialize() */
+
+MessageBuffer::MessageBuffer() {
+       initialize();
+       reallocate(DEFAULT_MESSAGE_BUFFER_SIZE);
+} /* end of MessageBuffer::MessageBuffer() */
+
+MessageBuffer::MessageBuffer(uint32_t n) {
+       initialize();
+       reallocate(n);
+} /* end of MessageBuffer::MessageBuffer(uint32_t) */
+
+/* 
+ * FIXME we may put a COMPILED FLAG here in order
+ * to prevent reallocation beside the first one (when buffer==NULL)
+ */
+void MessageBuffer::reallocate(uint32_t n) {
+       uint8_t* oldbuf = buffer;
+       /* (re)allocation is done iff
+        *  - buffer is NULL (never allocated)
+        *  or
+        *  - requested size exceed current bufferMaxSize
+        */
+       if ((NULL==buffer) || (n > bufferMaxSize)) {
+               // FIXME should try/catch for alloc error
+               // ands wrap-up inside RTIinternalError
+               buffer = new uint8_t[n];
+               bufferMaxSize = n;
+               /* 
+                * If oldbuf wasn't null then copy
+                * oldbuf in the new buf 
+                * the writeOffset should be valid.
+                */
+               if (NULL!=oldbuf) {
+                       memcpy(buffer, oldbuf, writeOffset);
+                       delete[] oldbuf;
+                       oldbuf = NULL;
+               }
+       }
+} /* end of MessageBuffer::MessageBuffer(uint32_t) */
+
+MessageBuffer::~MessageBuffer() {
+       if (NULL!=buffer) {
+               delete[] buffer;
+       }
+} /* end of MessageBuffer::~MessageBuffer() */
+
+uint32_t MessageBuffer::size() const {
+       return writeOffset;
+}
+
+uint32_t MessageBuffer::maxSize() const {
+       return bufferMaxSize;
+}
+
+void MessageBuffer::assumeBufferIsBigEndian() {
+#ifdef HOST_IS_BIG_ENDIAN
+       this->bufferHasMyEndianness = true;
+#else    
+       this->bufferHasMyEndianness = false;
+#endif
+} /* end of MessageBuffer::assumeBufferIsBigEndian() */
+
+void MessageBuffer::assumeBufferIsLittleEndian() {
+#ifdef HOST_IS_BIG_ENDIAN
+       this->bufferHasMyEndianness = false;
+#else    
+       this->bufferHasMyEndianness = true;
+#endif    
+} /* end of MessageBuffer::assumeBufferIsLittleEndian() */
+
+void MessageBuffer::resetBuffer() {
+       bufferHasMyEndianness = true;
+       writeOffset = 0;
+       readOffset = 0;
+} /* MessageBuffer::resetBuffer() */
+
+int32_t MessageBuffer::write_uint8s(const uint8_t* data, uint32_t n) {
+
+       if (n >= (bufferMaxSize - writeOffset)) {
+               /* reallocate buffer on-demand */
+               reallocate(bufferMaxSize+ (n-(bufferMaxSize-writeOffset))
+                               + DEFAULT_MESSAGE_BUFFER_SIZE);
+       }
+       /* copy data */
+       memcpy(buffer+writeOffset, data, n);
+       /* update write offset */
+       writeOffset += n;
+       return (writeOffset-n);
+} /* end of MessageBuffer::write_uint8s(uint8_t*, uint32_t) */
+
+int32_t MessageBuffer::read_uint8s(uint8_t* data, uint32_t n) {
+
+       if (n + readOffset > writeOffset) {
+               std::stringstream smsg;
+               smsg << __func__ << "invalid read of siwritePtrze <" << n
+                               << "> inside a buffer of readable size <"
+                               << (int32_t)writeOffset-readOffset << "> 
(writeOffset="
+                               <<writeOffset << ",readOffset="<<readOffset 
<<").";
+               throw RTIinternalError(smsg.str().c_str());
+       }
+
+       memcpy(data, buffer+readOffset, n);
+       readOffset += n;
+       return (readOffset-n);
+} /* end of MessageBuffer::read_uint8s(uint8_t*, uint32_t) */
+
+int32_t MessageBuffer::write_uint16s(const uint16_t* data, uint32_t n) {
+       uint32_t i;
+       uint16_t* buffer_uint16;
+
+       if ((2*n) >= (bufferMaxSize - writeOffset)) {
+               /* reallocate buffer on-demand */
+               reallocate(bufferMaxSize+ (2*n)-(bufferMaxSize - writeOffset)
+                               + DEFAULT_MESSAGE_BUFFER_SIZE);
+       }
+
+       /* do not swap byte if it is not necessary */
+       if (bufferHasMyEndianness) {
+               memcpy(buffer+writeOffset, data, 2*n);
+               writeOffset += 2*n;
+       } else {
+               buffer_uint16 = reinterpret_cast<uint16_t*>(buffer+writeOffset);
+               for (i=0; i<n; ++i) {
+                       buffer_uint16[i] = CERTI_UINT16_SWAP_BYTES(data[i]);
+                       writeOffset += 2;
+               }
+       }
+       return (writeOffset-2*n);
+} /* end of MessageBuffer::write_uint16s(uint16_t*, uint32_t) */
+
+int32_t MessageBuffer::read_uint16s(uint16_t* data, uint32_t n) {
+       uint32_t i;
+       uint16_t* buffer_uint16;
+
+       if (2*n + readOffset > writeOffset) {
+               std::stringstream smsg;
+               smsg << __func__ << "invalid read of size <" << 2*n
+                               << "> inside a buffer of readable size <"
+                               << (int32_t)writeOffset-readOffset << "> 
(writeOffset="
+                               <<writeOffset << ",readOffset="<<readOffset 
<<").";
+               throw RTIinternalError(smsg.str().c_str());
+       }
+
+       /* do not swap byte if it is not necessary */
+       if (bufferHasMyEndianness) {
+               memcpy(data, buffer+readOffset, 2*n);
+               readOffset += 2*n;
+       } else {
+               buffer_uint16 = reinterpret_cast<uint16_t*>(buffer+readOffset);
+               for (i=0; i<n; ++i) {
+                       data[i] = CERTI_UINT16_SWAP_BYTES(buffer_uint16[i]);
+                       readOffset += 2;
+               }
+       }
+       return (readOffset-2*n);
+} /* end of MessageBuffer::read_uint16s(uint16_t*, uint32_t) */
+
+int32_t MessageBuffer::write_uint32s(const uint32_t* data, uint32_t n) {
+       uint32_t i;
+       uint32_t* buffer_uint32;
+
+       if ((4*n) >= (bufferMaxSize - writeOffset)) {
+               /* reallocate buffer on-demand */
+               reallocate(bufferMaxSize+ (4*n)-(bufferMaxSize - writeOffset)
+                               + DEFAULT_MESSAGE_BUFFER_SIZE);
+       }
+
+       /* do not swap byte if it is not necessary */
+       if (bufferHasMyEndianness) {
+               memcpy(buffer+writeOffset, data, 4*n);
+               writeOffset += 4*n;
+       } else {
+               buffer_uint32 = reinterpret_cast<uint32_t*>(buffer+writeOffset);
+               for (i=0; i<n; ++i) {
+                       buffer_uint32[i] = CERTI_UINT32_SWAP_BYTES(data[i]);
+                       writeOffset += 4;
+               }
+       }
+       return (writeOffset-4*n);
+} /* end of write_uint32s */
+
+int32_t MessageBuffer::read_uint32s(uint32_t* data, uint32_t n) {
+       uint32_t i;
+       uint32_t* buffer_uint32;
+
+       if (4*n + readOffset > writeOffset) {
+               std::stringstream smsg;
+               smsg << __func__ << "invalid read of size <" << 4*n
+                               << "> inside a buffer of readable size <"
+                               << (int32_t)writeOffset-readOffset << "> 
(writeOffset="
+                               <<writeOffset << ",readOffset="<<readOffset 
<<").";
+               throw RTIinternalError(smsg.str().c_str());
+       }
+
+       /* do not swap byte if it is not necessary */
+       if (bufferHasMyEndianness) {
+               memcpy(data, buffer+readOffset, 4*n);
+               readOffset += 4*n;
+       } else {
+               buffer_uint32 = reinterpret_cast<uint32_t*>(buffer+readOffset);
+               for (i=0; i<n; ++i) {
+                       data[i] = CERTI_UINT32_SWAP_BYTES(buffer_uint32[i]);
+                       readOffset += 4;
+               }
+       }
+       return (readOffset-4*n);
+}
+
+int32_t MessageBuffer::write_uint64s(const uint64_t* data, uint32_t n) {
+       uint32_t i;
+       uint32_t* buffer_uint32;
+       const uint32_t* data32;
+
+       if ((8*n) >= (bufferMaxSize - writeOffset)) {
+               /* reallocate buffer on-demand */
+               reallocate(bufferMaxSize+ (8*n)-(bufferMaxSize - writeOffset)
+                               + DEFAULT_MESSAGE_BUFFER_SIZE);
+       }
+
+       /* do not swap byte if it is not necessary */
+       if (bufferHasMyEndianness) {
+               memcpy(buffer+writeOffset, data, 8*n);
+               writeOffset += 8*n;
+       } else {
+               buffer_uint32 = reinterpret_cast<uint32_t*>(buffer+writeOffset);
+               data32 = reinterpret_cast<const uint32_t*>(data);
+               for (i=0; i<2*n; ++i) {
+                       buffer_uint32[i] = CERTI_UINT32_SWAP_BYTES(data32[i]);
+                       writeOffset += 4;
+               }
+       }
+       return (writeOffset-8*n);
+}
+
+int32_t MessageBuffer::read_uint64s(uint64_t* data, uint32_t n) {
+       uint32_t i;
+       uint32_t* buffer_uint32;
+       uint32_t* data32;
+
+       if (8*n + readOffset > writeOffset) {
+               std::stringstream smsg;
+               smsg << __func__ << "invalid read of size <" << 4*n
+                               << "> inside a buffer of readable size <"
+                               << (int32_t)writeOffset-readOffset << "> 
(writeOffset="
+                               <<writeOffset << ",readOffset="<<readOffset 
<<").";
+               throw RTIinternalError(smsg.str().c_str());
+       }
+
+       /* do not swap byte if it is not necessary */
+       if (bufferHasMyEndianness) {
+               memcpy(data, buffer+readOffset, 8*n);
+               readOffset += 8*n;
+       } else {
+               buffer_uint32 = reinterpret_cast<uint32_t*>(buffer+readOffset);
+               data32 = reinterpret_cast<uint32_t*>(data);
+               for (i=0; i<2*n; ++i) {
+                       data32[i] = CERTI_UINT32_SWAP_BYTES(buffer_uint32[i]);
+                       readOffset += 4;
+               }
+       }
+       return (readOffset-8*n);
+}
+
+int32_t MessageBuffer::write_floats(const float* data, uint32_t n) {
+       const uint32_t* data32;
+       data32 = reinterpret_cast<const uint32_t*>(data);       
+       return write_uint32s(data32,n);
+}
+
+int32_t MessageBuffer::read_floats(float* data, uint32_t n) {
+       uint32_t* data32;
+       data32 = reinterpret_cast<uint32_t*>(data);     
+       return read_uint32s(data32,n);  
+}
+
+int32_t MessageBuffer::write_doubles(const double* data, uint32_t n) {
+       const uint64_t* data64;
+       data64 = reinterpret_cast<const uint64_t*>(data);       
+       return write_uint64s(data64,n); 
+}
+
+int32_t MessageBuffer::read_doubles(double* data, uint32_t n) {
+       uint64_t* data64;
+       data64 = reinterpret_cast<uint64_t*>(data);     
+       return read_uint64s(data64,n);
+}
+
+} // certi
+

Index: libCERTI/MessageBuffer.hh
===================================================================
RCS file: libCERTI/MessageBuffer.hh
diff -N libCERTI/MessageBuffer.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libCERTI/MessageBuffer.hh   14 Feb 2008 15:29:58 -0000      3.1
@@ -0,0 +1,218 @@
+// ----------------------------------------------------------------------------
+// CERTI - HLA RunTime Infrastructure
+// Copyright (C) 2002-2005  ONERA
+//
+// This program is free software ; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation ; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY ; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program ; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// ----------------------------------------------------------------------------
+
+#ifndef LIBCERTI_MESSAGE_BUFFER_HH
+#define LIBCERTI_MESSAGE_BUFFER_HH
+
+#include "certi.hh"
+#include <string>
+
+#define DEFAULT_MESSAGE_BUFFER_SIZE 255
+
+namespace certi {
+
+/**
+ * MessageBuffer is a class managing a byte buffer for Message exchange.
+ * It provides member functions to read and write basics types
+ * [unsigned] int 8/16/32/64, float, double, byte etc...
+ * The message buffer will encode the written [type] data with proper
+ * byte ordering and padding.
+ * A message buffer handles heterogeneous write/read pair, in fact
+ * it the central class for heterogeneity handling.
+ * One must read from the buffer in the exact order the write was done.
+ * MessageBuffer is dynamically sized.
+ */
+class MessageBuffer
+{
+public:
+  /**
+   * Default message buffer constructor.
+   * The default message buffer size is DEFAULT_MESSAGE_BUFFER_SIZE.
+   */
+  MessageBuffer();
+
+  /**
+   * Constructor with size.
+   * Build a MessageBuffer with provisionned bufSize buffer.
+   * @param[in] bufferMaxSize, the [initial] maixmum size of the buffer
+   */
+  MessageBuffer(uint32_t bufferMaxSize);
+  
+  /**
+   * Destructor 
+   */
+  ~MessageBuffer();  
+  
+  /**
+   * Return the current buffer size (in bytes).
+   * This is the size in bytes 
+   * of the element that were written to the buffer.
+   * @return the current buffer size
+   */
+  uint32_t size() const;                                       
+
+  /**
+   * Return the current maximum buffer size (in bytes).
+   * This is the size of the allocated buffer.
+   * @return the current buffer maximum size
+   */
+  uint32_t maxSize() const;
+
+  /**
+   * Assume the buffer is big endian.
+   */
+  void
+  assumeBufferIsBigEndian();
+
+  /**
+   * Assume the buffer is little endian.
+   */
+  void
+  assumeBufferIsLittleEndian();
+
+  /**
+   * Reset buffer state
+   * This method should be called if ones want
+   * to re-use a buffer in order to avoid reallocation.
+   */
+  void 
+  resetBuffer();
+  
+#define DECLARE_SIGNED(type)                           \
+  int32_t                                              \
+  write_##type##s(const type##_t* data, uint32_t n) {          \
+    write_u##type##s(reinterpret_cast<const u##type##_t*>(data),n);    \
+  }                                                    \
+                                                       \
+  int32_t                                              \
+  read_##type##s(type##_t* data, uint32_t n) {         \
+    read_u##type##s(reinterpret_cast<u##type##_t*>(data),n);   \
+  }                                                    \
+    
+#define DECLARE_SINGLE_READ_WRITE(type,suffix)     \
+  int32_t                                              \
+  write_##type(const type##suffix data) {              \
+    return write_##type##s(&data,1);   \
+  }                                                    \
+                                                       \
+  int32_t                                              \
+  read_##type(type##suffix* data) {            \
+    read_##type##s(data,1);    \
+  }        
+      
+  int32_t 
+  write_uint8s(const uint8_t* data, uint32_t n);
+  
+  int32_t 
+  read_uint8s(uint8_t* data, uint32_t n);
+
+  DECLARE_SINGLE_READ_WRITE(uint8,_t)
+  DECLARE_SIGNED(int8)
+  DECLARE_SINGLE_READ_WRITE(int8,_t)
+  
+  int32_t
+  write_chars(const char* data, uint32_t n) {
+         return write_uint8s(reinterpret_cast<const uint8_t*>(data),n);
+  }
+  
+  int32_t
+  read_chars(char* data, uint32_t n) {
+         return read_uint8s(reinterpret_cast<uint8_t*>(data),n);
+  }
+  DECLARE_SINGLE_READ_WRITE(char,)
+
+#define write_bytes  write_chars
+#define read_bytes   read_chars
+#define write_byte   write_char
+#define read_byte    read_char
+
+  int32_t 
+  write_uint16s(const uint16_t* data, uint32_t n);
+  int32_t 
+  read_uint16s(uint16_t* data, uint32_t n);
+  
+  DECLARE_SINGLE_READ_WRITE(uint16,_t)
+  DECLARE_SIGNED(int16)
+  DECLARE_SINGLE_READ_WRITE(int16,_t)
+
+  int32_t 
+  write_uint32s(const uint32_t* data, uint32_t n);
+
+  int32_t 
+  read_uint32s(uint32_t* data, uint32_t n);
+  
+  DECLARE_SINGLE_READ_WRITE(uint32,_t)
+  DECLARE_SIGNED(int32)
+  DECLARE_SINGLE_READ_WRITE(int32,_t)
+
+  int32_t 
+  write_uint64s(const uint64_t* data, uint32_t n);
+  int32_t 
+  read_uint64s(uint64_t* data, uint32_t n);
+
+  DECLARE_SINGLE_READ_WRITE(uint64,_t)      
+  DECLARE_SIGNED(int64)
+  DECLARE_SINGLE_READ_WRITE(int64,_t)  
+    
+  int32_t
+  write_floats(const float* data, uint32_t n);
+  int32_t
+  read_floats(float* data, uint32_t n);
+  
+  DECLARE_SINGLE_READ_WRITE(float,)
+  
+  int32_t
+  write_doubles(const double* data, uint32_t n);
+  int32_t
+  read_doubles(double* data, uint32_t n);
+  
+  DECLARE_SINGLE_READ_WRITE(double,)    
+  
+  MessageBuffer& operator<<(uint8_t data) {
+         this->write_uint8(data);
+         return *this;
+  }
+
+private: 
+  /** The buffer itself */
+  uint8_t*         buffer;  
+  /** The provisioned buffer size */
+  uint32_t        bufferMaxSize;
+  /** Endianness toggle */
+  bool             bufferHasMyEndianness;
+  /** 
+   * The write offset is the offset of the buffer
+   * where the next write operation will write to.
+   */
+  uint32_t        writeOffset;
+  /** 
+   * The read offset is the offset of the buffer
+   * where the next read operation will read from.
+   */
+  uint32_t        readOffset;
+
+  void initialize();
+  void reallocate(uint32_t n);
+};
+
+} // certi
+
+#endif // LIBCERTI_MESSAGE_BUFFER_HH
+




reply via email to

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