00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "UnionDef.h"
00024
00025 #include "Repository.h"
00026 #include "PersistNode.h"
00027 #include "string_to.h"
00028
00029 #include <string.h>
00030
00031 namespace Omniifr {
00032
00033 TypeCode_ptr UnionDef_impl::discriminator_type()
00034 {
00035 return _discriminator_type_def.in()->type();
00036 }
00037
00038 IDLType_ptr UnionDef_impl::discriminator_type_def()
00039 {
00040 return _discriminator_type_def.copy();
00041 }
00042
00043 void UnionDef_impl::discriminator_type_def(IDLType_ptr v)
00044 {
00045 checkReadonly();
00046 TypeCode_var tc =v->type();
00047 TCKind kind =tc->kind();
00048
00049 while(kind==tk_alias)
00050 {
00051 tc=tc->content_type();
00052 kind=tc->kind();
00053 }
00054
00055 switch(kind)
00056 {
00057 case tk_short:
00058 case tk_ushort:
00059 case tk_long:
00060 case tk_ulong:
00061 #ifdef HAS_LongLong
00062 case tk_longlong:
00063 case tk_ulonglong:
00064 #endif
00065 case tk_char:
00066 case tk_wchar:
00067 case tk_boolean:
00068 case tk_enum:
00069 {
00070
00071
00072 if(!is_nil(_discriminator_type_def.in()))
00073 {
00074 TypeCode_var oldTc =discriminator_type();
00075 if(!tc->equivalent(oldTc.in()))
00076 _members.assign(UnionMemberSeq());
00077 }
00078 _discriminator_type_def.assign(CORBA::IDLType::_duplicate(v));
00079 }
00080 break;
00081
00082 default:
00083 throw CORBA::BAD_PARAM(
00084 IFELSE_OMNIORB4(omni::BAD_PARAM_IllegitimateDiscriminatorType,20),
00085 CORBA::COMPLETED_NO
00086 );
00087 }
00088 }
00089
00090 UnionMemberSeq* UnionDef_impl::members()
00091 {
00092 return _members.copy();
00093 }
00094
00095 void UnionDef_impl::members(const UnionMemberSeq& v)
00096 {
00097 checkReadonly();
00098 UnionMemberSeq temp(v);
00099 TypeCode_var discriminatorType =discriminator_type();
00100
00101
00102
00103
00104 for(ULong i=0; i<temp.length(); ++i)
00105 {
00106 IdentifierUtil::checkInvalid(temp[i].name);
00107 if(CORBA::is_nil(temp[i].type_def))
00108 throw CORBA::BAD_PARAM(
00109 IFELSE_OMNIORB4(omni::BAD_PARAM_InvalidObjectRef,43),
00110 CORBA::COMPLETED_NO
00111 );
00112
00113
00114 try
00115 {
00116 temp[i].type=temp[i].type_def->type();
00117 }
00118 catch(...)
00119 {
00120 DB(15,"Caught exception at "<<__FILE__<<":"<<__LINE__)
00121 throw;
00122 }
00123
00124
00125 CORBA::Octet oct;
00126 bool isDefaultLabel=((temp[i].label>>=CORBA::Any::to_octet(oct)) && oct==0);
00127 if(!isDefaultLabel)
00128 {
00129
00130 TypeCode_var labelType =temp[i].label.type();
00131 if(!labelType->equivalent(discriminatorType.in()))
00132 throw CORBA::BAD_PARAM(
00133 IFELSE_OMNIORB4(omni::BAD_PARAM_IncompatibleDiscriminatorType,19),
00134 CORBA::COMPLETED_NO
00135 );
00136
00137
00138 DynamicAny::DynAny_var dai =
00139 Repository_impl::inst()._DynAnyFactory->create_dyn_any(temp[i].label);
00140 bool uniqueLabel =true;
00141 for(ULong j=0; uniqueLabel && j<i; ++j)
00142 {
00143 DynamicAny::DynAny_var daj =
00144 Repository_impl::inst()._DynAnyFactory->create_dyn_any(temp[j].label);
00145 if(dai->equal(daj))
00146 uniqueLabel=false;
00147 daj->destroy();
00148 }
00149 dai->destroy();
00150 if(!uniqueLabel)
00151 throw CORBA::BAD_PARAM(
00152 IFELSE_OMNIORB4(omni::BAD_PARAM_DuplicateLabelValue,18),
00153 CORBA::COMPLETED_NO
00154 );
00155 }
00156
00157
00158
00159
00160 bool match =true;
00161 for(Long k=i-1; k>=0; --k)
00162 {
00163 switch(IdentifierUtil::compare(temp[i].name,temp[k].name))
00164 {
00165 case IdentifierUtil::equalMatch:
00166 if(! (match && temp[i].type->equal(temp[k].type)) )
00167 throw CORBA::BAD_PARAM();
00168 break;
00169
00170 case IdentifierUtil::equivalentMatch:
00171 throw CORBA::BAD_PARAM(
00172 IFELSE_OMNIORB4(omni::BAD_PARAM_InvalidMemberName,17),
00173 CORBA::COMPLETED_NO
00174 );
00175
00176 case IdentifierUtil::noMatch:
00177 match=false;
00178 break;
00179
00180 default:
00181 assert(false);
00182 };
00183 }
00184 }
00185
00186
00187 _members.uncheckedAssign(temp);
00188 }
00189
00190 TypeCode_ptr UnionDef_impl::type()
00191 {
00192 TypeCode_var tc =discriminator_type();
00193 return Repository_impl::inst()._orb
00194 ->create_union_tc(_id.in(),_name.in(),tc.in(),_members.in());
00195 }
00196
00197 void UnionDef_impl::uncheckedDestroy()
00198 {
00199 _members.clear();
00200 _discriminator_type_def.clear();
00201 Contained_impl::uncheckedDestroy();
00202 Container_impl::uncheckedDestroy();
00203 }
00204
00205 bool UnionDef_impl::canContain(DefinitionKind kind)
00206 {
00207 switch(kind)
00208 {
00209 case dk_Struct:
00210 case dk_Union:
00211 case dk_Enum:
00212 return true;
00213 default:
00214 return false;
00215 }
00216 }
00217
00218 void UnionDef_impl::reincarnate(const PersistNode& node)
00219 {
00220 _discriminator_type_def.assign(
00221 string_to_<CORBA::IDLType>(node.attrString("discriminator_type_def").c_str())
00222 );
00223
00224 cdrMemoryStream memstr =node.attrCdrStream("state");
00225 UnionMemberSeq m;
00226 m<<=memstr;
00227 _members.uncheckedAssign(m);
00228 }
00229
00230 void UnionDef_impl::output(ostream &os)
00231 {
00232 outputSelf(os,"UnionDef");
00233 PersistNode::outputIOR(os,
00234 _discriminator_type_def.in(),
00235 "\n discriminator_type_def="
00236 );
00237 cdrMemoryStream memstr(CORBA::ULong(0),CORBA::Boolean(1));
00238 _members.in()>>=memstr;
00239 PersistNode::outputCdrMemoryStream(os,memstr,"\n state=");
00240 os<<" ;;\n";
00241 outputContents(os);
00242 }
00243
00244 }