1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #ifndef _micxx_instance_h
26 #define _micxx_instance_h
27
28 #include <MI.h>
29 #include "linkage.h"
30 #include "atomic.h"
31 #include "memory.h"
32 #include "string.h"
33 #include "field.h"
34 #include "array.h"
35 #include "types.h"
36
37 MI_BEGIN_NAMESPACE
38
39 //////////////////////////
40 // Base class for C++ MI_Instance representation
41 class MICXX_LINKAGE Instance
42 {
43 mike 1.1 public:
44
45 Instance();
46
47 Instance(const Instance& x);
48
49 ~Instance();
50
51 Instance& operator=(const Instance& x);
52
53 String GetNamespace() const;
54
55 void SetNamespace(const String& nameSpace);
56
57 void Print(FILE* os = stdout, MI_Uint32 level = 0) const;
58
59 static const MI_ClassDecl* GetClassDecl();
60
61 protected:
62
63 Instance(
64 mike 1.1 const MI_ClassDecl* clDecl,
65 const MI_Instance* instance,
66 bool keysOnly);
67
68 Instance(
69 const MI_ClassDecl* clDecl);
70
71 Instance(
72 const MI_MethodDecl* methodDecl);
73
74 Instance(
75 const MI_MethodDecl* methodDecl,
76 const MI_Instance* instance,
77 bool keysOnly);
78
79 void CopyRef(
80 const Instance& x);
81
82 void COW()
83 {
84 if (AtomicGet(GetHeader(m_instance)->u.s.m_refCounter) != 1)
85 mike 1.1 {
86 MI_Instance* current = m_instance;
87 m_instance = Clone();
88 AddRef(m_instance);
89 Release(current);
90 }
91 }
92
93 template<typename T>
94 Field<T>& GetField(size_t offset)
95 {
96 COW();
97 void* ptr = reinterpret_cast<char*>(m_instance) + offset;
98 return *(reinterpret_cast<Field<T>*>(ptr));
99 }
100
101 template<typename T>
102 const Field<T>& GetField(size_t offset) const
103 {
104 const void* ptr = reinterpret_cast<const char*>(m_instance) + offset;
105 return *(reinterpret_cast<const Field<T>*>(ptr));
106 mike 1.1 }
107
108 private:
109
110 // helper data - placed before MI_Instance strucutre
111 struct Header
112 {
113 union
114 {
115 struct _HeaderData
116 {
117 AtomicType m_refCounter;
118 }
119 s;
120 char alignment[(sizeof(struct _HeaderData) + 7) & ~7];
121 }
122 u;
123 };
124
125 void Initialize(
126 const MI_ClassDecl* clDecl,
127 mike 1.1 const MI_Instance* instance,
128 bool keysOnly);
129
130 static Header* GetHeader(MI_Instance* instance)
131 {
132 return reinterpret_cast<Header*>(
133 reinterpret_cast<char*>(instance) - sizeof(Header));
134 }
135
136 static void AddRef(MI_Instance* instance)
137 {
138 AtomicInc(GetHeader(instance)->u.s.m_refCounter);
139 }
140
141 static void Release(MI_Instance* instance);
142
143 static MI_Instance* Create(const MI_ClassDecl* clDecl);
144
145 MI_Instance* Clone() const;
146
147 MI_Instance* m_instance;
148 mike 1.1
149 friend class Context;
150 friend class DInstance;
151
152 MICXX_LINKAGE
153 friend bool __IsA(const MI_ClassDecl*, const Instance*);
154 };
155
156 inline Instance::Instance() : m_instance(0)
157 {
158 }
159
160 inline Instance::Instance(const Instance& x) : m_instance(0)
161 {
162 CopyRef(x);
163 }
164
165 inline Instance::~Instance()
166 {
167 Release(m_instance);
168 }
169 mike 1.1
170 inline Instance& Instance::operator=(const Instance& x)
171 {
172 CopyRef(x);
173 return *this;
174 }
175
176 template<>
177 inline const ArrayTraits* GetArrayTraits<Instance>()
178 {
179 return __traits[MI_INSTANCE];
180 };
181
182 typedef Array<Instance> InstanceA;
183
184 MICXX_LINKAGE
185 bool __IsA(const MI_ClassDecl* classDecl, const Instance* instance);
186
187 template<class CLASS>
188 bool IsA(const Instance& instance)
189 {
190 mike 1.1 return __IsA(((CLASS*)0)->GetClassDecl(), &instance);
191 }
192
193 MI_END_NAMESPACE
194
195 #endif /* _micxx_instance_h */
|