00001
00002
00003 #include "tao/CodecFactory/CDR_Encaps_Codec.h"
00004
00005 #include "tao/CDR.h"
00006 #include "tao/OctetSeqC.h"
00007 #include "tao/AnyTypeCode/Any.h"
00008 #include "tao/AnyTypeCode/Any_Impl.h"
00009 #include "tao/AnyTypeCode/TypeCode.h"
00010 #include "tao/AnyTypeCode/Marshal.h"
00011 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00012 #include "tao/AnyTypeCode/TypeCode_Constants.h"
00013 #include "tao/SystemException.h"
00014 #include "tao/ORB_Constants.h"
00015 #include "tao/Codeset_Translator_Base.h"
00016
00017 #include "ace/Auto_Ptr.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/CORBA_macros.h"
00020
00021
00022 ACE_RCSID (CodecFactory,
00023 CDR_Encaps_Codec,
00024 "$Id: CDR_Encaps_Codec.cpp 77455 2007-02-28 12:43:12Z johnnyw $")
00025
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027
00028 TAO_CDR_Encaps_Codec::TAO_CDR_Encaps_Codec (
00029 CORBA::Octet major,
00030 CORBA::Octet minor,
00031 TAO_ORB_Core * orb_core,
00032 TAO_Codeset_Translator_Base * char_trans,
00033 TAO_Codeset_Translator_Base * wchar_trans)
00034 : major_ (major),
00035 minor_ (minor),
00036 orb_core_ (orb_core),
00037 char_translator_ (char_trans),
00038 wchar_translator_ (wchar_trans)
00039 {
00040 }
00041
00042 TAO_CDR_Encaps_Codec::~TAO_CDR_Encaps_Codec (void)
00043 {
00044 }
00045
00046 CORBA::OctetSeq *
00047 TAO_CDR_Encaps_Codec::encode (const CORBA::Any & data)
00048 {
00049 this->check_type_for_encoding (data);
00050
00051
00052
00053 TAO_OutputCDR cdr ((size_t) 0,
00054 (int) TAO_ENCAP_BYTE_ORDER,
00055 (ACE_Allocator *) 0,
00056 (ACE_Allocator *) 0,
00057 (ACE_Allocator *) 0,
00058 0,
00059 this->major_,
00060 this->minor_);
00061
00062 if (this->char_translator_)
00063 {
00064 this->char_translator_->assign (&cdr);
00065 }
00066 if (this->wchar_translator_)
00067 {
00068 this->wchar_translator_->assign (&cdr);
00069 }
00070
00071 if ((cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
00072 && (cdr << data))
00073 {
00074 CORBA::OctetSeq * octet_seq = 0;
00075
00076 ACE_NEW_THROW_EX (octet_seq,
00077 CORBA::OctetSeq,
00078 CORBA::NO_MEMORY (
00079 CORBA::SystemException::_tao_minor_code (
00080 0,
00081 ENOMEM),
00082 CORBA::COMPLETED_NO));
00083
00084 CORBA::OctetSeq_var safe_octet_seq = octet_seq;
00085
00086 octet_seq->length (static_cast<CORBA::ULong> (cdr.total_length ()));
00087 CORBA::Octet *buf = octet_seq->get_buffer ();
00088
00089 for (const ACE_Message_Block *i = cdr.begin ();
00090 i != 0;
00091 i = i->cont ())
00092 {
00093 size_t const len = i->length ();
00094 ACE_OS::memcpy (buf, i->rd_ptr (), len);
00095 buf += len;
00096 }
00097
00098 return safe_octet_seq._retn ();
00099 }
00100
00101 throw ::CORBA::MARSHAL ();
00102 }
00103
00104 CORBA::Any *
00105 TAO_CDR_Encaps_Codec::decode (const CORBA::OctetSeq & data)
00106 {
00107
00108
00109
00110
00111
00112
00113
00114
00115 ACE_Message_Block mb (data.length () + 2 * ACE_CDR::MAX_ALIGNMENT);
00116 ACE_CDR::mb_align (&mb);
00117
00118 ACE_OS::memcpy (mb.rd_ptr (), data.get_buffer (), data.length ());
00119
00120 size_t rd_pos = mb.rd_ptr () - mb.base ();
00121 size_t wr_pos = mb.wr_ptr () - mb.base () + data.length ();
00122
00123 TAO_InputCDR cdr (mb.data_block (),
00124 ACE_Message_Block::DONT_DELETE,
00125 rd_pos,
00126 wr_pos,
00127 ACE_CDR_BYTE_ORDER,
00128 this->major_,
00129 this->minor_,
00130 this->orb_core_);
00131
00132 if (this->char_translator_)
00133 {
00134 this->char_translator_->assign (&cdr);
00135 }
00136 if (this->wchar_translator_)
00137 {
00138 this->wchar_translator_->assign (&cdr);
00139 }
00140
00141 CORBA::Boolean byte_order;
00142 if (cdr >> TAO_InputCDR::to_boolean (byte_order))
00143 {
00144 cdr.reset_byte_order (static_cast<int> (byte_order));
00145
00146 CORBA::Any * any = 0;
00147 ACE_NEW_THROW_EX (any,
00148 CORBA::Any,
00149 CORBA::NO_MEMORY (
00150 CORBA::SystemException::_tao_minor_code (
00151 0,
00152 ENOMEM),
00153 CORBA::COMPLETED_NO));
00154
00155 CORBA::Any_var safe_any = any;
00156
00157 if (cdr >> (*any))
00158 return safe_any._retn ();
00159 }
00160
00161 throw IOP::Codec::FormatMismatch ();
00162 }
00163
00164 CORBA::OctetSeq *
00165 TAO_CDR_Encaps_Codec::encode_value (const CORBA::Any & data)
00166 {
00167 this->check_type_for_encoding (data);
00168
00169
00170 TAO_OutputCDR cdr ((size_t) 0,
00171 (int) TAO_ENCAP_BYTE_ORDER,
00172 (ACE_Allocator *) 0,
00173 (ACE_Allocator *) 0,
00174 (ACE_Allocator *) 0,
00175 0,
00176 this->major_,
00177 this->minor_);
00178
00179 if (this->char_translator_)
00180 {
00181 this->char_translator_->assign (&cdr);
00182 }
00183 if (this->wchar_translator_)
00184 {
00185 this->wchar_translator_->assign (&cdr);
00186 }
00187
00188 if ((cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)))
00189 {
00190 TAO::Any_Impl *impl = data.impl ();
00191
00192 if (impl->encoded ())
00193 {
00194 TAO::Unknown_IDL_Type * const unk =
00195 dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00196
00197 if (!unk)
00198 throw ::CORBA::INTERNAL ();
00199
00200
00201
00202 TAO_InputCDR for_reading (unk->_tao_get_cdr ());
00203
00204 TAO_Marshal_Object::perform_append (data._tao_get_typecode (),
00205 &for_reading,
00206 &cdr);
00207 }
00208 else
00209 {
00210 impl->marshal_value (cdr);
00211 }
00212
00213
00214
00215 CORBA::OctetSeq * octet_seq = 0;
00216
00217 ACE_NEW_THROW_EX (octet_seq,
00218 CORBA::OctetSeq,
00219 CORBA::NO_MEMORY (
00220 CORBA::SystemException::_tao_minor_code (
00221 0,
00222 ENOMEM
00223 ),
00224 CORBA::COMPLETED_NO
00225 ));
00226
00227 CORBA::OctetSeq_var safe_octet_seq = octet_seq;
00228
00229 octet_seq->length (static_cast<CORBA::ULong> (cdr.total_length ()));
00230 CORBA::Octet *buf = octet_seq->get_buffer ();
00231
00232 for (const ACE_Message_Block *i = cdr.begin ();
00233 i != 0;
00234 i = i->cont ())
00235 {
00236 size_t len = i->length ();
00237 ACE_OS::memcpy (buf,
00238 i->rd_ptr (),
00239 len);
00240 buf += len;
00241 }
00242
00243 return safe_octet_seq._retn ();
00244 }
00245
00246 throw ::CORBA::MARSHAL ();
00247 }
00248
00249 CORBA::Any *
00250 TAO_CDR_Encaps_Codec::decode_value (const CORBA::OctetSeq & data,
00251 CORBA::TypeCode_ptr tc)
00252 {
00253
00254
00255
00256
00257
00258
00259 ACE_Message_Block mb (data.length () + 2 * ACE_CDR::MAX_ALIGNMENT);
00260 ACE_CDR::mb_align (&mb);
00261
00262 ACE_OS::memcpy (mb.rd_ptr (),
00263 data.get_buffer (),
00264 data.length ());
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 size_t rd_pos = mb.rd_ptr () - mb.base ();
00280 size_t wr_pos = mb.wr_ptr () - mb.base () + data.length ();
00281
00282 TAO_InputCDR cdr (mb.data_block (),
00283 ACE_Message_Block::DONT_DELETE,
00284 rd_pos,
00285 wr_pos,
00286 ACE_CDR_BYTE_ORDER,
00287 this->major_,
00288 this->minor_,
00289 this->orb_core_);
00290
00291 if (this->char_translator_)
00292 {
00293 this->char_translator_->assign (&cdr);
00294 }
00295 if (this->wchar_translator_)
00296 {
00297 this->wchar_translator_->assign (&cdr);
00298 }
00299
00300 CORBA::Boolean byte_order;
00301
00302 if (cdr >> TAO_InputCDR::to_boolean (byte_order))
00303 {
00304 cdr.reset_byte_order (static_cast<int> (byte_order));
00305
00306 CORBA::Any * any = 0;
00307 ACE_NEW_THROW_EX (any,
00308 CORBA::Any,
00309 CORBA::NO_MEMORY (
00310 CORBA::SystemException::_tao_minor_code (
00311 0,
00312 ENOMEM
00313 ),
00314 CORBA::COMPLETED_NO
00315 ));
00316
00317 CORBA::Any_var safe_any = any;
00318
00319
00320 TAO::Unknown_IDL_Type *unk = 0;
00321 ACE_NEW_RETURN (unk,
00322 TAO::Unknown_IDL_Type (tc, cdr),
00323 0);
00324 any->replace (unk);
00325 return safe_any._retn ();
00326 }
00327
00328 throw IOP::Codec::FormatMismatch ();
00329 }
00330
00331 void
00332 TAO_CDR_Encaps_Codec::check_type_for_encoding (const CORBA::Any & data)
00333 {
00334
00335
00336 CORBA::TypeCode_var typecode = data.type ();
00337 if (this->major_ == 1
00338 && this->minor_ == 0
00339 && typecode->equivalent (CORBA::_tc_wstring))
00340 throw IOP::Codec::InvalidTypeForEncoding ();
00341 }
00342
00343 TAO_END_VERSIONED_NAMESPACE_DECL