// -*- Mode: C++; -*-
// Package : omniORBpy
// pyTypeCode.cc Created on: 1999/07/19
// Author : Duncan Grisby (dpg1)
//
// Copyright (C) 1999 AT&T Laboratories Cambridge
//
// This file is part of the omniORBpy library
//
// The omniORBpy library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation;
// either version 2.1 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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:
// TypeCode support
// $Id: pyTypeCode.cc,v 1.1.4.9 2007/09/18 20:04:14 dgrisby Exp $
// $Log: pyTypeCode.cc,v $
// Revision 1.1.4.9 2007/09/18 20:04:14 dgrisby
// Set _parent_id on enums generated from TypeCodes.
//
// Revision 1.1.4.8 2006/05/24 18:33:42 dgrisby
// Off by one error in abstract interface typecode marshalling.
//
// Revision 1.1.4.7 2006/05/15 10:26:11 dgrisby
// More relaxation of requirements for old-style classes, for Python 2.5.
//
// Revision 1.1.4.6 2005/06/29 17:31:43 dgrisby
// Update valuetype examples; fix values in Anys.
//
// Revision 1.1.4.5 2005/06/24 17:36:00 dgrisby
// Support for receiving valuetypes inside Anys; relax requirement for
// old style classes in a lot of places.
//
// Revision 1.1.4.4 2005/01/07 00:22:33 dgrisby
// Big merge from omnipy2_develop.
//
// Revision 1.1.4.3 2003/11/06 12:00:35 dgrisby
// ValueType TypeCode support; track ORB core changes.
//
// Revision 1.1.4.2 2003/05/20 17:10:24 dgrisby
// Preliminary valuetype support.
//
// Revision 1.1.4.1 2003/03/23 21:51:57 dgrisby
// New omnipy3_develop branch.
//
// Revision 1.1.2.11 2001/09/24 10:48:28 dpg1
// Meaningful minor codes.
//
// Revision 1.1.2.10 2001/09/20 14:51:25 dpg1
// Allow ORB reinitialisation after destroy(). Clean up use of omni namespace.
//
// Revision 1.1.2.9 2001/08/21 10:52:41 dpg1
// Update to new ORB core APIs.
//
// Revision 1.1.2.8 2001/04/10 11:11:14 dpg1
// TypeCode support and tests for Fixed point.
//
// Revision 1.1.2.7 2001/04/09 15:52:07 dpg1
// Bring up-to-date with omnipy1_develop.
//
// Revision 1.1.2.6 2001/03/13 10:38:08 dpg1
// Fixes from omnipy1_develop
//
// Revision 1.1.2.5 2000/12/05 17:48:36 dpg1
// Strings in TypeCodes need to be marshalled as raw strings. Fix
// incorrect offset in recursive indirections.
//
// Revision 1.1.2.4 2000/12/04 18:58:02 dpg1
// Fix bug with TypeCode indirections.
//
// Revision 1.1.2.3 2000/11/06 17:10:09 dpg1
// Update to cdrStream interface
//
// Revision 1.1.2.2 2000/11/01 15:29:00 dpg1
// Support for forward-declared structs and unions
// RepoIds in indirections are now resolved at the time of use
//
// Revision 1.1.2.1 2000/10/13 13:55:27 dpg1
// Initial support for omniORB 4.
//
#include <omnipy.h>
OMNI_USING_NAMESPACE(omni)
// Objects to map descriptors to typecode offsets and vice-versa:
class DescriptorOffsetMap {
public:
DescriptorOffsetMap() :
dict_(PyDict_New()), base_(0)
{
}
DescriptorOffsetMap(DescriptorOffsetMap& dom, CORBA::Long offset) :
dict_(dom.getDict()), base_(dom.getBase() + offset)
{
}
~DescriptorOffsetMap() {
Py_DECREF(dict_);
}
inline void add(PyObject* desc, CORBA::Long offset) {
PyObject* desc_o = omniPy::newTwin(desc);
PyObject* oo = PyInt_FromLong(offset + base_);
PyDict_SetItem(dict_, desc_o, oo);
Py_DECREF(desc_o);
Py_DECREF(oo);
}
inline CORBA::Boolean lookup(PyObject* desc, CORBA::Long& offset) {
PyObject* desc_o = omniPy::newTwin(desc);
PyObject* oo = PyDict_GetItem(dict_, desc_o);
Py_DECREF(desc_o);
if (oo) {
offset = PyInt_AS_LONG(oo) - base_;
return 1;
}
return 0;
}
protected:
inline PyObject* getDict() { Py_INCREF(dict_); return dict_; }
inline CORBA::Long getBase() { return base_; }
private:
PyObject* dict_;
CORBA::Long base_;
DescriptorOffsetMap(const DescriptorOffsetMap&);
DescriptorOffsetMap& operator=(const DescriptorOffsetMap&);
};
class OffsetDescriptorMap {
public:
OffsetDescriptorMap() :
dict_(PyDict_New()), base_(0)
{
}
OffsetDescriptorMap(OffsetDescriptorMap& odm, CORBA::Long offset) :
dict_(odm.getDict()), base_(odm.getBase() + offset)
{
}
~OffsetDescriptorMap() {
Py_DECREF(dict_);
}
inline void add(PyObject* desc, CORBA::Long offset) {
PyObject* oo = PyInt_FromLong(offset + base_);
PyDict_SetItem(dict_, oo, desc);
Py_DECREF(oo);
}
inline CORBA::Boolean lookup(PyObject*& desc, CORBA::Long offset) {
PyObject* oo = PyInt_FromLong(offset + base_);
desc = PyDict_GetItem(dict_, oo);
Py_DECREF(oo);
if (desc) {
Py_INCREF(desc);
return 1;
}
return 0;
}
protected:
inline PyObject* getDict() { Py_INCREF(dict_); return dict_; }
inline CORBA::Long getBase() { return base_; }
private:
PyObject* dict_;
CORBA::Long base_;
OffsetDescriptorMap(const OffsetDescriptorMap&);
OffsetDescriptorMap& operator=(const OffsetDescriptorMap&);
};
static void
r_marshalTypeCode(cdrStream& stream,
PyObject* d_o,
DescriptorOffsetMap& dom)
{
CORBA::Long tc_offset;
// If this TypeCode has already been sent, use an indirection:
if (orbParameters::useTypeCodeIndirections && dom.lookup(d_o, tc_offset)) {
CORBA::ULong tk_ind = 0xffffffff;
tk_ind >>= stream;
CORBA::Long offset = tc_offset - stream.currentOutputPtr();
offset >>= stream;
}
else {
CORBA::ULong tk;
PyObject* t_o;
if (PyTuple_Check(d_o)) {
t_o = PyTuple_GET_ITEM(d_o, 0); OMNIORB_ASSERT(PyInt_Check(t_o));
tk = PyInt_AS_LONG(t_o);
}
else {
OMNIORB_ASSERT(PyInt_Check(d_o));
tk = PyInt_AS_LONG(d_o);
}
// Marshal the kind
if (tk != 0xffffffff) {
tk >>= stream;
// Offset of this TypeCode (within the current encapsulation if any):
tc_offset = stream.currentOutputPtr() - 4;
}
switch (tk) {
case CORBA::tk_null:
case CORBA::tk_void:
case CORBA::tk_short:
case CORBA::tk_long:
case CORBA::tk_ushort:
case CORBA::tk_ulong:
case CORBA::tk_float:
case CORBA::tk_double:
case CORBA::tk_boolean:
case CORBA::tk_char:
case CORBA::tk_octet:
case CORBA::tk_any:
case CORBA::tk_TypeCode:
case CORBA::tk_Principal:
#ifdef HAS_LongLong
case CORBA::tk_longlong:
case CORBA::tk_ulonglong:
#endif
case CORBA::tk_wchar:
// Nothing more to be sent
break;
case CORBA::tk_string:
{
// Send max length
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::ULong len = PyInt_AS_LONG(t_o);
len >>= stream;
}
break;
case CORBA::tk_wstring:
{
// Send max length
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::ULong len = PyInt_AS_LONG(t_o);
len >>= stream;
}
break;
case CORBA::tk_fixed:
{
// Send digits followed by scale
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::UShort digits = PyInt_AS_LONG(t_o);
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::Short scale = PyInt_AS_LONG(t_o);
digits >>= stream;
scale >>= stream;
}
break;
case CORBA::tk_objref:
{
// Add entry to descriptor offset map:
dom.add(d_o, tc_offset);
// Stream for the encapsulation
cdrEncapsulationStream encap;
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_struct:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 3); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// Count
CORBA::ULong cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
cnt >>= encap;
CORBA::ULong i, j, slen;
char* str;
for (i=0, j=4; i < cnt; i++) {
// member name
t_o = PyTuple_GET_ITEM(d_o, j++);
OMNIORB_ASSERT(PyString_Check(t_o));
str = PyString_AS_STRING(t_o);
slen = PyString_GET_SIZE(t_o) + 1;
if (str[0] == '_') { --slen; ++str; }
slen >>= encap;
if (slen > 1) {
encap.put_octet_array((const CORBA::Octet*)((const char*)str),
slen);
}
// member type
r_marshalTypeCode(encap, PyTuple_GET_ITEM(d_o, j++), edom);
}
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_union:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 3); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// Discriminant type
PyObject* discriminant = PyTuple_GET_ITEM(d_o, 4);
r_marshalTypeCode(encap, discriminant, edom);
// Default used
t_o = PyTuple_GET_ITEM(d_o, 5);
OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::Long defu = PyInt_AS_LONG(t_o);
defu >>= encap;
PyObject* mems;
PyObject* mem;
// Count
mems = PyTuple_GET_ITEM(d_o, 6); OMNIORB_ASSERT(PyTuple_Check(mems));
CORBA::ULong cnt = PyTuple_GET_SIZE(mems);
cnt >>= encap;
CORBA::ULong slen;
char* str;
for (CORBA::ULong i=0; i < cnt; i++) {
mem = PyTuple_GET_ITEM(mems, i); OMNIORB_ASSERT(PyTuple_Check(mem));
// Label value
omniPy::marshalPyObject(encap, discriminant,
PyTuple_GET_ITEM(mem, 0));
// Member name
t_o = PyTuple_GET_ITEM(mem, 1); OMNIORB_ASSERT(PyString_Check(t_o));
str = PyString_AS_STRING(t_o);
slen = PyString_GET_SIZE(t_o) + 1;
if (str[0] == '_') { --slen; ++str; }
slen >>= encap;
if (slen > 1) {
encap.put_octet_array((const CORBA::Octet*)((const char*)str),
slen);
}
// Member typecode
r_marshalTypeCode(encap, PyTuple_GET_ITEM(mem, 2), edom);
}
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_enum:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
PyObject* mems;
PyObject* mem;
// Count
mems = PyTuple_GET_ITEM(d_o, 3); OMNIORB_ASSERT(PyTuple_Check(mems));
CORBA::ULong cnt = PyTuple_GET_SIZE(mems);
cnt >>= encap;
for (CORBA::ULong i=0; i < cnt; i++) {
mem = PyTuple_GET_ITEM(mems, i);
OMNIORB_ASSERT(PyInstance_Check(mem));
// Member name
t_o = PyDict_GetItemString(((PyInstanceObject*)mem)->in_dict,
(char*)"_n");
omniPy::marshalRawPyString(encap, t_o);
}
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_sequence:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// Element type
r_marshalTypeCode(encap, PyTuple_GET_ITEM(d_o, 1), edom);
// Max length
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::ULong max_len = PyInt_AS_LONG(t_o);
max_len >>= encap;
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_array:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// Element type
r_marshalTypeCode(encap, PyTuple_GET_ITEM(d_o, 1), edom);
// Length
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::ULong arr_len = PyInt_AS_LONG(t_o);
arr_len >>= encap;
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_alias:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// TypeCode
r_marshalTypeCode(encap, PyTuple_GET_ITEM(d_o, 3), edom);
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_except:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 3); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// Count
CORBA::ULong cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
cnt >>= encap;
CORBA::ULong i, j, slen;
char* str;
for (i=0, j=4; i < cnt; i++) {
// member name
t_o = PyTuple_GET_ITEM(d_o, j++);
OMNIORB_ASSERT(PyString_Check(t_o));
str = PyString_AS_STRING(t_o);
slen = PyString_GET_SIZE(t_o) + 1;
if (str[0] == '_') { --slen; ++str; }
slen >>= encap;
if (slen > 1) {
encap.put_octet_array((const CORBA::Octet*)((const char*)str),
slen);
}
// member type
r_marshalTypeCode(encap, PyTuple_GET_ITEM(d_o, j++), edom);
}
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_value:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 3); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// ValueModifier
t_o = PyTuple_GET_ITEM(d_o, 4); OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::ValueModifier mod = PyInt_AS_LONG(t_o);
mod >>= encap;
// Concrete base
t_o = PyTuple_GET_ITEM(d_o, 6);
if (t_o == Py_None) {
// No base.
CORBA::ULong nulltk = CORBA::tk_null;
nulltk >>= encap;
}
else {
r_marshalTypeCode(encap, t_o, edom);
}
// Count
CORBA::ULong cnt = (PyTuple_GET_SIZE(d_o) - 7) / 3;
cnt >>= encap;
CORBA::ULong i, j, slen;
char* str;
for (i=0, j=7; i < cnt; i++) {
// member name
t_o = PyTuple_GET_ITEM(d_o, j++);
OMNIORB_ASSERT(PyString_Check(t_o));
str = PyString_AS_STRING(t_o);
slen = PyString_GET_SIZE(t_o) + 1;
if (str[0] == '_') { --slen; ++str; }
slen >>= encap;
if (slen > 1) {
encap.put_octet_array((const CORBA::Octet*)((const char*)str),
slen);
}
// member type
r_marshalTypeCode(encap, PyTuple_GET_ITEM(d_o, j++), edom);
// member visiblity
t_o = PyTuple_GET_ITEM(d_o, j++);
OMNIORB_ASSERT(PyInt_Check(t_o));
CORBA::UShort vis = PyInt_AS_LONG(t_o);
vis >>= encap;
}
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_value_box:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 3); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// Boxed type
t_o = PyTuple_GET_ITEM(d_o, 4);
r_marshalTypeCode(encap, t_o, edom);
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case CORBA::tk_abstract_interface:
{
dom.add(d_o, tc_offset);
cdrEncapsulationStream encap;
DescriptorOffsetMap edom(dom, tc_offset + 8);
// RepoId and name
t_o = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
t_o = PyTuple_GET_ITEM(d_o, 2); OMNIORB_ASSERT(PyString_Check(t_o));
omniPy::marshalRawPyString(encap, t_o);
// Send encapsulation
::operator>>=((CORBA::ULong)encap.bufSize(), stream);
stream.put_octet_array((CORBA::Octet*)encap.bufPtr(), encap.bufSize());
}
break;
case 0xffffffff:
{
PyObject* l = PyTuple_GET_ITEM(d_o, 1);
OMNIORB_ASSERT(PyList_Check(l));
t_o = PyList_GET_ITEM(l, 0); OMNIORB_ASSERT(t_o);
if (PyString_Check(t_o)) {
// Indirection to a repoId -- find the corresponding descriptor
t_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, t_o);
if (!t_o)
OMNIORB_THROW(BAD_PARAM, BAD_PARAM_IncompletePythonType,
(CORBA::CompletionStatus)stream.completion());
Py_INCREF(t_o);
PyList_SetItem(l, 0, t_o);
}
CORBA::Long position, offset;
if (dom.lookup(t_o, position)) {
tk >>= stream;
offset = position - stream.currentOutputPtr();
offset >>= stream;
}
else {
r_marshalTypeCode(stream, t_o, dom);
}
}
break;
default:
OMNIORB_THROW(BAD_TYPECODE, BAD_TYPECODE_UnknownKind,
(CORBA::CompletionStatus)stream.completion());
}
}
}
static inline void
skipString(cdrStream& stream)
{
CORBA::ULong len; len <<= stream;
if (!stream.checkInputOverrun(1, len))
OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
(CORBA::CompletionStatus)stream.completion());
stream.skipInput(len);
}
PyObject*
r_unmarshalTypeCode(cdrStream& stream, OffsetDescriptorMap& odm)
{
PyObject* d_o = 0; // Descriptor object to build
PyObject* t_o;
// Read kind
CORBA::ULong tk; tk <<= stream;
// Offset of current TypeCode
CORBA::Long tc_offset = stream.currentInputPtr() - 4;
switch (tk) {
case CORBA::tk_null:
case CORBA::tk_void:
case CORBA::tk_short:
case CORBA::tk_long:
case CORBA::tk_ushort:
case CORBA::tk_ulong:
case CORBA::tk_float:
case CORBA::tk_double:
case CORBA::tk_boolean:
case CORBA::tk_char:
case CORBA::tk_octet:
case CORBA::tk_any:
case CORBA::tk_TypeCode:
case CORBA::tk_Principal:
#ifdef HAS_LongLong
case CORBA::tk_longlong:
case CORBA::tk_ulonglong:
#endif
case CORBA::tk_wchar:
{
d_o = PyInt_FromLong(tk); odm.add(d_o, tc_offset);
}
break;
case CORBA::tk_string:
{
d_o = PyTuple_New(2); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
CORBA::ULong len; len <<= stream;
PyTuple_SET_ITEM(d_o, 1, PyInt_FromLong(len));
}
break;
case CORBA::tk_wstring:
{
d_o = PyTuple_New(2); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
CORBA::ULong len; len <<= stream;
PyTuple_SET_ITEM(d_o, 1, PyInt_FromLong(len));
}
break;
case CORBA::tk_fixed:
{
d_o = PyTuple_New(3); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
CORBA::UShort digits; digits <<= stream;
CORBA::Short scale; scale <<= stream;
PyTuple_SET_ITEM(d_o, 1, PyInt_FromLong(digits));
PyTuple_SET_ITEM(d_o, 2, PyInt_FromLong(scale));
}
break;
case CORBA::tk_objref:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
d_o = PyTuple_New(3); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
// RepoId and name
t_o = omniPy::unmarshalRawPyString(encap); PyTuple_SET_ITEM(d_o, 1, t_o);
t_o = omniPy::unmarshalRawPyString(encap); PyTuple_SET_ITEM(d_o, 2, t_o);
}
break;
case CORBA::tk_struct:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the structure
Py_INCREF(d_o);
Py_DECREF(repoId);
// We could unmarshal the whole TypeCode and check it for
// equivalence, but we don't bother. We still have to recurse
// into the TypeCode in case there are later indirections into
// it.
odm.add(d_o, tc_offset);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
skipString(encap); // Name
CORBA::ULong cnt; cnt <<= encap;
for (CORBA::ULong i=0; i < cnt; i++) {
// Member name and type
skipString(encap);
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
}
}
else {
// Don't know this structure
OffsetDescriptorMap eodm(odm, tc_offset + 8);
PyObject* name = omniPy::unmarshalRawPyString(encap);
CORBA::ULong cnt; cnt <<= encap;
d_o = PyTuple_New(cnt * 2 + 4); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyTuple_SET_ITEM(d_o, 2, repoId);
PyTuple_SET_ITEM(d_o, 3, name);
PyObject* mems = PyTuple_New(cnt);
CORBA::ULong i, j;
PyObject* word;
for (i=0, j=4; i < cnt; i++) {
// member name
t_o = omniPy::unmarshalRawPyString(encap);
if ((word = PyDict_GetItem(omniPy::pyomniORBwordMap, t_o))) {
Py_INCREF(word);
Py_DECREF(t_o);
t_o = word;
}
PyTuple_SET_ITEM(d_o, j++, t_o);
Py_INCREF(t_o);
PyTuple_SET_ITEM(mems, i, t_o);
// member type
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, j++, t_o);
}
// Create class object:
// *** Could be made faster by finding the createUnknownStruct
// function only once, and manually building the argument tuple
t_o = PyObject_GetAttrString(omniPy::pyomniORBmodule,
(char*)"createUnknownStruct");
OMNIORB_ASSERT(t_o && PyFunction_Check(t_o));
t_o = PyObject_CallFunction(t_o, (char*)"OO", repoId, mems);
OMNIORB_ASSERT(t_o);
Py_DECREF(mems);
PyTuple_SET_ITEM(d_o, 1, t_o);
}
}
break;
case CORBA::tk_union:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the union
Py_INCREF(d_o);
Py_DECREF(repoId);
// We could unmarshal the whole TypeCode and check it for
// equivalence, but we don't bother. We still have to recurse
// into the TypeCode in case there are later indirections into
// it.
odm.add(d_o, tc_offset);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
skipString(encap); // Name
PyObject* discriminant = r_unmarshalTypeCode(encap, eodm);
CORBA::Long def_used; def_used <<= encap;
CORBA::ULong cnt; cnt <<= encap;
for (CORBA::ULong i=0; i<cnt; i++) {
// Label value
t_o = omniPy::unmarshalPyObject(encap, discriminant); Py_DECREF(t_o);
// Member name
skipString(encap);
// Member type
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
}
Py_DECREF(discriminant);
}
else {
// Don't know this union
OffsetDescriptorMap eodm(odm, tc_offset + 8);
d_o = PyTuple_New(9); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyTuple_SET_ITEM(d_o, 2, repoId);
// name
t_o = omniPy::unmarshalRawPyString(encap);
PyTuple_SET_ITEM(d_o, 3, t_o);
// discriminant type
PyObject* discriminant = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, 4, discriminant);
// default used
CORBA::Long def_used; def_used <<= encap;
PyTuple_SET_ITEM(d_o, 5, PyInt_FromLong(def_used));
if (def_used < 0) {
Py_INCREF(Py_None);
PyTuple_SET_ITEM(d_o, 7, Py_None);
}
// count
CORBA::ULong cnt; cnt <<= encap;
PyObject* mems = PyTuple_New(cnt);
PyTuple_SET_ITEM(d_o, 6, mems);
PyObject* dict = PyDict_New();
PyTuple_SET_ITEM(d_o, 8, dict);
PyObject* mem;
PyObject* label;
PyObject* word;
for (CORBA::ULong i=0; i<cnt; i++) {
mem = PyTuple_New(3);
// Label value
label = omniPy::unmarshalPyObject(encap, discriminant);
PyTuple_SET_ITEM(mem, 0, label);
// Member name
t_o = omniPy::unmarshalRawPyString(encap);
if ((word = PyDict_GetItem(omniPy::pyomniORBwordMap, t_o))) {
Py_INCREF(word);
Py_DECREF(t_o);
t_o = word;
}
PyTuple_SET_ITEM(mem, 1, t_o);
// Member type
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(mem, 2, t_o);
PyTuple_SET_ITEM(mems, i, mem);
if (def_used > 0 && i == (CORBA::ULong)def_used) {
PyTuple_SET_ITEM(d_o, 7, mem);
}
else {
PyDict_SetItem(dict, label, mem);
}
}
// Create class object
t_o = PyObject_GetAttrString(omniPy::pyomniORBmodule,
(char*)"createUnknownUnion");
OMNIORB_ASSERT(t_o && PyFunction_Check(t_o));
t_o = PyObject_CallFunction(t_o, (char*)"OiO", repoId, def_used, mems);
OMNIORB_ASSERT(t_o);
PyTuple_SET_ITEM(d_o, 1, t_o);
}
}
break;
case CORBA::tk_enum:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the enum
Py_INCREF(d_o);
Py_DECREF(repoId);
odm.add(d_o, tc_offset);
}
else {
// Don't know this enum
d_o = PyTuple_New(4); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyTuple_SET_ITEM(d_o, 1, repoId);
// name
t_o = omniPy::unmarshalRawPyString(encap);
PyTuple_SET_ITEM(d_o, 2, t_o);
// count
CORBA::ULong cnt; cnt <<= encap;
PyObject* mems = PyTuple_New(cnt);
PyTuple_SET_ITEM(d_o, 3, mems);
PyObject* eclass = PyObject_GetAttrString(omniPy::pyomniORBmodule,
(char*)"EnumItem");
PyObject* aclass = PyObject_GetAttrString(omniPy::pyomniORBmodule,
(char*)"AnonymousEnumItem");
OMNIORB_ASSERT(eclass);
OMNIORB_ASSERT(aclass);
// members
for (CORBA::ULong i=0; i<cnt; i++) {
PyObject* mname = omniPy::unmarshalRawPyString(encap);
if (PyString_GET_SIZE(mname) > 0)
t_o = PyObject_CallFunction(eclass, (char*)"Oi", mname, i);
else
t_o = PyObject_CallFunction(aclass, (char*)"i", i);
Py_DECREF(mname);
OMNIORB_ASSERT(t_o);
PyObject_SetAttrString(t_o, (char*)"_parent_id", repoId);
PyTuple_SET_ITEM(mems, i, t_o);
}
}
}
break;
case CORBA::tk_sequence:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
d_o = PyTuple_New(3); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
// Element type
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, 1, t_o);
// Max length
CORBA::ULong len; len <<= encap;
PyTuple_SET_ITEM(d_o, 2, PyInt_FromLong(len));
}
break;
case CORBA::tk_array:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
d_o = PyTuple_New(3); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
// Element type
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, 1, t_o);
// Length
CORBA::ULong len; len <<= encap;
PyTuple_SET_ITEM(d_o, 2, PyInt_FromLong(len));
}
break;
case CORBA::tk_alias:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the alias
Py_INCREF(d_o);
Py_DECREF(repoId);
odm.add(d_o, tc_offset);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
skipString(encap); // name
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
}
else {
OffsetDescriptorMap eodm(odm, tc_offset + 8);
d_o = PyTuple_New(4); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyTuple_SET_ITEM(d_o, 1, repoId);
// name
t_o = omniPy::unmarshalRawPyString(encap);
PyTuple_SET_ITEM(d_o, 2, t_o);
// TypeCode
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, 3, t_o);
}
}
break;
case CORBA::tk_except:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the exception
Py_INCREF(d_o);
Py_DECREF(repoId);
odm.add(d_o, tc_offset);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
skipString(encap); // name
CORBA::ULong cnt; cnt <<= encap;
for (CORBA::ULong i=0; i < cnt; i++) {
// Member name and type
skipString(encap);
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
}
}
else {
// Don't know this exception
OffsetDescriptorMap eodm(odm, tc_offset + 8);
PyObject* name = omniPy::unmarshalRawPyString(encap);
CORBA::ULong cnt; cnt <<= encap;
d_o = PyTuple_New(cnt * 2 + 4); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyTuple_SET_ITEM(d_o, 2, repoId);
PyTuple_SET_ITEM(d_o, 3, name);
PyObject* mems = PyTuple_New(cnt);
CORBA::ULong i, j;
PyObject* word;
for (i=0, j=4; i < cnt; i++) {
// member name
t_o = omniPy::unmarshalRawPyString(encap);
if ((word = PyDict_GetItem(omniPy::pyomniORBwordMap, t_o))) {
Py_INCREF(word);
Py_DECREF(t_o);
t_o = word;
}
PyTuple_SET_ITEM(d_o, j++, t_o);
Py_INCREF(t_o);
PyTuple_SET_ITEM(mems, i, t_o);
// member type
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, j++, t_o);
}
// Create class object:
// *** Could be made faster by finding the createUnknownUserException
// function only once, and manually building the argument tuple
t_o = PyObject_GetAttrString(omniPy::pyomniORBmodule,
(char*)"createUnknownUserException");
OMNIORB_ASSERT(t_o && PyFunction_Check(t_o));
t_o = PyObject_CallFunction(t_o, (char*)"OO", repoId, mems);
OMNIORB_ASSERT(t_o);
Py_DECREF(mems);
PyTuple_SET_ITEM(d_o, 1, t_o);
}
}
break;
case CORBA::tk_value:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the value
Py_INCREF(d_o);
Py_DECREF(repoId);
// Unmarshal the rest in case of later indirections
odm.add(d_o, tc_offset);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
skipString(encap); // Name
CORBA::ValueModifier mod; mod <<= encap; // Modifier
// Skip concrete base
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
CORBA::ULong cnt; cnt <<= encap;
for (CORBA::ULong i=0; i < cnt; i++) {
// Member name, type, visibility
skipString(encap);
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
CORBA::UShort vis; vis <<= encap;
}
}
else {
// Don't know this value
OffsetDescriptorMap eodm(odm, tc_offset + 8);
PyObject* name = omniPy::unmarshalRawPyString(encap);
CORBA::ValueModifier mod; mod <<= encap;
PyObject* base = r_unmarshalTypeCode(encap, eodm);
CORBA::ULong basekind = omniPy::descriptorToTK(base);
if (!(basekind == CORBA::tk_value || basekind == CORBA::tk_null))
OMNIORB_THROW(MARSHAL, MARSHAL_InvalidTypeCodeKind,
(CORBA::CompletionStatus)stream.completion());
CORBA::ULong cnt; cnt <<= encap;
d_o = PyTuple_New(cnt * 3 + 7); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyTuple_SET_ITEM(d_o, 2, repoId);
PyTuple_SET_ITEM(d_o, 3, name);
PyTuple_SET_ITEM(d_o, 4, PyInt_FromLong(mod));
Py_INCREF(Py_None);
PyTuple_SET_ITEM(d_o, 5, Py_None); // Empty truncatable bases
PyTuple_SET_ITEM(d_o, 6, base);
CORBA::ULong i, j;
PyObject* word;
for (i=0, j=7; i < cnt; i++) {
// member name
t_o = omniPy::unmarshalRawPyString(encap);
if ((word = PyDict_GetItem(omniPy::pyomniORBwordMap, t_o))) {
Py_INCREF(word);
Py_DECREF(t_o);
t_o = word;
}
PyTuple_SET_ITEM(d_o, j++, t_o);
Py_INCREF(t_o);
// member type
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, j++, t_o);
// member visibility
CORBA::UShort vis; vis <<= encap;
PyTuple_SET_ITEM(d_o, j++, PyInt_FromLong(vis));
}
// Create class object
t_o = PyObject_GetAttrString(omniPy::pyomniORBmodule,
(char*)"createUnknownValue");
OMNIORB_ASSERT(t_o && PyFunction_Check(t_o));
t_o = PyObject_CallFunction(t_o, (char*)"OO", repoId, base);
OMNIORB_ASSERT(t_o);
PyTuple_SET_ITEM(d_o, 1, t_o);
}
}
break;
case CORBA::tk_value_box:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
PyObject* repoId = omniPy::unmarshalRawPyString(encap);
d_o = PyDict_GetItem(omniPy::pyomniORBtypeMap, repoId);
if (d_o) {
// Static knowledge of the valuebox
Py_INCREF(d_o);
Py_DECREF(repoId);
odm.add(d_o, tc_offset);
OffsetDescriptorMap eodm(odm, tc_offset + 8);
skipString(encap); // name
t_o = r_unmarshalTypeCode(encap, eodm); Py_DECREF(t_o);
}
else {
OffsetDescriptorMap eodm(odm, tc_offset + 8);
d_o = PyTuple_New(5); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
// Member 1 is valuebox class in static stubs, but it's not used.
Py_INCREF(Py_None);
PyTuple_SET_ITEM(d_o, 1, Py_None);
PyTuple_SET_ITEM(d_o, 2, repoId);
// name
t_o = omniPy::unmarshalRawPyString(encap);
PyTuple_SET_ITEM(d_o, 3, t_o);
// TypeCode
t_o = r_unmarshalTypeCode(encap, eodm);
PyTuple_SET_ITEM(d_o, 4, t_o);
}
}
break;
case CORBA::tk_abstract_interface:
{
CORBA::ULong size; size <<= stream;
cdrEncapsulationStream encap(stream, size);
d_o = PyTuple_New(3); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
// RepoId and name
t_o = omniPy::unmarshalRawPyString(encap); PyTuple_SET_ITEM(d_o, 1, t_o);
t_o = omniPy::unmarshalRawPyString(encap); PyTuple_SET_ITEM(d_o, 2, t_o);
}
break;
case 0xffffffff:
{
CORBA::Long position, offset;
offset <<= stream;
position = tc_offset + 4 + offset;
if (!odm.lookup(t_o, position))
OMNIORB_THROW(MARSHAL, MARSHAL_InvalidIndirection,
(CORBA::CompletionStatus)stream.completion());
d_o = PyTuple_New(2); odm.add(d_o, tc_offset);
PyTuple_SET_ITEM(d_o, 0, PyInt_FromLong(tk));
PyObject* olist = PyList_New(1);
PyList_SET_ITEM(olist, 0, t_o);
PyTuple_SET_ITEM(d_o, 1, olist);
}
break;
default:
OMNIORB_THROW(BAD_TYPECODE, BAD_TYPECODE_UnknownKind,
(CORBA::CompletionStatus)stream.completion());
}
return d_o;
}
void
omniPy::marshalTypeCode(cdrStream& stream, PyObject* d_o)
{
DescriptorOffsetMap dom;
r_marshalTypeCode(stream, d_o, dom);
}
PyObject*
omniPy::unmarshalTypeCode(cdrStream& stream)
{
OffsetDescriptorMap odm;
return r_unmarshalTypeCode(stream, odm);
}
syntax highlighted by Code2HTML, v. 0.9.1