4 #include <netinet/in.h>
11 #include "carma/util/ByteBuffer.h"
12 #include "carma/correlator/lib/CorrelatorPolarization.h"
44 void serialIntoByteBuffer(
ByteBuffer & byteBuffer )
const;
46 void serialIntoByteArray(
char * byteArray,
48 int * totalSerialBytes )
const;
50 int getTotalSerialBytes( )
const;
57 void deserial(
const char * byteArray,
int byteArraySize );
58 void deserial( const ::std::vector< char > & byteVec );
65 int *
const offset )
const;
79 int * offset )
const = 0;
91 int byteArraySize ) = 0;
93 virtual void deserializeVer1(
const char * byteArray,
95 int byteArraySize ) = 0;
107 int byteArraySize ) = 0;
109 virtual void deserializeSwapVer1(
const char * byteArray,
111 int byteArraySize ) = 0;
113 template <
typename T >
114 static void pack( const ::std::vector< T > & tmpv,
118 template <
typename T >
119 static void pack(
const T tmp,
123 template <
typename T >
124 static void unpack( T & val,
125 const char * byteArray,
129 template <
typename T >
130 static void unpack( ::std::vector< T > & tmpv,
131 const char * byteArray,
135 static void unpackSwap(
char& val,
136 const char * byteArray,
140 static void unpackSwap(
bool& val,
141 const char * byteArray,
145 static void unpackSwap(
short& val,
146 const char * byteArray,
150 static void unpackSwap(
int& val,
151 const char * byteArray,
155 static void unpackSwap(
long& val,
156 const char * byteArray,
160 static void unpackSwap(
float& val,
161 const char * byteArray,
165 static void unpackSwap(
double& val,
166 const char * byteArray,
170 static void unpackSwap( ::std::complex< float > & tmpv,
171 const char * byteArray,
175 static void unpackSwap( ::std::vector< short > & tmpv,
176 const char * byteArray,
180 static void unpackSwap( ::std::vector< int > & tmpv,
181 const char * byteArray,
185 static void unpackSwap( ::std::vector< float > & tmpv,
186 const char * byteArray,
190 static void unpackSwap( ::std::vector< ::std::complex< float > > & tmpv,
191 const char * byteArray,
195 static void unpackSwap(
unsigned int & tmpv,
const char * byteArray,
199 static void unpackSwap( carma::correlator::lib::Polarization & val,
200 const char * byteArray,
204 static int32_t getVersion();
206 static int32_t version_;
217 static bool isLittleEndian( );
219 static void swapAnyBytes(
void * in,
size_t size );
221 template <
typename T >
222 static T swapBytes( T val );
224 static void throwByteArrayTooSmallError(
int neededBytes,
227 static void throwByteArrayOverrunError(
int bufferSize,
230 static void preemptivelyCheckForByteArrayOverrun(
int maxBufferSize,
238 carma::util::Serializable::isLittleEndian( )
241 const int b = htonl(a);
250 carma::util::Serializable::swapAnyBytes(
void *
const in,
253 char *
const tmp =
static_cast< char *
>( in );
254 const size_t halfSize = (size >> 1);
255 for (
size_t i = 0; i < halfSize; ++i ) {
256 const size_t j = size - 1 - i;
257 const char t = tmp[i];
264 template <
typename T >
266 carma::util::Serializable::swapBytes( T val )
269 swapAnyBytes( static_cast< void * >( &tmp ),
sizeof( T ) );
275 template <
typename T >
277 carma::util::Serializable::pack( const ::std::vector< T > & tmpv,
278 char *
const byteArray,
281 const size_t size = tmpv.size() *
sizeof( T );
282 memcpy(&(byteArray[*offset]), &tmpv[0], size);
287 template <
typename T >
289 carma::util::Serializable::pack(
const T tmp,
290 char *
const byteArray,
293 const size_t size =
sizeof( T );
294 memcpy( &(byteArray[*offset]), &tmp, size );
299 template <
typename T >
301 carma::util::Serializable::unpack( T & val,
302 const char *
const byteArray,
304 const int byteArraySize )
306 const int size =
sizeof( val );
307 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
308 memcpy( &val, &(byteArray[*offset]), size );
313 template <
typename T >
315 carma::util::Serializable::unpack( ::std::vector< T > & tmpv,
316 const char *
const byteArray,
318 const int byteArraySize )
320 const int size = tmpv.size() *
sizeof( T );
321 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
322 memcpy(&tmpv[0], &(byteArray[*offset]), size);
328 carma::util::Serializable::unpackSwap(
char& val,
329 const char *
const byteArray,
331 const int byteArraySize )
333 unpack(val, byteArray, offset, byteArraySize );
338 carma::util::Serializable::unpackSwap(
bool& val,
339 const char *
const byteArray,
341 const int byteArraySize )
343 unpack(val, byteArray, offset, byteArraySize );
348 carma::util::Serializable::unpackSwap(
short& val,
349 const char *
const byteArray,
351 const int byteArraySize )
353 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset +
sizeof(val) );
354 memcpy(&val, &(byteArray[*offset]),
sizeof(val));
355 val = swapBytes(val);
356 *offset +=
sizeof(val);
361 carma::util::Serializable::unpackSwap(
int& val,
362 const char *
const byteArray,
364 const int byteArraySize )
366 long lval =
static_cast< long >(val);
367 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset +
sizeof(lval));
368 memcpy(&lval, &(byteArray[*offset]),
sizeof(lval));
369 lval = swapBytes(lval);
370 val =
static_cast< int >(lval);
371 *offset +=
sizeof(lval);
375 carma::util::Serializable::unpackSwap(
unsigned int& val,
376 const char *
const byteArray,
378 const int byteArraySize )
380 long lval =
static_cast< long >(val);
381 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset +
sizeof(lval));
382 memcpy(&lval, &(byteArray[*offset]),
sizeof(lval));
383 lval = swapBytes(lval);
384 val =
static_cast< int >(lval);
385 *offset +=
sizeof(lval);
389 carma::util::Serializable::unpackSwap(
long& val,
390 const char *
const byteArray,
392 const int byteArraySize )
394 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset +
sizeof(val));
395 memcpy(&val, &(byteArray[*offset]),
sizeof(val));
396 val = swapBytes(val);
397 *offset +=
sizeof(val);
402 carma::util::Serializable::unpackSwap(
float& val,
403 const char *
const byteArray,
405 const int byteArraySize )
407 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset +
sizeof(val));
408 memcpy(&val, &(byteArray[*offset]),
sizeof(val));
409 val = swapBytes(val);
410 *offset +=
sizeof(val);
414 carma::util::Serializable::unpackSwap(
double& val,
415 const char *
const byteArray,
417 const int byteArraySize )
419 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset +
sizeof(val));
420 memcpy(&val, &(byteArray[*offset]),
sizeof(val));
421 val = swapBytes(val);
422 *offset +=
sizeof(val);
427 carma::util::Serializable::unpackSwap(std::complex<float>& tmpv,
428 const char *
const byteArray,
430 const int byteArraySize )
432 int size =
sizeof(std::complex<float>);
433 int size2 =
static_cast< int >(size * .5);
438 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
440 memcpy(&real, &(byteArray[*offset]), size2);
441 real = swapBytes(real);
443 memcpy(&imag, &(byteArray[*offset]), size2);
444 imag = swapBytes(imag);
447 tmpv = std::complex<float>(real, imag);
452 carma::util::Serializable::unpackSwap(std::vector<short>& tmpv,
453 const char *
const byteArray,
455 const int byteArraySize )
457 int size = tmpv.size() *
sizeof(short);
458 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
459 memcpy(&tmpv[0], &(byteArray[*offset]), size);
460 for (
unsigned int idx = 0; idx < tmpv.size(); ++idx)
461 tmpv[idx] = swapBytes(tmpv[idx]);
467 carma::util::Serializable::unpackSwap(std::vector<int>& tmpv,
468 const char *
const byteArray,
470 const int byteArraySize )
472 int size = tmpv.size() *
sizeof(int);
473 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
474 memcpy(&tmpv[0], &(byteArray[*offset]), size);
475 for (
unsigned int idx = 0; idx < tmpv.size(); ++idx)
476 tmpv[idx] = swapBytes(tmpv[idx]);
482 carma::util::Serializable::unpackSwap(std::vector<float>& tmpv,
483 const char *
const byteArray,
485 const int byteArraySize )
487 int size = tmpv.size() *
sizeof(float);
488 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
489 memcpy(&tmpv[0], &(byteArray[*offset]), size);
490 for (
unsigned int idx = 0; idx < tmpv.size(); ++idx)
491 tmpv[idx] = swapBytes(tmpv[idx]);
497 carma::util::Serializable::unpackSwap(std::vector<std::complex<float> >& tmpv,
498 const char *
const byteArray,
500 const int byteArraySize )
502 int length = tmpv.size();
503 int size = length *
sizeof( std::complex<float> );
504 int size2 =
sizeof(float);
506 preemptivelyCheckForByteArrayOverrun( byteArraySize, *offset + size );
510 for (
int idx = 0; idx < length; ++idx) {
511 memcpy(&real, &(byteArray[*offset]), size2);
512 real = swapBytes(real);
514 memcpy(&imag, &(byteArray[*offset]), size2);
515 imag = swapBytes(imag);
517 tmpv[idx] = std::complex<float>(real, imag);
523 carma::util::Serializable::unpackSwap( carma::correlator::lib::Polarization& val,
524 const char *
const byteArray,
526 const int byteArraySize )
528 unpack(val, byteArray, offset, byteArraySize );
534 const int byteArraySize )
536 if ( byteArraySize == 0 )
537 throwByteArrayOverrunError( byteArraySize, 1 );
540 if ( byteArray[0] == isLittleEndian() ) {
541 unpack( version_, byteArray, &offset, byteArraySize );
542 switch ( version_ ) {
544 deserializeVer0( byteArray, &offset, byteArraySize );
548 deserializeVer1( byteArray, &offset, byteArraySize );
552 unpackSwap( version_, byteArray, &offset, byteArraySize );
553 switch ( version_ ) {
555 deserializeSwapVer0( byteArray, &offset, byteArraySize );
559 deserializeSwapVer1( byteArray, &offset, byteArraySize );
568 deserial( &(byteVec[0]), byteVec.size() );
575 deserial( byteBuffer.get(), byteBuffer.size() );
580 carma::util::Serializable::getTotalSerialBytes( )
const
582 return (1 +
sizeof(
long ) + getSizeInBytes());
588 ::std::vector< char > & byteVec )
const
590 byteVec.resize( getTotalSerialBytes() );
592 char *
const byteArray = &(byteVec[0]);
595 byteArray[0] = isLittleEndian();
600 const int32_t version = 2;
601 pack( version, byteArray, &offset );
604 mySerialize( byteArray, &offset );
609 carma::util::Serializable::serialIntoByteBuffer(
614 char *
const byteArray = byteBuffer.
get();
617 byteArray[0] = isLittleEndian();
622 const int32_t version = 2;
623 pack( version, byteArray, &offset );
626 mySerialize( byteArray, &offset );
631 carma::util::Serializable::serialIntoByteArray(
632 char *
const byteArray,
633 const int byteArraySize,
634 int *
const totalSerialBytes )
const
636 const int totalNeededBytes = getTotalSerialBytes();
638 if ( totalNeededBytes > byteArraySize ) {
639 throwByteArrayTooSmallError( totalNeededBytes, byteArraySize );
642 byteArray[0] = isLittleEndian();
647 const int32_t version = 2;
648 pack( version, byteArray, &offset );
651 mySerialize( byteArray, &offset );
653 if ( totalSerialBytes != 0 )
654 *totalSerialBytes = totalNeededBytes;
661 int *
const offset )
const
663 mySerialize( byteArray, offset );
668 carma::util::Serializable::preemptivelyCheckForByteArrayOverrun(
669 const int maxBufferSize,
670 const int futureOffset )
672 if ( futureOffset > maxBufferSize )
673 throwByteArrayOverrunError( maxBufferSize,
char * get() const
Get the present pointer to the buffer.
Abstract Class used to allow object to serialize themselves into a byte array.
void serialize(char *const byteArray, int *const offset) const
Write objects data members into a byte array.
virtual void deserializeSwapVer0(const char *byteArray, int *offset, int byteArraySize)=0
Called to continue the reconstruction of member objects from the byte Array.
virtual int getSizeInBytes() const =0
Return size in bytes of object.
virtual void deserializeVer0(const char *byteArray, int *offset, int byteArraySize)=0
Called to continue the reconstruction of member objects from the byte Array.
void destructiveResize(size_t count)
Resize the buffer.
void serialIntoByteVec(::std::vector< char > &byteVec) const
Write objects data members into a byte vector.
void deserial(const char *byteArray, int byteArraySize)
Call to initiate the reconstruction of the object from the byte Array.
virtual void mySerialize(char *byteArray, int *offset) const =0
Called by serialize().
Manages a (possibly destructively) resizable buffer of raw bytes.