00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file TypeCode.h 00006 * 00007 * $Id: TypeCode.h 89975 2010-04-23 08:27:53Z johnnyw $ 00008 * 00009 * Header file the @c CORBA::TypeCode class. 00010 * 00011 * @author Ossama Othman <ossama@dre.vanderbilt.edu> 00012 * @author DOC group at Vanderbilt University, Washington University 00013 * and the University of California at Irvine. 00014 */ 00015 //============================================================================= 00016 00017 #ifndef TAO_TYPECODE_H 00018 #define TAO_TYPECODE_H 00019 00020 #include /**/ "ace/pre.h" 00021 00022 #include "tao/AnyTypeCode/TAO_AnyTypeCode_Export.h" 00023 00024 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00025 # pragma once 00026 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00027 00028 #include "tao/AnyTypeCode/AnyTypeCode_methods.h" 00029 #include "tao/AnyTypeCode/ValueModifierC.h" 00030 #include "tao/AnyTypeCode/VisibilityC.h" 00031 #include "tao/UserException.h" 00032 #include "tao/Basic_Types.h" 00033 #include "tao/Typecode_typesC.h" 00034 #include "tao/Any_Insert_Policy_T.h" 00035 #include "tao/CORBA_methods.h" 00036 #include "tao/Pseudo_VarOut_T.h" 00037 #include "tao/Object_Argument_T.h" 00038 #include "tao/Arg_Traits_T.h" 00039 #include "tao/Objref_VarOut_T.h" 00040 00041 #if defined (TAO_EXPORT_MACRO) 00042 #undef TAO_EXPORT_MACRO 00043 #endif 00044 #define TAO_EXPORT_MACRO TAO_AnyTypeCode_Export 00045 00046 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00047 00048 namespace CORBA 00049 { 00050 typedef TAO_Pseudo_Var_T<TypeCode> TypeCode_var; 00051 typedef TAO_Pseudo_Out_T<TypeCode> TypeCode_out; 00052 00053 /** 00054 * @class TypeCode 00055 * 00056 * @brief A representation of the structure of a given OMG 00057 * IDL-declared type. 00058 * 00059 * @c TypeCodes are primarily used by @c CORBA::Anys, the CORBA 00060 * Interface Repository and the CORBA Dynamic Invocation Interface. 00061 */ 00062 class TAO_AnyTypeCode_Export TypeCode 00063 { 00064 public: 00065 00066 /** 00067 * @class Bounds 00068 * 00069 * @brief Out-of-bounds member index exception. 00070 * 00071 * Exception thrown when attempting to pass an out-of-bounds index 00072 * value to a @c TypeCode operation that accepts a member index 00073 * argument. 00074 */ 00075 class TAO_AnyTypeCode_Export Bounds : public UserException 00076 { 00077 public: 00078 00079 /// Constructor. 00080 Bounds (void); 00081 00082 static Bounds * _downcast (CORBA::Exception * ex); 00083 static CORBA::Exception * _alloc (void); 00084 00085 virtual CORBA::Exception * _tao_duplicate (void) const; 00086 00087 virtual void _raise (void) const; 00088 00089 virtual void _tao_encode (TAO_OutputCDR & cdr) const; 00090 virtual void _tao_decode (TAO_InputCDR & cdr); 00091 }; 00092 00093 /** 00094 * @class BadKind 00095 * 00096 * @brief Invalid @c TypeCode operation exception. 00097 * 00098 * Exception thrown when attempting to invoke a @c TypeCode 00099 * operation that is not valid for the type represented by the 00100 * @c TypeCode. 00101 */ 00102 class TAO_AnyTypeCode_Export BadKind : public CORBA::UserException 00103 { 00104 public: 00105 00106 BadKind (void); 00107 00108 static BadKind * _downcast (CORBA::Exception * ex); 00109 static CORBA::Exception * _alloc (void); 00110 00111 virtual CORBA::Exception * _tao_duplicate (void) const; 00112 00113 virtual void _raise (void) const; 00114 00115 virtual void _tao_encode (TAO_OutputCDR & cdr) const; 00116 virtual void _tao_decode (TAO_InputCDR & cdr); 00117 }; 00118 00119 static CORBA::TypeCode_ptr const _tc_Bounds; 00120 static CORBA::TypeCode_ptr const _tc_BadKind; 00121 00122 /// Duplicate this @c TypeCode. 00123 /** 00124 * Statically instantiated @c TypeCodes incur no reference count 00125 * manipulation, i.e. reference counting is a no-op. 00126 * 00127 * Dynamically instantiated @c TypeCodes will have their reference 00128 * count incremented by one each time this function is called. 00129 */ 00130 static CORBA::TypeCode_ptr _duplicate (CORBA::TypeCode_ptr tc); 00131 00132 /// Returns a NULL typecode. 00133 static CORBA::TypeCode_ptr _nil (void); 00134 00135 /** 00136 * @name @c CORBA::TypeCode Methods 00137 * 00138 * These methods are part of the public interface of @c 00139 * CORBA::TypeCode class, as defined by the OMG CORBA 00140 * specification and C++ mapping. 00141 * 00142 * The C++ mapping does not declare the methods in the public 00143 * @c CORBA::TypeCode API as @c virtual, so work around that by 00144 * making these methods inlined to forward all calls to the 00145 * corresponding protected template method (i.e. the design 00146 * pattern, not the C++ feature) listed below in the @c protected 00147 * block. 00148 */ 00149 //@{ 00150 /// Equality of two @c TypeCodes. 00151 /** 00152 * @return @c true if and only if the set of legal operations is 00153 * the same and invoking any operation on the this 00154 * @c TypeCode and @a tc returns identical results. 00155 */ 00156 Boolean equal (TypeCode_ptr tc) const; 00157 00158 /// Equivalence of two @c TypeCodes. 00159 /** 00160 * Equivalence of two @c TypeCodes satisfies a subset of the 00161 * requirements necessary for equality. 00162 * 00163 * @see equal 00164 */ 00165 Boolean equivalent (TypeCode_ptr tc) const; 00166 00167 /// The kind of @c TypeCode. 00168 TCKind kind (void) const; 00169 00170 /// Return @c TypeCode stripped of optional @c name and 00171 /// @c member_name fields. 00172 /** 00173 * @note Calling this method will incur additional run-time memory 00174 * consumption since TAO's implementation relies on the 00175 * TypeCodeFactory to dynamically create a compact @c 00176 * TypeCode; the exception being @c TypeCodes with empty 00177 * parameter lists. Those @c TypeCodes are already compact, 00178 * meaning that call this method on such @c TypeCodes incurs 00179 * no additional run-time memory requirements. 00180 * 00181 * Unless you need to send compact @c TypeCodes 00182 * "over-the-wire" or your @c TypeCode corresponds to a 00183 * type with a large number of members, try to stick with 00184 * the existing potentially non-compact @c TypeCode. 00185 * 00186 * @note Compact @c TypeCodes may also be generated statically by 00187 * the TAO_IDL compiler by invoking it with its "-Gt" 00188 * (i.e. enable optimized TypeCodes) command line option. 00189 */ 00190 TypeCode_ptr get_compact_typecode (void) const; 00191 00192 /// The @c RepositoryId globally identifying the type. 00193 /** 00194 * This method is valid for the following kinds of @c TypeCodes: 00195 * 00196 * @li @c tk_objref 00197 * @li @c tk_struct 00198 * @li @c tk_union 00199 * @li @c tk_enum 00200 * @li @c tk_alias 00201 * @li @c tk_value 00202 * @li @c tk_value_box 00203 * @li @c tk_native 00204 * @li @c tk_abstract_interface 00205 * @li @c tk_local_interface 00206 * @li @c tk_except 00207 * @li @c tk_component 00208 * @li @c tk_home 00209 * @li @c tk_event 00210 * 00211 * @note CORBA::TypeCode::id() does not follow the usual parameter 00212 * passing rules defined by the C++ mapping. This behavior 00213 * is required by the C++ mapping. In particular, ownership 00214 * is maintained by the @c TypeCode. 00215 */ 00216 char const * id (void) const; 00217 00218 /// The simple name identifying the type within its enclosing 00219 /// scope. 00220 /** 00221 * This method is valid for the following kinds of @c TypeCodes: 00222 * 00223 * @li @c tk_objref 00224 * @li @c tk_struct 00225 * @li @c tk_union 00226 * @li @c tk_enum 00227 * @li @c tk_alias 00228 * @li @c tk_value 00229 * @li @c tk_value_box 00230 * @li @c tk_native 00231 * @li @c tk_abstract_interface 00232 * @li @c tk_local_interface 00233 * @li @c tk_except 00234 * @li @c tk_component 00235 * @li @c tk_home 00236 * @li @c tk_event 00237 * 00238 * @note CORBA::TypeCode::name() does not follow the usual 00239 * parameter passing rules defined by the C++ mapping. This 00240 * behavior is required by the C++ mapping. In particular, 00241 * ownership is maintained by the @c TypeCode. 00242 */ 00243 char const * name (void) const; 00244 00245 /// The type member count. 00246 /** 00247 * This method is valid for the following kinds of @c TypeCodes: 00248 * 00249 * @li @c tk_struct 00250 * @li @c tk_union 00251 * @li @c tk_enum 00252 * @li @c tk_value 00253 * @li @c tk_except 00254 * @li @c tk_event 00255 */ 00256 ULong member_count (void) const; 00257 00258 /// The type member name. 00259 /** 00260 * This method is valid for the following kinds of @c TypeCodes: 00261 * 00262 * @li @c tk_struct 00263 * @li @c tk_union 00264 * @li @c tk_enum 00265 * @li @c tk_value 00266 * @li @c tk_except 00267 * @li @c tk_event 00268 * 00269 * @note CORBA::TypeCode::member_name() does not follow the usual 00270 * parameter passing rules defined by the C++ mapping. This 00271 * behavior is required by the C++ mapping. In particular, 00272 * ownership is maintained by the @c TypeCode. 00273 */ 00274 char const * member_name (ULong index) const; 00275 00276 /// The type member @c TypeCode. 00277 /** 00278 * This method is valid for the following kinds of @c TypeCodes: 00279 * 00280 * @li @c tk_struct 00281 * @li @c tk_union 00282 * @li @c tk_value 00283 * @li @c tk_except 00284 * @li @c tk_event 00285 */ 00286 TypeCode_ptr member_type (ULong index) const; 00287 00288 /// The union member label. 00289 /** 00290 * This method is valid for the following kinds of @c TypeCodes: 00291 * 00292 * @li @c tk_union 00293 */ 00294 Any * member_label (ULong index) const; 00295 00296 /// The type of all non-default union member labels. 00297 /** 00298 * This method is valid for the following kinds of @c TypeCodes: 00299 * 00300 * @li @c tk_union 00301 */ 00302 TypeCode_ptr discriminator_type (void) const; 00303 00304 /// The index of the default union member. 00305 /** 00306 * This method is valid for the following kinds of @c TypeCodes: 00307 * 00308 * @li @c tk_union 00309 */ 00310 Long default_index (void) const; 00311 00312 /// The length of the type. 00313 /** 00314 * This method is valid for the following kinds of @c TypeCodes: 00315 * 00316 * @li @c tk_string 00317 * @li @c tk_wstring 00318 * @li @c tk_sequence 00319 * @li @c tk_array 00320 */ 00321 ULong length (void) const; 00322 00323 /// The underlying content type. 00324 /** 00325 * This method is valid for the following kinds of @c TypeCodes: 00326 * 00327 * @li @c tk_sequence 00328 * @li @c tk_array 00329 * @li @c tk_value_box 00330 * @li @c tk_alias 00331 */ 00332 TypeCode_ptr content_type (void) const; 00333 00334 /// The number of significant digits. 00335 /** 00336 * This method is valid for the following kinds of @c TypeCodes: 00337 * 00338 * @li @c tk_fixed 00339 */ 00340 UShort fixed_digits (void) const; 00341 00342 /// The scale factor. 00343 /** 00344 * This method is valid for the following kinds of @c TypeCodes: 00345 * 00346 * @li @c tk_fixed 00347 */ 00348 UShort fixed_scale (void) const; 00349 00350 /// The @c Visibility of the @c valuetype or @c eventtype member 00351 /// corresponding to index @a index. 00352 /** 00353 * This method is valid for the following kinds of @c TypeCodes: 00354 * 00355 * @li @c tk_value 00356 * @li @c tk_event 00357 */ 00358 Visibility member_visibility (ULong index) const; 00359 00360 /// The @c ValueModifier of the @c valuetype of @c eventtype 00361 /// represented by this @c TypeCode. 00362 /** 00363 * This method is valid for the following kinds of @c TypeCodes: 00364 * 00365 * @li @c tk_value 00366 * @li @c tk_event 00367 */ 00368 ValueModifier type_modifier (void) const; 00369 00370 /// The @c TypeCode corresponding to the concrete base 00371 /// @c valuetype or @c eventtype. 00372 /** 00373 * This method is valid for the following kinds of @c TypeCodes: 00374 * 00375 * @li @c tk_value 00376 * @li @c tk_event 00377 * 00378 * @return @c TypeCode corresponding to the concrete base 00379 * @c valuetype or @c eventtype. 00380 * @c CORBA::TypeCode::_nil() if no concrete base exists. 00381 */ 00382 TypeCode_ptr concrete_base_type (void) const; 00383 //@} 00384 00385 /// Marshal the @c TypeCode @c TCKind. 00386 /** 00387 * 00388 */ 00389 virtual bool tao_marshal_kind (TAO_OutputCDR & cdr) const; 00390 00391 /// Marshal this @c TypeCode into a CDR output stream. 00392 /** 00393 * Marshal this @c TypeCode into the @a cdr output CDR stream, 00394 * excluding the @c TypeCode kind. Existing @a cdr contents will 00395 * not be altered. The marshaled @c TypeCode will be appended to 00396 * the given @a cdr CDR output stream. 00397 * 00398 * @param cdr Output CDR stream into which the @c TypeCode will be 00399 * marshaled. 00400 * 00401 * @param offset Number of bytes currently in the output CDR 00402 * stream, including the top-level TypeCode @c 00403 * TCKind. This argument is useful for recursive 00404 * @c TypeCodes. @c TypeCodes that contain other 00405 * @c TypeCodes should pass an updated @a offset 00406 * value to the marshaling operation for those 00407 * contained @c TypeCodes. 00408 * 00409 * @return @c true if marshaling was successful. 00410 * 00411 * @note This is a TAO-specific method that is not part of the 00412 * standard @c CORBA::TypeCode interface. 00413 * 00414 * @note If this method returns false, the contents of the @a cdr 00415 * output CDR stream are undefined. 00416 */ 00417 virtual bool tao_marshal (TAO_OutputCDR & cdr, 00418 CORBA::ULong offset) const = 0; 00419 00420 /// Increase the reference count on this @c TypeCode. 00421 virtual void tao_duplicate (void) = 0; 00422 00423 /// Decrease the reference count on this object. 00424 virtual void tao_release (void) = 0; 00425 00426 /// Destruction callback for Anys. 00427 static void _tao_any_destructor (void * x); 00428 00429 typedef CORBA::TypeCode_ptr _ptr_type; 00430 typedef CORBA::TypeCode_var _var_type; 00431 typedef CORBA::TypeCode_out _out_type; 00432 00433 protected: 00434 00435 /// Constructor. 00436 TypeCode (CORBA::TCKind kind); 00437 00438 /// Destructor. 00439 /** 00440 * Protected destructor to enforce proper memory management 00441 * through the reference counting mechanism. 00442 */ 00443 virtual ~TypeCode (void); 00444 00445 /** 00446 * @name @c TypeCode Template Methods 00447 * 00448 * Methods that must be implemented by @c CORBA::TypeCode 00449 * subclasses if valid for those subclasses. 00450 * 00451 * The default implementations of the non-pure virtual methods 00452 * throw the @c CORBA::TypeCode::BadKind exception since many of 00453 * these methods are @c TypeCode type-specific. This reduces code 00454 * duplication and bloat. 00455 * 00456 * The @c TypeCode @c equal(), @c equivalent(), @c kind() and 00457 * @c get_compact_typecode() methods are valid for all 00458 * @c TypeCodes which is why their template method "@c _i" 00459 * counterparts are pure virtual. 00460 */ 00461 //@{ 00462 virtual Boolean equal_i (TypeCode_ptr tc) const = 0; 00463 virtual Boolean equivalent_i (TypeCode_ptr tc) const = 0; 00464 virtual TypeCode_ptr get_compact_typecode_i (void) const = 0; 00465 00466 virtual char const * id_i (void) const; 00467 virtual char const * name_i (void) const; 00468 virtual ULong member_count_i (void) const; 00469 virtual char const * member_name_i (ULong index) const; 00470 virtual TypeCode_ptr member_type_i (ULong index) const; 00471 virtual Any * member_label_i (ULong index) const; 00472 virtual TypeCode_ptr discriminator_type_i (void) const; 00473 virtual Long default_index_i (void) const; 00474 virtual ULong length_i (void) const; 00475 virtual TypeCode_ptr content_type_i (void) const; 00476 virtual UShort fixed_digits_i (void) const; 00477 virtual UShort fixed_scale_i (void) const; 00478 virtual Visibility member_visibility_i (ULong index) const; 00479 virtual ValueModifier type_modifier_i (void) const; 00480 virtual TypeCode_ptr concrete_base_type_i (void) const; 00481 //@} 00482 00483 private: 00484 00485 // Prevent copying and assignment. 00486 TypeCode (TypeCode const &); 00487 void operator= (TypeCode const &); 00488 00489 protected: 00490 00491 /// The kind of TypeCode. 00492 TCKind const kind_; 00493 00494 }; 00495 } // End namespace CORBA 00496 00497 00498 TAO_AnyTypeCode_Export CORBA::Boolean 00499 operator<< (TAO_OutputCDR & cdr, const CORBA::TypeCode_ptr tc); 00500 00501 TAO_AnyTypeCode_Export CORBA::Boolean 00502 operator>> (TAO_InputCDR & cdr, CORBA::TypeCode_ptr & tc); 00503 00504 #if defined (GEN_OSTREAM_OPS) 00505 00506 // Used in optionally generated ostream operators (for debugging). 00507 TAO_AnyTypeCode_Export std::ostream & 00508 operator<< (std::ostream &, const CORBA::TypeCode_ptr tc); 00509 00510 #endif /* GEN_OSTREAM_OPS */ 00511 00512 namespace TAO 00513 { 00514 namespace TypeCode 00515 { 00516 /// Marshal the @c TypeCode @a tc in to the output CDR stream @a 00517 /// cdr. 00518 /** 00519 * @see @CORBA::TypeCode::tao_marshal() description for details. 00520 */ 00521 00522 TAO_AnyTypeCode_Export bool marshal (TAO_OutputCDR & cdr, 00523 CORBA::TypeCode_ptr tc, 00524 CORBA::ULong offset); 00525 00526 /// Return @a offset aligned on the appropriate CDR boundary. 00527 TAO_AnyTypeCode_Export CORBA::ULong aligned_offset (CORBA::ULong offset); 00528 } 00529 00530 /// Return the unaliased content @c TypeCode of the given 00531 /// @c TypeCode. 00532 TAO_AnyTypeCode_Export 00533 CORBA::TypeCode_ptr unaliased_typecode (CORBA::TypeCode_ptr tc); 00534 00535 /// Return the unaliased @c TCKind of the given @c TypeCode. 00536 /** 00537 * @note This is a convenience function that simply calls @c kind() 00538 * on the unaliased @c TypeCode returned from 00539 * @c unaliased_typecode(). 00540 */ 00541 TAO_AnyTypeCode_Export 00542 CORBA::TCKind unaliased_kind (CORBA::TypeCode_ptr tc); 00543 00544 // --------------------------------------------------------------- 00545 00546 // Used in generated code if CORBA::TypeCode is an argument or 00547 // return type. 00548 template<> 00549 class TAO_AnyTypeCode_Export Arg_Traits<CORBA::TypeCode> 00550 : public Object_Arg_Traits_T<CORBA::TypeCode_ptr, 00551 CORBA::TypeCode_var, 00552 CORBA::TypeCode_out, 00553 TAO::Objref_Traits<CORBA::TypeCode>, 00554 TAO::Any_Insert_Policy_Stream> 00555 { 00556 }; 00557 00558 template<> 00559 struct TAO_AnyTypeCode_Export Objref_Traits< ::CORBA::TypeCode> 00560 { 00561 static ::CORBA::TypeCode_ptr duplicate (::CORBA::TypeCode_ptr); 00562 static void release (::CORBA::TypeCode_ptr); 00563 static ::CORBA::TypeCode_ptr nil (void); 00564 static CORBA::Boolean marshal (::CORBA::TypeCode_ptr p, 00565 TAO_OutputCDR & cdr); 00566 }; 00567 00568 template<> 00569 struct TAO_AnyTypeCode_Export In_Object_Argument_Cloner_T<CORBA::TypeCode_ptr> 00570 { 00571 static void duplicate(CORBA::TypeCode_ptr objref); 00572 static void release(CORBA::TypeCode_ptr objref); 00573 }; 00574 } 00575 00576 TAO_END_VERSIONED_NAMESPACE_DECL 00577 00578 #if defined (__ACE_INLINE__) 00579 # include "tao/AnyTypeCode/TypeCode.inl" 00580 #endif /* __ACE_INLINE__ */ 00581 00582 #include /**/ "ace/post.h" 00583 00584 #endif /* TAO_TYPECODE_H */