/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * ORBit: A CORBA v2.2 ORB * * Copyright (C) 1998 Richard H. Porter * * This 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * Author: Dick Porter * */ #include #include #include "orbit.h" /* FIXME: Right now this function doesn't record whether or not it has already visited a given TypeCode. I'm not sure if every recursive type will have a tk_recursive node in it; if not, then this will need to be reworked a bit. */ CORBA_boolean CORBA_TypeCode_equal(CORBA_TypeCode obj, CORBA_TypeCode tc, CORBA_Environment *ev) { int i; g_return_val_if_fail(obj!=NULL, CORBA_FALSE); g_return_val_if_fail(tc!=NULL, CORBA_FALSE); if (obj->kind != tc->kind) { return CORBA_FALSE; } switch (obj->kind) { case CORBA_tk_wstring: case CORBA_tk_string: return obj->length == tc->length; case CORBA_tk_objref: return ! strcmp (obj->repo_id, tc->repo_id); case CORBA_tk_except: case CORBA_tk_struct: if (strcmp (obj->repo_id, tc->repo_id) || obj->sub_parts != tc->sub_parts) return CORBA_FALSE; for (i = 0; i < obj->sub_parts; ++i) if (! CORBA_TypeCode_equal (obj->subtypes[i], tc->subtypes[i], ev)) return CORBA_FALSE; break; case CORBA_tk_union: if (strcmp (obj->repo_id, tc->repo_id) || obj->sub_parts != tc->sub_parts || ! CORBA_TypeCode_equal (obj->discriminator, tc->discriminator, ev) || obj->default_index != tc->default_index) return CORBA_FALSE; for (i = 0; i < obj->sub_parts; ++i) /* FIXME: I think the only way to check two CORBA_any's for equivalence is to understand their implementation. But we haven't written that yet. So we fake it for now. */ if (! CORBA_TypeCode_equal (obj->subtypes[i], tc->subtypes[i], ev) || ! ORBit_any_equivalent (obj->sublabels[i], tc->sublabels[i], ev)) return CORBA_FALSE; break; case CORBA_tk_enum: if (obj->sub_parts != tc->sub_parts || strcmp (obj->repo_id, tc->repo_id)) return CORBA_FALSE; for (i = 0; i < obj->sub_parts; ++i) if (strcmp (obj->subnames[i], tc->subnames[i])) return CORBA_FALSE; break; case CORBA_tk_sequence: case CORBA_tk_array: if (obj->length != tc->length) return CORBA_FALSE; g_assert (obj->sub_parts == 1); g_assert (tc->sub_parts == 1); return CORBA_TypeCode_equal (obj->subtypes[0], tc->subtypes[0], ev); case CORBA_tk_alias: if (strcmp (obj->repo_id, tc->repo_id)) return CORBA_FALSE; g_assert (obj->sub_parts == 1); g_assert (tc->sub_parts == 1); return CORBA_TypeCode_equal (obj->subtypes[0], tc->subtypes[0], ev); break; case CORBA_tk_recursive: return obj->recurse_depth == tc->recurse_depth; case CORBA_tk_fixed: return obj->digits == tc->digits && obj->scale == tc->scale; default: /* Everything else is primitive. */ break; } return CORBA_TRUE; } CORBA_TCKind CORBA_TypeCode_kind(CORBA_TypeCode obj, CORBA_Environment *ev) { return obj->kind; } static void bad_kind (CORBA_Environment *ev) { CORBA_TypeCode_BadKind *err; err = g_new (CORBA_TypeCode_BadKind, 1); if (err == NULL) { CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO); } else { err->dummy = 23; CORBA_exception_set (ev, CORBA_USER_EXCEPTION, "IDL:omg.org/CORBA/TypeCode/BadKind/1.0", err); } } CORBA_RepositoryId CORBA_TypeCode_id(CORBA_TypeCode obj, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_objref || obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_enum || obj->kind == CORBA_tk_alias || obj->kind == CORBA_tk_except)) { bad_kind (ev); return NULL; } return obj->repo_id; } CORBA_Identifier CORBA_TypeCode_name(CORBA_TypeCode obj, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_objref || obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_enum || obj->kind == CORBA_tk_alias || obj->kind == CORBA_tk_except)) { bad_kind (ev); return NULL; } return obj->name; } CORBA_unsigned_long CORBA_TypeCode_member_count(CORBA_TypeCode obj, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union || obj->kind == CORBA_tk_enum)) { bad_kind (ev); return 0; } return obj->sub_parts; } static void bounds_error (CORBA_Environment *ev) { CORBA_TypeCode_Bounds *err; err = g_new (CORBA_TypeCode_Bounds, 1); if (err == NULL) { CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO); } else { err->dummy = 23; CORBA_exception_set (ev, CORBA_USER_EXCEPTION, "IDL:omg.org/CORBA/TypeCode/Bounds/1.0", err); } } CORBA_Identifier CORBA_TypeCode_member_name(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union || obj->kind == CORBA_tk_enum)) { bad_kind (ev); return NULL; } if (index > obj->sub_parts) { bounds_error (ev); return NULL; } return obj->subnames[index]; } CORBA_TypeCode CORBA_TypeCode_member_type(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_struct || obj->kind == CORBA_tk_union || obj->kind == CORBA_tk_enum)) { bad_kind (ev); return NULL; } if (index > obj->sub_parts) { bounds_error (ev); return NULL; } return obj->subtypes[index]; } CORBA_any *CORBA_TypeCode_member_label(CORBA_TypeCode obj, CORBA_unsigned_long index, CORBA_Environment *ev) { if (obj->kind != CORBA_tk_union) { bad_kind (ev); return NULL; } if (index > obj->sub_parts) { bounds_error (ev); return NULL; } return &obj->sublabels[index]; } CORBA_TypeCode CORBA_TypeCode_discriminator_type(CORBA_TypeCode obj, CORBA_Environment *ev) { if (obj->kind != CORBA_tk_union) { bad_kind (ev); return NULL; } return obj->discriminator; } CORBA_long CORBA_TypeCode_default_index(CORBA_TypeCode obj, CORBA_Environment *ev) { if (obj->kind != CORBA_tk_union) { bad_kind (ev); return 0; } return obj->default_index; } CORBA_unsigned_long CORBA_TypeCode_length(CORBA_TypeCode obj, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_string || obj->kind == CORBA_tk_wstring || obj->kind == CORBA_tk_array)) { bad_kind (ev); return 0; } return obj->length; } CORBA_TypeCode CORBA_TypeCode_content_type(CORBA_TypeCode obj, CORBA_Environment *ev) { if (! (obj->kind == CORBA_tk_sequence || obj->kind == CORBA_tk_array || obj->kind == CORBA_tk_alias)) { bad_kind (ev); return NULL; } g_assert (obj->sub_parts == 1); return obj->subtypes[0]; } CORBA_unsigned_short CORBA_TypeCode_fixed_digits(CORBA_TypeCode obj, CORBA_Environment *ev) { if (obj->kind != CORBA_tk_fixed) { bad_kind (ev); return 0; } return obj->digits; } CORBA_short CORBA_TypeCode_fixed_scale(CORBA_TypeCode obj, CORBA_Environment *ev) { if (obj->kind != CORBA_tk_fixed) { bad_kind (ev); return 0; } return obj->scale; } CORBA_long CORBA_TypeCode_param_count(CORBA_TypeCode obj, CORBA_Environment *ev) { g_assert(!"Deprecated"); return(0); } CORBA_any *CORBA_TypeCode_parameter(CORBA_TypeCode obj, CORBA_long index, CORBA_Environment *ev) { g_assert(!"Deprecated"); return(NULL); }