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