1 karl 1.35 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.10 //
|
3 karl 1.32 // 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.29 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.32 // 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.33 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.35 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.10 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.19 // 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.10 // 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 karl 1.37 //
|
21 kumpf 1.19 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.10 // 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.19 // 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.10 // 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 //%/////////////////////////////////////////////////////////////////////////////
33
34 //
|
35 karl 1.37 // implementation of valueFactory
|
36 mike 1.10 //
37
|
38 kumpf 1.39 #include <cstring>
39 #include <cstdlib>
|
40 sage 1.11 #include <Pegasus/Common/Config.h>
|
41 a.arora 1.30 #include <Pegasus/Common/AutoPtr.h>
|
42 kumpf 1.39 #include <Pegasus/Common/String.h>
43 #include <Pegasus/Common/StringConversion.h>
44 #include "cimmofMessages.h"
|
45 mike 1.10 #include "cimmofParser.h"
46 to know about cimmofParser, it might as well
|
47 karl 1.37 be rolled into it. */
|
48 kumpf 1.39 #include "valueFactory.h"
|
49 mike 1.10
|
50 e.boden 1.31 // put any debug include, I'd say about here
51
|
52 mike 1.12 #define local_min(a,b) ( a < b ? a : b )
53 #define local_max(a,b) ( a > b ? a : b )
|
54 mike 1.10
|
55 karl 1.28 /* Fix up a string with embedded comma with extra
56 escape character and return the result. This is a hack
57 to get around the problem that arrays having strings
58 with an embedded comma are treat the embedded comma
59 as an array item separator.
60 NOTE: The correct solution is to add a new value factory
61 funciton for arrays specifically that uses a different
62 separator on an array of values.
63 BUG 497 fix, KS Sept 2003
64 */
65 String valueFactory::stringWComma(String tmp)
66 {
|
67 karl 1.37 //String tmp = *$3;
68 String rtn = String::EMPTY;
69 Uint32 len;
70 while((len = tmp.find(',')) != PEG_NOT_FOUND)
71 {
72 rtn.append(tmp.subString(0,len));
73 rtn.append("\\,");
74 tmp = tmp.subString(len+1);
75 }
76 if (tmp.size() > 0)
77 rtn.append(tmp);
78 return(rtn);
|
79 karl 1.28 }
80
|
81 kumpf 1.39 Uint64 valueFactory::stringToUint(
|
82 kumpf 1.38 const String &val,
83 CIMType type)
84 {
85 Uint64 u64;
86 CString valCString = val.getCString();
87
88 Boolean success =
89 (StringConversion::decimalStringToUint64(valCString, u64) ||
90 StringConversion::hexStringToUint64(valCString, u64) ||
91 StringConversion::octalStringToUint64(valCString, u64) ||
92 StringConversion::binaryStringToUint64(valCString, u64)) &&
93 StringConversion::checkUintBounds(u64, type);
|
94 karl 1.28
|
95 kumpf 1.38 if (!success)
|
96 karl 1.37 {
|
97 kumpf 1.39 String message;
98 cimmofMessages::arglist arglist;
99 arglist.append(cimTypeToString(type));
100 arglist.append(val);
101 cimmofMessages::getMessage(
102 message, cimmofMessages::INVALID_LITERAL_VALUE, arglist);
103 throw Exception(message);
|
104 mike 1.10 }
|
105 kumpf 1.38
106 return u64;
|
107 mike 1.10 }
108
|
109 kumpf 1.39 Sint64 valueFactory::stringToSint(
|
110 kumpf 1.38 const String &val,
111 CIMType type)
|
112 karl 1.37 {
|
113 kumpf 1.38 Sint64 s64;
114 CString valCString = val.getCString();
115
116 Boolean success =
117 (StringConversion::stringToSint64(
118 valCString, StringConversion::decimalStringToUint64, s64) ||
119 StringConversion::stringToSint64(
120 valCString, StringConversion::hexStringToUint64, s64) ||
121 StringConversion::stringToSint64(
122 valCString, StringConversion::octalStringToUint64, s64) ||
123 StringConversion::stringToSint64(
124 valCString, StringConversion::binaryStringToUint64, s64)) &&
125 StringConversion::checkSintBounds(s64, type);
126
127 if (!success)
|
128 karl 1.37 {
|
129 kumpf 1.39 String message;
130 cimmofMessages::arglist arglist;
131 arglist.append(cimTypeToString(type));
132 arglist.append(val);
133 cimmofMessages::getMessage(
134 message, cimmofMessages::INVALID_LITERAL_VALUE, arglist);
135 throw Exception(message);
|
136 mike 1.10 }
|
137 kumpf 1.38
138 return s64;
|
139 mike 1.10 }
140
|
141 kumpf 1.39 Real64 valueFactory::stringToReal(
142 const String &val,
143 CIMType type)
|
144 karl 1.37 {
|
145 kumpf 1.38 Real64 r64;
146 Boolean success = StringConversion::stringToReal64(val.getCString(), r64);
147
148 if (!success)
|
149 karl 1.37 {
|
150 kumpf 1.39 String message;
151 cimmofMessages::arglist arglist;
152 arglist.append(cimTypeToString(type));
153 arglist.append(val);
154 cimmofMessages::getMessage(
155 message, cimmofMessages::INVALID_LITERAL_VALUE, arglist);
156 throw Exception(message);
|
157 karl 1.37 }
|
158 kumpf 1.38
159 return r64;
|
160 mike 1.10 }
161
162 //-------------------------------------------------------------------------
163 // This is a parser for a comma-separated value String. It returns one
164 // value per call. It handles quoted String and depends on the caller to
165 // tell it where the end of the String is.
|
166 karl 1.37 // Returns value in value and return pointing to character after separator
|
167 karl 1.14 // string
|
168 mike 1.10 //-------------------------------------------------------------------------
|
169 karl 1.37 static Uint32 nextcsv(const String &csv, int sep, const Uint32 start,
170 const Uint32 end, String &value)
|
171 mike 1.10 {
|
172 karl 1.37 enum parsestate {INDQUOTE, INSQUOTE, NOTINQUOTE};
173 value = "";
174 Uint32 maxend = local_min(csv.size(), end);
175 Uint32 idx = start;
176 parsestate state = NOTINQUOTE;
177 // ATTN-RK-P3-071702: Added hack to check for null character because Strings
178 // were sometimes getting created that included an extra null character.
179 while (idx <= maxend && csv[idx])
180 {
181 char idxchar = csv[idx];
182 switch (state)
183 {
184 case NOTINQUOTE:
185 switch (idxchar)
186 {
187 case '\\':
188 state = INSQUOTE;
189 break;
190 case '"':
191 state = INDQUOTE;
192 break;
193 karl 1.37 default:
194 if (idxchar == sep)
195 return idx + 1;
196 else
197 value.append(idxchar);
198 break;
199 }
200 break;
201 case INSQUOTE:
202 value.append(idxchar);
203 state = NOTINQUOTE;
204 break;
205 case INDQUOTE:
206 switch (idxchar)
207 {
208 case '"':
209 state = NOTINQUOTE;
210 break;
211 default:
212 value.append(idxchar);
213 break;
214 karl 1.37 }
215 }
216 idx++;
217 } // end while
218 return idx;
|
219 mike 1.10 }
220
|
221 e.boden 1.31
|
222 mike 1.10 // ------------------------------------------------------------------
223 // When the value to be build is of Array type, this routine
224 // parses out the comma-separated values and builds the array
|
225 karl 1.37 // -----------------------------------------------------------------
|
226 kumpf 1.39 CIMValue* valueFactory::_buildArrayValue(
227 CIMType type,
228 unsigned int arrayDimension,
229 const String& rep)
|
230 mike 1.10 {
|
231 karl 1.37 String sval;
232 Uint32 start = 0;
233 Uint32 strsize = rep.size();
234 Uint32 end = strsize;
235
236 /* KS Changed all of the following from whil {...} to do {...}
237 * while (start < end);
238 * The combination of the testing and nexcsv meant the last entry was not
239 * processed.
240 */
241 switch (type)
242 {
243 case CIMTYPE_BOOLEAN:
244 {
245 Array<Boolean> *a = new Array<Boolean>;
246 if (strsize != 0)
247 {
248 do
249 {
250 start = nextcsv(rep, ',', start, end, sval);
251 if (sval[0] == 'T')
252 karl 1.37 a->append(1);
253 else
254 a->append(0);
255 } while (start < end);
256 }
257 return new CIMValue(*a);
258 }
259 case CIMTYPE_UINT8:
260 {
261 Array<Uint8> *a = new Array<Uint8>;
262 if (strsize != 0)
263 {
264 do
265 {
266 start = nextcsv(rep, ',', start, end, sval);
|
267 kumpf 1.38 a->append((Uint8)stringToUint(sval, type));
|
268 karl 1.37 } while (start < end);
269 }
270 return new CIMValue(*a);
271 }
272 case CIMTYPE_SINT8:
273 {
274 Array<Sint8> *a = new Array<Sint8>;
275 if (strsize != 0)
276 {
277 do
278 {
279 start = nextcsv(rep, ',', start, end, sval);
|
280 kumpf 1.38 a->append((Sint8)stringToSint(sval, type));
|
281 karl 1.37 } while (start < end);
282 }
283 return new CIMValue(*a);
284 }
285 case CIMTYPE_UINT16:
286 {
287 Array<Uint16> *a = new Array<Uint16>;
288 if (strsize != 0)
289 {
290 do
291 {
292 start = nextcsv(rep, ',', start, end, sval);
|
293 kumpf 1.38 a->append((Uint16)stringToUint(sval, type));
|
294 karl 1.37 } while (start < end);
295 }
296 return new CIMValue(*a);
297 }
298 case CIMTYPE_SINT16:
299 {
300 Array<Sint16> *a = new Array<Sint16>;
301 if (strsize != 0)
302 {
303 do
304 {
305 start = nextcsv(rep, ',', start, end, sval);
|
306 kumpf 1.38 a->append((Sint16)stringToSint(sval, type));
|
307 karl 1.37 } while (start < end);
308 }
309 return new CIMValue(*a);
310 }
311 case CIMTYPE_UINT32:
312 {
313 Array<Uint32> *a = new Array<Uint32>;
314 if (strsize != 0)
315 {
316 do
317 {
318 start = nextcsv(rep, ',', start, end, sval);
|
319 kumpf 1.38 a->append((Uint32)stringToUint(sval, type));
|
320 karl 1.37 } while (start < end);
321 }
322 return new CIMValue(*a);
323 }
324 case CIMTYPE_SINT32:
325 {
326 Array<Sint32> *a = new Array<Sint32>;
327 if (strsize != 0)
328 {
329 do
330 {
331 start = nextcsv(rep, ',', start, end, sval);
|
332 kumpf 1.38 a->append((Sint32)stringToSint(sval, type));
|
333 karl 1.37 } while (start < end);
334 }
335 return new CIMValue(*a);
336 }
337 case CIMTYPE_UINT64:
338 {
339 Array<Uint64> *a = new Array<Uint64>;
340 if (strsize != 0)
341 {
342 do
343 {
344 start = nextcsv(rep, ',', start, end, sval);
|
345 kumpf 1.38 a->append((Uint64)stringToUint(sval, type));
|
346 karl 1.37 } while (start < end);
347 }
348 return new CIMValue(*a);
349 }
350 case CIMTYPE_SINT64:
351 {
352 Array<Sint64> *a = new Array<Sint64>;
353 if (strsize != 0)
354 {
355 do
356 {
357 start = nextcsv(rep, ',', start, end, sval);
|
358 kumpf 1.38 a->append((Sint64)stringToSint(sval, type));
|
359 karl 1.37 } while (start < end);
360 }
361 return new CIMValue(*a);
362 }
363 case CIMTYPE_REAL32:
364 {
365 Array<Real32> *a = new Array<Real32>;
366 if (strsize != 0)
367 {
368 do
369 {
370 start = nextcsv(rep, ',', start, end, sval);
|
371 kumpf 1.39 a->append((Real32)stringToReal(sval, type));
|
372 karl 1.37 } while (start < end);
373 }
374 return new CIMValue(*a);
375 }
376 case CIMTYPE_REAL64:
377 {
378 Array<Real64> *a = new Array<Real64>;
379 if (strsize != 0)
380 {
381 do
382 {
383 start =
384 nextcsv(rep, ',', start, end, sval);
|
385 kumpf 1.39 a->append((Real64)stringToReal(sval, type));
|
386 karl 1.37 } while (start < end);
387 }
388 return new CIMValue(*a);
389 }
390 case CIMTYPE_CHAR16:
391 {
392 Array<Char16> *a = new Array<Char16>;
393 if (strsize != 0)
394 {
395 do
396 {
397 start =
398 nextcsv(rep, ',', start, end, sval);
399 a->append(sval[0]);
400 } while (start < end);
401 }
402 return new CIMValue(*a);
403 }
404 case CIMTYPE_STRING:
405 {
406 Array<String> *a = new Array<String>;
407 karl 1.37 if (strsize != 0)
408 {
409 do
410 {
411 start =
412 nextcsv(rep, ',', start, end, sval);
413 a->append(sval);
414 } while (start < end);
415 }
416 return new CIMValue(*a);
417 }
418 case CIMTYPE_DATETIME:
419 {
420 Array<CIMDateTime> *a = new Array<CIMDateTime>;
421 while (strsize &&
422 (start = nextcsv(rep, ',', start, end, sval)) < end )
423 {
|
424 kumpf 1.38 a->append(CIMDateTime(sval));
|
425 karl 1.37 }
426 return new CIMValue(*a);
427 }
428 case CIMTYPE_REFERENCE:
429 break;
430 // PEP 194:
431 // Note that "object" (ie. CIMTYPE_OBJECT) is not a real
432 // CIM datatype, just a Pegasus internal representation
433 // of an embedded object, so it won't be found here.
434 case CIMTYPE_OBJECT:
|
435 a.dunfey 1.36 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
|
436 karl 1.37 case CIMTYPE_INSTANCE:
|
437 a.dunfey 1.36 #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
|
438 karl 1.37 break;
439 } // end switch
440 return 0;
|
441 mike 1.10 }
442
|
443 karl 1.13 /* ATTN: KS 20 Feb 02 - Think we need to account for NULL value here differently
|
444 karl 1.37 They come in as an empty string from devaultValue and if they are an empty
|
445 karl 1.13 string we need to create the correct type but without a value in it.
|
446 karl 1.37 Easiest may be to test in each converter since otherwise would have to
|
447 karl 1.13 create a second switch. Either that or if strlength = zero
448 create an empty CIMValue and then put in the type
449 CIMValue x;
450 x.set(Uint16(9)
451 */
|
452 e.boden 1.31 //----------------------------------------------------------------
|
453 karl 1.37 CIMValue * valueFactory::createValue(CIMType type, int arrayDimension,
454 Boolean isNULL,
455 const String *repp)
|
456 mike 1.10 {
457 const String &rep = *repp;
|
458 karl 1.28 //cout << "valueFactory, value = " << rep << endl;
|
459 mike 1.10 CIMDateTime dt;
460 if (arrayDimension == -1) { // this is not an array type
|
461 karl 1.37
|
462 kumpf 1.16 if (isNULL)
463 {
464 return new CIMValue(type, false);
465 }
|
466 e.boden 1.31
|
467 mike 1.10 switch(type) {
|
468 kumpf 1.38 case CIMTYPE_UINT8: return new CIMValue((Uint8) stringToUint(rep, type));
469 case CIMTYPE_SINT8: return new CIMValue((Sint8) stringToSint(rep, type));
470 case CIMTYPE_UINT16: return new CIMValue((Uint16) stringToUint(rep, type));
471 case CIMTYPE_SINT16: return new CIMValue((Sint16) stringToSint(rep, type));
472 case CIMTYPE_UINT32: return new CIMValue((Uint32) stringToUint(rep, type));
473 case CIMTYPE_SINT32: return new CIMValue((Sint32) stringToSint(rep, type));
474 case CIMTYPE_UINT64: return new CIMValue((Uint64) stringToUint(rep, type));
475 case CIMTYPE_SINT64: return new CIMValue((Sint64) stringToSint(rep, type));
|
476 kumpf 1.39 case CIMTYPE_REAL32: return new CIMValue((Real32) stringToReal(rep, type));
477 case CIMTYPE_REAL64: return new CIMValue((Real64) stringToReal(rep, type));
|
478 kumpf 1.38 case CIMTYPE_CHAR16: return new CIMValue((Char16) rep[0]);
|
479 karl 1.37 case CIMTYPE_BOOLEAN: return new CIMValue((Boolean) (rep[0] == 'T'?1:0));
|
480 kumpf 1.38 case CIMTYPE_STRING: return new CIMValue(rep);
481 case CIMTYPE_DATETIME: return new CIMValue(CIMDateTime(rep));
|
482 kumpf 1.39 case CIMTYPE_REFERENCE: return new CIMValue(CIMObjectPath(rep));
|
483 dave.sudlik 1.34 // PEP 194:
484 // Note that "object" (ie. CIMTYPE_OBJECT) is not a real CIM datatype, just a
|
485 karl 1.37 // Pegasus internal representation of an embedded object, so it won't be
486 // found here.
|
487 a.dunfey 1.36 case CIMTYPE_OBJECT:
488 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
489 case CIMTYPE_INSTANCE:
490 #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
491 break;
|
492 mike 1.10 }
493 return(new CIMValue((Uint32) 0)); // default
|
494 karl 1.37 }
495 else
496 { // an array type, either fixed or variable
|
497 karl 1.13
|
498 kumpf 1.15 const String &rep = *repp;
|
499 karl 1.13 // KS If empty string set CIMValue type but Null attribute.
|
500 kumpf 1.15 if (isNULL)
|
501 karl 1.13 return new CIMValue(type, true, arrayDimension);
502
|
503 kumpf 1.39 return _buildArrayValue(type, (unsigned int)arrayDimension, rep);
|
504 mike 1.10 }
505 }
|