1 karl 1.20 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.12 //
|
3 karl 1.18 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.17 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.18 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.19 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.20 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.12 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.13 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.12 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
|
21 kumpf 1.13 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.12 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.13 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.12 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 // Author: Bob Blair (bblair@bmc.com)
33 //
|
34 kumpf 1.16 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
35 // (carolann_graves@hp.com)
|
36 mike 1.12 //
37 //%/////////////////////////////////////////////////////////////////////////////
38
39
40 //
41 // implementation of valueFactory
42 //
43 //
44 // implementation of objectName and its related classes
45 //
46
47 #include "objname.h"
48 #include <iostream> // for debug
49
50 PEGASUS_USING_STD;
51
52
53 PEGASUS_NAMESPACE_BEGIN
54
55 #define WHITESPACE(x) (x==' ' || x=='\t' || x=='\n' || x=='\r')
56 #define DIGIT(x) (x=='0' || x=='1' || x=='2' || x=='3' || x=='4' || x=='5' || x=='6' || x=='7' || x=='8' || x=='9')
57 mike 1.12
58 // The String representation of the namespaceHandle begins
59 // with 0 or more slashes, followed by a host designation,
60 // followed by a path. The path begins with a slash and
61 // terminates with the end of the String
62
63 namespaceHandle::namespaceHandle(const String &rep) {
64 namespaceHandleRepToComponents(rep);
65 }
66
67 namespaceHandle::namespaceHandle(const String &host, const String &path) {
68 String str = "/" + host + "/" + path;
69 namespaceHandleRepToComponents(str);
70 }
71
72 const String &
73 namespaceHandle::namespaceHandleComponentsToRep() {
74 _Stringrep = _host;
75 if (!String::equal(_host, String::EMPTY))
|
76 kumpf 1.14 _Stringrep.append(":");
77 _Stringrep.append(_path);
|
78 mike 1.12 return _Stringrep;
79 }
80
81 void
82 namespaceHandle::namespaceHandleRepToComponents(const String &rep)
83 {
84 _host.clear();
85 _path.clear();
86 Uint32 n = rep.size();
87 typedef enum _states {BEGIN, INHOST, INPATH, DONE} states;
88 states state = BEGIN;
89 Boolean hashost = false;
90 for (Uint32 i = 0; i < n; i++)
91 if (rep[i] == ':')
92 hashost = true;
93
94 for (Uint32 i = 0; i < n; i++) {
95 Char16 c = rep[i];
96 switch (state) {
97 case BEGIN:
98 if (!WHITESPACE(c)) {
99 mike 1.12 if (hashost) {
100 _host.append(c);
101 state = INHOST;
102 } else {
103 _path.append(c);
104 state = INPATH;
105 }
106 }
107 break;
108 case INHOST:
109 {
110 if (char(c) != ':')
111 _host.append(c);
112 else
113 state = INPATH;
114 break;
115 }
116 case INPATH:
117 {
118 if (char(c) != ':')
119 _path.append(c);
120 mike 1.12 else
121 state = DONE;
122 break;
123 }
124 default:
125 break;
126 } // end switch
127 } // end for
128 }
129
130 modelPath::modelPath(const String &rep) {
131 modelPathRepToComponents(rep);
132 }
133
134 modelPath::modelPath(const String &rep, const String &keyString) {
135 String str = rep + "." + keyString;
136 modelPathRepToComponents(str);
137 }
138
|
139 kumpf 1.15 modelPath::modelPath(const String &rep, const Array<CIMKeyBinding> &kba) {
|
140 mike 1.12 _className = rep;
141 _KeyBindings = kba;
142 }
143
144 modelPath::~modelPath() {
145 }
146
|
147 kumpf 1.15 CIMKeyBinding::Type
|
148 mike 1.12 modelPath::KeyBindingTypeOf(const String &s)
149 {
150 Char16 c = s[0];
|
151 kumpf 1.15 if (DIGIT(c)) return CIMKeyBinding::NUMERIC;
152 if (c == '\"') return CIMKeyBinding::STRING;
153 return CIMKeyBinding::BOOLEAN;
|
154 mike 1.12 }
155
156
157 const String &
158 modelPath::modelPathComponentsToRep() {
159 String stringrep = _className;
160 Uint32 numkeys = _KeyBindings.size();
161 if (numkeys) {
|
162 kumpf 1.14 stringrep.append(".");
|
163 mike 1.12 }
|
164 kumpf 1.14 stringrep.append(KeyBindingsToKeyString());
|
165 mike 1.12 _Stringrep = stringrep;
166 return _Stringrep;
167 }
168
169 void
170 modelPath::modelPathRepToComponents(const String &rep) {
|
171 kumpf 1.15 CIMKeyBinding kb;
|
172 mike 1.12 String keyname;
|
173 kumpf 1.15 CIMKeyBinding::Type kbtype = CIMKeyBinding::STRING;
|
174 mike 1.12 String keyvalue;
175 Uint32 n = rep.size();
176 enum _states{BEGIN, INCLASS, KEYBEGIN, INKEYNAME, KEYVALBEGIN,
177 INSTRINGKEYVAL, INNUMERICKEYVAL,
178 INBOOLEANKEYVAL, ENDINGKEYVAL};
179 _states state = BEGIN;
180 for (Uint32 i = 0; i < n; i++) {
181 Char16 c = rep[i];
182 switch(state) {
183 case BEGIN:
184 if (c != ':' && !WHITESPACE(c)) {
185 _className.append(c);
186 state = INCLASS;
187 }
188 break;
189 case INCLASS:
190 if (c != '.') {
191 _className.append(c);
192 } else {
193 state = KEYBEGIN;
194 }
195 mike 1.12 break;
196 case KEYBEGIN:
197 if (!WHITESPACE(c)) {
198 keyname.clear();
199 keyname.append(c);
200 state = INKEYNAME;
201 }
202 break;
203 case INKEYNAME:
204 if (c == '=') {
|
205 kumpf 1.14 _keyString.append(keyname);
|
206 mike 1.12 state = KEYVALBEGIN;
207 } else {
208 if (!WHITESPACE(c)) {
209 keyname.append(c);
210 }
211 }
212 break;
213 case KEYVALBEGIN:
214 if (!WHITESPACE(c)) {
215 keyvalue.clear();
216 if (c == '"') {
|
217 kumpf 1.15 kbtype = CIMKeyBinding::STRING;
|
218 mike 1.12 state = INSTRINGKEYVAL;
219 } else {
220 if (DIGIT(c)) {
|
221 kumpf 1.15 kbtype = CIMKeyBinding::NUMERIC;
|
222 mike 1.12 keyvalue.append(c);
223 state = INNUMERICKEYVAL;
224 } else {
|
225 kumpf 1.15 kbtype = CIMKeyBinding::BOOLEAN;
|
226 mike 1.12 keyvalue.append(c);
227 state = INBOOLEANKEYVAL;
228 }
229 }
230 }
231 break;
232 case INSTRINGKEYVAL: {
233 if (c != '"') { // What about escaped quotes in the value?
234 keyvalue.append(c);
235 } else {
236 state = ENDINGKEYVAL;
237 }
238 break;
239 case INNUMERICKEYVAL:
240 case INBOOLEANKEYVAL:
241 if (WHITESPACE(c) || c == ',') {
|
242 kumpf 1.14 _keyString.append(keyvalue);
|
243 mike 1.12 kb.setName(keyname);
244 kb.setValue(keyvalue);
245 kb.setType(kbtype);
246 _KeyBindings.append(kb);
247 state = KEYBEGIN;
248 } else {
249 keyvalue.append(c);
250 }
251 break;
252 case ENDINGKEYVAL: // (applies only to String value)
253 if (c == ',') {
|
254 kumpf 1.14 _keyString.append(keyvalue);
|
255 mike 1.12 kb.setName(keyname);
256 kb.setValue(keyvalue);
257 kb.setType(kbtype);
258 _KeyBindings.append(kb);
259 state = KEYBEGIN;
260 } else {
261 // it's really a syntactical error, but we'll let it go
262 }
263 }
264 } // end switch
265 } // end for length of input
266 if (state == ENDINGKEYVAL || state == INSTRINGKEYVAL
267 || state == INNUMERICKEYVAL || state == INBOOLEANKEYVAL) {
|
268 kumpf 1.14 _keyString.append(keyvalue);
|
269 mike 1.12 kb.setName(keyname);
270 kb.setValue(keyvalue);
271 kb.setType(kbtype);
272 _KeyBindings.append(kb);
273 }
274 }
275
276 const String &
277 modelPath::KeyBindingsToKeyString()
278 {
279 String stringrep;
280 Uint32 numkeys = _KeyBindings.size();
281 for (Uint32 i = 0; i < numkeys; i++) {
|
282 kumpf 1.15 const CIMKeyBinding &kb = _KeyBindings[i];
|
283 kumpf 1.16 const CIMName &keyname = kb.getName();
|
284 kumpf 1.15 CIMKeyBinding::Type keytype = kb.getType();
|
285 mike 1.12 const String &keyvalue = kb.getValue();
286 if (i)
|
287 kumpf 1.14 stringrep.append(",");
|
288 kumpf 1.16 stringrep.append(keyname.getString() + "=" +
|
289 kumpf 1.15 (keytype == CIMKeyBinding::STRING ? "\"" : "") +
|
290 kumpf 1.14 keyvalue +
|
291 kumpf 1.15 (keytype == CIMKeyBinding::STRING ? "\"" : ""));
|
292 mike 1.12 }
293 _keyString = stringrep;
294 return _keyString;
295 }
296
297 // The object name has three parts: A namespace type; a
298 // namespace handle, and a model path. It's in a form
299 // something like this:
300 // namespaceType://namespacePath:modelPath
301 // The namespacePath has two parts:
302 // host/rest_of_path
303 // The modelPath has two parts:
304 // className.key=val[, key=val ...
305 // I'm working on the assumption that the colon is they key:
306 // if there are 2 then the name divides
307 // namespaceType:namespaceHandle:modelPath
308 // if there is only 1, then the division is
309 // namespaceHandle:modelPath
310 //
311
312 objectName::objectName(const String &stringrep) :
313 mike 1.12 _namespaceHandle(0), _modelPath(0), _reference(0), _instance(0)
314 {
315 set(stringrep);
316 }
317
318 objectName::objectName(const String &namespaceType,
319 const String &namespaceHandle,
320 const String &modelPath)
321 {
322 set(namespaceType, namespaceHandle, modelPath);
323 }
324
325 objectName::~objectName() {
|
326 kumpf 1.21 delete _namespaceHandle;
327 delete _modelPath;
328 delete _reference;
329 delete _instance;
|
330 mike 1.12 }
331
332 void
333 objectName::set(const String &stringrep) {
334 Uint32 n = stringrep.size();
335 Char16 lastchar = '\0';
336 Array<Uint32> colons;
337 for (Uint32 i = 0; i < n; i++) {
338 Char16 c = stringrep[i];
339 if (c == ':' && lastchar != '\\') {
340 colons.append(i);
341 }
342 lastchar = c;
343 }
344 int delimiter1 = 0; // if non-zero, this separates namespacetype from rest
345 int delimiter2 = 0; // if non-zero, separates host from path
346 int delimiter3 = 0; // if non-zero, separates path from object name & key
347 int handlestart = 0; // where the namspaceHandle, if any, starts
348 int numcolons = colons.size();
349 if (numcolons == 3) {
350 delimiter1 = colons[0];
351 mike 1.12 delimiter2 = colons[1];
352 delimiter3 = colons[2];
353 } else if (numcolons == 2) {
354 delimiter2 = colons[0];
355 delimiter3 = colons[1];
356 } else if (numcolons == 1) {
357 delimiter3 = colons[0];
358 } else { // no problemo. It's just a model path
359 }
360
361 if (delimiter1) { // all three components are present
362 _namespaceType = stringrep.subString(0, delimiter1 + 1);
363 handlestart = delimiter1 + 1;
364 }
365 if (delimiter3) { // the last two components are present
366 _namespaceHandle = new namespaceHandle(stringrep.subString(handlestart,
367 delimiter3 - handlestart));
368 }
369 _modelPath = new modelPath(stringrep.subString(delimiter3));
370 }
371
372 mike 1.12 void
373 objectName::set(const String &namespaceType, const String &snamespaceHandle,
374 const String &smodelPath)
375 {
376 _namespaceType = namespaceType;
377 _namespaceHandle = new namespaceHandle(snamespaceHandle);
378 _modelPath = new modelPath(smodelPath);
379 }
380
381 objectName::objectName() : _namespaceHandle(0), _modelPath(0),
382 _reference(0), _instance(0)
383 {}
384
385 PEGASUS_NAMESPACE_END
|