// -*- Mode: C++; -*- // Package : omniORB // cdrStream.h Created on: 11/1/99 // Author : Sai Lai Lo (sll) // // Copyright (C) 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: // *** PROPRIETARY INTERFACE *** // /* $Log: cdrStream.h,v $ Revision 1.1.4.17 2007/04/12 19:50:33 dgrisby A few cases of sizeof(bool) > 1 were not handled correctly. Revision 1.1.4.16 2007/02/11 23:44:59 dgrisby Value chunk stream looked at wrong byteswap flag in getLength. Revision 1.1.4.15 2006/06/06 16:39:37 dgrisby marshalRawString and chunking stream did not byte-swap length fields when required to. Revision 1.1.4.14 2006/05/21 17:43:24 dgrisby Remove obsolete pd_chunked flag. Revision 1.1.4.13 2006/05/20 16:23:37 dgrisby Minor cdrMemoryStream and TypeCode performance tweaks. Revision 1.1.4.12 2006/05/15 10:13:00 dgrisby Data was overwritten when a chunk ended with an array; make declareArrayLength() virtual. Revision 1.1.4.11 2006/04/28 18:40:46 dgrisby Merge from omni4_0_develop. Revision 1.1.4.10 2005/12/08 14:22:31 dgrisby Better string marshalling performance; other minor optimisations. Revision 1.1.4.9 2005/07/22 17:18:40 dgrisby Another merge from omni4_0_develop. Revision 1.1.4.8 2005/01/06 23:08:09 dgrisby Big merge from omni4_0_develop. Revision 1.1.4.7 2005/01/06 17:31:07 dgrisby Changes (mainly from omni4_0_develop) to compile on gcc 3.4. Revision 1.1.4.6 2004/07/23 10:29:56 dgrisby Completely new, much simpler Any implementation. Revision 1.1.4.5 2004/07/04 23:53:35 dgrisby More ValueType TypeCode and Any support. Revision 1.1.4.4 2003/11/06 11:56:55 dgrisby Yet more valuetype. Plain valuetype and abstract valuetype are now working. Revision 1.1.4.3 2003/07/10 21:52:31 dgrisby Value chunks should start after URL / repoids. Revision 1.1.4.2 2003/05/20 16:53:12 dgrisby Valuetype marshalling support. Revision 1.1.4.1 2003/03/23 21:04:17 dgrisby Start of omniORB 4.1.x development branch. Revision 1.1.2.20 2003/03/02 17:10:41 dgrisby AIX patches integrated in main tree. Revision 1.1.2.19 2002/03/14 14:39:44 dpg1 Obscure bug in objref creation with unaligned buffers. Revision 1.1.2.18 2002/03/11 12:23:03 dpg1 Tweaks to avoid compiler warnings. Revision 1.1.2.17 2001/11/14 17:13:41 dpg1 Long double support. Revision 1.1.2.16 2001/10/17 16:33:27 dpg1 New downcast mechanism for cdrStreams. Revision 1.1.2.15 2001/09/19 17:29:04 dpg1 Cosmetic changes. Revision 1.1.2.14 2001/08/22 13:29:45 dpg1 Re-entrant Any marshalling. Revision 1.1.2.13 2001/08/17 17:02:22 sll Removed static variables ncs_c, ncs_w, default_tcs_c, default_tcs_w. Revision 1.1.2.12 2001/07/31 16:32:02 sll Added virtual function is_giopStream to check if a cdrStream is a giopStream. That is, a poor man's substitute for dynamic_cast. Revision 1.1.2.11 2001/06/13 19:58:37 sll Added omni namespace scoping for omniCodeSet. Revision 1.1.2.10 2001/05/10 15:03:50 dpg1 Update cdrStreamAdapter to modified cdrStream interface. Revision 1.1.2.9 2001/04/18 17:50:44 sll Big checkin with the brand new internal APIs. Scoped where appropriate with the omni namespace. Revision 1.1.2.8 2001/01/09 17:16:59 dpg1 New cdrStreamAdapter class to allow omniORBpy to intercept buffer management. Revision 1.1.2.7 2000/12/05 17:39:31 dpg1 New cdrStream functions to marshal and unmarshal raw strings. Revision 1.1.2.6 2000/11/22 14:37:58 dpg1 Code set marshalling functions now take a string length argument. Revision 1.1.2.5 2000/11/15 17:16:23 sll Added char, wchar codeset convertor support to cdrStream. Revision 1.1.2.4 2000/11/09 12:27:49 dpg1 Huge merge from omni3_develop, plus full long long from omni3_1_develop. Revision 1.1.2.3 2000/11/03 18:49:16 sll Separate out the marshalling of byte, octet and char into 3 set of distinct marshalling functions. Renamed put_char_array and get_char_array to put_octet_array and get_octet_array. New string marshal member functions. Revision 1.1.2.2 2000/10/10 10:14:27 sll Extra ctor for cdrEncapsulationStream which initialise the buffer by fetching data from the argument cdrStream. Revision 1.1.2.1 2000/09/27 16:54:08 sll *** empty log message *** */ #ifndef __CDRSTREAM_H__ #define __CDRSTREAM_H__ #include #ifndef Swap16 #define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) #else #error "Swap16 has already been defined" #endif #ifndef Swap32 #define Swap32(l) ((((l) & 0xff000000) >> 24) | \ (((l) & 0x00ff0000) >> 8) | \ (((l) & 0x0000ff00) << 8) | \ (((l) & 0x000000ff) << 24)) #else #error "Swap32 has already been defined" #endif #ifdef HAS_LongLong #ifndef Swap64 #define Swap64(l) \ ((((l) & _CORBA_LONGLONG_CONST(0xff00000000000000)) >> 56) | \ (((l) & _CORBA_LONGLONG_CONST(0x00ff000000000000)) >> 40) | \ (((l) & _CORBA_LONGLONG_CONST(0x0000ff0000000000)) >> 24) | \ (((l) & _CORBA_LONGLONG_CONST(0x000000ff00000000)) >> 8) | \ (((l) & _CORBA_LONGLONG_CONST(0x00000000ff000000)) << 8) | \ (((l) & _CORBA_LONGLONG_CONST(0x0000000000ff0000)) << 24) | \ (((l) & _CORBA_LONGLONG_CONST(0x000000000000ff00)) << 40) | \ (((l) & _CORBA_LONGLONG_CONST(0x00000000000000ff)) << 56)) #else #error "Swap64 has already been defined" #endif #endif // Technically, we have to declare friend functions outside of the // class to put them into the global scope (this is pretty esoteric: // friend functions are not in class scope but if they are first // declared inside the class they aren't in global scope either...or // something like that...) It is too bad we have to have operators in // global scope but some compilers don't handle Koenig lookup // correctly. class cdrStream; inline void operator>>= (_CORBA_Short a, cdrStream& s); inline void operator<<= (_CORBA_Short& a, cdrStream& s); inline void operator>>= (_CORBA_UShort a, cdrStream& s); inline void operator<<= (_CORBA_UShort& a, cdrStream& s); inline void operator>>= (_CORBA_Long a, cdrStream& s); inline void operator<<= (_CORBA_Long& a, cdrStream& s); inline void operator>>= (_CORBA_ULong a, cdrStream& s); inline void operator<<= (_CORBA_ULong& a, cdrStream& s); #ifdef HAS_LongLong inline void operator>>= (_CORBA_LongLong a, cdrStream& s); inline void operator<<= (_CORBA_LongLong& a, cdrStream& s); inline void operator>>= (_CORBA_ULongLong a, cdrStream& s); inline void operator<<= (_CORBA_ULongLong& a, cdrStream& s); #endif class cdrStreamAdapter; class cdrValueChunkStream; OMNI_NAMESPACE_BEGIN(omni) class ValueIndirectionTracker { public: virtual ~ValueIndirectionTracker(); }; OMNI_NAMESPACE_END(omni) class cdrStream { public: cdrStream(); virtual ~cdrStream(); #ifndef CdrMarshal #define CdrMarshal(s,type,align,arg) do {\ again: \ omni::ptr_arith_t p1 = omni::align_to((omni::ptr_arith_t)s.pd_outb_mkr,align);\ omni::ptr_arith_t p2 = p1 + sizeof(type);\ if( (void*)p2 > s.pd_outb_end ) {\ if (s.reserveOutputSpaceForPrimitiveType(align,sizeof(type)))\ goto again;\ else {\ s.pd_outb_mkr = (void*) p2;\ break;\ }\ }\ s.pd_outb_mkr = (void*) p2;\ *((type*)p1) = arg;\ } while(0) #else #error "CdrMarshal has already been defined" #endif #ifndef CdrUnMarshal #define CdrUnMarshal(s,type,align,arg) do {\ again: \ omni::ptr_arith_t p1 = omni::align_to((omni::ptr_arith_t)s.pd_inb_mkr,align);\ omni::ptr_arith_t p2 = p1 + sizeof(type);\ if ((void *)p2 > s.pd_inb_end) {\ s.fetchInputData(align,sizeof(type));\ goto again;\ }\ s.pd_inb_mkr = (void*) p2;\ arg = *((type*)p1);\ } while(0) #else #error "CdrUnMarshal has already been defined" #endif // Macros to convert floats to integers or arrays of integers so they // may be byte-swapped. The default version uses a union to do the // conversion, but that fails for VMS which uses classes to represent // float types. The version with reinterpret_cast<> fails on some // platforms with strict aliasing. #ifndef USING_PROXY_FLOAT #define convertFromFloat(float_t, int_t) \ union { float_t a; int_t l; } u; \ u.a = a; \ int_t l = u.l #define convertToFloat(float_t, int_t) \ union { float_t a; int_t l; } u; \ u.l = l; \ a = u.a #else #define convertFromFloat(float_t, int_t) \ int_t l = OMNI_REINTERPRET_CAST(int_t, a) #define convertToFloat(float_t, int_t) \ a = OMNI_REINTERPRET_CAST(float_t, l) #endif inline void marshalChar(_CORBA_Char a) { pd_ncs_c->marshalChar(*this,pd_tcs_c,a); } inline _CORBA_Char unmarshalChar() { return pd_ncs_c->unmarshalChar(*this,pd_tcs_c); } inline void marshalWChar(_CORBA_WChar a) { pd_ncs_w->marshalWChar(*this,pd_tcs_w,a); } inline _CORBA_WChar unmarshalWChar() { return pd_ncs_w->unmarshalWChar(*this,pd_tcs_w); } inline void marshalOctet(_CORBA_Octet a) { // No need to align here do { again: omni::ptr_arith_t p1 = (omni::ptr_arith_t)pd_outb_mkr; omni::ptr_arith_t p2 = p1 + 1; if( (void*)p2 > pd_outb_end ) { if (reserveOutputSpaceForPrimitiveType(omni::ALIGN_1, 1)) goto again; else { pd_outb_mkr = (void*) p2; break; } } pd_outb_mkr = (void*) p2; *((_CORBA_Octet*)p1) = a; } while (0); } inline _CORBA_Octet unmarshalOctet() { _CORBA_Octet a; do { again: omni::ptr_arith_t p1 = (omni::ptr_arith_t)pd_inb_mkr; omni::ptr_arith_t p2 = p1 + sizeof(_CORBA_Octet); if ((void *)p2 > pd_inb_end) { fetchInputData(omni::ALIGN_1,sizeof(_CORBA_Octet)); goto again; } pd_inb_mkr = (void*) p2; a = *((_CORBA_Octet*)p1); } while(0); return a; } inline void marshalBoolean(_CORBA_Boolean b) { _CORBA_Char c = b ? 1 : 0; CdrMarshal((*this),_CORBA_Char,omni::ALIGN_1,c); } inline _CORBA_Boolean unmarshalBoolean() { _CORBA_Char c; CdrUnMarshal((*this),_CORBA_Char,omni::ALIGN_1,c); #ifdef HAS_Cplusplus_Bool return c ? true : false; #else return c; #endif } #ifndef OMNI_NO_INLINE_FRIENDS friend inline void operator>>= (_CORBA_Short a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_Short t = Swap16(a); a = t; } CdrMarshal(s,_CORBA_Short,omni::ALIGN_2,a); } friend inline void operator<<= (_CORBA_Short& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_Short,omni::ALIGN_2,a); if (s.pd_unmarshal_byte_swap) { _CORBA_Short t = Swap16(a); a = t; } } friend inline void operator>>= (_CORBA_UShort a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_UShort t = Swap16(a); a = t; } CdrMarshal(s,_CORBA_UShort,omni::ALIGN_2,a); } friend inline void operator<<= (_CORBA_UShort& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_UShort,omni::ALIGN_2,a); if (s.pd_unmarshal_byte_swap) { _CORBA_UShort t = Swap16(a); a = t; } } friend inline void operator>>= (_CORBA_Long a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_Long t = Swap32(a); a = t; } CdrMarshal(s,_CORBA_Long,omni::ALIGN_4,a); } friend inline void operator<<= (_CORBA_Long& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_Long,omni::ALIGN_4,a); if (s.pd_unmarshal_byte_swap) { _CORBA_Long t = Swap32(a); a = t; } } friend inline void operator>>= (_CORBA_ULong a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_ULong t = Swap32(a); a = t; } CdrMarshal(s,_CORBA_ULong,omni::ALIGN_4,a); } friend inline void operator<<= (_CORBA_ULong& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_ULong,omni::ALIGN_4,a); if (s.pd_unmarshal_byte_swap) { _CORBA_ULong t = Swap32(a); a = t; } } # ifdef HAS_LongLong friend inline void operator>>= (_CORBA_LongLong a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_LongLong t = Swap64(a); a = t; } CdrMarshal(s,_CORBA_LongLong,omni::ALIGN_8,a); } friend inline void operator<<= (_CORBA_LongLong& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_LongLong,omni::ALIGN_8,a); if (s.pd_unmarshal_byte_swap) { _CORBA_LongLong t = Swap64(a); a = t; } } friend inline void operator>>= (_CORBA_ULongLong a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_ULongLong t = Swap64(a); a = t; } CdrMarshal(s,_CORBA_ULongLong,omni::ALIGN_8,a); } friend inline void operator<<= (_CORBA_ULongLong& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_ULongLong,omni::ALIGN_8,a); if (s.pd_unmarshal_byte_swap) { _CORBA_ULongLong t = Swap64(a); a = t; } } # endif #else friend inline void operator>>= (_CORBA_Short a, cdrStream& s); friend inline void operator<<= (_CORBA_Short& a, cdrStream& s); friend inline void operator>>= (_CORBA_UShort a, cdrStream& s); friend inline void operator<<= (_CORBA_UShort& a, cdrStream& s); friend inline void operator>>= (_CORBA_Long a, cdrStream& s); friend inline void operator<<= (_CORBA_Long& a, cdrStream& s); friend inline void operator>>= (_CORBA_ULong a, cdrStream& s); friend inline void operator<<= (_CORBA_ULong& a, cdrStream& s); # ifdef HAS_LongLong friend inline void operator>>= (_CORBA_LongLong a, cdrStream& s); friend inline void operator<<= (_CORBA_LongLong& a, cdrStream& s); friend inline void operator>>= (_CORBA_ULongLong a, cdrStream& s); friend inline void operator<<= (_CORBA_ULongLong& a, cdrStream& s); # endif #endif #if !defined(NO_FLOAT) #ifndef OMNI_NO_INLINE_FRIENDS friend inline void operator>>= (_CORBA_Float a, cdrStream& s) { convertFromFloat(_CORBA_Float, _CORBA_ULong); if (s.pd_marshal_byte_swap) { l = Swap32(l); } CdrMarshal(s,_CORBA_ULong,omni::ALIGN_4,l); } friend inline void operator<<= (_CORBA_Float& a, cdrStream& s) { _CORBA_ULong l; CdrUnMarshal(s,_CORBA_ULong,omni::ALIGN_4,l); if (s.pd_unmarshal_byte_swap) { l = Swap32(l); } convertToFloat(_CORBA_Float, _CORBA_ULong); } friend inline void operator>>= (_CORBA_Double a, cdrStream& s) { struct LongArray2 { _CORBA_ULong l[2]; }; convertFromFloat(_CORBA_Double, LongArray2); if (s.pd_marshal_byte_swap) { LongArray2 m; m.l[0] = Swap32(l.l[1]); m.l[1] = Swap32(l.l[0]); l = m; } #ifdef OMNI_MIXED_ENDIAN_DOUBLE { _CORBA_ULong v = l.l[0]; l.l[0] = l.l[1]; l.l[1] = v; } #endif CdrMarshal(s,LongArray2,omni::ALIGN_8,l); } friend inline void operator<<= (_CORBA_Double& a, cdrStream& s) { struct LongArray2 { _CORBA_ULong l[2]; } l; CdrUnMarshal(s,LongArray2,omni::ALIGN_8,l); if (s.pd_unmarshal_byte_swap) { LongArray2 m; m.l[0] = Swap32(l.l[1]); m.l[1] = Swap32(l.l[0]); l = m; } #ifdef OMNI_MIXED_ENDIAN_DOUBLE { _CORBA_ULong v = l.l[0]; l.l[0] = l.l[1]; l.l[1] = v; } #endif convertToFloat(_CORBA_Double, LongArray2); } #else friend inline void operator>>= (_CORBA_Float a, cdrStream& s); friend inline void operator<<= (_CORBA_Float& a, cdrStream& s); friend inline void operator>>= (_CORBA_Double a, cdrStream& s); friend inline void operator<<= (_CORBA_Double& a, cdrStream& s); #endif #endif #ifdef HAS_LongDouble #if SIZEOF_LONG_DOUBLE == 16 #ifndef OMNI_NO_INLINE_FRIENDS friend inline void operator>>= (_CORBA_LongDouble a, cdrStream& s) { struct LongArray4 { _CORBA_ULong l[4]; }; convertFromFloat(_CORBA_LongDouble, LongArray4); if (s.pd_marshal_byte_swap) { LongArray4 m; m.l[0] = Swap32(l.l[3]); m.l[1] = Swap32(l.l[2]); m.l[2] = Swap32(l.l[1]); m.l[3] = Swap32(l.l[0]); l = m; } CdrMarshal(s,LongArray4,omni::ALIGN_8,l); } friend inline void operator<<= (_CORBA_LongDouble& a, cdrStream& s) { struct LongArray4 { _CORBA_ULong l[4]; } l; CdrUnMarshal(s,LongArray4,omni::ALIGN_8,l); if (s.pd_unmarshal_byte_swap) { LongArray4 m; m.l[0] = Swap32(l.l[3]); m.l[1] = Swap32(l.l[2]); m.l[2] = Swap32(l.l[1]); m.l[3] = Swap32(l.l[0]); l = m; } convertToFloat(_CORBA_LongDouble, LongArray4); } #else friend inline void operator>>= (_CORBA_LongDouble a, cdrStream& s); friend inline void operator<<= (_CORBA_LongDouble& a, cdrStream& s); #endif #else // Code for long double < 16 bytes is too painful to put inline friend void operator>>= (_CORBA_LongDouble a, cdrStream& s); friend void operator<<= (_CORBA_LongDouble& a, cdrStream& s); #endif #endif inline void marshalString(const char* s,int bounded=0) { OMNIORB_USER_CHECK(s); pd_ncs_c->marshalString(*this,pd_tcs_c,bounded,0,s); } inline char* unmarshalString(int bounded=0) { char* s; pd_ncs_c->unmarshalString(*this,pd_tcs_c,bounded,s); return s; } _CORBA_ULong marshalRawString(const char* s); // Marshal a raw string, with no code set conversion. char* unmarshalRawString(); // Unmarshal a raw string. inline void marshalWString(const _CORBA_WChar* s,int bounded=0) { OMNIORB_USER_CHECK(s); pd_ncs_w->marshalWString(*this,pd_tcs_w,bounded, _CORBA_WString_helper::len(s),s); } inline _CORBA_WChar* unmarshalWString(int bounded=0) { _CORBA_WChar* s; pd_ncs_w->unmarshalWString(*this,pd_tcs_w,bounded,s); return s; } virtual void put_octet_array(const _CORBA_Octet* b, int size, omni::alignment_t align=omni::ALIGN_1) = 0; // must be a multiple of . // For instance, if == omni::ALIGN_8 then % 8 == 0. void put_small_octet_array(const _CORBA_Octet* b, int size); // Put a small octet array which must have ALIGN_1. Since it is // small, we expect it to fit in the stream's current buffer without // having to allocate more space. virtual void get_octet_array(_CORBA_Octet* b, int size, omni::alignment_t align=omni::ALIGN_1) = 0; // Get array of octets. virtual void skipInput(_CORBA_ULong size) = 0; // Skip bytes from the input stream. virtual _CORBA_Boolean checkInputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1) = 0; // Return true if the input stream contains data for at least // of size . The initial alignment of the data // starts at . Return false otherwise. virtual _CORBA_ULong currentInputPtr() const = 0; // Return a value that represents the position of the next byte in // the input stream. Later bytes in the stream has a higher return // value. The absolute value of the return value has no meaning. // The only use of this function is to compute the distance between // two bytes in the stream. virtual _CORBA_ULong currentOutputPtr() const = 0; // Return a value that represents the position of the next byte in // the output stream. Later bytes in the stream have a higher return // value. The absolute value of the return value has no meaning. // The only use of this function is to compute the distance between // two bytes in the stream. virtual _CORBA_Boolean checkOutputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1) = 0; // Return true if data of at least of size can // be inserted to the output stream. The initial alignment of the // data starts at . Return false otherwise. virtual void copy_to(cdrStream&,int size, omni::alignment_t align=omni::ALIGN_1); // From this stream, copy bytes to the argument stream. // The initial alignment starts at . // Derived classes may provided more efficent implementation than the // default. inline void alignInput(omni::alignment_t align) // Align the buffer of the input stream to . { again: omni::ptr_arith_t p1 = omni::align_to((omni::ptr_arith_t)pd_inb_mkr, align); if ((void*)p1 > pd_inb_end) { fetchInputData(align,0); goto again; } pd_inb_mkr = (void*)p1; } inline void alignOutput(omni::alignment_t align) // Align the buffer of the output stream to . { again: omni::ptr_arith_t p1 = omni::align_to((omni::ptr_arith_t)pd_outb_mkr, align); if ((void*)p1 > pd_outb_end) { if (reserveOutputSpaceForPrimitiveType(align,0)) goto again; } pd_outb_mkr = (void*)p1; } inline _CORBA_Boolean unmarshal_byte_swap() const { return pd_unmarshal_byte_swap; } // Return TRUE(1) if unmarshalled data have to be byte-swapped. inline _CORBA_Boolean marshal_byte_swap() const { return pd_marshal_byte_swap; } inline void* PR_get_outb_mkr() { return pd_outb_mkr; } // internal function used by cdrStream implementations protected: _CORBA_Boolean pd_unmarshal_byte_swap; // TRUE(1) if unmarshalled data have to be byte-swapped. _CORBA_Boolean pd_marshal_byte_swap; // TRUE(1) if marshalled data have to be byte-swapped. I.e. data are not // going into the stream with the host endian. // Input buffer pointers, the region (*p) containing valid data // is pd_inb_mkr <= p < pd_inb_end. // pd_inb_end and pd_inb_mkr are initialised by fetchInputData(). // pd_inb_mkr is also updated by the unmarshalling operators between // calls to fetchInputData(). void* pd_inb_end; void* pd_inb_mkr; virtual void fetchInputData(omni::alignment_t align, size_t required) = 0; // Fetch at least bytes into the input buffer. // must be no more than 8 bytes && align == required!! // The data block should start at alignment . // If the space available is less than specified, raise a // MARSHAL system exception. // Output buffer pointers, the region (*p) that can be written // into is pd_outb_mkr <= p < pd_outb_end. // pd_outb_end and pd_outb_mkr are initialised by reserveOutputSpace(). // pd_outb_mkr is also updated by the marshalling operators between // calls to reserveOutputSpace(). void* pd_outb_end; void* pd_outb_mkr; virtual _CORBA_Boolean reserveOutputSpaceForPrimitiveType(omni::alignment_t align, size_t required) = 0; // Allocate at least bytes in the output buffer. // The data block should start at alignment . // must be no more than 8 bytes && align == required!! // Returns TRUE(1) if at least bytes with the starting // alignment as specified has been allocated. // Returns FALSE(0) if the required space cannot be allocated. // When the return value is FALSE, the cdrStream would skip writing // the current argument quietly. // If the derived class do not want the cdrStream to skip writing // quietly, it should raise a MARSHAL system exception instead of // returning FALSE. virtual _CORBA_Boolean maybeReserveOutputSpace(omni::alignment_t align, size_t required) = 0; // Same as reserveOutputSpaceForPrimitiveType, except the following: // 1. The required size can be any size. // 2. The implementation of this function can throw CORBA::BAD_PARAM // if the nature of the stream makes it impossible to fullfil this // request. The caller should fall back to use put_octet_array or // other means instead. _OMNI_NS(omniCodeSet::TCS_C)* pd_tcs_c; // Transmission code set convertor for char and string _OMNI_NS(omniCodeSet::TCS_W)* pd_tcs_w; // Transmission code set convertor for wchar and wstring _OMNI_NS(omniCodeSet::NCS_C)* pd_ncs_c; _OMNI_NS(omniCodeSet::NCS_W)* pd_ncs_w; _OMNI_NS(ValueIndirectionTracker)* pd_valueTracker; // Object used to track offsets of indirections in valuetypes. public: // Access functions to the char and wchar code set convertors inline _OMNI_NS(omniCodeSet::TCS_C)* TCS_C() const { return pd_tcs_c; } inline void TCS_C(_OMNI_NS(omniCodeSet::TCS_C)* c) { pd_tcs_c = c; } inline _OMNI_NS(omniCodeSet::TCS_W)* TCS_W() const { return pd_tcs_w; } inline void TCS_W(_OMNI_NS(omniCodeSet::TCS_W)* c) { pd_tcs_w = c; } // Access functions to the value indirection tracker inline _OMNI_NS(ValueIndirectionTracker)* valueTracker() const { return pd_valueTracker; } inline void valueTracker(_OMNI_NS(ValueIndirectionTracker)* v) { pd_valueTracker = v; } inline void clearValueTracker() { if (pd_valueTracker) { delete pd_valueTracker; pd_valueTracker = 0; } } virtual void declareArrayLength(omni::alignment_t align, size_t size); inline void unmarshalArrayChar(_CORBA_Short* a, int length) { for( int i = 0; i < length; i++ ) a[i] = unmarshalChar(); } inline void unmarshalArrayBoolean(_CORBA_Boolean* a, int length) { #if !defined(HAS_Cplusplus_Bool) || (SIZEOF_BOOL == 1) get_octet_array((_CORBA_Char*)a, length, omni::ALIGN_1); #else for( int i = 0; i < length; i++ ) a[i] = unmarshalBoolean(); #endif } inline void unmarshalArrayShort(_CORBA_Short* a, int length) { get_octet_array((_CORBA_Char*) a, length * 2, omni::ALIGN_2); if( unmarshal_byte_swap() ) for( int i = 0; i < length; i++ ) a[i] = Swap16(a[i]); } inline void unmarshalArrayUShort(_CORBA_UShort* a, int length) { get_octet_array((_CORBA_Char*) a, length * 2, omni::ALIGN_2); if( unmarshal_byte_swap() ) for( int i = 0; i < length; i++ ) a[i] = Swap16(a[i]); } inline void unmarshalArrayLong(_CORBA_Long* a, int length) { get_octet_array((_CORBA_Char*) a, length * 4, omni::ALIGN_4); if( unmarshal_byte_swap() ) for( int i = 0; i < length; i++ ) a[i] = Swap32(a[i]); } inline void unmarshalArrayULong(_CORBA_ULong* a, int length) { get_octet_array((_CORBA_Char*) a, length * 4, omni::ALIGN_4); if( unmarshal_byte_swap() ) for( int i = 0; i < length; i++ ) a[i] = Swap32(a[i]); } #ifdef HAS_LongLong inline void unmarshalArrayLongLong(_CORBA_LongLong* a, int length) { get_octet_array((_CORBA_Char*) a, length * 8, omni::ALIGN_8); if( unmarshal_byte_swap() ) for( int i = 0; i < length; i++ ) a[i] = Swap64(a[i]); } inline void unmarshalArrayULongLong(_CORBA_ULongLong* a, int length) { get_octet_array((_CORBA_Char*) a, length * 8, omni::ALIGN_8); if( unmarshal_byte_swap() ) for( int i = 0; i < length; i++ ) a[i] = Swap64(a[i]); } #endif #if !defined(NO_FLOAT) inline void unmarshalArrayFloat(_CORBA_Float* a, int length) { get_octet_array((_CORBA_Char*) a, length * 4, omni::ALIGN_4); if( unmarshal_byte_swap() ) { _CORBA_ULong* p=(_CORBA_ULong*)a; for( int i = 0; i < length; i++ ) { p[i] = Swap32(p[i]); } } } inline void unmarshalArrayDouble(_CORBA_Double* a, int length) { get_octet_array((_CORBA_Char*) a, length * 8, omni::ALIGN_8); if( unmarshal_byte_swap() ) { struct LongArray2 { _CORBA_ULong l[2]; }; LongArray2* p=(LongArray2*)a; for( int i = 0; i < length; i++ ) { LongArray2 l; l.l[0] = Swap32(p[i].l[1]); l.l[1] = Swap32(p[i].l[0]); p[i] = l; } } #ifdef OMNI_MIXED_ENDIAN_DOUBLE { struct LongArray2 { _CORBA_ULong l[2]; }; LongArray2* p=(LongArray2*)a; for( int i = 0; i < length; i++ ) { _CORBA_ULong v = p[i].l[0]; p[i].l[0] = p[i].l[1]; p[i].l[1] = v; } } #endif } #endif public: ///////////////////////////////////////////////////////////////////// virtual _CORBA_ULong completion(); // If an error occurs when a value is marshalled or unmarshalled, a // system exception will be raised. The "completed" member of the // exception must be taken from the return value of this function. // Note: the return value is really of type CORBA::CompletionStatus. // Since this declaration must appear before the CORBA declaration, // we have to live with returning a _CORBA_ULong. ///////////////////////////////////////////////////////////////////// virtual void* ptrToClass(int* cptr); // Yet another dynamic casting mechanism to cope with compilers // without dynamic_cast<>. Each class derived from cdrStream has a // static int declared in it. The address of this int is used to // compare the required class with the target object. Apart from the // use of the integer pointer, it works just like _ptrToInterface // and _ptrToObjRef in omniObjRef etc. static inline cdrStream* downcast(cdrStream* s) { return (cdrStream*)s->ptrToClass(&_classid); } // Not really necessary in the base class, but here for consistency. static _core_attr int _classid; private: cdrStream(const cdrStream&); cdrStream& operator=(const cdrStream&); friend class cdrStreamAdapter; friend class cdrValueChunkStream; // cdrStreamAdapter and cdrValueChunkStream need to access protected // pointers and virtual functions. }; #ifdef OMNI_NO_INLINE_FRIENDS inline void operator>>= (_CORBA_Short a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_Short t = Swap16(a); a = t; } CdrMarshal(s,_CORBA_Short,omni::ALIGN_2,a); } inline void operator<<= (_CORBA_Short& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_Short,omni::ALIGN_2,a); if (s.pd_unmarshal_byte_swap) { _CORBA_Short t = Swap16(a); a = t; } } inline void operator>>= (_CORBA_UShort a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_UShort t = Swap16(a); a = t; } CdrMarshal(s,_CORBA_UShort,omni::ALIGN_2,a); } inline void operator<<= (_CORBA_UShort& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_UShort,omni::ALIGN_2,a); if (s.pd_unmarshal_byte_swap) { _CORBA_UShort t = Swap16(a); a = t; } } inline void operator>>= (_CORBA_Long a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_Long t = Swap32(a); a = t; } CdrMarshal(s,_CORBA_Long,omni::ALIGN_4,a); } inline void operator<<= (_CORBA_Long& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_Long,omni::ALIGN_4,a); if (s.pd_unmarshal_byte_swap) { _CORBA_Long t = Swap32(a); a = t; } } inline void operator>>= (_CORBA_ULong a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_ULong t = Swap32(a); a = t; } CdrMarshal(s,_CORBA_ULong,omni::ALIGN_4,a); } inline void operator<<= (_CORBA_ULong& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_ULong,omni::ALIGN_4,a); if (s.pd_unmarshal_byte_swap) { _CORBA_ULong t = Swap32(a); a = t; } } #ifdef HAS_LongLong inline void operator>>= (_CORBA_LongLong a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_LongLong t = Swap64(a); a = t; } CdrMarshal(s,_CORBA_LongLong,omni::ALIGN_8,a); } inline void operator<<= (_CORBA_LongLong& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_LongLong,omni::ALIGN_8,a); if (s.pd_unmarshal_byte_swap) { _CORBA_LongLong t = Swap64(a); a = t; } } inline void operator>>= (_CORBA_ULongLong a, cdrStream& s) { if (s.pd_marshal_byte_swap) { _CORBA_ULongLong t = Swap64(a); a = t; } CdrMarshal(s,_CORBA_ULongLong,omni::ALIGN_8,a); } inline void operator<<= (_CORBA_ULongLong& a, cdrStream& s) { CdrUnMarshal(s,_CORBA_ULongLong,omni::ALIGN_8,a); if (s.pd_unmarshal_byte_swap) { _CORBA_ULongLong t = Swap64(a); a = t; } } #endif #if !defined(NO_FLOAT) inline void operator>>= (_CORBA_Float a, cdrStream& s) { convertFromFloat(_CORBA_Float, _CORBA_ULong); if (s.pd_marshal_byte_swap) { l = Swap32(l); } CdrMarshal(s,_CORBA_ULong,omni::ALIGN_4,l); } inline void operator<<= (_CORBA_Float& a, cdrStream& s) { _CORBA_ULong l; CdrUnMarshal(s,_CORBA_ULong,omni::ALIGN_4,l); if (s.pd_unmarshal_byte_swap) { l = Swap32(l); } convertToFloat(_CORBA_Float, _CORBA_ULong); } inline void operator>>= (_CORBA_Double a, cdrStream& s) { struct LongArray2 { _CORBA_ULong l[2]; }; convertFromFloat(_CORBA_Double, LongArray2); if (s.pd_marshal_byte_swap) { LongArray2 m; m.l[0] = Swap32(l.l[1]); m.l[1] = Swap32(l.l[0]); l = m; } #ifdef OMNI_MIXED_ENDIAN_DOUBLE { _CORBA_ULong v = l.l[0]; l.l[0] = l.l[1]; l.l[1] = v; } #endif CdrMarshal(s,LongArray2,omni::ALIGN_8,l); } inline void operator<<= (_CORBA_Double& a, cdrStream& s) { struct LongArray2 { _CORBA_ULong l[2]; } l; CdrUnMarshal(s,LongArray2,omni::ALIGN_8,l); if (s.pd_unmarshal_byte_swap) { LongArray2 m; m.l[0] = Swap32(l.l[1]); m.l[1] = Swap32(l.l[0]); l = m; } #ifdef OMNI_MIXED_ENDIAN_DOUBLE { _CORBA_ULong v = l.l[0]; l.l[0] = l.l[1]; l.l[1] = v; } #endif convertToFloat(_CORBA_Double, LongArray2); } #endif #ifdef HAS_LongDouble #if SIZEOF_LONG_DOUBLE == 16 inline void operator>>= (_CORBA_LongDouble a, cdrStream& s) { struct LongArray4 { _CORBA_ULong l[4]; }; convertFromFloat(_CORBA_LongDouble, LongArray4); if (s.pd_marshal_byte_swap) { LongArray4 m; m.l[0] = Swap32(l.l[3]); m.l[1] = Swap32(l.l[2]); m.l[2] = Swap32(l.l[1]); m.l[3] = Swap32(l.l[0]); l = m; } CdrMarshal(s,LongArray4,omni::ALIGN_8,l); } inline void operator<<= (_CORBA_LongDouble& a, cdrStream& s) { struct LongArray4 { _CORBA_ULong l[4]; } l; CdrUnMarshal(s,LongArray4,omni::ALIGN_8,l); if (s.pd_unmarshal_byte_swap) { LongArray4 m; m.l[0] = Swap32(l.l[3]); m.l[1] = Swap32(l.l[2]); m.l[2] = Swap32(l.l[1]); m.l[3] = Swap32(l.l[0]); l = m; } convertToFloat(_CORBA_LongDouble, LongArray4); } #endif #endif #endif class cdrMemoryStream : public cdrStream { public: cdrMemoryStream(_CORBA_ULong initialBufsize = 0, _CORBA_Boolean clearMemory = 0); virtual ~cdrMemoryStream(); void rewindInputPtr(); // Rewind the input pointer to the beginning of the buffer void rewindPtrs(); // Rewind the both input and output pointers to the beginning of the buffer // bufSize() returns 0 after this call. _CORBA_ULong bufSize() const; // Returns the size of the buffer containing valid data. void* bufPtr() const; // Returns a pointer to the beginning of the buffer. void setByteSwapFlag(_CORBA_Boolean littleendian); // Data in the buffer is little-endian ( = TRUE(1)) or // big-endian ( = FALSE(0)). Setup the cdrStream // accordingly. inline _CORBA_Boolean readOnly() { return pd_readonly_and_external_buffer; } // Return true if the stream is read-only -- i.e. it is using an // external buffer. cdrMemoryStream(const cdrMemoryStream&, _CORBA_Boolean read_only = 0); // Copy a stream. If the source stream is read-only, or // is true, the new stream uses the same underlying memory buffer as // the source, and assumes the buffer stays valid for the lifetime // of the new stream. cdrMemoryStream& operator=(const cdrMemoryStream&); cdrMemoryStream(void* databuffer); cdrMemoryStream(void* databuffer, size_t maxLen); // Constructors for a read-only buffered stream. virtual void* ptrToClass(int* cptr); static inline cdrMemoryStream* downcast(cdrStream* s) { return (cdrMemoryStream*)s->ptrToClass(&_classid); } static _core_attr int _classid; protected: _CORBA_Boolean pd_readonly_and_external_buffer; _CORBA_Boolean pd_clear_memory; void* pd_bufp; void* pd_bufp_8; char pd_inline_buffer[32]; public: // The following implement the abstract functions defined in cdrStream void put_octet_array(const _CORBA_Octet* b, int size, omni::alignment_t align=omni::ALIGN_1); void get_octet_array(_CORBA_Octet* b,int size, omni::alignment_t align=omni::ALIGN_1); void skipInput(_CORBA_ULong size); _CORBA_Boolean checkInputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); _CORBA_Boolean checkOutputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); void copy_to(cdrStream&,int size, omni::alignment_t align=omni::ALIGN_1); void fetchInputData(omni::alignment_t,size_t); _CORBA_Boolean reserveOutputSpaceForPrimitiveType(omni::alignment_t,size_t); _CORBA_Boolean maybeReserveOutputSpace(omni::alignment_t,size_t); _CORBA_ULong currentInputPtr() const; _CORBA_ULong currentOutputPtr() const; private: _CORBA_Boolean reserveOutputSpace(omni::alignment_t,size_t); }; class cdrEncapsulationStream : public cdrMemoryStream { public: cdrEncapsulationStream(_CORBA_ULong initialBufsize = 0, _CORBA_Boolean clearMemory = 0); cdrEncapsulationStream(const _CORBA_Octet* databuffer, _CORBA_ULong bufsize, _CORBA_Boolean allowAlign4 = 0); cdrEncapsulationStream(cdrStream& s,_CORBA_ULong fetchsize); // copy from bytes of data. void getOctetStream(_CORBA_Octet*& databuffer, _CORBA_ULong& max, _CORBA_ULong& len); virtual void* ptrToClass(int* cptr); static inline cdrEncapsulationStream* downcast(cdrStream* s) { return (cdrEncapsulationStream*)s->ptrToClass(&_classid); } static _core_attr int _classid; }; class cdrCountingStream : public cdrStream { public: cdrCountingStream(_OMNI_NS(omniCodeSet::TCS_C)* tcs_c, _OMNI_NS(omniCodeSet::TCS_W)* tcs_w, size_t initialoffset = 0) : pd_total(initialoffset) { pd_tcs_c = tcs_c; pd_tcs_w = tcs_w; } virtual ~cdrCountingStream() {} size_t total() { return pd_total; } // The following implements the abstract functions defined in cdrStream void put_octet_array(const _CORBA_Octet* b, int size, omni::alignment_t align=omni::ALIGN_1); _CORBA_Boolean reserveOutputSpaceForPrimitiveType(omni::alignment_t align, size_t required); _CORBA_Boolean maybeReserveOutputSpace(omni::alignment_t align, size_t required); _CORBA_Boolean checkOutputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); void copy_to(cdrStream&,int size, omni::alignment_t align=omni::ALIGN_1); void get_octet_array(_CORBA_Octet* b,int size, omni::alignment_t align=omni::ALIGN_1); void skipInput(_CORBA_ULong); _CORBA_Boolean checkInputOverrun(_CORBA_ULong,_CORBA_ULong, omni::alignment_t align=omni::ALIGN_1); void fetchInputData(omni::alignment_t,size_t); _CORBA_ULong currentInputPtr() const; _CORBA_ULong currentOutputPtr() const; virtual void* ptrToClass(int* cptr); static inline cdrCountingStream* downcast(cdrStream* s) { return (cdrCountingStream*)s->ptrToClass(&_classid); } static _core_attr int _classid; private: size_t pd_total; cdrCountingStream(const cdrCountingStream&); cdrCountingStream& operator=(const cdrCountingStream&); }; // In some circumstances, for example in omniORBpy, it is necessary to // perform some extra work around operations which manage a // cdrStream's buffers. cdrStreamAdapter provides a wrapper around a // cdrStream object. A class derived from cdrStreamAdapter may do // anything it likes in its implementations of the cdrStream virtual // functions, as long as it also calls the cdrStreamAdapter versions. class cdrStreamAdapter : public cdrStream { protected: cdrStreamAdapter(cdrStream& stream) : pd_actual(stream) { pd_unmarshal_byte_swap = pd_actual.pd_unmarshal_byte_swap; pd_marshal_byte_swap = pd_actual.pd_marshal_byte_swap; pd_tcs_c = pd_actual.pd_tcs_c; pd_tcs_w = pd_actual.pd_tcs_w; copyStateFromActual(); } virtual ~cdrStreamAdapter() { copyStateToActual(); pd_valueTracker = 0; } // Implementations of abstract functions... void put_octet_array(const _CORBA_Octet* b, int size, omni::alignment_t align=omni::ALIGN_1); void get_octet_array(_CORBA_Octet* b,int size, omni::alignment_t align=omni::ALIGN_1); void skipInput(_CORBA_ULong size); _CORBA_Boolean checkInputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); _CORBA_Boolean checkOutputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); void copy_to(cdrStream&, int size, omni::alignment_t align=omni::ALIGN_1); void fetchInputData(omni::alignment_t align,size_t required); _CORBA_Boolean reserveOutputSpaceForPrimitiveType(omni::alignment_t align, size_t required); _CORBA_Boolean maybeReserveOutputSpace(omni::alignment_t align, size_t required); _CORBA_ULong currentInputPtr() const; _CORBA_ULong currentOutputPtr() const; _CORBA_ULong completion(); public: inline void copyStateFromActual() { pd_inb_end = pd_actual.pd_inb_end; pd_inb_mkr = pd_actual.pd_inb_mkr; pd_outb_end = pd_actual.pd_outb_end; pd_outb_mkr = pd_actual.pd_outb_mkr; pd_valueTracker = pd_actual.pd_valueTracker; } inline void copyStateToActual() const { pd_actual.pd_inb_end = pd_inb_end; pd_actual.pd_inb_mkr = pd_inb_mkr; pd_actual.pd_outb_end = pd_outb_end; pd_actual.pd_outb_mkr = pd_outb_mkr; pd_actual.pd_valueTracker = pd_valueTracker; } virtual void* ptrToClass(int* cptr); static inline cdrStreamAdapter* downcast(cdrStream* s) { return (cdrStreamAdapter*)s->ptrToClass(&_classid); } static _core_attr int _classid; private: cdrStream& pd_actual; }; // cdrValueChunkStream is similar to cdrStreamAdapter. It implements // chunked encoding of valuetypes by wrapping an existing stream. // // Use for reading and writing is slightly asymmetric: for writing, // the stream wrapper must be created before marshalling the value tag // indicating chunked encoding; for reading, the wrapper is created // after unmarshalling the outer-most value tag (since it is not until // then that the reader knows chunking is is use). class cdrValueChunkStream : public cdrStream { public: cdrValueChunkStream(cdrStream& stream) : pd_actual(stream), pd_nestLevel(0), pd_lengthPtr(0), pd_remaining(0), pd_inHeader(0), pd_inChunk(0), pd_justEnded(0), pd_reader(0), pd_exception(0) { pd_unmarshal_byte_swap = pd_actual.pd_unmarshal_byte_swap; pd_marshal_byte_swap = pd_actual.pd_marshal_byte_swap; pd_tcs_c = pd_actual.pd_tcs_c; pd_tcs_w = pd_actual.pd_tcs_w; copyStateFromActual(); } virtual ~cdrValueChunkStream(); void startOutputValueHeader(_CORBA_Long valueTag); // Start a new value with the given value tag. The value tag must // specify chunking. Must be called at least once before using the // stream for writing. void startOutputValueBody(); // End the value header and start a chunk for the value body. void endOutputValue(); // End the current value, decrementing the nesting level. void initialiseInput(); // Initialise stream as an input stream. void startInputValueBody(); // Start reading the value body. inline _CORBA_Long nestLevel() { return pd_nestLevel; } inline void exceptionOccurred() { pd_exception = 1; } _CORBA_Boolean skipToNestedValue(_CORBA_Long level); // Function used by truncation. Skip the remaining octets in the // value at the specified nesting level. If a nested value is // encountered, return true; if the end of the value is reached, // return false. // // We need this because we might truncate a value containing a // member that is a value we know about. Later on, an indirection // might point to that member. // Implementations of abstract functions... void put_octet_array(const _CORBA_Octet* b, int size, omni::alignment_t align=omni::ALIGN_1); void get_octet_array(_CORBA_Octet* b,int size, omni::alignment_t align=omni::ALIGN_1); void skipInput(_CORBA_ULong size); _CORBA_Boolean checkInputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); _CORBA_Boolean checkOutputOverrun(_CORBA_ULong itemSize, _CORBA_ULong nItems, omni::alignment_t align=omni::ALIGN_1); void fetchInputData(omni::alignment_t align,size_t required); _CORBA_Boolean reserveOutputSpaceForPrimitiveType(omni::alignment_t align, size_t required); _CORBA_Boolean maybeReserveOutputSpace(omni::alignment_t align, size_t required); _CORBA_ULong currentInputPtr() const; _CORBA_ULong currentOutputPtr() const; _CORBA_ULong completion(); virtual void declareArrayLength(omni::alignment_t align, size_t size); inline void copyStateFromActual() { pd_inb_end = pd_actual.pd_inb_end; pd_inb_mkr = pd_actual.pd_inb_mkr; pd_outb_end = pd_actual.pd_outb_end; pd_outb_mkr = pd_actual.pd_outb_mkr; pd_valueTracker = pd_actual.pd_valueTracker; } inline void copyStateToActual() const { pd_actual.pd_inb_mkr = pd_inb_mkr; pd_actual.pd_outb_mkr = pd_outb_mkr; pd_actual.pd_valueTracker = pd_valueTracker; } static _core_attr int _classid; virtual void* ptrToClass(int* cptr); static inline cdrValueChunkStream* downcast(cdrStream* s) { return (cdrValueChunkStream*)s->ptrToClass(&_classid); } private: void startOutputChunk(); void endOutputChunk(); void maybeStartNewChunk(omni::alignment_t align, size_t size); // Start a new chunk by doing the equivalent of endOutputChunk, // startOutputChunk, unless ending the chunk now would cause us to // output a zero length chunk. In that case, we use // declareArrayLength to reserve space in the chunk for an element // of the specified size. void startInputChunk(); void endInputValue(); _CORBA_Long peekChunkTag(); // Retrieve a chunk tag from the stream without moving the pointers along. inline void setLength(_CORBA_ULong len) { *pd_lengthPtr = pd_marshal_byte_swap ? Swap32(len) : len; } inline _CORBA_ULong getLength() { return pd_unmarshal_byte_swap ? Swap32(*pd_lengthPtr) : *pd_lengthPtr; } cdrStream& pd_actual; // Stream being wrapped _CORBA_Long pd_nestLevel; // The nesting level of chunks _CORBA_Long* pd_lengthPtr; // Pointer to the chunk length field _CORBA_ULong pd_remaining; // !=0 => octets remaining in chunk _CORBA_Boolean pd_inHeader; // True if we're inside a value header _CORBA_Boolean pd_inChunk; // True if we're inside a chunk _CORBA_Boolean pd_justEnded; // True if we've just ended a value _CORBA_Boolean pd_reader; // True if we're a reader not a writer _CORBA_Boolean pd_exception; // Set true if an exception occurs, to // prevent further exceptions during // clean-up. }; #undef CdrMarshal #undef CdrUnMarshal #undef convertFromFloat #undef convertToFloat #undef Swap16 #undef Swap32 #undef Swap64 #endif /* __CDRSTREAM_H__ */