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 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 namespace OpenDDS {
00021 namespace DCPS {
00022 
00023 const char Serializer::ALIGN_PAD[] = {0};
00024 
00025 bool Serializer::use_rti_serialization_(false);
00026 
00027 Serializer::Serializer(ACE_Message_Block* chain,
00028                        bool swap_bytes, Alignment align)
00029   : current_(chain)
00030   , swap_bytes_(swap_bytes)
00031   , good_bit_(true)
00032   , alignment_(align)
00033   , align_rshift_(chain ? ptrdiff_t(chain->rd_ptr()) % MAX_ALIGN : 0)
00034   , align_wshift_(chain ? ptrdiff_t(chain->wr_ptr()) % MAX_ALIGN : 0)
00035 {
00036 }
00037 
00038 Serializer::~Serializer()
00039 {
00040 }
00041 
00042 void
00043 Serializer::reset_alignment()
00044 {
00045   align_rshift_ = current_ ? ptrdiff_t(current_->rd_ptr()) % MAX_ALIGN : 0;
00046   align_wshift_ = current_ ? ptrdiff_t(current_->wr_ptr()) % MAX_ALIGN : 0;
00047 }
00048 
00049 void
00050 Serializer::smemcpy(char* to, const char* from, size_t n)
00051 {
00052     (void) ACE_OS::memcpy(
00053       reinterpret_cast<void*>(to),
00054       reinterpret_cast<const void*>(from),
00055       n);
00056 }
00057 
00058 void
00059 Serializer::swapcpy(char* to, const char* from, size_t n)
00060 {
00061   // Unroll the loop...
00062   switch (n) {               // 2   4   8   16
00063   case 16:
00064     to[ 15] = from[ n - 16]; // x   x   x    0
00065     // fallthrough
00066   case 15:
00067     to[ 14] = from[ n - 15]; // x   x   x    1
00068     // fallthrough
00069   case 14:
00070     to[ 13] = from[ n - 14]; // x   x   x    2
00071     // fallthrough
00072   case 13:
00073     to[ 12] = from[ n - 13]; // x   x   x    3
00074     // fallthrough
00075   case 12:
00076     to[ 11] = from[ n - 12]; // x   x   x    4
00077     // fallthrough
00078   case 11:
00079     to[ 10] = from[ n - 11]; // x   x   x    5
00080     // fallthrough
00081   case 10:
00082     to[  9] = from[ n - 10]; // x   x   x    6
00083     // fallthrough
00084   case  9:
00085     to[  8] = from[ n -  9]; // x   x   x    7
00086     // fallthrough
00087   case  8:
00088     to[  7] = from[ n -  8]; // x   x   0    8
00089     // fallthrough
00090   case  7:
00091     to[  6] = from[ n -  7]; // x   x   1    9
00092     // fallthrough
00093   case  6:
00094     to[  5] = from[ n -  6]; // x   x   2   10
00095     // fallthrough
00096   case  5:
00097     to[  4] = from[ n -  5]; // x   x   3   11
00098     // fallthrough
00099   case  4:
00100     to[  3] = from[ n -  4]; // x   0   4   12
00101     // fallthrough
00102   case  3:
00103     to[  2] = from[ n -  3]; // x   1   5   13
00104     // fallthrough
00105   case  2:
00106     to[  1] = from[ n -  2]; // 0   2   6   14
00107     // fallthrough
00108   case  1:
00109     to[  0] = from[ n -  1]; // 1   3   7   15
00110     // fallthrough
00111   case  0:
00112     return;
00113   default:
00114     this->good_bit_ = false;
00115   }
00116 }
00117 
00118 size_t
00119 Serializer::read_string(ACE_CDR::Char*& dest,
00120     ACE_CDR::Char* str_alloc(ACE_CDR::ULong),
00121     void str_free(ACE_CDR::Char*))
00122 {
00123   this->alignment_ == ALIGN_NONE ? 0 : this->align_r(sizeof(ACE_CDR::ULong));
00124   //
00125   // Ensure no bad values leave the routine.
00126   //
00127   str_free(dest);
00128   dest = 0;
00129 
00130   //
00131   // Extract the string length.
00132   //
00133   ACE_CDR::ULong length; // includes the null
00134   this->buffer_read(reinterpret_cast<char*>(&length), sizeof(ACE_CDR::ULong), this->swap_bytes());
00135 
00136   if (!this->good_bit_) {
00137     return 0;
00138   }
00139 
00140   if (length == 0) {
00141     // not legal CDR, but we need to accept it since other implementations may generate this
00142     dest = str_alloc(0);
00143     return 0;
00144   }
00145 
00146   //
00147   // NOTE: Maintain the ACE implementation where the length check is
00148   //       done here before the allocation even though it will be
00149   //       checked during the actual read as well.
00150   //
00151   if (length <= this->current_->total_length()) {
00152 
00153     dest = str_alloc(length - 1);
00154 
00155     if (dest == 0) {
00156       this->good_bit_ = false;
00157 
00158     } else {
00159       //
00160       // Extract the string.
00161       //
00162       this->read_char_array(dest, length);
00163     }
00164 
00165     if (!this->good_bit_) {
00166       str_free(dest);
00167       dest = 0;
00168     }
00169 
00170   } else {
00171     good_bit_ = false;
00172   }
00173 
00174   return length - 1;
00175 }
00176 
00177 size_t
00178 Serializer::read_string(ACE_CDR::WChar*& dest,
00179     ACE_CDR::WChar* str_alloc(ACE_CDR::ULong),
00180     void str_free(ACE_CDR::WChar*))
00181 {
00182   this->alignment_ == ALIGN_NONE ? 0 : this->align_r(sizeof(ACE_CDR::ULong));
00183   //
00184   // Ensure no bad values leave the routine.
00185   //
00186   str_free(dest);
00187   dest = 0;
00188 
00189   //
00190   // Extract the string length.
00191   //
00192   ACE_CDR::ULong bytecount = 0;
00193   this->buffer_read(reinterpret_cast<char*>(&bytecount),
00194                     sizeof(ACE_CDR::ULong), this->swap_bytes());
00195 
00196   if (!this->good_bit_) {
00197     return 0;
00198   }
00199 
00200   //
00201   // NOTE: Maintain the ACE implementation where the length check is
00202   //       done here before the allocation even though it will be
00203   //       checked during the actual read as well.
00204   //
00205   ACE_CDR::ULong length = 0;
00206   if (bytecount <= this->current_->total_length()) {
00207     length = bytecount / WCHAR_SIZE;
00208     dest = str_alloc(length);
00209 
00210     if (dest == 0) {
00211       this->good_bit_ = false;
00212       return 0;
00213     }
00214 
00215 #if ACE_SIZEOF_WCHAR == 2
00216     this->read_array(reinterpret_cast<char*>(dest), WCHAR_SIZE, length, SWAP_BE);
00217 #else
00218     for (size_t i = 0; i < length && this->good_bit_; ++i) {
00219       ACE_UINT16 as_utf16;
00220       this->buffer_read(reinterpret_cast<char*>(&as_utf16), WCHAR_SIZE, SWAP_BE);
00221       if (this->good_bit_) {
00222         dest[i] = as_utf16;
00223       }
00224     }
00225 #endif
00226 
00227     if (this->good_bit_) {
00228       //
00229       // Null terminate the string.
00230       //
00231       dest[length] = L'\0';
00232     } else {
00233       str_free(dest);
00234       dest = 0;
00235       length = 0;
00236     }
00237 
00238   } else {
00239     good_bit_ = false;
00240   }
00241 
00242   return length;
00243 }
00244 
00245 void
00246 Serializer::set_use_rti_serialization(bool should_use)
00247 {
00248   use_rti_serialization_ = should_use;
00249 }
00250 
00251 bool
00252 Serializer::use_rti_serialization()
00253 {
00254   return use_rti_serialization_;
00255 }
00256 
00257 } // namespace DCPS
00258 } // namespace OpenDDS
00259 
00260 OPENDDS_END_VERSIONED_NAMESPACE_DECL
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1