Serializer.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #include "DCPS/DdsDcps_pch.h" //Only the _pch include should start with DCPS/
00009 #include "Serializer.h"
00010 #include <tao/String_Alloc.h>
00011 #include <ace/OS_NS_string.h>
00012 #include <ace/OS_Memory.h>
00013 
00014 #if !defined (__ACE_INLINE__)
00015 # include "Serializer.inl"
00016 #endif /* !__ACE_INLINE__ */
00017 
00018 namespace OpenDDS {
00019 namespace DCPS {
00020 
00021 const char Serializer::ALIGN_PAD[] = {0};
00022 
00023 bool Serializer::use_rti_serialization_(false);
00024 
00025 Serializer::Serializer(ACE_Message_Block* chain,
00026                        bool swap_bytes, Alignment align)
00027   : current_(chain)
00028   , swap_bytes_(swap_bytes)
00029   , good_bit_(true)
00030   , alignment_(align)
00031   , align_rshift_(chain ? ptrdiff_t(chain->rd_ptr()) % MAX_ALIGN : 0)
00032   , align_wshift_(chain ? ptrdiff_t(chain->wr_ptr()) % MAX_ALIGN : 0)
00033 {
00034 }
00035 
00036 Serializer::~Serializer()
00037 {
00038 }
00039 
00040 void
00041 Serializer::reset_alignment()
00042 {
00043   align_rshift_ = current_ ? ptrdiff_t(current_->rd_ptr()) % MAX_ALIGN : 0;
00044   align_wshift_ = current_ ? ptrdiff_t(current_->wr_ptr()) % MAX_ALIGN : 0;
00045 }
00046 
00047 void
00048 Serializer::smemcpy(char* to, const char* from, size_t n)
00049 {
00050     (void) ACE_OS::memcpy(
00051       reinterpret_cast<void*>(to),
00052       reinterpret_cast<const void*>(from),
00053       n);
00054 }
00055 
00056 void
00057 Serializer::swapcpy(char* to, const char* from, size_t n)
00058 {
00059   // Unroll the loop...
00060   switch (n) {               // 2   4   8   16
00061   case 16:
00062     to[ 15] = from[ n - 16]; // x   x   x    0
00063   case 15:
00064     to[ 14] = from[ n - 15]; // x   x   x    1
00065   case 14:
00066     to[ 13] = from[ n - 14]; // x   x   x    2
00067   case 13:
00068     to[ 12] = from[ n - 13]; // x   x   x    3
00069   case 12:
00070     to[ 11] = from[ n - 12]; // x   x   x    4
00071   case 11:
00072     to[ 10] = from[ n - 11]; // x   x   x    5
00073   case 10:
00074     to[  9] = from[ n - 10]; // x   x   x    6
00075   case  9:
00076     to[  8] = from[ n -  9]; // x   x   x    7
00077   case  8:
00078     to[  7] = from[ n -  8]; // x   x   0    8
00079   case  7:
00080     to[  6] = from[ n -  7]; // x   x   1    9
00081   case  6:
00082     to[  5] = from[ n -  6]; // x   x   2   10
00083   case  5:
00084     to[  4] = from[ n -  5]; // x   x   3   11
00085   case  4:
00086     to[  3] = from[ n -  4]; // x   0   4   12
00087   case  3:
00088     to[  2] = from[ n -  3]; // x   1   5   13
00089   case  2:
00090     to[  1] = from[ n -  2]; // 0   2   6   14
00091   case  1:
00092     to[  0] = from[ n -  1]; // 1   3   7   15
00093   case  0:
00094     return;
00095   default:
00096     this->good_bit_ = false;
00097   }
00098 }
00099 
00100 void
00101 Serializer::read_string(ACE_CDR::Char*& dest,
00102     ACE_CDR::Char* str_alloc(ACE_CDR::ULong),
00103     void str_free(ACE_CDR::Char*))
00104 {
00105   this->alignment_ == ALIGN_NONE ? 0 : this->align_r(sizeof(ACE_CDR::ULong));
00106   //
00107   // Ensure no bad values leave the routine.
00108   //
00109   str_free(dest);
00110   dest = 0;
00111 
00112   //
00113   // Extract the string length.
00114   //
00115   ACE_CDR::ULong length; // includes the null
00116   this->buffer_read(reinterpret_cast<char*>(&length), sizeof(ACE_CDR::ULong), this->swap_bytes());
00117 
00118   if (!this->good_bit_) {
00119     return;
00120   }
00121 
00122   //
00123   // NOTE: Maintain the ACE implementation where the length check is
00124   //       done here before the allocation even though it will be
00125   //       checked during the actual read as well.
00126   //
00127   if (length <= this->current_->total_length()) {
00128 
00129     dest = str_alloc(length - 1);
00130 
00131     if (dest == 0) {
00132       this->good_bit_ = false;
00133 
00134     } else {
00135       //
00136       // Extract the string.
00137       //
00138       this->read_char_array(dest, length);
00139     }
00140 
00141     if (!this->good_bit_) {
00142       str_free(dest);
00143       dest = 0;
00144     }
00145   }
00146 }
00147 
00148 void
00149 Serializer::read_string(ACE_CDR::WChar*& dest,
00150     ACE_CDR::WChar* str_alloc(ACE_CDR::ULong),
00151     void str_free(ACE_CDR::WChar*))
00152 {
00153   this->alignment_ == ALIGN_NONE ? 0 : this->align_r(sizeof(ACE_CDR::ULong));
00154   //
00155   // Ensure no bad values leave the routine.
00156   //
00157   str_free(dest);
00158   dest = 0;
00159 
00160   //
00161   // Extract the string length.
00162   //
00163   ACE_CDR::ULong bytecount = 0;
00164   this->buffer_read(reinterpret_cast<char*>(&bytecount),
00165                     sizeof(ACE_CDR::ULong), this->swap_bytes());
00166 
00167   if (!this->good_bit_) {
00168     return;
00169   }
00170 
00171   //
00172   // NOTE: Maintain the ACE implementation where the length check is
00173   //       done here before the allocation even though it will be
00174   //       checked during the actual read as well.
00175   //
00176   if (bytecount <= this->current_->total_length()) {
00177 
00178     const ACE_CDR::ULong length = bytecount / WCHAR_SIZE;
00179 
00180     dest = str_alloc(length);
00181 
00182     if (dest == 0) {
00183       this->good_bit_ = false;
00184       return;
00185     }
00186 
00187 #if ACE_SIZEOF_WCHAR == 2
00188     this->read_array(reinterpret_cast<char*>(dest), WCHAR_SIZE, length, SWAP_BE);
00189 #else
00190     for (size_t i = 0; i < length && this->good_bit_; ++i) {
00191       ACE_UINT16 as_utf16;
00192       this->buffer_read(reinterpret_cast<char*>(&as_utf16), WCHAR_SIZE, SWAP_BE);
00193       if (this->good_bit_) {
00194         dest[i] = as_utf16;
00195       }
00196     }
00197 #endif
00198 
00199     if (this->good_bit_) {
00200       //
00201       // Null terminate the string.
00202       //
00203       dest[length] = L'\0';
00204 
00205     } else {
00206       str_free(dest);
00207       dest = 0;
00208     }
00209   }
00210 }
00211 
00212 void
00213 Serializer::set_use_rti_serialization(bool should_use)
00214 {
00215   use_rti_serialization_ = should_use;
00216 }
00217 
00218 bool
00219 Serializer::use_rti_serialization()
00220 {
00221   return use_rti_serialization_;
00222 }
00223 
00224 } // namespace DCPS
00225 } // namespace OpenDDS

Generated on Fri Feb 12 20:05:26 2016 for OpenDDS by  doxygen 1.4.7