summaryrefslogtreecommitdiff
path: root/TAO/tao/Valuetype/ValueBase.h
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/Valuetype/ValueBase.h')
-rw-r--r--TAO/tao/Valuetype/ValueBase.h380
1 files changed, 380 insertions, 0 deletions
diff --git a/TAO/tao/Valuetype/ValueBase.h b/TAO/tao/Valuetype/ValueBase.h
new file mode 100644
index 00000000000..95f46be0647
--- /dev/null
+++ b/TAO/tao/Valuetype/ValueBase.h
@@ -0,0 +1,380 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file ValueBase.h
+ *
+ * $Id$
+ *
+ * @author Torsten Kuepper <kuepper2@lfa.uni-wuppertal.de>
+ */
+//=============================================================================
+
+#ifndef TAO_VALUEBASE_H
+#define TAO_VALUEBASE_H
+
+#include /**/ "ace/pre.h"
+
+#include "tao/Valuetype/valuetype_export.h"
+#include "tao/orbconf.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "tao/Valuetype/Value_CORBA_methods.h"
+#include "tao/Valuetype/Value_VarOut_T.h"
+
+#include "tao/Object_Argument_T.h"
+#include "tao/Arg_Traits_T.h"
+#include "tao/Any_Insert_Policy_T.h"
+
+#include "ace/Basic_Types.h"
+#include "ace/Synch_Traits.h"
+#include "ace/Thread_Mutex.h"
+#include "ace/Atomic_Op.h"
+#include "ace/Null_Mutex.h"
+#include "ace/Vector_T.h"
+
+#if defined (TAO_EXPORT_MACRO)
+#undef TAO_EXPORT_MACRO
+#endif
+#define TAO_EXPORT_MACRO TAO_Valuetype_Export
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+class TAO_Valuetype_Export TAO_ChunkInfo
+{
+public:
+ TAO_ChunkInfo (CORBA::Boolean do_chunking = 0,
+ CORBA::Long init_level = 0);
+
+ /// Methods to support chunking.
+ /// Note: These methods are called for both chunking and non-chunking
+ /// valuetype. These methods checks the chunking_ flag. If it's
+ /// set to be false the methods return true rightaway.
+
+ /// Methods for marshalling a valuetype.
+
+ /// This is called in the _tao_marshal_state (). This method reserves
+ /// space for the chunk size of the next chunk and also increments the
+ /// nesting level. The reservasion actually occurs the first time that
+ /// the start_chunk is called if there are multiple continuous start_chunk()
+ /// calls without the close_chunk() called in between.
+ CORBA::Boolean start_chunk (TAO_OutputCDR &strm);
+
+ /// This is called in the _tao_marshal_state (). This method writes the
+ /// actual chunk size to the reserved chunk size space and writes an end
+ /// tag with the negation value of current nesting level. A start_chunk()
+ /// needs an end_chunk() to close the current chunk. It's also needed for
+ /// writing the outmost endtag to the stream.
+ CORBA::Boolean end_chunk (TAO_OutputCDR &strm);
+
+ /// Methods for unmarshalling a valuetype.
+
+ /// This is called in the _tao_unmarshal_state () to read the chunk
+ /// size or an end tag.
+ CORBA::Boolean handle_chunking (TAO_InputCDR &strm);
+ /// This is called in the _tao_unmarshal_state () to skip the rest
+ /// chunks until the outmost endtag (-1) if the value is truncated
+ /// to its truncatable parent.
+ CORBA::Boolean skip_chunks (TAO_InputCDR &strm);
+ /// This is called in end_chunk(). It writes the actual chunk size to the
+ /// reserved chunk size space.
+ CORBA::Boolean write_previous_chunk_size (TAO_OutputCDR &strm);
+ /// Reserve space for chunk size. The memory in the stream will be
+ /// overwritten after all the chunk data is written. This method
+ /// only allows the reservasion being made once if the reserved
+ /// space has not been overwritten.
+ CORBA::Boolean reserve_chunk_size (TAO_OutputCDR &strm);
+
+ /// A flag to indicate that this instance is actually involved in a chunked
+ /// or truncatable valuetype.
+ CORBA::Boolean chunking_;
+
+ /// The level of nesting valuetypes.
+ CORBA::Long value_nesting_level_;
+ /// The starting position of the size of current chunk.
+ char* chunk_size_pos_;
+ /// The length of CDR stream from the begining to the current
+ /// chunk data starting position. Used to calculate the chunk size
+ /// across multiple chained ACE_Message_Blocks.
+ size_t length_to_chunk_octets_pos_;
+ /// The end position of current chunk.
+ char* chunk_octets_end_pos_;
+};
+
+namespace CORBA
+{
+ class ValueFactoryBase;
+ typedef ValueFactoryBase *ValueFactory;
+
+ class ValueBase;
+
+ typedef TAO_Value_Var_T<ValueBase> ValueBase_var;
+ typedef TAO_Value_Out_T<ValueBase> ValueBase_out;
+
+ /**
+ * @class ValueBase
+ *
+ * @brief Abstract baseclass for Valuetypes
+ *
+ * @see CORBA 2.3 - Section 20.17.5
+ */
+ class TAO_Valuetype_Export ValueBase
+ {
+ public:
+ friend class TAO_ChunkInfo;
+
+ typedef ValueBase* _ptr_type;
+ typedef ValueBase_var _var_type;
+ typedef ValueBase_out _out_type;
+
+ typedef ACE_Vector < ACE_CString > Repository_Id_List;
+
+ // Reference counting.
+ /// %! virtual CORBA::ValueBase* _copy_value (void) = 0;
+
+ virtual void _add_ref (void) = 0;
+ virtual void _remove_ref (void) = 0;
+ virtual CORBA::ULong _refcount_value (void) = 0;
+
+ // dynamic casting
+ static CORBA::ValueBase* _downcast (CORBA::ValueBase *);
+
+ /// TAO extension
+
+ /// Used in the implementation of CORBA::Any
+ static void _tao_any_destructor (void *);
+ virtual CORBA::TypeCode_ptr _tao_type (void) const = 0;
+
+ /// Return the repository id of this valuetype.
+ virtual const char * _tao_obv_repository_id (void) const = 0;
+
+ /// Give the list of the RepositoryIds in the valuetype "truncatable"
+ /// inheritance hierarchy. List the id of this valuetype as first
+ /// RepositoryID and go up the "truncatable" derivation hierarchy.
+ /// Note the truncatable repo ids only list the truncatable base types
+ /// to which this type is safe to truncate, not all its parents.
+ virtual void _tao_obv_truncatable_repo_ids (Repository_Id_List &) const = 0;
+
+ // TAO internal --------------------------
+
+ /// Marshal a valuetype (see operator<< in tao_idl generated file
+ /// how it is called)
+ static CORBA::Boolean _tao_marshal (TAO_OutputCDR &strm,
+ const ValueBase *_this,
+ ptrdiff_t formal_type_id = 0);
+
+ /// Unmarshal a valuetype, if formal type is a pointer to
+ /// ValueBase
+ static CORBA::Boolean _tao_unmarshal (TAO_InputCDR &strm,
+ ValueBase *&new_object);
+
+ // static CORBA::Boolean
+ // T::_tao_unmarshal (TAO_InputCDR &, ValueBase *&_this)
+ // is typespecific for valuetype T and generated from tao_idl
+ // Use this for unmarshaling.
+
+ /// Both used internally and are called from T::_tao_unmarshal ()
+ static CORBA::Boolean _tao_unmarshal_pre (TAO_InputCDR &strm,
+ ValueBase *&,
+ const char * const repo_id);
+
+ CORBA::Boolean _tao_unmarshal_post (TAO_InputCDR &strm);
+
+ /// Check repository id for value box type against what is
+ /// in the CDR stream.
+ static CORBA::Boolean _tao_validate_box_type (
+ TAO_InputCDR &strm,
+ const char * const repo_id_expected,
+ CORBA::Boolean & null_object);
+
+ public: // otherwise these cannot be called from a static function
+
+ /// During marshal jump to the most derived part
+ virtual CORBA::Boolean _tao_marshal_v (TAO_OutputCDR &) const = 0;
+
+ /// Called after obtaining the fresh object from create_for_unmarshal ()
+ virtual CORBA::Boolean _tao_unmarshal_v (TAO_InputCDR &) = 0;
+
+ /// Notify the truncated parent valuetype to skip the rest of the chunks
+ /// when unmarshalling a value from its derived valuetype.
+ /// This is called when the factory for the most derived valuetype (in
+ /// the repository id list) does not exist and a truncated parent factory
+ /// is registered.
+ virtual void truncation_hook ();
+
+ protected:
+ ValueBase (void);
+ ValueBase (const ValueBase&);
+ virtual ~ValueBase (void);
+
+ /// This flag is set to be true when the valuetype defined
+ /// in the idl has the truncatable parent.
+ CORBA::Boolean is_truncatable_;
+
+ /// This flag is set to be true when marshalling uses chunking.
+ /// According to spec, the truncatable valuetype should use chunking
+ /// and it can be used for marshalling large valuetype. In current
+ /// implementation, we just use chunking for the truncatable valuetype.
+ CORBA::Boolean chunking_;
+
+ /// Compare the supplied formal type identifier with our actual type.
+ /// This is used during marshaling of valuetypes to detect when it is
+ /// appropriate to not explicitly marshal the typecode for the value.
+ virtual CORBA::Boolean _tao_match_formal_type (ptrdiff_t ) const = 0;
+
+ private:
+ /// Write some special values such as null value or indirection value.
+ static CORBA::Boolean _tao_write_special_value(TAO_OutputCDR &strm,
+ const CORBA::ValueBase * value);
+ /// Write whole value.
+ static CORBA::Boolean _tao_write_value(TAO_OutputCDR &strm,
+ const CORBA::ValueBase * value,
+ ptrdiff_t formal_type_id);
+
+ /// Write the header of the value which includes the valuetag, number of
+ /// repository ids and list of repository ids.
+ CORBA::Boolean _tao_write_value_header(TAO_OutputCDR &strm,
+ ptrdiff_t formal_type_id) const;
+
+ /// Read a single repository id from the CDR input stream,
+ /// accounting for indirection.
+ static CORBA::Boolean _tao_read_repository_id (ACE_InputCDR& strm,
+ Repository_Id_List& ids);
+
+ /// Read a list of repository ids from the CDR input stream,
+ /// accounting for indirection
+ static CORBA::Boolean _tao_read_repository_id_list (ACE_InputCDR& strm,
+ Repository_Id_List& ids);
+
+ private:
+ ValueBase & operator= (const ValueBase &);
+
+#ifdef SUN_CC_HAS_PVFC_BUG
+ // Need ugly fix for sun cc "pure virtual function called" bug.
+ private:
+ unsigned long tao_sun_cc_pvfc_bug_fix_;
+
+#endif /* SUN_CC_HAS_PVFC_BUG */
+
+ }; // ValueBase
+
+ /// Valuetype-related type codes.
+ extern TAO_Valuetype_Export TypeCode_ptr const _tc_ValueBase;
+ extern TAO_Valuetype_Export TypeCode_ptr const _tc_EventBase;
+
+ /**
+ * @class DefaultValueRefCountBase
+ *
+ * @brief Default mix-in for reference count of a valuetype.
+ *
+ * Default mix-in for reference count of a valuetype.
+ */
+ class TAO_Valuetype_Export DefaultValueRefCountBase
+ : public virtual ValueBase
+ {
+ public:
+ virtual void _add_ref (void);
+ virtual void _remove_ref (void);
+ virtual CORBA::ULong _refcount_value (void);
+
+ /// The _tao variants are inline for fast access from T_var
+ /// (if valuetype T is compiled with optimization for that.) %! (todo)
+ void _tao_add_ref (void);
+ void _tao_remove_ref (void);
+ CORBA::ULong _tao_refcount_value (void);
+
+ protected:
+ DefaultValueRefCountBase (void);
+ DefaultValueRefCountBase (const DefaultValueRefCountBase&);
+ virtual ~DefaultValueRefCountBase ();
+
+ private:
+ void operator= (const DefaultValueRefCountBase &);
+
+ private: // data
+ /// Reference counter.
+ ACE_Atomic_Op<TAO_SYNCH_MUTEX, unsigned long> refcount_;
+ }; // DefaultValueRefCountBase
+
+ // which lock has the lowest memory overhead ?
+ // %! todo refcountbase w/o locking (now memory overhead)
+ // $! todo: debug aids for refcounts
+
+} // End CORBA namespace
+
+/**
+ * @namespace TAO_OBV_GIOP_Flags
+ *
+ * @brief TAO_OBV_GIOP_Flags
+ *
+ * @see CORBA 2.3 -- Section 15.3.4
+ */
+namespace TAO_OBV_GIOP_Flags
+{
+ const CORBA::Long Value_tag_base = 0x7fffff00L;
+ const CORBA::Long Value_tag_sigbits = 0xffffff00L;
+ const CORBA::Long Codebase_url = 1;
+ const CORBA::Long Type_info_sigbits = 0x00000006L;
+ const CORBA::Long Type_info_none = 0;
+ const CORBA::Long Type_info_single = 2;
+ const CORBA::Long Type_info_list = 6;
+ const CORBA::Long Chunking_tag_sigbits = 0x00000008L;
+ const CORBA::Long Indirection_tag = 0x7fffffffL;
+ const CORBA::Long Null_tag = 0x00000000L;
+
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_null_ref (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_value_tag (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean has_codebase_url (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean has_no_type_info (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean has_single_type_info (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean has_list_type_info (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_chunked (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_indirection_tag (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_indirection (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_block_size (CORBA::Long);
+ TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_end_tag (CORBA::Long);
+}
+
+TAO_Valuetype_Export CORBA::Boolean
+operator<< (TAO_OutputCDR&, const CORBA::ValueBase *);
+
+TAO_Valuetype_Export CORBA::Boolean
+operator>> (TAO_InputCDR&, CORBA::ValueBase *&);
+
+/// Used in generated code if CORBA::ValueBase is an argument or return type.
+namespace TAO
+{
+ template<>
+ class TAO_Valuetype_Export Arg_Traits<CORBA::ValueBase>
+ : public Object_Arg_Traits_T<CORBA::ValueBase *,
+ CORBA::ValueBase_var,
+ CORBA::ValueBase_out,
+ TAO::Value_Traits<CORBA::ValueBase>,
+ TAO::Any_Insert_Policy_Stream <CORBA::ValueBase *> >
+ {
+ };
+
+ template<>
+ struct TAO_Valuetype_Export Value_Traits<CORBA::ValueBase>
+ {
+ static void add_ref (CORBA::ValueBase *);
+ static void remove_ref (CORBA::ValueBase *);
+
+ // For INOUT value type arguments, so they can use the same set
+ // of arg classes as interfaces.
+ static void release (CORBA::ValueBase *);
+ };
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (__ACE_INLINE__)
+# include "tao/Valuetype/ValueBase.inl"
+#endif /* __ACE_INLINE__*/
+
+#include /**/ "ace/post.h"
+
+#endif /* TAO_VALUEBASE_H */