tcparser.cc
来自「编译工具」· CC 代码 · 共 1,382 行 · 第 1/3 页
CC
1,382 行
f >>= obuf; break; } default: OMNIORB_ASSERT(0); }}void skipUsingTC(TypeCode_base* tc, cdrStream& buf){ tc = TypeCode_indirect::strip(tc); CORBA::Char dummy; const TypeCode_alignTable& alignTbl = tc->alignmentTable(); unsigned i = 0; // don't even ask ... just accept it. OMNIORB_ASSERT(alignTbl.entries() > 0); for( i = 0; i < alignTbl.entries(); i++ ) { switch( alignTbl[i].type ) { case TypeCode_alignTable::it_simple: buf.alignInput(alignTbl[i].simple.alignment); buf.skipInput(alignTbl[i].simple.size); break; case TypeCode_alignTable::it_nasty: { tc = alignTbl[i].nasty.tc; switch( tc->NP_kind() ) { //?? Some of these could be faster (Any, TypeCode, objref ...) case CORBA::tk_char: { buf.unmarshalOctet(); break; } case CORBA::tk_wchar: { CORBA::Octet len = buf.unmarshalOctet(); buf.skipInput(len); break; } case CORBA::tk_any: { CORBA::Any d; d <<= buf; break; } case CORBA::tk_Principal: case CORBA::tk_string: { CORBA::ULong len; len <<= buf; buf.skipInput(len); break; } case CORBA::tk_wstring: { CORBA::ULong len; len <<= buf; buf.skipInput(len); break; } case CORBA::tk_objref: { CORBA::Object_Member d; d <<= buf; break; } case CORBA::tk_TypeCode: { CORBA::TypeCode_member d; d <<= buf; break; } case CORBA::tk_union: { // Fetch the discriminator value. TypeCode_base* discrimTC = tc->NP_discriminator_type(); TypeCode_union::Discriminator discrim = TypeCode_union_helper::unmarshalLabel(discrimTC, buf); // Skip the value, using the type for the selected member. CORBA::Long i = ((TypeCode_union*)tc)->NP_index_from_discriminator(discrim); if( i >= 0 ) skipUsingTC(tc->NP_member_type(i), buf); break; } case CORBA::tk_sequence: { CORBA::ULong length; length <<= buf; if( !length ) break; TypeCode_base* elem_tc = tc->NP_content_type(); elem_tc = TypeCode_indirect::strip(elem_tc); const TypeCode_alignTable& eat = elem_tc->alignmentTable(); if( eat.is_simple() ) { // Skip as a single block. CORBA::ULong size_aligned = omni::align_to(eat[0].simple.size, eat[0].simple.alignment); buf.alignInput(eat[0].simple.alignment); buf.skipInput(eat[0].simple.size + (length - 1) * size_aligned); } else if( eat.has_only_simple() ) { // Skip the first element ... CORBA::ULong start = 0; for( unsigned j = 0; j < eat.entries(); j++ ) { start = omni::align_to(start, eat[j].simple.alignment); start += eat[j].simple.size; buf.alignInput(eat[j].simple.alignment); buf.skipInput(eat[j].simple.size); } // Calculate the size of subsequent elements ... CORBA::ULong end = start; for( unsigned k = 0; k < eat.entries(); k++ ) { end = omni::align_to(end, eat[k].simple.alignment); end += eat[k].simple.size; } // ... then skip the rest as a block. buf.skipInput((length - 1) * (end - start)); } else { // We can't do better than skipping element by element. for( CORBA::ULong j = 0; j < length; j++ ) skipUsingTC(elem_tc, buf); } break; } case CORBA::tk_array: { // If element type is_simple(), or has_only_simple() // then it will have been deal with above. We only // get here if the best we can do is to copy element // by element. CORBA::ULong length = tc->NP_length(); TypeCode_base* elemTC = tc->NP_content_type(); for( CORBA::ULong j = 0; j < length; j++ ) skipUsingTC(elemTC, buf); break; } case CORBA::tk_alias: skipUsingTC(tc->NP_content_type(), buf); break; case CORBA::tk_fixed: { CORBA::Fixed f; f.PR_setLimits(tc->NP_fixed_digits(), tc->NP_fixed_scale()); f <<= buf; break; } default: OMNIORB_ASSERT(0); } break; } default: OMNIORB_ASSERT(0); } }}//////////////////////////////////////////////////////////////////////////////////////////////////// tcParser ////////////////////////////////////////////////////////////////////////////////////////////////////void appendItem(const TypeCode_base *tc, const tcDescriptor& src, cdrStream& dest);void fetchItem(const TypeCode_base *tc, cdrStream& src, tcDescriptor& dest);voidtcParser::copyStreamToStream(const CORBA::TypeCode_ptr tc, cdrStream& src, cdrStream& dest) { if (src.unmarshal_byte_swap() == dest.marshal_byte_swap()) fastCopyUsingTC(_OMNI_NS(ToTcBase_Checked)(tc), src, dest); else copyUsingTC(_OMNI_NS(ToTcBase_Checked)(tc), src, dest);}voidtcParser::copyTcDescriptorToStream(const CORBA::TypeCode_ptr tc, const tcDescriptor &src, cdrStream& dest) { appendItem(_OMNI_NS(ToTcBase_Checked)(tc), src, dest);}voidtcParser::copyStreamToTcDescriptor(const CORBA::TypeCode_ptr tc, cdrStream& src, tcDescriptor& dest) { fetchItem(_OMNI_NS(ToTcBase_Checked)(tc), src, dest);} voidtcParser::skip(const CORBA::TypeCode_ptr tc, cdrStream &s) { skipUsingTC(_OMNI_NS(ToTcBase_Checked)(tc), s);}///////////////////////////////////////////////////////////////////////////////////////////// Internal Implementation ////////////////////////////////////////////////////////////////////////////////////////////static inline CORBA::ULong getEnumData(const tcDescriptor &tcdata) { switch (tcdata.p_enum.size) { case 1: return *((CORBA::Octet*)tcdata.p_enum.data); case 2: return *((CORBA::UShort*)tcdata.p_enum.data); default: return *((CORBA::ULong*)tcdata.p_enum.data);#ifdef HAS_LongLong case 8: return *((CORBA::ULongLong*)tcdata.p_enum.data);#endif };#ifndef __DECCXX OMNIORB_ASSERT(0);#endif // Fails if compiler has picked sizeof(enum) which is not a power of 2.}static inline void setEnumData(tcDescriptor &tcdata,const CORBA::ULong value) { switch (tcdata.p_enum.size) { case 1: *((CORBA::Octet*)tcdata.p_enum.data) = value; return; case 2: *((CORBA::UShort*)tcdata.p_enum.data) = value; return; default: *((CORBA::ULong*)tcdata.p_enum.data) = value; return;#ifdef HAS_LongLong case 8: *((CORBA::ULongLong*)tcdata.p_enum.data) = value; return;#endif };#ifndef __DECCXX OMNIORB_ASSERT(0);#endif // Fails if compiler has picked sizeof(enum) which is not a power of 2.}void appendSimpleItem(CORBA::TCKind tck, const tcDescriptor &tcdata, cdrStream& buf){ switch (tck) { // SIMPLE TYPES case CORBA::tk_short: *tcdata.p_short >>= buf; break; case CORBA::tk_ushort: *tcdata.p_ushort >>= buf; break; case CORBA::tk_long: *tcdata.p_long >>= buf; break; case CORBA::tk_ulong: *tcdata.p_ulong >>= buf; break; case CORBA::tk_float: *tcdata.p_float >>= buf; break; case CORBA::tk_double: *tcdata.p_double >>= buf; break; case CORBA::tk_boolean: buf.marshalBoolean(*tcdata.p_boolean); break; case CORBA::tk_char: buf.marshalChar(*tcdata.p_char); break; case CORBA::tk_wchar: buf.marshalWChar(*tcdata.p_wchar); break; case CORBA::tk_octet: buf.marshalOctet(*tcdata.p_octet); break; case CORBA::tk_enum: getEnumData(tcdata) >>= buf; break;#ifdef HAS_LongLong case CORBA::tk_longlong: *tcdata.p_longlong >>= buf; break; case CORBA::tk_ulonglong: *tcdata.p_ulonglong >>= buf; break;#endif#ifdef HAS_LongDouble case CORBA::tk_longdouble: *tcdata.p_longdouble >>= buf; break;#endif // OTHER TYPES default: OMNIORB_ASSERT(0); }}void appendItem(const TypeCode_base* tc, const tcDescriptor& tcdata, cdrStream& buf){ tc = TypeCode_indirect::strip(tc); // How to marshal the data depends entirely on the TypeCode switch (tc->NP_kind()) { // TYPES WITH NO DATA TO MARSHAL case CORBA::tk_null: case CORBA::tk_void: break; // SIMPLE TYPES case CORBA::tk_short: case CORBA::tk_ushort: case CORBA::tk_long: case CORBA::tk_ulong: case CORBA::tk_float: case CORBA::tk_double: case CORBA::tk_boolean: case CORBA::tk_char: case CORBA::tk_wchar: case CORBA::tk_octet: case CORBA::tk_enum:#ifdef HAS_LongLong case CORBA::tk_longlong: case CORBA::tk_ulonglong:#endif#ifdef HAS_LongDouble case CORBA::tk_longdouble:#endif appendSimpleItem(tc->NP_kind(), tcdata, buf); break; case CORBA::tk_any: *tcdata.p_any >>= buf; break; // COMPLEX TYPES case CORBA::tk_Principal: // For the principal type, the caller passes us a CORBA::PrincipalId, // which will directly marshal itself to the wire. *tcdata.p_Principal >>= buf; break; case CORBA::tk_objref: // Call the user-defined callback to get the ptr in a suitable form CORBA::Object_Helper:: marshalObjRef(tcdata.p_objref.getObjectPtr(&tcdata.p_objref), buf); break; case CORBA::tk_TypeCode: CORBA::TypeCode::marshalTypeCode(tcdata.p_TypeCode->_ptr, buf); break; case CORBA::tk_string: { buf.marshalString(*tcdata.p_string.ptr); break; } case CORBA::tk_wstring: { buf.marshalWString(*tcdata.p_wstring.ptr); break; } case CORBA::tk_fixed: { CORBA::Fixed f(*tcdata.p_fixed); f.PR_setLimits(tc->fixed_digits(), tc->fixed_scale()); f >>= buf; break; } // CONSTRUCTED TYPES case CORBA::tk_union: { tcUnionDiscriminatorType disc_val; tcDescriptor disc_desc; CORBA::PR_unionDiscriminator discrim; disc_desc.p_char = (CORBA::Char*) &disc_val; // Get a descriptor for the discriminator, and marshal it // into the buffer. tcdata.p_union.getDiscriminator(&tcdata.p_union, disc_desc, discrim); appendSimpleItem(tc->NP_discriminator_type()->kind(), disc_desc, buf); // Determine the index of the selected member. CORBA::Long index = ((TypeCode_union*)tc)->NP_index_from_discriminator(discrim); if( index < 0 ) // Implicit default, so no member. break; // Get the data. tcDescriptor data_desc; if( !tcdata.p_union.getValueDesc(&tcdata.p_union, data_desc) ) OMNIORB_ASSERT(0); appendItem(tc->NP_member_type(index), data_desc, buf); break; } case CORBA::tk_struct: { CORBA::ULong nmembers = tc->NP_member_count(); // Save the individual elements. for (CORBA::ULong i=0; i < nmembers; i++) { tcDescriptor desc; // Get a descriptor for the member. if( !tcdata.p_struct.getMemberDesc(&tcdata.p_struct, i, desc) ) OMNIORB_ASSERT(0); // Append the element to the mbuf. TypeCode_base* tctmp = tc->NP_member_type(i); appendItem(tctmp, desc, buf); } break; } case CORBA::tk_except: { // Exceptions are passed on the wire as repo id followed // by members - but for contents of Any we are only interested // in members. Therefore we copy the members only here, and // the stubs/GIOP_S code deals with the repo id. CORBA::ULong nmembers = tc->member_count(); // Save the individual elements. for (CORBA::ULong i=0; i < nmembers; i++) { tcDescriptor desc; // Get a descriptor for the member. if( !tcdata.p_except.getMemberDesc(&tcdata.p_except, i, desc) ) OMNIORB_ASSERT(0); // Append the element to the mbuf. TypeCode_base* tctmp = tc->NP_member_type(i); appendItem(tctmp, desc, buf); } break; } case CORBA::tk_sequence: { CORBA::ULong max = tcdata.p_sequence.getElementCount(&tcdata.p_sequence); TypeCode_base* tctmp = tc->NP_content_type(); tctmp = TypeCode_indirect::strip(tctmp); // Save the length of the sequence. max >>= buf; // Save the sequence data. for (CORBA::ULong i=0; i < max; i++)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?