summaryrefslogtreecommitdiff
path: root/TAO/tao/xdr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/xdr.cpp')
-rw-r--r--TAO/tao/xdr.cpp772
1 files changed, 0 insertions, 772 deletions
diff --git a/TAO/tao/xdr.cpp b/TAO/tao/xdr.cpp
deleted file mode 100644
index 113d68a589f..00000000000
--- a/TAO/tao/xdr.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-// @(#)xdr.cpp 1.3 95/11/07
-// Copyright 1995 by Sun Microsystems, Inc.
-//
-// XDR/TCP ORB Marshaler/unmarshaler
-//
-// Includes functions to encode 64 and 128 bit quantities, interpretive
-// encoder/decoder.
-//
-// XXX note -- this is incomplete (see xdr.hh) and doesn't do
-// exactly what the Prelude protocol does, particularly in the
-// area of typecodes.
-//
-// XXX implement the put/get primitives for 64 and 128 bit data types
-//
-// XXX strings, principals, typecodes, char arrays, char seqs, and
-// same for octets ... all should marshal the bulk characters tightly
-// packed, four to a word, else this violates the XDR spec.
-//
-// XXX optimization 1: allowed by current XDR spec, when marshaling
-// true bulk data could eliminate a buffer copy by writing long
-// buffers (bigger than 'remainder of current fragment') in single
-// large chunks ... weigh cost of an extra kernel write against data
-// copy getting added. Applies to byte-structured bulk data only,
-// not (portably) to arrays of longs etc.
-//
-// XXX optimization 2: modifies current XDR spec: when marshaling
-// arrays of "short" data (e.g. unicode strings) pack tightly.
-//
-
-#include "tao/orb.h"
-#include "tao/debug.h"
-#include "tao/principa.h"
-#include "tao/xdr.h"
-
-// I/O for 64 bit quantities -- integers, doubles
-
-CORBA_Boolean
-XDR_stream::put_longlong (const CORBA_LongLong &)
-THROWS_NOTHING
-{
- return CORBA_B_FALSE;
-}
-
-CORBA_Boolean
-XDR_stream::get_longlong (CORBA_LongLong &)
-THROWS_NOTHING
-{
- return CORBA_B_FALSE;
-}
-
-// I/O for 128 bit quantities -- long doubles
-
-CORBA_Boolean
-XDR_stream::put_longdouble (const CORBA_LongDouble &)
-THROWS_NOTHING
-{
- return CORBA_B_FALSE;
-}
-
-CORBA_Boolean
-XDR_stream::get_longdouble (CORBA_LongDouble &)
-THROWS_NOTHING
-{
- return CORBA_B_FALSE;
-}
-
-// Encode instances of arbitrary data types based only on typecode.
-// "data" points to the data type; if it's not a primitve data type,
-// the TypeCode interpreter is used to recursively encode its
-// components. "context" is the marshaling stream on which to encode
-// the data value.
-//
-// This is a fairly typical TypeCode interpreter visit() routine; it
-// works on a single data value in conjunction with context
-// information, and must handle all IDL data types.
-
-CORBA_TypeCode::traverse_status
-XDR_stream::encoder (CORBA_TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA_Environment &env)
- THROWS_NOTHING
-{
- CORBA_Boolean continue_encoding = CORBA_B_TRUE;
- XDR_stream *stream = (XDR_stream *)context;
-
- switch (tc->kind_)
- {
- case tk_null:
- case tk_void:
- // nothing to encode!
- break;
-
- case tk_char:
- case tk_octet:
- continue_encoding = stream->put_char (*(char *)data);
- break;
-
- case tk_short:
- case tk_ushort:
- continue_encoding = stream->put_short (*(short *)data);
- break;
-
- case tk_long:
- case tk_ulong:
- case tk_float:
- continue_encoding = stream->put_long (*(CORBA_Long *)data);
- break;
-
- case tk_double:
- case tk_longlong:
- case tk_ulonglong:
- continue_encoding = stream->put_longlong (*(CORBA_LongLong *)data);
- break;
-
- case tk_boolean:
- continue_encoding = stream->put_boolean (*(CORBA_Boolean *)data);
- break;
-
- case tk_enum:
- {
- // NOTE assumption that this is in-range.
- //
- // XXX should check this, it's a hard-to-recover error
- // for the other side
- u_int value = *(u_int *)data;
- continue_encoding = stream->put_ulong (value);
- }
- break;
-
- case tk_any:
- {
- CORBA_Any *any = (CORBA_Any *)data;
-
- tc = any->type ();
- if (encoder (_tc_CORBA_TypeCode, &tc, 0, context, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE)
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- data = any->value ();
- return encoder (tc, data, 0, context, env);
- }
- // NOTREACHED
-
- case tk_TypeCode:
- {
- CORBA_TypeCode_ptr tc2;
-
- tc2 = *(CORBA_TypeCode_ptr *)data;
-
- continue_encoding = stream->put_ulong ((CORBA_ULong) tc2->kind_);
- if (continue_encoding == CORBA_B_FALSE)
- break;
-
- switch (tc2->kind_)
- {
- // Most TypeCodes have empty parameter lists
- default:
- break;
-
- //
- // A few have "simple" parameter lists
- //
- case tk_string:
- case tk_wstring:
- continue_encoding = stream->put_ulong (tc2->length_);
- break;
-
- //
- // Indirected typecodes can't occur at "top level" like
- // this, only nested inside others!
- //
- case ~0:
- dmsg ("indirected typecode at top level!");
- continue_encoding = CORBA_B_FALSE;
- break;
-
- //
- // The rest have "complex" parameter lists that are already
- // encoded as bulk octets ... put length, then octets
- //
- case tk_objref:
- case tk_struct:
- case tk_union:
- case tk_enum:
- case tk_sequence:
- case tk_array:
- case tk_alias:
- case tk_except:
- {
- u_int i;
-
- continue_encoding = stream->put_ulong (tc2->length_);
- for (i = 0; i < tc2->length_ && continue_encoding; i++)
- continue_encoding =
- stream->put_octet (tc2->_buffer [i]);
- }
- }
- }
- break;
-
- case tk_Principal:
- {
- CORBA_Principal_ptr p = *(CORBA_Principal_ptr*) data;
- u_int i;
-
- if (p != 0)
- {
- continue_encoding = stream->put_long (p->id.length);
- for (i = 0; continue_encoding && i < p->id.length; i++)
- continue_encoding = stream->put_octet (p->id.buffer [i]);
- }
- else
- continue_encoding = stream->put_long (0);
- }
- break;
-
- case tk_objref:
- // XXX implement me
- break;
-
- case tk_sequence:
- {
- // First marshal the sequence length, verifying that it's
- // within the sequence bounds ...
- CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data;
- CORBA_ULong len = seq ? seq->length : 0;
-
- if (len > 0)
- {
- CORBA_ULong bounds;
-
- bounds = tc->ulong_param (1, env);
- if (env.exception () != 0)
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- if (bounds != 0 && len > bounds)
- {
- env.exception (new CORBA_BAD_PARAM (COMPLETED_MAYBE));
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- }
- continue_encoding = stream->put_ulong (len);
-
- // Fast exit on error or empty sequence
- if (!continue_encoding || len == 0)
- break;
- }
- // FALLTHROUGH
-
- case tk_struct:
- case tk_union:
- case tk_array:
- case tk_alias:
- //
- // Marshal each member in order.
- //
- return tc->traverse (data, 0, encoder, context, env);
-
- case tk_except:
- // Convert the the "hidden" TypeCode at the beginning of the
- // exception into an on-the-wire ID, then marshal the members in
- // order (traversal skips that hidden typecode, and more).
- //
- // NOTE: This is asymmetric with respect to decoding the
- // exception, since whoever decodes must pull off the ID and map
- // it to the typecode to be used to unmarshal it (search among
- // legal choices).
- {
- CORBA_String id = tc->id (env);
-
- if (env.exception () == 0)
- {
- continue_encoding =
- encoder (_tc_CORBA_String, &id, 0, context, env)
- == CORBA_TypeCode::TRAVERSE_CONTINUE
- && tc->traverse (data, 0, encoder, context, env);
- }
- else
- continue_encoding = CORBA_B_FALSE;
- }
- break;
-
- case tk_string:
- {
- CORBA_String str = *(CORBA_String *) data;
- CORBA_ULong len, bounds;
-
- // Be nice to programmers: treat nulls as empty strings not
- // errors. (OMG-IDL supports languages that don't use the
- // C/C++ notion of null v. empty strings; nulls aren't part of
- // the OMG-IDL string model.)
- if (str == 0)
- {
- stream->put_ulong (1);
- stream->put_char (0);
- break;
- }
-
- // Verify string satisfies bounds requirements. We're not so
- // permissive as to send messages violating the interface spec
- // by having excessively long strings!
- bounds = tc->ulong_param (0, env);
- if (env.exception () != 0)
- return CORBA_TypeCode::TRAVERSE_STOP;
- len = ACE_OS::strlen ((char *)str);
-
- if (bounds != 0 && len > bounds) {
- continue_encoding = CORBA_B_FALSE;
- break;
- }
-
- // Encode the string, followed by a NUL character.
- continue_encoding = stream->put_ulong (len + 1);
- while (continue_encoding != CORBA_B_FALSE && *str)
- continue_encoding = stream->put_char (*str++);
- stream->put_char (0);
- }
- break;
-
- case tk_wstring:
- {
- wchar_t *str = *(wchar_t **) data;
- CORBA_ULong len, bounds;
-
- // Be nice to programmers: treat nulls as empty strings not
- // errors. (OMG-IDL supports languages that don't use the
- // C/C++ notion of null v. empty strings; nulls aren't part of
- // the OMG-IDL string model.)
-
- if (str == 0)
- {
- stream->put_ulong (1);
- stream->put_wchar (0);
- break;
- }
-
- // Verify wide string satisfies bounds requirements. We're
- // not so permissive as to send messages violating the
- // interface spec by having excessively long strings!
- bounds = tc->ulong_param (0, env);
- if (env.exception () != 0)
- return CORBA_TypeCode::TRAVERSE_STOP;
- len = ACE_OS::strlen (str);
- if (bounds != 0 && len > bounds)
- {
- continue_encoding = CORBA_B_FALSE;
- break;
- }
-
- // Encode the wide string, followed by a NUL character.
- continue_encoding = stream->put_ulong (ACE_OS::strlen (str) + 1);
- while (continue_encoding != CORBA_B_FALSE && *str)
- continue_encoding = stream->put_wchar (*str++);
- stream->put_wchar (0);
- }
- break;
-
- case tk_longdouble:
- continue_encoding =
- stream->put_longdouble (*(CORBA_LongDouble *)data);
- break;
-
- case tk_wchar:
- continue_encoding = stream->put_wchar (*(wchar_t *)data);
- break;
-
- // case ~0:
- default:
- dmsg ("encoder default case ?");
- continue_encoding = CORBA_B_FALSE;
- break;
- }
-
- if (continue_encoding == CORBA_B_FALSE)
- {
- env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE));
- dmsg ("marshaling encoder detected error");
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- return CORBA_TypeCode::TRAVERSE_CONTINUE;
-}
-
-// Array of typecodes used to unmarshal ...
-
-extern CORBA_TypeCode_ptr __tc_consts [TC_KIND_COUNT];
-
-CORBA_TypeCode::traverse_status
-XDR_stream::decoder (CORBA_TypeCode_ptr tc,
- const void *data,
- const void *,
- void *context,
- CORBA_Environment &env)
- THROWS_NOTHING
-{
- CORBA_Boolean continue_decoding = CORBA_B_TRUE;
- XDR_stream *stream = (XDR_stream *)context;
-
- switch (tc->kind_)
- {
- case tk_null:
- case tk_void:
- // nothing to decode!
- break;
-
- case tk_char:
- case tk_octet:
- continue_decoding = stream->get_char (*(CORBA_Char *)data);
- break;
-
- case tk_short:
- case tk_ushort:
- continue_decoding = stream->get_short (*(short *)data);
- break;
-
- case tk_long:
- case tk_ulong:
- case tk_float:
- continue_decoding = stream->get_long (*(CORBA_Long *)data);
- break;
-
- case tk_longlong:
- case tk_ulonglong:
- case tk_double:
- continue_decoding = stream->get_longlong (*(CORBA_LongLong *)data);
- break;
-
- case tk_boolean:
- continue_decoding = stream->get_boolean (*(CORBA_Boolean *)data);
- break;
-
- case tk_enum:
- {
- CORBA_ULong val;
-
- // NOTE assumption that this is in-range.
- //
- // XXX should check this, it's rather hard to recover from
- // such errors since they "do not occur" and are essentially
- // never tested for.
- continue_decoding = stream->get_ulong (val);
- *(u_int *)data = (u_int) val;
- }
- break;
-
- case tk_any:
- {
- CORBA_Any *any = (CORBA_Any *)data;
- CORBA_TypeCode_ptr tc2;
- void *value;
-
- if (decoder (_tc_CORBA_TypeCode, &tc2, 0, context, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE)
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- value = new CORBA_Octet [tc2->size (env)];
-
- if (decoder (tc2, value, 0, context, env)
- != CORBA_TypeCode::TRAVERSE_CONTINUE)
- {
- delete value;
- CORBA_release (tc2);
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- (void) new (any) CORBA_Any (tc2, value, CORBA_B_TRUE);
- }
- break;
-
- case tk_TypeCode:
- {
- CORBA_ULong kind;
- CORBA_TypeCode_ptr *tcp;
-
- continue_decoding = stream->get_ulong (kind);
- if (continue_decoding == CORBA_B_FALSE)
- break;
- if (kind >= TC_KIND_COUNT)
- {
- continue_decoding = CORBA_B_FALSE;
- break;
- }
-
- tcp = (CORBA_TypeCode_ptr *)data;
-
- // Typecodes with empty parameter lists all have preallocated
- // constants. We use those to reduce memory consumption and
- // heap access ... also, to speed things up!
- if (((*tcp) = __tc_consts [(u_int) kind]) != 0)
- {
- *tcp = __tc_consts [(u_int) kind];
- break;
- }
- else switch (kind)
- {
- // Need special handling for all kinds of typecodes that
- // have nonempty parameter lists ...
- default: // error: missed a case!
- env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE));
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- // Some have "simple" parameter lists ... some of these also
- // have preallocated constants that could be used.
- case tk_string:
- case tk_wstring:
- {
- CORBA_ULong bound;
-
- continue_decoding = stream->get_ulong (bound);
- if (continue_decoding)
- {
- if (bound == 0)
- {
- if (kind == tk_string)
- *tcp = _tc_CORBA_String;
- else
- *tcp = _tc_CORBA_WString;
- }
- else
- *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind,
- bound, 0, CORBA_B_TRUE);
- }
- }
- break;
-
- // Indirected typecodes, illegal at "top level" but we allow
- // unmarshaling of them here because we use the same code to
- // read "off the wire" (where they're illegal) and to read
- // out of an encapsulation stream. We distinguish the case
- // where this is legal as described above.
-
- case ~0:
- // XXX implement me
- break;
-
- // The rest have "complex" parameter lists that are
- // encoded as bulk octets ...
- case tk_objref:
- case tk_struct:
- case tk_union:
- case tk_enum:
- case tk_sequence:
- case tk_array:
- case tk_alias:
- case tk_except:
- {
- u_int len, i;
- CORBA_ULong length;
- CORBA_Octet *buffer;
-
- continue_decoding = stream->get_ulong (length);
- if (!continue_decoding)
- break;
-
- // if length > MAXUNSIGNED, error ...
- len = (u_int) length;
-
- buffer = new CORBA_Octet [len];
-
- for (i = 0; i < len && continue_decoding; i++)
- continue_decoding = stream->get_octet (buffer [i]);
-
- if (!continue_decoding)
- {
- delete [] buffer;
- break;
- }
- *tcp = new CORBA_TypeCode ((CORBA_TCKind)kind,
- len, buffer, CORBA_B_TRUE);
- }
- }
- }
- break;
-
- case tk_Principal:
- {
- CORBA_Principal_ptr *pp = (CORBA_Principal_ptr *)data;
- CORBA_ULong len;
-
- continue_decoding = stream->get_ulong (len);
- if (len == 0)
- *pp = 0;
- else
- {
- *pp = new CORBA_Principal;
- (*pp)->id.buffer = new CORBA_Octet [(size_t) len];
- (*pp)->id.maximum = (*pp)->id.length = len;
-
- for (u_int i = 0;
- continue_decoding != CORBA_B_FALSE && i < len;
- i++)
- continue_decoding =
- stream->get_octet ((*pp)->id.buffer [i]);
- }
- }
- break;
-
- case tk_objref:
- // XXX implement me
- break;
-
- case tk_sequence:
- {
- // First unmarshal the sequence length ... we trust it to be
- // right here, on the "be gracious in what you accept"
- // principle. We don't generate illegal sequences
- // (i.e. length > bounds).
- CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data;
-
- continue_decoding = stream->get_ulong (seq->length);
- seq->maximum = seq->length;
- seq->buffer = 0;
-
- // Fast exit on empty sequences or errors
- if (!continue_decoding || seq->length == 0)
- break;
-
- // ... then allocate the memory into which we'll unmarshal
- CORBA_TypeCode_ptr tc2;
- size_t size;
-
- tc2 = tc->typecode_param (0, env);
- if (env.exception ())
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- size = tc2->size (env);
- if (env.exception ())
- return CORBA_TypeCode::TRAVERSE_STOP;
-
- tc2->Release ();
-
- seq->buffer = new CORBA_Octet [size * (size_t) seq->maximum];
- }
- // FALLTHROUGH
-
- case tk_struct:
- case tk_union:
- case tk_array:
- case tk_alias:
- // Unmarshal all the individual elements using the per-member
- // description held in the "parent" TypeCode.
-
- // FALLTHROUGH
-
- case tk_except:
- // For exceptions, the "hidden" type ID near the front of the
- // on-wire representation was previously unmarshaled and mapped
- // to the "tc" typcode we're using to traverse the memory ...
- // at the same time its vtable, refcount, and other state was
- // established.
- //
- // NOTE: This is asymmetric with respect to encoding exceptions.
- return tc->traverse (data, 0, decoder, context, env);
-
- case tk_string:
- {
- CORBA_String str;
- CORBA_ULong len = 0;
-
- // On decode, omit the check against specified string bounds,
- // and cope with illegal "zero length" strings (all lengths on
- // the wire must include a NUL).
- //
- // This is on the principle of being gracious in what we
- // accept; we don't generate messages that fail to comply with
- // protocol specs, but we will accept them when it's clear how
- // to do so.
-
- continue_decoding = stream->get_ulong (len);
- *((CORBA_String*)data) = str = new CORBA_Char [(size_t) (len)];
- if (len != 0)
- while (continue_decoding != CORBA_B_FALSE && len-- != 0)
- {
- continue_decoding = stream->get_char (*(CORBA_Char *)str);
- str++;
- }
- break;
- }
-
- case tk_wstring:
- {
- wchar_t *str;
- CORBA_ULong len = 0;
-
- // On decode, omit the check against specified wstring bounds,
- // and cope with illegal "zero length" strings (all lengths on
- // the wire must include a NUL).
- //
- // This is on the principle of being gracious in what we accept;
- // we don't generate messages that fail to comply with protocol
- // specs, but we will accept them when it's clear how to do so.
-
- continue_decoding = stream->get_ulong (len);
- *((wchar_t **)data) = str = new wchar_t [(size_t) (len)];
- if (len != 0)
- while (continue_decoding != CORBA_B_FALSE && len--)
- {
- continue_decoding = stream->get_wchar (*str);
- str++;
- }
- }
- break;
-
- case tk_longdouble:
- continue_decoding =
- stream->get_longdouble (*(CORBA_LongDouble *)data);
- break;
-
- case tk_wchar:
- continue_decoding = stream->get_wchar (*(wchar_t *)data);
- break;
-
- // case ~0:
- default:
- continue_decoding = CORBA_B_FALSE;
- dmsg ("decode, default case?");
- break;
- }
-
- if (continue_decoding == CORBA_B_FALSE)
- {
- env.exception (new CORBA_MARSHAL (COMPLETED_NO));
- dmsg ("marshaling decoder detected error");
- return CORBA_TypeCode::TRAVERSE_STOP;
- }
- return CORBA_TypeCode::TRAVERSE_CONTINUE;
-}
-
-// Write an XDR message fragment out on the stream.
-
-CORBA_Boolean
-XDR_stream::flush_frag (CORBA_Boolean /* is_last */)
- THROWS_NOTHING
-{
- return CORBA_B_FALSE;
-
-#if 0
- int status;
- CORBA_ULong size, header;
-
- size = index * sizeof (CORBA_ULong); // byte length of msg
- if (is_last)
- header = 0x80000000 | size; // indicates last frag
- else
- header = size;
- buffer [0] = htonl (header);
-
- //
- // XXX for portability, loop until there's no error. Some
- // platforms/mode don't guarantee full TCP writes even when
- // async (or nonblocking) mode was not set on this socket.
- //
- size += sizeof (CORBA_ULong);
- status = ACE_OS::write (fd, &buffer [0], size);
-
- index = 0;
-
- return (status == size);
-#endif /* 0 */
-}
-
-// Read an XDR message fragment in from the stream.
-
-CORBA_Boolean
-XDR_stream::read_frag (void)
- THROWS_NOTHING
-{
- // read cookie, split out size and "is last" flag
- // read rest of buffer
-
- return CORBA_B_FALSE;
-}