tcparser.cc

来自「编译工具」· CC 代码 · 共 1,382 行 · 第 1/3 页

CC
1,382
字号
// -*- Mode: C++; -*-//                            Package   : omniORB// tcParser.cc                Created on: 8/1998//                            Author1   : James Weatherall (jnw)//                            Author2   : David Riddoch (djr)////    Copyright (C) 1996-1999 AT&T Laboratories Cambridge////    This file is part of the omniORB library////    The omniORB library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library is distributed in the hope that it will be useful,//    but WITHOUT ANY WARRANTY; without even the implied warranty of//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  //    02111-1307, USA////// Description://#include <omniORB4/CORBA.h>#ifdef HAS_pch#pragma hdrstop#endif#include <tcParser.h>#include <typecode.h>#include <codeSetUtil.h>OMNI_NAMESPACE_BEGIN(omni)///////////////////////////////////////////////////////////////////////////////////////////// Internal Implementation //////////////////////////////////////////////////////////////////////////////////////////////?? Further optimisations possible if source and destination have// the same alignment at any point - 'cos we can then just byte// copy EVERYTHING from there onwards.// ie. if( src_posn % 8 == dst_posn % 8 ) ...//  The only interesting question is knowing when to stop.//  Code set conversion means that we would have to stop at any char//  or wchar data.inline void fastCopyUsingTC(TypeCode_base* tc, cdrStream& ibuf, cdrStream& obuf){  // This can only be used if both streams have the same  // byte order.  // Follow any TypeCode_indirect objects created by  // ORB::create_recursive_tc().  tc = TypeCode_indirect::strip(tc);  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:      // Can copy data across as a block.      ibuf.copy_to(obuf,alignTbl[i].simple.size,		   alignTbl[i].simple.alignment);      break;    case TypeCode_alignTable::it_nasty:      { // Data is variable length or has variable alignment requirements.	tc = alignTbl[i].nasty.tc;	switch( tc->NP_kind() ) {	  //?? Some of these could be faster (Any, TypeCode, objref ...)	case CORBA::tk_char:	  {	    if (ibuf.TCS_C() == obuf.TCS_C()) {	      // No conversion necessary	      CORBA::Octet o = ibuf.unmarshalOctet(); obuf.marshalOctet(o);	    }	    else {	      omniCodeSet::UniChar uc = ibuf.TCS_C()->unmarshalChar(ibuf);	      obuf.TCS_C()->marshalChar(obuf, uc);	    }	    break;	  }	case CORBA::tk_wchar:	  {	    if (ibuf.TCS_W() == obuf.TCS_W()) {	      // No conversion necessary	      CORBA::Octet len = ibuf.unmarshalOctet();	      obuf.marshalOctet(len);	      ibuf.copy_to(obuf, len, omni::ALIGN_1);	    }	    else {	      omniCodeSet::UniChar uc = ibuf.TCS_W()->unmarshalWChar(ibuf);	      obuf.TCS_W()->marshalWChar(obuf, uc);	    }	    break;	  }	case CORBA::tk_any:	  { CORBA::Any d; d <<= ibuf; d >>= obuf; break; }	case CORBA::tk_Principal:	  {	    CORBA::ULong len;	    len <<= ibuf;	    len >>= obuf;	    ibuf.copy_to(obuf,len);	    break;	  }	case CORBA::tk_objref:	  { CORBA::Object_Member d; d <<= ibuf; d >>= obuf; break; }	case CORBA::tk_TypeCode:	  { CORBA::TypeCode_member d; d <<= ibuf; d >>= obuf; break; }	case CORBA::tk_string:	  {	    if (ibuf.TCS_C() == obuf.TCS_C()) {	      // No conversion necessary	      CORBA::ULong len;	      len <<= ibuf;	      len >>= obuf;	      ibuf.copy_to(obuf,len);	    }	    else {	      // Convert via UTF-16	      omniCodeSet::UniChar* us;	      CORBA::ULong len = ibuf.TCS_C()->unmarshalString(ibuf, 0, us);	      omniCodeSetUtil::HolderU uh(us);	      obuf.TCS_C()->marshalString(obuf, len, us);	    }	    break;	  }	case CORBA::tk_wstring:	  {	    if (ibuf.TCS_W() == obuf.TCS_W()) {	      // No conversion necessary	      CORBA::ULong len;	      len <<= ibuf;	      len >>= obuf;	      ibuf.copy_to(obuf,len);	    }	    else {	      // Convert via UTF-16	      omniCodeSet::UniChar* us;	      CORBA::ULong len = ibuf.TCS_W()->unmarshalWString(ibuf, 0, us);	      omniCodeSetUtil::HolderU uh(us);	      obuf.TCS_W()->marshalWString(obuf, len, us);	    }	    break;	  }	case CORBA::tk_union:	  {	    // Fetch and copy the discriminator value.	    TypeCode_base* discrimTC = tc->NP_discriminator_type();	    TypeCode_union::Discriminator discrim =	      TypeCode_union_helper::unmarshalLabel(discrimTC, ibuf);	    TypeCode_union_helper::marshalLabel(discrim, discrimTC, obuf);	    // Copy the value, using the type for the selected member,	    // unless we have an implicit default, in which case no	    // value is copied.	    CORBA::Long i =	      ((TypeCode_union*)tc)->NP_index_from_discriminator(discrim);	    if( i >= 0 )	      fastCopyUsingTC(tc->NP_member_type(i), ibuf, obuf);	    break;	  }	case CORBA::tk_sequence:	  {	    CORBA::ULong length; length <<= ibuf; length >>= obuf;	    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() ) {	      // Copy as a single block.	      CORBA::ULong size_aligned =		omni::align_to(eat[0].simple.size, eat[0].simple.alignment);	      ibuf.copy_to(obuf, eat[0].simple.size +			     (length - 1) * size_aligned,			     eat[0].simple.alignment);	    }	    else if( eat.has_only_simple() ) {	      // Copy 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;		ibuf.copy_to(obuf, eat[j].simple.size,			     eat[j].simple.alignment);	      }	      // 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 copy the rest as a block.	      ibuf.copy_to(obuf, (length - 1) * (end - start));	    }	    else {	      // We can't do better than copying element by element.	      for( CORBA::ULong j = 0 ; j < length; j++ )		fastCopyUsingTC(elem_tc, ibuf, obuf);	    }	    break;	  }	case CORBA::tk_array:	  {	    // If element type is_simple(), or has_only_simple()	    // then it will have been dealt 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++ )	      fastCopyUsingTC(elemTC, ibuf, obuf);	    break;	  }	case CORBA::tk_alias:	  fastCopyUsingTC(tc->NP_content_type(), ibuf, obuf);	  break;	case CORBA::tk_fixed:	  {	    CORBA::Fixed f;	    f.PR_setLimits(tc->NP_fixed_digits(), tc->NP_fixed_scale());	    f <<= ibuf;	    f >>= obuf;	    break;	  }	default:	  OMNIORB_ASSERT(0);	}	break;      }    default:      OMNIORB_ASSERT(0);    }  }}void copyUsingTC(TypeCode_base* tc, cdrStream& ibuf, cdrStream& obuf){  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:      return;      // SIMPLE TYPES    case CORBA::tk_short:      { CORBA::Short d;   d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_ushort:      { CORBA::UShort d;  d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_long:      { CORBA::Long d;    d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_ulong:      { CORBA::ULong d;   d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_float:      { CORBA::Float d;   d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_double:      { CORBA::Double d;  d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_boolean:      { CORBA::Boolean d; d = ibuf.unmarshalBoolean();         obuf.marshalBoolean(d); return; }    case CORBA::tk_octet:      { CORBA::Octet d; d = ibuf.unmarshalOctet();      obuf.marshalOctet(d); return; }    case CORBA::tk_enum:      { CORBA::ULong d;   d <<= ibuf; d >>= obuf; return; }#ifdef HAS_LongLong    case CORBA::tk_longlong:      { CORBA::LongLong d;    d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_ulonglong:      { CORBA::ULongLong d;   d <<= ibuf; d >>= obuf; return; }#endif#ifdef HAS_LongDouble    case CORBA::tk_longdouble:      { CORBA::LongDouble d;  d <<= ibuf; d >>= obuf; return; }#endif    case CORBA::tk_any:      { CORBA::Any d;     d <<= ibuf; d >>= obuf; return; }    // COMPLEX TYPES    case CORBA::tk_char:      {	if (ibuf.TCS_C() == obuf.TCS_C()) {	  // No conversion necessary	  CORBA::Octet o = ibuf.unmarshalOctet(); obuf.marshalOctet(o);	}	else {	  omniCodeSet::UniChar uc = ibuf.TCS_C()->unmarshalChar(ibuf);	  obuf.TCS_C()->marshalChar(obuf, uc);	}	return;      }    case CORBA::tk_wchar:      {	// Always do a conversion via UTF-16, to avoid the pain of	// possibly byteswapping.	omniCodeSet::UniChar uc = ibuf.TCS_W()->unmarshalWChar(ibuf);	obuf.TCS_W()->marshalWChar(obuf, uc);	return;      }    case CORBA::tk_Principal:      {	CORBA::ULong len;	len <<= ibuf;	len >>= obuf;	ibuf.copy_to(obuf,len);	return;      }    case CORBA::tk_objref:      { CORBA::Object_Member d; d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_TypeCode:      { CORBA::TypeCode_member d; d <<= ibuf; d >>= obuf; return; }    case CORBA::tk_string:      {	// Convert via UTF-16	omniCodeSet::UniChar* us;	CORBA::ULong len = ibuf.TCS_C()->unmarshalString(ibuf, 0, us);	omniCodeSetUtil::HolderU uh(us);	obuf.TCS_C()->marshalString(obuf, len, us);	return;      }          case CORBA::tk_wstring:      {	// Convert via UTF-16	omniCodeSet::UniChar* us;	CORBA::ULong len = ibuf.TCS_W()->unmarshalWString(ibuf, 0, us);	omniCodeSetUtil::HolderU uh(us);	obuf.TCS_W()->marshalWString(obuf, len, us);	return;      }    // CONSTRUCTED TYPES    case CORBA::tk_union:      {	// Fetch and copy the discriminator value	TypeCode_base* discrimTC = tc->NP_discriminator_type();	TypeCode_union::Discriminator discrim =	  TypeCode_union_helper::unmarshalLabel(discrimTC, ibuf);	TypeCode_union_helper::marshalLabel(discrim, discrimTC, obuf);	// Copy the value, using the type for the selected member,	// unless we have an implicit default, in which case no	// value is copied.	CORBA::Long i =	  ((TypeCode_union*)tc)->NP_index_from_discriminator(discrim);	if( i >= 0 )	  copyUsingTC(tc->NP_member_type(i), ibuf, obuf);	return;      }    case CORBA::tk_struct:      {	CORBA::ULong nmembers = tc->NP_member_count();	// Copy the individual elements.	for (CORBA::ULong i=0; i < nmembers; i++)	  copyUsingTC(tc->NP_member_type(i), ibuf, obuf);	return;      }        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->NP_member_count();	// Copy the individual elements.	for (CORBA::ULong i=0; i < nmembers; i++)	  copyUsingTC(tc->NP_member_type(i), ibuf, obuf);	return;      }    case CORBA::tk_sequence:      {	CORBA::ULong max; max <<= ibuf; max >>= obuf;	TypeCode_base* tctmp = tc->NP_content_type();	for (CORBA::ULong i=0; i < max; i++)	  copyUsingTC(tctmp, ibuf, obuf);	return;      }    case CORBA::tk_array:      {	CORBA::ULong max = tc->NP_length();	TypeCode_base* tctmp = tc->NP_content_type();	for (CORBA::ULong i=0; i < max; i++)	  copyUsingTC(tctmp, ibuf, obuf);	return;      }    case CORBA::tk_alias:      {	// This could be made more efficient	copyUsingTC(tc->NP_content_type(), ibuf, obuf);	return;      }    case CORBA::tk_fixed:      {	CORBA::Fixed f;	f.PR_setLimits(tc->NP_fixed_digits(), tc->NP_fixed_scale());	f <<= ibuf;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?