summaryrefslogtreecommitdiff
path: root/TAO/tao/Valuetype/ValueBase.h
blob: 1b1880cadc9bdc7bd4b33ad933348571eca8a227 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
// -*- 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/CORBA_macros.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 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 *);

    /// Used in the implementation of CORBA::Any
    static void _tao_any_destructor (void *);

    /// TAO extension

    /// 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 write_special_value(TAO_OutputCDR &strm, const CORBA::ValueBase * value);
    /// Write whole value.
    static CORBA::Boolean 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 write_value_header(TAO_OutputCDR &strm,
                                      ptrdiff_t formal_type_id) const;

    /// Read the repository ids from the CDR input stream.
    static CORBA::Boolean read_repository_ids(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;
  extern TAO_Valuetype_Export TypeCode_ptr const _tc_ValueModifier;

  /**
   * @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, CORBA::ULong> 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 */