1 lawrence.luo 1.2 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 lawrence.luo 1.2 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //////////////////////////////////////////////////////////////////////////
29 //
30 //%////////////////////////////////////////////////////////////////////////////
31
32 #include <Pegasus/Common/Tracer.h>
33 #include <Pegasus/Common/MessageLoader.h>
34 #include <Pegasus/Common/StrLit.h>
35 #include <Pegasus/Common/CIMClass.h>
36 #include <Pegasus/Common/CIMClassRep.h>
37 #include <Pegasus/Common/StringConversion.h>
38 #include <Pegasus/Common/Array.h>
39 #include <Pegasus/Common/ArrayInter.h>
40 #include <cctype>
41 #include <cstdio>
42
43 lawrence.luo 1.2 #include "JSONWriter.h"
44
45 PEGASUS_USING_STD;
46
47 PEGASUS_NAMESPACE_BEGIN
48
49
50 // From XMLGenerator
51 // Note: we cannot use StrLit here since it has a constructor (forbids
52 // structure initialization).
53
54 struct SpecialChar
55 {
56 const char* str;
57 Uint32 size;
58 };
59
60 // Defines encodings of special characters. Just use a 7-bit ASCII character
61 // as an index into this array to retrieve its string encoding and encoding
62 // length in bytes.
63 /*From RFC 4627:
64 lawrence.luo 1.2 All Unicode characters may be placed within the
65 quotation marks except for the characters that must be escaped:
66 quotation mark, reverse solidus, and the control characters (U+0000
67 through U+001F).
68 [...]
69 string = quotation-mark *char quotation-mark
70
71 char = unescaped /
72 escape (
73 %x22 / ; " quotation mark U+0022
74 %x5C / ; \ reverse solidus U+005C
75 %x2F / ; / solidus U+002F
76 %x62 / ; b backspace U+0008
77 %x66 / ; f form feed U+000C
78 %x6E / ; n line feed U+000A
79 %x72 / ; r carriage return U+000D
80 %x74 / ; t tab U+0009
81 %x75 4HEXDIG ) ; uXXXX U+XXXX
82
83 escape = %x5C ; \
84
85 lawrence.luo 1.2 quotation-mark = %x22 ; "
86
87 unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
88 */
89 static const SpecialChar _specialChars[] =
90 {
91 {STRLIT_ARGS("\\u0000")},
92 {STRLIT_ARGS("\\u0001")},
93 {STRLIT_ARGS("\\u0002")},
94 {STRLIT_ARGS("\\u0003")},
95 {STRLIT_ARGS("\\u0004")},
96 {STRLIT_ARGS("\\u0005")},
97 {STRLIT_ARGS("\\u0006")},
98 {STRLIT_ARGS("\\u0007")},
99 {STRLIT_ARGS("\\u0008")},
100 {STRLIT_ARGS("\\u0009")},
101 {STRLIT_ARGS("\\u000A")},
102 {STRLIT_ARGS("\\u000B")},
103 {STRLIT_ARGS("\\u000C")},
104 {STRLIT_ARGS("\\u000D")},
105 {STRLIT_ARGS("\\u000E")},
106 lawrence.luo 1.2 {STRLIT_ARGS("\\u000F")},
107 {STRLIT_ARGS("\\u0010")},
108 {STRLIT_ARGS("\\u0011")},
109 {STRLIT_ARGS("\\u0012")},
110 {STRLIT_ARGS("\\u0013")},
111 {STRLIT_ARGS("\\u0014")},
112 {STRLIT_ARGS("\\u0015")},
113 {STRLIT_ARGS("\\u0016")},
114 {STRLIT_ARGS("\\u0017")},
115 {STRLIT_ARGS("\\u0018")},
116 {STRLIT_ARGS("\\u0019")},
117 {STRLIT_ARGS("\\u001A")},
118 {STRLIT_ARGS("\\u001B")},
119 {STRLIT_ARGS("\\u001C")},
120 {STRLIT_ARGS("\\u001D")},
121 {STRLIT_ARGS("\\u001E")},
122 {STRLIT_ARGS("\\u001F")},
123 {STRLIT_ARGS(" ")},
124 {STRLIT_ARGS("!")},
125 {STRLIT_ARGS("\\u0022")}, // "
126 {STRLIT_ARGS("#")},
127 lawrence.luo 1.2 {STRLIT_ARGS("$")},
128 {STRLIT_ARGS("%")},
129 {STRLIT_ARGS("&")},
130 {STRLIT_ARGS("'")},
131 {STRLIT_ARGS("(")},
132 {STRLIT_ARGS(")")},
133 {STRLIT_ARGS("*")},
134 {STRLIT_ARGS("+")},
135 {STRLIT_ARGS(",")},
136 {STRLIT_ARGS("-")},
137 {STRLIT_ARGS(".")},
138 {STRLIT_ARGS("\\/")}, // slash
139 {STRLIT_ARGS("0")},
140 {STRLIT_ARGS("1")},
141 {STRLIT_ARGS("2")},
142 {STRLIT_ARGS("3")},
143 {STRLIT_ARGS("4")},
144 {STRLIT_ARGS("5")},
145 {STRLIT_ARGS("6")},
146 {STRLIT_ARGS("7")},
147 {STRLIT_ARGS("8")},
148 lawrence.luo 1.2 {STRLIT_ARGS("9")},
149 {STRLIT_ARGS(":")},
150 {STRLIT_ARGS(";")},
151 {STRLIT_ARGS("<")},
152 {STRLIT_ARGS("=")},
153 {STRLIT_ARGS(">")},
154 {STRLIT_ARGS("?")},
155 {STRLIT_ARGS("@")},
156 {STRLIT_ARGS("A")},
157 {STRLIT_ARGS("B")},
158 {STRLIT_ARGS("C")},
159 {STRLIT_ARGS("D")},
160 {STRLIT_ARGS("E")},
161 {STRLIT_ARGS("F")},
162 {STRLIT_ARGS("G")},
163 {STRLIT_ARGS("H")},
164 {STRLIT_ARGS("I")},
165 {STRLIT_ARGS("J")},
166 {STRLIT_ARGS("K")},
167 {STRLIT_ARGS("L")},
168 {STRLIT_ARGS("M")},
169 lawrence.luo 1.2 {STRLIT_ARGS("N")},
170 {STRLIT_ARGS("O")},
171 {STRLIT_ARGS("P")},
172 {STRLIT_ARGS("Q")},
173 {STRLIT_ARGS("R")},
174 {STRLIT_ARGS("S")},
175 {STRLIT_ARGS("T")},
176 {STRLIT_ARGS("U")},
177 {STRLIT_ARGS("V")},
178 {STRLIT_ARGS("W")},
179 {STRLIT_ARGS("X")},
180 {STRLIT_ARGS("Y")},
181 {STRLIT_ARGS("Z")},
182 {STRLIT_ARGS("[")},
183 {STRLIT_ARGS("\\\\")},
184 {STRLIT_ARGS("]")},
185 {STRLIT_ARGS("^")},
186 {STRLIT_ARGS("_")},
187 {STRLIT_ARGS("`")},
188 {STRLIT_ARGS("a")},
189 {STRLIT_ARGS("b")},
190 lawrence.luo 1.2 {STRLIT_ARGS("c")},
191 {STRLIT_ARGS("d")},
192 {STRLIT_ARGS("e")},
193 {STRLIT_ARGS("f")},
194 {STRLIT_ARGS("g")},
195 {STRLIT_ARGS("h")},
196 {STRLIT_ARGS("i")},
197 {STRLIT_ARGS("j")},
198 {STRLIT_ARGS("k")},
199 {STRLIT_ARGS("l")},
200 {STRLIT_ARGS("m")},
201 {STRLIT_ARGS("n")},
202 {STRLIT_ARGS("o")},
203 {STRLIT_ARGS("p")},
204 {STRLIT_ARGS("q")},
205 {STRLIT_ARGS("r")},
206 {STRLIT_ARGS("s")},
207 {STRLIT_ARGS("t")},
208 {STRLIT_ARGS("u")},
209 {STRLIT_ARGS("v")},
210 {STRLIT_ARGS("w")},
211 lawrence.luo 1.2 {STRLIT_ARGS("x")},
212 {STRLIT_ARGS("y")},
213 {STRLIT_ARGS("z")},
214 {STRLIT_ARGS("{")},
215 {STRLIT_ARGS("|")},
216 {STRLIT_ARGS("}")},
217 {STRLIT_ARGS("~")},
218 {STRLIT_ARGS("\\u007F")},
219 };
220
221 // From XMLGenerator
222 static const int _isSpecialChar7[] =
223 {
224 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
225 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
226 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
227 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
228 };
229
230
231 // From XMLWriter
232 lawrence.luo 1.2 static StrLit _JsonWriterTypeStrings[] =
233 {
234 STRLIT("boolean"), STRLIT("uint8"),
235 STRLIT("sint8"), STRLIT("uint16"),
236 STRLIT("sint16"), STRLIT("uint32"),
237 STRLIT("sint32"), STRLIT("uint64"),
238 STRLIT("sint64"), STRLIT("real32"),
239 STRLIT("real64"), STRLIT("char16"),
240 STRLIT("string"), STRLIT("datetime"),
241 STRLIT("reference"), STRLIT("object"),
242 STRLIT("instance")
243 };
244
245
246 JSONWriter::JSONWriter(Buffer& buf) :
247 _buffer(buf), _propCount(0), _numObjectsEnumerated(0)
248 {
249 }
250
251 JSONWriter::~JSONWriter()
252 {
253 lawrence.luo 1.2 _deletePropertyNames();
254 }
255
256 void JSONWriter::append(CIMInvokeMethodResponseMessage* methodResult,
257 CIMRepository* repository,
258 RsURI& requestUri)
259 {
260 PEG_METHOD_ENTER(TRC_RSSERVER,
261 "JSONWriter::append(CIMInvokeMethodResponseMessage)");
262
263 /*
264 {
265 "kind": " methodresponse",
266 "self": "/cimrs/root%2Fcimv2/Square/1/GetArea",
267 "method": "GetArea",
268 "returnvalue": 100,
269 "parameters": {}
270 }
271
272 */
273 Array<CIMParamValue>& outParms = methodResult->outParameters;
274 lawrence.luo 1.2
275 _buffer.append('{');
276 _append(String("kind"));
277 _buffer.append(':');
278 _append(String("methodresponse"));
279 _buffer.append(',');
280
281 _append(String("self"));
282 _buffer.append(':');
283 _buffer.append('"');
284 _buffer.append(requestUri.getString().getCString(),
285 requestUri.getString().size());
286 _buffer.append('"');
287 _buffer.append(',');
288
289 _append(String("method"));
290 _buffer.append(':');
291 _append(methodResult->methodName.getString());
292 _buffer.append(',');
293
294 _append(String("returnvalue"));
295 lawrence.luo 1.2 _buffer.append(':');
296 _append(methodResult->retValue, repository, requestUri);
297 _buffer.append(',');
298
299 _append(String("parameters"));
300 _buffer.append(':');
301 _buffer.append('{');
302 for (Uint32 x = 0; x < outParms.size(); ++x)
303 {
304 _append(outParms[x].getParameterName());
305 _buffer.append(':');
306 _append(outParms[x].getValue(), repository, requestUri);
307
308 if( x + 1 < outParms.size())
309 {
310 _buffer.append(',');
311 }
312 }
313 _buffer.append('}');
314 _buffer.append('}');
315
316 lawrence.luo 1.2
317 PEG_METHOD_EXIT();
318 }
319
320 void JSONWriter::append(CIMReferencesResponseMessage* referencesResult,
321 CIMRepository* repository,
322 RsURI& requestUri)
323 {
324
325 PEG_METHOD_ENTER(TRC_RSSERVER,
326 "JSONWriter::append(CIMAssociatorsResponseMessage*"
327 "enumResult, Uint32 firstInstance, Uint32 lastInstance)");
328
329 Uint32 numInstances = referencesResult->
330 getResponseData().getObjects().size();
331
332 if (numInstances == 0)
333 {
334 return;
335 }
336
337 lawrence.luo 1.2 Uint32 firstInstance = 0;
338 Uint32 lastInstance = numInstances;
339
340 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
341 "JSONWriter::append() _numObjectsEnumerated = %d, "
342 "firstInstance = %d, lastInstance = %d, numInstances = %d",
343 _numObjectsEnumerated, firstInstance, lastInstance, numInstances));
344
345 if (_numObjectsEnumerated == 0)
346 {
347 _buffer.append('{'); // start the response
348 _buffer.append(STRLIT_ARGS("\"kind\":\"instance\""));
349
350 CIMClass cimClass = repository->getClass(
351 requestUri.getNamespaceName(),
352 requestUri.getClassName(),
353 false /*localOnly*/);
354 CIMObjectPath objectPath = requestUri.getReferencePath(cimClass);
355
356 Buffer instanceUri = RsURI::fromObjectPath(objectPath, true);
357 _buffer.append(STRLIT_ARGS(",\"self\":\""));
358 lawrence.luo 1.2 _buffer.append(instanceUri.getData(), instanceUri.size());
359 _buffer.append('"');
360
361 // the class name
362 _buffer.append(STRLIT_ARGS(",\"class\":"));
363 _append(requestUri.getClassName().getString());
364
365 // the key properties
366 _buffer.append(STRLIT_ARGS(",\"properties\":{"));
367 _buffer.append('}'); // end properties
368
369 // now provide paths to all methods
370 _appendMethods(cimClass, instanceUri, CIMInstance(), true);
371
372 _buffer.append(',');
373 // assoc nav name here
374 _append(requestUri.getNavString());
375
376 _buffer.append(STRLIT_ARGS(": {\"kind\":\"instancecollection\","
377 "\"instances\":"));
378
379 lawrence.luo 1.2 _buffer.append('[');
380 }
381 else if (_buffer.size() > 0 &&
382 _buffer.get(_buffer.size()-1) == '}' &&
383 _buffer.get(_buffer.size()-2) == '}' &&
384 _buffer.get(_buffer.size()-3) == ']')
385 {
386 _buffer.set(_buffer.size()-3, ',');
387 _buffer.set(_buffer.size()-2, ' ');
388 _buffer.set(_buffer.size()-1, ' ');
389 }
390
391 _append(referencesResult->getResponseData().getObjects(),
392 repository,
393 requestUri);
394
395 if (_buffer.size() > 0 && _buffer.get(_buffer.size()-1) == ',')
396 {
397 _buffer.remove(_buffer.size()-1);
398 }
399
400 lawrence.luo 1.2 _buffer.append(']');
401
402 _buffer.append('}'); // end nav property
403 _buffer.append('}'); // end the response
404 _numObjectsEnumerated += numInstances;
405
406 PEG_METHOD_EXIT();
407 }
408
409 void JSONWriter::append(CIMAssociatorsResponseMessage* enumResult,
410 CIMRepository* repository,
411 RsURI& requestUri)
412 {
413 PEG_METHOD_ENTER(TRC_RSSERVER,
414 "JSONWriter::append(CIMAssociatorsResponseMessage*"
415 "enumResult, Uint32 firstInstance, Uint32 lastInstance)");
416
417 Uint32 numInstances = enumResult->getResponseData().getObjects().size();
418
419 if (numInstances == 0)
420 {
421 lawrence.luo 1.2 return;
422 }
423
424 Uint32 firstInstance = 0;
425 Uint32 lastInstance = numInstances;
426
427 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
428 "JSONWriter::append() _numObjectsEnumerated = %d, "
429 "firstInstance = %d, lastInstance = %d, numInstances = %d",
430 _numObjectsEnumerated, firstInstance, lastInstance, numInstances));
431
432 if (_numObjectsEnumerated == 0)
433 {
434 _buffer.append('{'); // start the response
435 _buffer.append(STRLIT_ARGS("\"kind\":\"instance\""));
436
437 CIMClass cimClass = repository->getClass(
438 requestUri.getNamespaceName(),
439 requestUri.getClassName(),
440 false /*localOnly*/);
441 CIMObjectPath objectPath = requestUri.getAssociationPath(cimClass);
442 lawrence.luo 1.2
443 Buffer instanceUri = RsURI::fromObjectPath(objectPath, true);
444 _buffer.append(STRLIT_ARGS(",\"self\":\""));
445 _buffer.append(instanceUri.getData(), instanceUri.size());
446 _buffer.append('"');
447
448 // the class name
449 _buffer.append(STRLIT_ARGS(",\"class\":"));
450 _append(requestUri.getClassName().getString());
451
452 // the key properties
453 _buffer.append(STRLIT_ARGS(",\"properties\":{"));
454 _buffer.append('}'); // end properties
455
456 // now provide paths to all methods
457 _appendMethods(cimClass, instanceUri, CIMInstance(), true);
458
459 _buffer.append(',');
460 // assoc nav name here
461 _append(requestUri.getNavString());
462
463 lawrence.luo 1.2 _buffer.append(STRLIT_ARGS(": {\"kind\":\"instancecollection\","
464 "\"instances\":"));
465 _buffer.append('[');
466 }
467 else if (_buffer.size() > 0 &&
468 _buffer.get(_buffer.size()-1) == '}' &&
469 _buffer.get(_buffer.size()-2) == '}' &&
470 _buffer.get(_buffer.size()-3) == ']')
471 {
472 _buffer.set(_buffer.size()-3, ',');
473 _buffer.set(_buffer.size()-2, ' ');
474 _buffer.set(_buffer.size()-1, ' ');
475 }
476
477 _append(enumResult->getResponseData().getObjects(),
478 repository,
479 requestUri);
480
481 if (_buffer.size() > 0 && _buffer.get(_buffer.size()-1) == ',')
482 {
483 _buffer.remove(_buffer.size()-1);
484 lawrence.luo 1.2 }
485
486 _buffer.append(']');
487
488 _buffer.append('}'); // end nav property
489 _buffer.append('}'); // end the response
490 _numObjectsEnumerated += numInstances;
491
492 PEG_METHOD_EXIT();
493 }
494
495 void JSONWriter::append(CIMEnumerateInstancesResponseMessage* enumResult,
496 Uint32 firstInstance, Uint32 lastInstance, CIMRepository* repository,
497 RsURI& requestUri)
498 {
499 PEG_METHOD_ENTER(TRC_RSSERVER,
500 "JSONWriter::append(CIMEnumerateInstancesResponseMessage*"
501 "enumResult, Uint32 firstInstance, Uint32 lastInstance)");
502
503 Uint32 numInstances =
504 enumResult->getResponseData().getInstances().size();
505 lawrence.luo 1.2
506 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
507 "JSONWriter::append()"
508 "firstInstance = %d, lastInstance = %d, numInstances = %d, "
509 "_numObjectsEnumerated = %d",
510 firstInstance, lastInstance, numInstances, _numObjectsEnumerated));
511
512 // If instances are available through more than one provider
513 // make sure that they are contained in one array
514 Uint32 bufferSize = _buffer.size();
515 if (_numObjectsEnumerated == 0 &&
516 // bufferSize > 2 && _buffer.get(bufferSize-2) == '[' &&
517 _buffer.get(bufferSize-2) == ']' &&
518 _buffer.get(bufferSize-1) == '}')
519 {
520 _buffer.remove(_buffer.size()-1);
521 if (bufferSize > 2 && _buffer.get(bufferSize-3) == '[')
522 {
523 _buffer.remove(_buffer.size()-1);
524 }
525 }
526 lawrence.luo 1.2 else if (_numObjectsEnumerated == 0)
527 {
528 /// this is the start of the array
529 _buffer.append(STRLIT_ARGS("{\"kind\":\"instancecollection\","
530 "\"self\":\""));
531 _buffer.append(requestUri.getString().getCString(),
532 requestUri.getString().size());
533 _buffer.append(STRLIT_ARGS("\",\"class\":"));
534 _append(requestUri.getClassName().getString());
535 _buffer.append(STRLIT_ARGS(",\"instances\":["));
536 }
537
538 if (firstInstance == PEG_NOT_FOUND || lastInstance == PEG_NOT_FOUND)
539 {
540 firstInstance = 0;
541 lastInstance = numInstances;
542 }
543 else
544 {
545 // Called for ranged requests
546
547 lawrence.luo 1.2 // _numObjectsEnumerated tracks the number
548 // of instances that went by.
549 // Example: Assume a result set of 1000 instances,
550 // and a request for instances 299-501 of that set.
551 // The append method is called 10 times (numInstances = 100)
552 // with firstInstance = 299 and lastInstance = 501.
553 //
554 // The if statements below normalize firstInstance and
555 // lastInstance to fit the current call.
556 if (_numObjectsEnumerated + numInstances <= firstInstance)
557 {
558 // firstInstance is larger than the sum of
559 // objects enumerated to this point and the number
560 // of objects in this iteration.
561 // For the above example of firstInstance == 299 and
562 // lastInstance == 501 this is the case for the
563 // first two iterations (_numObjectsEnumerated == 0,
564 // _numObjectsEnumerated == 100) --> nothing to append
565 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
566 "JSONWriter::append() nothing to do - "
567 "firstInstance = %d, lastInstance = %d, numInstances = %d",
568 lawrence.luo 1.2 firstInstance, lastInstance, numInstances));
569
570 _numObjectsEnumerated += numInstances;
571 PEG_METHOD_EXIT();
572 return;
573 }
574 else if (_numObjectsEnumerated < firstInstance)
575 {
576 // firstInstance is within the range of the current
577 // iteration, e.g. firstInstance == 299,
578 // normalized to 299 - 200 = 99 (third iteration)
579 firstInstance -= _numObjectsEnumerated;
580 }
581 else
582 {
583 // _numObjectsEnumerated is larger than firstInstance.
584 firstInstance = 0;
585 }
586
587
588 if (_numObjectsEnumerated < lastInstance)
589 lawrence.luo 1.2 {
590 // _numObjectsEnumerated is within current
591 // iteration, e.g. lastInstance == 501,
592 // normalized to 501 - 500 = 1 (sixth iteration)
593 lastInstance -= _numObjectsEnumerated;
594 }
595 else
596 {
597 // _numObjectsEnumerated is larger than current iteration
598 // --> nothing to append
599 _numObjectsEnumerated += numInstances;
600 PEG_METHOD_EXIT();
601 return;
602 }
603 }
604
605 if (_numObjectsEnumerated > 0 && _buffer.get(_buffer.size()-1) == ']')
606 {
607 _buffer.set(_buffer.size()-1, ',');
608 }
609
610 lawrence.luo 1.2 for (Uint32 i = firstInstance; i <= lastInstance && i < numInstances; ++i)
611 {
612 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
613 "JSONWriter::append() firstInstance = %d,"
614 "EnumerateInstance i = %d, _numObjectsEnumerated = %d, "
615 "Buffer size: %d",
616 firstInstance, i, _numObjectsEnumerated, _buffer.size()));
617
618 _append(enumResult->getResponseData().getInstances()[i],
619 true, true, repository, requestUri);
620
621 if (i < lastInstance)
622 _buffer.append(',');
623
624 if (i == firstInstance && _numObjectsEnumerated == 0)
625 {
626 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
627 "JSONWriter::append() Adjusting Buffer by %d * %d",
628 lastInstance, _buffer.size()));
629
630 _buffer.reserveCapacity(_buffer.size() + ((lastInstance *
631 lawrence.luo 1.2 _buffer.size()) + 2));
632 }
633 }
634
635 if (_buffer.get(_buffer.size()-1) == ',')
636 {
637 _buffer.remove(_buffer.size()-1);
638 }
639
640 _buffer.append(']'); // end the array of instance
641 _buffer.append('}'); // end the instancecollection
642
643 _numObjectsEnumerated += numInstances;
644
645 PEG_METHOD_EXIT();
646 }
647
648
649 void JSONWriter::append(CIMGetClassResponseMessage* result)
650 {
651 _append(result->cimClass);
652 lawrence.luo 1.2 }
653
654 void JSONWriter::append(CIMGetInstanceResponseMessage* result,
655 CIMRepository* repository,
656 RsURI& requestUri)
657 {
658 _append(result->getResponseData().getInstance(),
659 true, true, repository, requestUri);
660 }
661
662 void JSONWriter::append(CIMException& e, String& httpMethod, RsURI& reqURI)
663 {
664
665 // {
666 // "kind": "errorresponse",
667 // "self": "/cimrs/root%2Fcimv2/Square/1",
668 // "httpmethod": "GET",
669 // "statuscode": 12,
670 // "statusdescription": "Program exited abnormally.",
671 // "errors": [
672 // {
673 lawrence.luo 1.2 // "kind": "instance",
674 // "class": "CIM_Error",
675 // "properties": {
676 // "ErrorType": 4,
677 // "PerceivedSeverity": 5,
678 // "ProbableCause": 48,
679 // "Message": "Program exited abnormally.",
680 // "MessageArguments": [ "42" ],
681 // "MessageID": "1234",
682 // "OwningEntity": "ACME"
683 // }
684 // }
685 // ]
686 // }
687
688 const char* message = cimStatusCodeToString( e.getCode());
689
690 _buffer.append(STRLIT_ARGS("{"));
691
692 _buffer.append(STRLIT_ARGS("\"kind\": \"errorresponse\",\"self\":\""));
693 _buffer.append(reqURI.getString().getCString(), reqURI.getString().size());
694 lawrence.luo 1.2 _buffer.append(STRLIT_ARGS("\","));
695 _buffer.append(STRLIT_ARGS("\"httpmethod\":"));
696 _append(httpMethod);
697 _buffer.append(',');
698 _buffer.append(STRLIT_ARGS("\"statuscode\":"));
699 _append((Uint32)e.getCode());
700 _buffer.append(',');
701 _buffer.append(STRLIT_ARGS("\"statusdescription\":"));
702 _append(String(message));
703 _buffer.append(',');
704
705 _buffer.append(STRLIT_ARGS("\"message\":\""));
706 _buffer.append(message, strlen(message));
707 _buffer.append(STRLIT_ARGS("\""));
708 _buffer.append(',');
709
710
711 _buffer.append(STRLIT_ARGS("\"errors\":["));
712 for(Uint32 i = 0; i < e.getErrorCount(); i++)
713 {
714 CIMConstInstance cimError = e.getError(i);
715 lawrence.luo 1.2 _append(cimError, false, true, NULL, reqURI, false);
716 if(i < e.getErrorCount()-1)
717 _buffer.append(',');
718 }
719 _buffer.append(']');
720
721 _buffer.append(STRLIT_ARGS("}"));
722 }
723
724 void JSONWriter::append(Exception& e, String& httpMethod, RsURI& reqURI)
725 {
726 CIMException cimException(CIM_ERR_FAILED,
727 cimStatusCodeToString(CIM_ERR_FAILED));
728 append(cimException, httpMethod, reqURI);
729 }
730
731
732
733 void JSONWriter::_append(Array<CIMObject>& objArray,
734 CIMRepository* repository,
735 RsURI& requestUri)
736 lawrence.luo 1.2 {
737 for (Uint32 i = 0, n = objArray.size(); i < n; ++i)
738 {
739 const CIMObject& cimObj = objArray[i];
740
741 if (cimObj.isInstance())
742 {
743 CIMConstInstance inst(cimObj);
744 _append(inst, true, true, repository, requestUri);
745 if(i < n - 1)
746 _buffer.append(',');
747 }
748 }
749 }
750
751 void JSONWriter::_append(const CIMConstClass& cimClass)
752 {
753 _buffer.append(STRLIT_ARGS("{\"name\":"));
754 _append(cimClass.getClassName().getString());
755 _buffer.append(STRLIT_ARGS(",\"superclass\":"));
756
757 lawrence.luo 1.2 if (cimClass.getSuperClassName().isNull())
758 {
759 _buffer.append(STRLIT_ARGS("null"));
760 }
761 else
762 {
763 _append(cimClass.getSuperClassName().getString());
764 }
765
766 _buffer.append(STRLIT_ARGS(",\"properties\":{"));
767 Uint32 propertyCount = cimClass.getPropertyCount();
768 for (Uint32 i = 0; i < propertyCount; i++)
769 {
770 _append(cimClass.getProperty(i));
771
772 if (i < propertyCount - 1)
773 _buffer.append(',');
774 }
775
776 _buffer.append(STRLIT_ARGS("},\"qualifiers\":{"));
777 Uint32 qualifierCount = cimClass.getQualifierCount();
778 lawrence.luo 1.2 for (Uint32 i = 0; i < qualifierCount; i++)
779 {
780 _append(cimClass.getQualifier(i));
781
782 if (i < qualifierCount - 1)
783 _buffer.append(',');
784 }
785 _buffer.append(STRLIT_ARGS("}"));
786
787 _buffer.append('}');
788 }
789
790 void JSONWriter::_appendMethods(const CIMClass &cimClass, Buffer instanceUri,
791 const CIMConstInstance& cimInstance, Boolean useAbsoluteUri)
792 {
793 // now provide paths to all methods
794 _buffer.append(STRLIT_ARGS(",\"methods\":{"));
795 if (!cimClass.isUninitialized())
796 {
797 // for each method produce a method URI
798 if (instanceUri.size() == 0)
799 lawrence.luo 1.2 {
800 CIMObjectPath objPath;
801 // for embedded instances we might not get a good object path
802 if (cimInstance.getPath().getKeyBindings().size() == 0)
803 objPath = cimInstance.buildPath(
804 cimInstance.getClassName());
805 else objPath = cimInstance.getPath();
806 instanceUri = RsURI::fromObjectPath(objPath, useAbsoluteUri);
807 }
808
809 for (Uint32 i = 0; i < cimClass.getMethodCount(); i++)
810 {
811 _append(cimClass.getMethod(i).getName().getString());
812 _buffer.append(':');
813
814 _buffer.append('"');
815 _buffer.append(instanceUri.getData(), instanceUri.size());
816 _buffer.append('/');
817 _buffer.append(cimClass.getMethod(i).getName().
818 getString().getCString(),
819 cimClass.getMethod(i).getName().getString().size());
820 lawrence.luo 1.2 _buffer.append('"');
821 // append a , if this is not the last method
822 if (i != cimClass.getMethodCount() - 1) _buffer.append(',');
823 }
824 }
825 else
826 {
827 PEG_TRACE(
828 (TRC_RSSERVER, Tracer::LEVEL4,
829 "JSONWriter::append instance could not get to class def."
830 " Leaving method list empty."));
831 }
832 _buffer.append(STRLIT_ARGS("}"));
833 }
834
835 void JSONWriter::_append(const CIMConstInstance& cimInstance,
836 Boolean includeUri, Boolean useAbsoluteUri, CIMRepository* repository,
837 RsURI& requestUri, Boolean includeMethods)
838 {
839 PEG_METHOD_ENTER(TRC_RSSERVER,
840 "JSONWriter::append(const CIMInstance& cimInstance, "
841 lawrence.luo 1.2 "Boolean includeUri)");
842
843 Uint32 propertyCount = cimInstance.getPropertyCount();
844
845 // get the class def
846 CIMClass cimClass;
847 if(repository != NULL)
848 {
849 try{
850 cimClass = repository->getClass(
851 requestUri.getNamespaceName(),
852 cimInstance.getClassName(),
853 false /*localOnly*/);
854 }
855 catch (CIMException& e)
856 {
857 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL1,
858 "JSONWriter::_append() CIMException thrown: %s / %s",
859 (const char*)e.getMessage().getCString(),
860 cimStatusCodeToString( e.getCode() )));
861 // No repository so log a message and leave the methods empty.
862 lawrence.luo 1.2 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
863 "JSONWriter::append instance"
864 " could not find class definition."));
865 throw;
866 }
867 }
868 else
869 {
870 // No repository so log a message and leave the methods empty.
871 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
872 "JSONWriter::append instance did not receive a repository."));
873 }
874
875 _buffer.append('{');
876 _buffer.append(STRLIT_ARGS("\"kind\":\"instance\""));
877
878 Buffer instanceUri;
879 if (includeUri)
880 {
881 _buffer.append(STRLIT_ARGS(",\"self\":\""));
882
883 lawrence.luo 1.2 CIMObjectPath objPath;
884 // for embedded instances we might not get a good object path
885 if(cimInstance.getPath().getKeyBindings().size() == 0)
886 objPath = cimInstance.buildPath(cimClass);
887 else
888 objPath = cimInstance.getPath();
889
890 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
891 "JSONWriter::append object path:%s",
892 (const char*)(objPath.toString().getCString())));
893
894 instanceUri = RsURI::fromObjectPath(objPath, useAbsoluteUri);
895 _buffer.append(instanceUri.getData(), instanceUri.size());
896 _buffer.append('"');
897 }
898
899 // the class name
900 _buffer.append(STRLIT_ARGS(",\"class\":"));
901 _append(cimInstance.getClassName().getString());
902
903
904 lawrence.luo 1.2 _buffer.append(STRLIT_ARGS(",\"properties\":{"));
905
906 // Invalid optimization. Code may be removed
907 /*if (_propClass != cimInstance.getClassName())
908 {
909 _deletePropertyNames();
910 _loadPropertyNames(cimInstance);
911 }*/
912
913 for (Uint32 i = 0; i < propertyCount; ++i)
914 {
915 _append(cimInstance.getProperty(i).getName().getString());
916 _buffer.append(':');
917 _append(cimInstance.getProperty(i).getValue(), repository, requestUri);
918
919 if (i < propertyCount - 1)
920 _buffer.append(',');
921 }
922
923 _buffer.append('}'); // end of properties
924
925 lawrence.luo 1.2 if(includeMethods)
926 {
927 // now provide paths to all methods
928 _appendMethods(cimClass, instanceUri, cimInstance, useAbsoluteUri);
929 }
930 _buffer.append(STRLIT_ARGS("}")); // end of instance
931 PEG_METHOD_EXIT();
932 }
933
934 void JSONWriter::_append(const CIMConstProperty& property)
935 {
936 _append(property.getName().getString());
937
938 _buffer.append(STRLIT_ARGS(":{\"type\":\""));
939 _buffer << _JsonWriterTypeStrings[property.getValue().getType()];
940
941 Uint32 qualifierCount = property.getQualifierCount();
942 _buffer.append(STRLIT_ARGS("\",\"qualifiers\":{"));
943 for (Uint32 i = 0; i < qualifierCount; i++)
944 {
945 _append(property.getQualifier(i));
946 lawrence.luo 1.2
947 if (i < qualifierCount - 1)
948 _buffer.append(',');
949 }
950 _buffer.append(STRLIT_ARGS("}}"));
951 }
952
953
954 void JSONWriter::_append(const CIMConstQualifier& qualifier)
955 {
956 //CheckRep(qualifier._rep);
957 //const CIMQualifierRep* rep = qualifier._rep;
958
959 _append(qualifier.getName().getString());
960 _buffer.append(STRLIT_ARGS(":"));
961 RsURI emptyURI("");
962 _append(qualifier.getValue(), NULL, emptyURI);
963 }
964
965
966 void JSONWriter::_append(const CIMValue& value, CIMRepository* repository,
967 lawrence.luo 1.2 RsURI& requestUri)
968 {
969 if (value.isNull())
970 {
971 _buffer.append(STRLIT_ARGS("null"));
972 return;
973 }
974
975 if (value.isArray())
976 {
977 _buffer.append('[');
978 switch (value.getType())
979 {
980 case CIMTYPE_BOOLEAN:
981 {
982 Array<Boolean> a;
983 value.get(a);
984
985 for (Uint32 i = 0; i < a.size(); ++i)
986 {
987 _append(a[i]);
988 lawrence.luo 1.2 if (i < a.size() - 1)
989 _buffer.append(',');
990 }
991 break;
992 }
993
994 case CIMTYPE_UINT8:
995 {
996 Array<Uint8> a;
997 value.get(a);
998
999 for (Uint32 i = 0; i < a.size(); ++i)
1000 {
1001 _append(a[i]);
1002 if (i < a.size() - 1)
1003 _buffer.append(',');
1004 }
1005 break;
1006 }
1007
1008 case CIMTYPE_SINT8:
1009 lawrence.luo 1.2 {
1010 Array<Sint8> a;
1011 value.get(a);
1012
1013 for (Uint32 i = 0; i < a.size(); ++i)
1014 {
1015 _append(a[i]);
1016 if (i < a.size() - 1)
1017 _buffer.append(',');
1018 }
1019 break;
1020 }
1021
1022 case CIMTYPE_UINT16:
1023 {
1024 Array<Uint16> a;
1025 value.get(a);
1026
1027 for (Uint32 i = 0; i < a.size(); ++i)
1028 {
1029 _append(a[i]);
1030 lawrence.luo 1.2 if (i < a.size() - 1)
1031 _buffer.append(',');
1032 }
1033 break;
1034 }
1035
1036 case CIMTYPE_SINT16:
1037 {
1038 Array<Sint16> a;
1039 value.get(a);
1040
1041 for (Uint32 i = 0; i < a.size(); ++i)
1042 {
1043 _append(a[i]);
1044 if (i < a.size() - 1)
1045 _buffer.append(',');
1046 }
1047 break;
1048 }
1049
1050 case CIMTYPE_UINT32:
1051 lawrence.luo 1.2 {
1052 Array<Uint32> a;
1053 value.get(a);
1054
1055 for (Uint32 i = 0; i < a.size(); ++i)
1056 {
1057 _append(a[i]);
1058 if (i < a.size() - 1)
1059 _buffer.append(',');
1060 }
1061 break;
1062 }
1063
1064 case CIMTYPE_SINT32:
1065 {
1066 Array<Sint32> a;
1067 value.get(a);
1068
1069 for (Uint32 i = 0; i < a.size(); ++i)
1070 {
1071 _append(a[i]);
1072 lawrence.luo 1.2 if (i < a.size() - 1)
1073 _buffer.append(',');
1074 }
1075 break;
1076 }
1077
1078 case CIMTYPE_UINT64:
1079 {
1080 Array<Uint64> a;
1081 value.get(a);
1082
1083 for (Uint32 i = 0; i < a.size(); ++i)
1084 {
1085 _append(a[i]);
1086 if (i < a.size() - 1)
1087 _buffer.append(',');
1088 }
1089 break;
1090 }
1091
1092 case CIMTYPE_SINT64:
1093 lawrence.luo 1.2 {
1094 Array<Sint64> a;
1095 value.get(a);
1096
1097 for (Uint32 i = 0; i < a.size(); ++i)
1098 {
1099 _append(a[i]);
1100 if (i < a.size() - 1)
1101 _buffer.append(',');
1102 }
1103 break;
1104 }
1105
1106 case CIMTYPE_REAL32:
1107 {
1108 Array<Real32> a;
1109 value.get(a);
1110
1111 for (Uint32 i = 0; i < a.size(); ++i)
1112 {
1113 _append(a[i]);
1114 lawrence.luo 1.2 if (i < a.size() - 1)
1115 _buffer.append(',');
1116 }
1117 break;
1118 }
1119
1120 case CIMTYPE_REAL64:
1121 {
1122 Array<Real64> a;
1123 value.get(a);
1124
1125 for (Uint32 i = 0; i < a.size(); ++i)
1126 {
1127 _append(a[i]);
1128 if (i < a.size() - 1)
1129 _buffer.append(',');
1130 }
1131 break;
1132 }
1133
1134 case CIMTYPE_CHAR16:
1135 lawrence.luo 1.2 {
1136 Array<Char16> a;
1137 value.get(a);
1138 String s;
1139
1140 for (Uint32 i = 0; i < a.size(); ++i)
1141 {
1142 s = String(&a[i]);
1143 _append(s);
1144 if (i < a.size() - 1)
1145 _buffer.append(',');
1146 }
1147
1148 break;
1149 }
1150
1151 case CIMTYPE_STRING:
1152 {
1153 Array<String> a;
1154 value.get(a);
1155
1156 lawrence.luo 1.2 for (Uint32 i = 0; i < a.size(); ++i)
1157 {
1158 _append(a[i]);
1159 if (i < a.size() - 1)
1160 _buffer.append(',');
1161 }
1162
1163 break;
1164 }
1165 case CIMTYPE_REFERENCE:
1166 {
1167 Array<CIMObjectPath> a;
1168 value.get(a);
1169 for (Uint32 i = 0; i < a.size(); ++i)
1170 {
1171 _append(a[i]);
1172 if (i < a.size() - 1)
1173 _buffer.append(',');
1174 }
1175 break;
1176 }
1177 lawrence.luo 1.2 case CIMTYPE_DATETIME:
1178 {
1179 Array<CIMDateTime> a;
1180 value.get(a);
1181 for (Uint32 i = 0; i < a.size(); ++i)
1182 {
1183 _append(a[i]);
1184 if (i < a.size() - 1)
1185 _buffer.append(',');
1186 }
1187 break;
1188 }
1189 case CIMTYPE_OBJECT:
1190 {
1191 Array<CIMObject> a;
1192 value.get(a);
1193 _append(a, repository, requestUri);
1194 break;
1195 }
1196 case CIMTYPE_INSTANCE:
1197 {
1198 lawrence.luo 1.2 Array<CIMInstance> a;
1199 value.get(a);
1200 for (Uint32 i = 0; i < a.size(); ++i)
1201 {
1202 _append(a[i], true, true, repository, requestUri);
1203 if (i < a.size() - 1)
1204 _buffer.append(',');
1205 }
1206 break;
1207 }
1208 default:
1209 PEGASUS_ASSERT(false);
1210 }
1211 _buffer.append(']');
1212 return;
1213 }
1214 else
1215 {
1216
1217 // from XmlWriter::appendValueElement
1218 switch (value.getType())
1219 lawrence.luo 1.2 {
1220 case CIMTYPE_BOOLEAN:
1221 {
1222 Boolean v;
1223 value.get(v);
1224 _append(v);
1225 break;
1226 }
1227 case CIMTYPE_UINT8:
1228 {
1229 Uint8 v;
1230 value.get(v);
1231 _append(v);
1232 break;
1233 }
1234 case CIMTYPE_SINT8:
1235 {
1236 Sint8 v;
1237 value.get(v);
1238 _append(v);
1239 break;
1240 lawrence.luo 1.2 }
1241 case CIMTYPE_UINT16:
1242 {
1243 Uint16 v;
1244 value.get(v);
1245 _append(v);
1246 break;
1247 }
1248 case CIMTYPE_SINT16:
1249 {
1250 Sint16 v;
1251 value.get(v);
1252 _append(v);
1253 break;
1254 }
1255 case CIMTYPE_UINT32:
1256 {
1257 Uint32 v;
1258 value.get(v);
1259 _append(v);
1260 break;
1261 lawrence.luo 1.2 }
1262 case CIMTYPE_SINT32:
1263 {
1264 Sint32 v;
1265 value.get(v);
1266 _append(v);
1267 break;
1268 }
1269 case CIMTYPE_UINT64:
1270 {
1271 Uint64 v;
1272 value.get(v);
1273 _append(v);
1274 break;
1275 }
1276 case CIMTYPE_SINT64:
1277 {
1278 Sint64 v;
1279 value.get(v);
1280 _append(v);
1281 break;
1282 lawrence.luo 1.2 }
1283 case CIMTYPE_REAL32:
1284 {
1285 Real32 v;
1286 value.get(v);
1287 _append(v);
1288 break;
1289 }
1290 case CIMTYPE_REAL64:
1291 {
1292 Real64 v;
1293 value.get(v);
1294 _append(v);
1295 break;
1296 }
1297 case CIMTYPE_CHAR16:
1298 {
1299 Char16 v;
1300 value.get(v);
1301 String s = String(&v);
1302
1303 lawrence.luo 1.2 _append(s);
1304 break;
1305 }
1306 case CIMTYPE_STRING:
1307 {
1308 String v;
1309 value.get(v);
1310 _append(v, true);
1311 break;
1312 }
1313 case CIMTYPE_DATETIME:
1314 {
1315 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
1316 "JSONWriter::appendValue()- DateTime"));
1317 CIMDateTime v;
1318 value.get(v);
1319 _append(v);
1320
1321 break;
1322 }
1323 case CIMTYPE_REFERENCE:
1324 lawrence.luo 1.2 {
1325 CIMObjectPath v;
1326 value.get(v);
1327 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
1328 "JSONWriter::appendValue()- Reference"));
1329 _append(v);
1330 break;
1331 }
1332 case CIMTYPE_OBJECT:
1333 {
1334 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
1335 "JSONWriter::appendValue()- Object"));
1336 CIMObject v;
1337 value.get(v);
1338 _append("CIMTYPE_OBJECT is TODO!");
1339 break;
1340 }
1341 case CIMTYPE_INSTANCE:
1342 {
1343 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL4,
1344 "JSONWriter::appendValue()- Instance"));
1345 lawrence.luo 1.2 CIMInstance v;
1346 value.get(v);
1347 _append(v, true, true, repository, requestUri);
1348 break;
1349 }
1350 default:
1351 {
1352 PEG_TRACE((TRC_RSSERVER, Tracer::LEVEL1,
1353 "JSONWriter::appendValue()- Unknown type"));
1354 PEGASUS_ASSERT(false);
1355 }
1356 }
1357 }
1358
1359 return;
1360 }
1361
1362
1363 void JSONWriter::_append(Boolean v)
1364 {
1365 if (v)
1366 lawrence.luo 1.2 {
1367 _buffer.append(STRLIT_ARGS("true"));
1368 }
1369 else
1370 {
1371 _buffer.append(STRLIT_ARGS("false"));
1372 }
1373 }
1374
1375 void JSONWriter::_append(Uint8 v)
1376 {
1377 Uint32 outputLength=0;
1378 char buffer[22];
1379 const char * output = Uint8ToString(buffer, v, outputLength);
1380
1381 _buffer.append(output, outputLength);
1382 }
1383
1384 void JSONWriter::_append(Sint8 v)
1385 {
1386 Uint32 outputLength=0;
1387 lawrence.luo 1.2 char buffer[22];
1388 const char * output = Sint8ToString(buffer, v, outputLength);
1389
1390 _buffer.append(output, outputLength);
1391 }
1392
1393 void JSONWriter::_append(Sint16 v)
1394 {
1395 Uint32 outputLength=0;
1396 char buffer[22];
1397 const char * output = Sint16ToString(buffer, v, outputLength);
1398
1399 _buffer.append(output, outputLength);
1400 }
1401
1402 void JSONWriter::_append(Sint32 v)
1403 {
1404
1405 Uint32 outputLength=0;
1406 char buffer[22];
1407 const char * output = Sint32ToString(buffer, v, outputLength);
1408 lawrence.luo 1.2
1409 _buffer.append(output, outputLength);
1410 }
1411
1412 void JSONWriter::_append(Sint64 v)
1413 {
1414 Uint32 outputLength=0;
1415 char buffer[22];
1416 const char * output = Sint64ToString(buffer, v, outputLength);
1417
1418 _buffer.append(output, outputLength);
1419 }
1420
1421 void JSONWriter::_append(Uint16 v)
1422 {
1423 Uint32 outputLength=0;
1424 char buffer[22];
1425 const char * output = Uint32ToString(buffer, v, outputLength);
1426
1427 _buffer.append(output, outputLength);
1428 }
1429 lawrence.luo 1.2
1430 void JSONWriter::_append(Uint32 v)
1431 {
1432
1433 Uint32 outputLength=0;
1434 char buffer[22];
1435 const char * output = Uint32ToString(buffer, v, outputLength);
1436
1437 _buffer.append(output, outputLength);
1438 }
1439
1440 void JSONWriter::_append(Uint64 v)
1441 {
1442 Uint32 outputLength=0;
1443 char buffer[22];
1444 const char * output = Uint64ToString(buffer, v, outputLength);
1445
1446 _buffer.append(output, outputLength);
1447 }
1448
1449 void JSONWriter::_append(Real32 v)
1450 lawrence.luo 1.2 {
1451 char buffer[128];
1452 // %.7e gives '[-]m.ddddddde+/-xx', which seems compatible with the format
1453 // given in the CIM/XML spec, and the precision required by the CIM 2.2 spec
1454 // (4 byte IEEE floating point)
1455 sprintf(buffer, "%.7e", v);
1456
1457 _buffer.append(buffer, sizeof(buffer));
1458 }
1459
1460 void JSONWriter::_append(Real64 v)
1461 {
1462 char buffer[128];
1463 // %.16e gives '[-]m.dddddddddddddddde+/-xx', which seems compatible
1464 // with the format given in the CIM/XML spec, and the precision required
1465 // by the CIM 2.2 spec (8 byte IEEE floating point)
1466 sprintf(buffer, "%.16e", v);
1467
1468 _buffer.append(buffer, sizeof(buffer));
1469 }
1470
1471 lawrence.luo 1.2
1472 void JSONWriter::_append(const CIMDateTime& v)
1473 {
1474 // see w3.org/TR/NOTE-datetime
1475 // and ECMAScript 3.1 spec draft
1476 String s = v.toString();
1477 _append(s);
1478 }
1479
1480 void JSONWriter::_append(const CIMObjectPath& v)
1481 {
1482 Buffer uri = RsURI::fromObjectPath(v, true);
1483 _append(String(uri.getData()));
1484 }
1485
1486 void JSONWriter::_append(const String& str, Boolean uriEncoded)
1487 {
1488 if(uriEncoded)
1489 {
1490 // we need to print an un-encoded version of the string
1491 _buffer.append('"');
1492 lawrence.luo 1.2 String uriEncodedStr = XmlGenerator::encodeURICharacters(str);
1493 _buffer.append((const char *)uriEncodedStr.getCString(),
1494 uriEncodedStr.size());
1495 _buffer.append('"');
1496 }
1497 else
1498 _append(_buffer, str);
1499 }
1500
1501
1502 void JSONWriter::_append(Buffer& out, const String& str)
1503 {
1504
1505 out.append('"');
1506 // COPY FROM XmlGenerator::appendSpecial(Buffer& out, const String& str)
1507 const Uint16* p = (const Uint16*)str.getChar16Data();
1508
1509 Uint16 c;
1510 while ((c = *p++) != 0)
1511 {
1512 if (c < 128)
1513 lawrence.luo 1.2 {
1514 if (_isSpecialChar7[c])
1515 {
1516 // Write the character reference for the special character
1517 out.append(
1518 _specialChars[int(c)].str, _specialChars[int(c)].size);
1519 }
1520 else
1521 {
1522 out.append(c);
1523 }
1524 }
1525 /*
1526 else
1527 {
1528
1529 if ((((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
1530 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) &&
1531 *p)
1532 {
1533 _appendSurrogatePair(out, c, *p++);
1534 lawrence.luo 1.2 }
1535 else
1536 {
1537 _appendChar(out, c);
1538 }
1539
1540 prevCharIsSpace = false;
1541
1542 }*/
1543 }
1544 out.append('"');
1545 }
1546
1547 Uint32 JSONWriter::getEnumerationCount()
1548 {
1549 return _numObjectsEnumerated;
1550 }
1551
1552
1553 void JSONWriter::_loadPropertyNames(const CIMConstInstance& prototype)
1554 {
1555 lawrence.luo 1.2 _propCount = prototype.getPropertyCount();
1556 _props = new Buffer*[_propCount];
1557 _propClass = prototype.getClassName();
1558
1559 for (Uint32 i = 0; i < _propCount; ++i)
1560 {
1561 _props[i] = new Buffer(2048);
1562 _append(*_props[i], prototype.getProperty(i).getName().getString());
1563 }
1564
1565 }
1566
1567 void JSONWriter::_deletePropertyNames()
1568 {
1569 for (Uint32 i = 0; i < _propCount; i++)
1570 {
1571 delete _props[i];
1572 }
1573 if (_propCount > 0)
1574 {
1575 delete[] _props;
1576 lawrence.luo 1.2 }
1577
1578 _propCount = 0;
1579 }
1580
1581
1582 PEGASUS_NAMESPACE_END
|