1 // -*- Mode: C++; -*-
2 //                            Package   : omniORB
3 // valueType.h                Created on: 2003/08/22
4 //                            Author    : Duncan Grisby
5 //
6 //    Copyright (C) 2003-2004 Apasphere Ltd.
7 //
8 //    This file is part of the omniORB library
9 //
10 //    The omniORB library is free software; you can redistribute it and/or
11 //    modify it under the terms of the GNU Lesser General Public
12 //    License as published by the Free Software Foundation; either
13 //    version 2.1 of the License, or (at your option) any later version.
14 //
15 //    This library is distributed in the hope that it will be useful,
16 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 //    Lesser General Public License for more details.
19 //
20 //    You should have received a copy of the GNU Lesser General Public
21 //    License along with this library. If not, see http://www.gnu.org/licenses/
22 //
23 //
24 // Description:
25 //    ValueType definitions
26 //
27 
28 #ifndef __OMNI_VALUETYPE_H__
29 #define __OMNI_VALUETYPE_H__
30 
31 #include <omniORB4/CORBA.h>
32 #include <omniORB4/valueFactoryManager.h>
33 
34 
35 struct _omni_ValueId {
36   const char*  repoId;
37   CORBA::ULong hashval;
38 };
39 
40 struct _omni_ValueIds {
41   CORBA::Long    idcount;
42   CORBA::ULong   hashval;
43   _omni_ValueId* repoIds;
44 };
45 
46 
47 class omniValueType {
48 public:
49   static void marshal(CORBA::ValueBase* val,
50 		      const char* repoId,
51 		      cdrStream& stream);
52   // Marshal the value, in a context where the IDL specifies the value
53   // has type given by <repoId>.
54 
55   static CORBA::ValueBase* unmarshal(const char* repoId, CORBA::ULong hashval,
56 				     CORBA::TypeCode_ptr tc,
57 				     cdrStream& stream);
58   // Unmarshal a value, in a context where the IDL specifies the value
59   // has type given by <repoId>, with hash <hashval>.
60   //
61   // If the TypeCode is present, it is the TypeCode of a value inside
62   // an Any. When this function is called by static stubs, the
63   // TypeCode pointer is zero, not nil, for efficiency and cleanliness
64   // in the stubs.
65 
66   static CORBA::ValueBase*
67   handleIncompatibleValue(const char* repoId,
68 			  CORBA::ULong hashval,
69 			  CORBA::ValueBase* val,
70 			  CORBA::CompletionStatus completion);
71   // When the stubs unmarshal a value, the value returned by unmarshal
72   // above may not downcast to the required valuetype class. This can
73   // happen for two reasons. One, the application registered a factory
74   // that did the wrong thing, in which case we throw BAD_PARAM. Two,
75   // the value has already been unmarshalled in an Any at a time when
76   // no factory was registered, meaning that it is an instance of
77   // UnknownValue. By the time the application tries to extract if
78   // from the Any, it may have registered a suitable factory, so we
79   // can now convert the UnknownValue into a suitable value. If that
80   // succeeds, we return a new value that can be downcast to the
81   // required valuetype class. If that fails, we throw MARSHAL.
82   //
83   // Whatever happens, the input value is consumed.
84 
hash_id(const char * id)85   static inline CORBA::ULong hash_id(const char* id)
86   {
87     CORBA::ULong n = 0;
88     while (*id)  n = ((n << 5) ^ (n >> 27)) ^ *id++;
89     return n;
90   }
91 
hash_ids(const _omni_ValueIds * ids)92   static inline CORBA::ULong hash_ids(const _omni_ValueIds* ids)
93   {
94     CORBA::ULong n = 0;
95 
96     for (CORBA::Long i=0; i < ids->idcount; i++)
97       n = ((n << 5) ^ (n >> 27)) ^ ids->repoIds[i].hashval;
98 
99     return n;
100   }
101 };
102 
103 
104 #endif // __OMNI_VALUETYPE_H__
105