0904aa63 |
1 | // Copyright (c) 2019 OPEN CASCADE SAS |
2 | // |
3 | // This file is part of Open CASCADE Technology software library. |
4 | // |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
10 | // |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
13 | |
14 | #include <Standard_Dump.hxx> |
15 | |
16 | #include <stdarg.h> |
17 | |
0904aa63 |
18 | // ======================================================================= |
3de0f784 |
19 | // function : AddValuesSeparator |
0904aa63 |
20 | // purpose : |
21 | // ======================================================================= |
3de0f784 |
22 | void Standard_Dump::AddValuesSeparator (Standard_OStream& theOStream) |
0904aa63 |
23 | { |
24 | Standard_SStream aStream; |
25 | aStream << theOStream.rdbuf(); |
26 | TCollection_AsciiString aStreamStr = Standard_Dump::Text (aStream); |
04114fd2 |
27 | if (!aStreamStr.IsEmpty() && !aStreamStr.EndsWith ("{") && !aStreamStr.EndsWith (", ")) |
3de0f784 |
28 | theOStream << ", "; |
0904aa63 |
29 | } |
30 | |
31 | //======================================================================= |
32 | //function : DumpKeyToClass |
33 | //purpose : |
34 | //======================================================================= |
35 | void Standard_Dump::DumpKeyToClass (Standard_OStream& theOStream, |
bc73b006 |
36 | const TCollection_AsciiString& theKey, |
0904aa63 |
37 | const TCollection_AsciiString& theField) |
38 | { |
3de0f784 |
39 | AddValuesSeparator (theOStream); |
0904aa63 |
40 | theOStream << "\"" << theKey << "\": {" << theField << "}"; |
41 | } |
42 | |
43 | //======================================================================= |
44 | //function : DumpCharacterValues |
45 | //purpose : |
46 | //======================================================================= |
47 | void Standard_Dump::DumpCharacterValues (Standard_OStream& theOStream, int theCount, ...) |
48 | { |
49 | va_list vl; |
50 | va_start(vl, theCount); |
51 | for(int i = 0; i < theCount; ++i) |
52 | { |
53 | if (i > 0) |
54 | theOStream << ", "; |
55 | theOStream << "\"" << va_arg(vl, char*) << "\""; |
56 | } |
57 | va_end(vl); |
58 | } |
59 | |
60 | //======================================================================= |
61 | //function : DumpRealValues |
62 | //purpose : |
63 | //======================================================================= |
64 | void Standard_Dump::DumpRealValues (Standard_OStream& theOStream, int theCount, ...) |
65 | { |
66 | va_list vl; |
67 | va_start(vl, theCount); |
68 | for(int i = 0; i < theCount; ++i) |
69 | { |
70 | if (i > 0) |
71 | theOStream << ", "; |
72 | theOStream << va_arg(vl, Standard_Real); |
73 | } |
74 | va_end(vl); |
75 | } |
76 | |
6b63dc83 |
77 | //======================================================================= |
78 | //function : ProcessStreamName |
79 | //purpose : |
80 | //======================================================================= |
81 | Standard_Boolean Standard_Dump::ProcessStreamName (const TCollection_AsciiString& theStreamStr, |
82 | const TCollection_AsciiString& theName, |
83 | Standard_Integer& theStreamPos) |
84 | { |
85 | if (theStreamStr.IsEmpty()) |
86 | return Standard_False; |
87 | |
88 | if (theStreamStr.Length () < theStreamPos) |
89 | return Standard_False; |
90 | |
91 | TCollection_AsciiString aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length()); |
92 | if (aSubText.StartsWith (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue))) |
93 | { |
94 | theStreamPos += JsonKeyLength (Standard_JsonKey_SeparatorValueToValue); |
95 | aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length()); |
96 | } |
97 | TCollection_AsciiString aKeyName = TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote)) |
98 | + theName |
99 | + TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote)) |
100 | + JsonKeyToString (Standard_JsonKey_SeparatorKeyToValue); |
101 | Standard_Boolean aResult = aSubText.StartsWith (aKeyName); |
102 | if (aResult) |
103 | theStreamPos += aKeyName.Length(); |
104 | |
105 | return aResult; |
106 | } |
107 | |
108 | //======================================================================= |
109 | //function : ProcessFieldName |
110 | //purpose : |
111 | //======================================================================= |
112 | Standard_Boolean Standard_Dump::ProcessFieldName (const TCollection_AsciiString& theStreamStr, |
113 | const TCollection_AsciiString& theName, |
114 | Standard_Integer& theStreamPos) |
115 | { |
116 | if (theStreamStr.IsEmpty()) |
117 | return Standard_False; |
118 | |
119 | TCollection_AsciiString aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length()); |
120 | if (aSubText.StartsWith (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue))) |
121 | { |
122 | theStreamPos += JsonKeyLength (Standard_JsonKey_SeparatorValueToValue); |
123 | aSubText = theStreamStr.SubString (theStreamPos, theStreamStr.Length()); |
124 | } |
125 | |
126 | TCollection_AsciiString aName = Standard_Dump::DumpFieldToName (theName.ToCString()); |
127 | TCollection_AsciiString aKeyName = TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote)) |
128 | + aName |
129 | + TCollection_AsciiString (JsonKeyToString (Standard_JsonKey_Quote)) |
130 | + JsonKeyToString (Standard_JsonKey_SeparatorKeyToValue); |
131 | |
132 | Standard_Boolean aResult = aSubText.StartsWith (aKeyName); |
133 | if (aResult) |
134 | theStreamPos += aKeyName.Length(); |
135 | |
136 | return aResult; |
137 | } |
138 | |
139 | //======================================================================= |
140 | //function : InitRealValues |
141 | //purpose : |
142 | //======================================================================= |
143 | Standard_Boolean Standard_Dump::InitRealValues (const TCollection_AsciiString& theStreamStr, |
144 | Standard_Integer& theStreamPos, |
145 | int theCount, ...) |
146 | { |
147 | Standard_Integer aStreamPos = theStreamPos + JsonKeyLength (Standard_JsonKey_OpenContainer); |
148 | |
149 | TCollection_AsciiString aSubText = theStreamStr.SubString (aStreamPos, theStreamStr.Length()); |
150 | |
151 | va_list vl; |
152 | va_start(vl, theCount); |
153 | aStreamPos = 1; |
154 | Standard_Integer aClosePos = aSubText.Location (JsonKeyToString (Standard_JsonKey_CloseContainer), aStreamPos, aSubText.Length()); |
155 | for(int i = 0; i < theCount; ++i) |
156 | { |
157 | Standard_Integer aNextPos = (i < theCount-1) ? aSubText.Location (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue), aStreamPos, aSubText.Length()) |
158 | : aClosePos; |
159 | |
160 | TCollection_AsciiString aValueText = aSubText.SubString (aStreamPos, aNextPos - 1); |
161 | |
162 | if (!aValueText.IsRealValue()) |
163 | return Standard_False; |
164 | |
165 | Standard_Real aValue = aValueText.RealValue(); |
166 | *(va_arg(vl, Standard_Real*)) = aValue; |
167 | |
168 | aStreamPos = aNextPos + JsonKeyLength (Standard_JsonKey_SeparatorValueToValue); |
169 | } |
170 | va_end(vl); |
171 | aClosePos = theStreamStr.Location (JsonKeyToString (Standard_JsonKey_CloseContainer), theStreamPos, theStreamStr.Length()); |
172 | theStreamPos = aClosePos + JsonKeyLength (Standard_JsonKey_CloseContainer); |
173 | |
174 | return Standard_True; |
175 | } |
176 | |
177 | //======================================================================= |
178 | //function : InitValue |
179 | //purpose : |
180 | //======================================================================= |
181 | Standard_Boolean Standard_Dump::InitValue (const TCollection_AsciiString& theStreamStr, |
182 | Standard_Integer& theStreamPos, |
183 | TCollection_AsciiString& theValue) |
184 | { |
185 | Standard_Integer aStreamPos = theStreamPos; |
186 | |
187 | TCollection_AsciiString aSubText = theStreamStr.SubString (aStreamPos, theStreamStr.Length()); |
188 | |
189 | aStreamPos = 1; |
190 | Standard_Integer aNextPos = aSubText.Location (JsonKeyToString (Standard_JsonKey_SeparatorValueToValue), aStreamPos, aSubText.Length()); |
191 | Standard_JsonKey aNextKey = Standard_JsonKey_SeparatorValueToValue; |
192 | |
193 | Standard_Integer aCloseChildPos = aSubText.Location (JsonKeyToString (Standard_JsonKey_CloseChild), aStreamPos, aSubText.Length()); |
194 | Standard_Boolean isUseClosePos = (aNextPos > 0 && aCloseChildPos > 0 && aCloseChildPos < aNextPos) || !aNextPos; |
195 | if (isUseClosePos) |
196 | { |
197 | aNextPos = aCloseChildPos; |
198 | aNextKey = Standard_JsonKey_CloseChild; |
199 | } |
200 | |
201 | theValue = aNextPos ? aSubText.SubString (aStreamPos, aNextPos - 1) : aSubText; |
202 | theStreamPos = aNextPos ? (theStreamPos + (aNextPos - aStreamPos) + JsonKeyLength (aNextKey)) : theStreamStr.Length(); |
203 | return Standard_True; |
204 | } |
205 | |
0904aa63 |
206 | // ======================================================================= |
207 | // function : GetPointerInfo |
208 | // purpose : |
209 | // ======================================================================= |
210 | TCollection_AsciiString Standard_Dump::GetPointerInfo (const Handle(Standard_Transient)& thePointer, |
211 | const bool isShortInfo) |
212 | { |
213 | if (thePointer.IsNull()) |
214 | return TCollection_AsciiString(); |
215 | |
216 | return GetPointerInfo (thePointer.get(), isShortInfo); |
217 | } |
218 | |
219 | // ======================================================================= |
220 | // function : GetPointerInfo |
221 | // purpose : |
222 | // ======================================================================= |
223 | TCollection_AsciiString Standard_Dump::GetPointerInfo (const void* thePointer, const bool isShortInfo) |
224 | { |
bc73b006 |
225 | if (!thePointer) |
226 | return TCollection_AsciiString(); |
227 | |
0904aa63 |
228 | std::ostringstream aPtrStr; |
229 | aPtrStr << thePointer; |
230 | if (!isShortInfo) |
231 | return aPtrStr.str().c_str(); |
232 | |
233 | TCollection_AsciiString anInfoPtr (aPtrStr.str().c_str()); |
234 | for (int aSymbolId = 1; aSymbolId < anInfoPtr.Length(); aSymbolId++) |
235 | { |
236 | if (anInfoPtr.Value(aSymbolId) != '0') |
237 | { |
238 | anInfoPtr = anInfoPtr.SubString (aSymbolId, anInfoPtr.Length()); |
239 | anInfoPtr.Prepend (GetPointerPrefix()); |
240 | return anInfoPtr; |
241 | } |
242 | } |
243 | return aPtrStr.str().c_str(); |
244 | } |
245 | |
246 | // ======================================================================= |
247 | // DumpFieldToName |
248 | // ======================================================================= |
bc73b006 |
249 | TCollection_AsciiString Standard_Dump::DumpFieldToName (const TCollection_AsciiString& theField) |
0904aa63 |
250 | { |
bc73b006 |
251 | TCollection_AsciiString aName = theField; |
252 | if (theField.StartsWith ('&')) |
253 | { |
254 | aName.Remove (1, 1); |
255 | } |
0904aa63 |
256 | |
bc73b006 |
257 | if (aName.Length() > 1 && aName.Value (1) == 'a') |
0904aa63 |
258 | { |
bc73b006 |
259 | if (aName.Length() > 2 && aName.Value (2) == 'n') |
260 | { |
261 | aName.Remove (1, 2); |
262 | } |
263 | else |
264 | aName.Remove (1, 1); |
265 | } |
266 | else if (aName.Length() > 2 && ::LowerCase (aName.Value (1)) == 'm' && aName.Value (2) == 'y') |
267 | { |
268 | aName.Remove (1, 2); |
0904aa63 |
269 | } |
bc73b006 |
270 | |
271 | if (aName.EndsWith (".get()")) |
272 | { |
273 | aName = aName.SubString (1, aName.Length() - TCollection_AsciiString (".get()").Length()); |
274 | } |
275 | else if (aName.EndsWith ("()")) |
0904aa63 |
276 | { |
bc73b006 |
277 | aName = aName.SubString (1, aName.Length() - TCollection_AsciiString ("()").Length()); |
0904aa63 |
278 | } |
3de0f784 |
279 | return aName; |
0904aa63 |
280 | } |
281 | |
282 | // ======================================================================= |
283 | // Text |
284 | // ======================================================================= |
285 | TCollection_AsciiString Standard_Dump::Text (const Standard_SStream& theStream) |
286 | { |
287 | return TCollection_AsciiString (theStream.str().c_str()); |
288 | } |
289 | |
290 | // ======================================================================= |
291 | // FormatJson |
292 | // ======================================================================= |
293 | TCollection_AsciiString Standard_Dump::FormatJson (const Standard_SStream& theStream, |
294 | const Standard_Integer theIndent) |
295 | { |
296 | TCollection_AsciiString aStreamStr = Text (theStream); |
297 | TCollection_AsciiString anIndentStr; |
298 | for (Standard_Integer anIndentId = 0; anIndentId < theIndent; anIndentId++) |
299 | anIndentStr.AssignCat (' '); |
300 | |
301 | TCollection_AsciiString aText; |
302 | |
303 | Standard_Integer anIndentCount = 0; |
304 | Standard_Boolean isMassiveValues = Standard_False; |
04114fd2 |
305 | for (Standard_Integer anIndex = 1; anIndex <= aStreamStr.Length(); anIndex++) |
0904aa63 |
306 | { |
307 | Standard_Character aSymbol = aStreamStr.Value (anIndex); |
04114fd2 |
308 | if (anIndex == 1 && aText.IsEmpty() && aSymbol != '{') |
309 | { |
310 | // append opening brace for json start |
311 | aSymbol = '{'; |
312 | anIndex--; |
313 | } |
0904aa63 |
314 | if (aSymbol == '{') |
315 | { |
316 | anIndentCount++; |
317 | |
318 | aText += aSymbol; |
319 | aText += '\n'; |
320 | |
321 | for (int anIndent = 0; anIndent < anIndentCount; anIndent++) |
04114fd2 |
322 | { |
0904aa63 |
323 | aText += anIndentStr; |
04114fd2 |
324 | } |
0904aa63 |
325 | } |
326 | else if (aSymbol == '}') |
327 | { |
328 | anIndentCount--; |
329 | |
330 | aText += '\n'; |
331 | for (int anIndent = 0; anIndent < anIndentCount; anIndent++) |
332 | aText += anIndentStr; |
333 | aText += aSymbol; |
334 | } |
335 | else if (aSymbol == '[') |
336 | { |
337 | isMassiveValues = Standard_True; |
338 | aText += aSymbol; |
339 | } |
340 | else if (aSymbol == ']') |
341 | { |
342 | isMassiveValues = Standard_False; |
343 | aText += aSymbol; |
344 | } |
345 | else if (aSymbol == ',') |
346 | { |
347 | if (!isMassiveValues) |
348 | { |
349 | aText += aSymbol; |
350 | aText += '\n'; |
351 | for (int anIndent = 0; anIndent < anIndentCount; anIndent++) |
352 | aText += anIndentStr; |
353 | if (anIndex + 1 < aStreamStr.Length() && aStreamStr.Value (anIndex + 1) == ' ') |
354 | anIndex++; // skip empty value after comma |
355 | } |
356 | else |
357 | aText += aSymbol; |
358 | } |
04114fd2 |
359 | else if (aSymbol == '\n') |
360 | { |
361 | aText += ""; // json does not support multi-lined values, skip this symbol |
362 | } |
0904aa63 |
363 | else |
364 | aText += aSymbol; |
04114fd2 |
365 | |
366 | if (anIndex == aStreamStr.Length() && aSymbol != '}') |
367 | { |
368 | // append closing brace for json end |
369 | aSymbol = '}'; |
370 | |
371 | anIndentCount--; |
372 | aText += '\n'; |
373 | for (int anIndent = 0; anIndent < anIndentCount; anIndent++) |
374 | aText += anIndentStr; |
375 | aText += aSymbol; |
376 | } |
0904aa63 |
377 | } |
378 | return aText; |
379 | } |
bc73b006 |
380 | |
381 | // ======================================================================= |
382 | // SplitJson |
383 | // ======================================================================= |
384 | Standard_Boolean Standard_Dump::SplitJson (const TCollection_AsciiString& theStreamStr, |
385 | NCollection_IndexedDataMap<TCollection_AsciiString, Standard_DumpValue>& theKeyToValues) |
386 | { |
387 | Standard_Integer aNextIndex = 1; |
388 | while (aNextIndex < theStreamStr.Length()) |
389 | { |
390 | Standard_JsonKey aKey = Standard_JsonKey_None; |
391 | if (!jsonKey (theStreamStr, aNextIndex, aNextIndex, aKey)) |
392 | return Standard_False; |
393 | |
394 | Standard_Boolean aProcessed = Standard_False; |
395 | switch (aKey) |
396 | { |
397 | case Standard_JsonKey_Quote: |
398 | { |
399 | aProcessed = splitKeyToValue (theStreamStr, aNextIndex, aNextIndex, theKeyToValues); |
400 | break; |
401 | } |
402 | case Standard_JsonKey_OpenChild: |
403 | { |
404 | Standard_Integer aStartIndex = aNextIndex; |
405 | Standard_Integer aClosePos = nextClosePosition (theStreamStr, aStartIndex, Standard_JsonKey_OpenChild, Standard_JsonKey_CloseChild); |
406 | if (aClosePos == 0) |
407 | return Standard_False; |
408 | |
409 | TCollection_AsciiString aSubStreamStr = theStreamStr.SubString (aStartIndex + JsonKeyLength (aKey), aNextIndex - 2); |
410 | if (!SplitJson (aSubStreamStr, theKeyToValues)) |
411 | return Standard_False; |
412 | |
413 | aNextIndex = aClosePos + Standard_Integer (JsonKeyLength (Standard_JsonKey_CloseChild)); |
414 | break; |
415 | } |
416 | case Standard_JsonKey_SeparatorValueToValue: |
417 | { |
418 | continue; |
419 | } |
420 | default: |
421 | break; |
422 | } |
423 | if (!aProcessed) |
424 | return Standard_False; |
425 | } |
426 | return Standard_True; |
427 | } |
428 | |
429 | // ======================================================================= |
430 | // HierarchicalValueIndices |
431 | // ======================================================================= |
432 | NCollection_List<Standard_Integer> Standard_Dump::HierarchicalValueIndices ( |
433 | const NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString>& theValues) |
434 | { |
435 | NCollection_List<Standard_Integer> anIndices; |
436 | |
437 | for (Standard_Integer anIndex = 1; anIndex <= theValues.Extent(); anIndex++) |
438 | { |
439 | if (HasChildKey (theValues.FindFromIndex (anIndex))) |
440 | anIndices.Append (anIndex); |
441 | } |
442 | return anIndices; |
443 | } |
444 | |
445 | // ======================================================================= |
446 | // splitKeyToValue |
447 | // ======================================================================= |
448 | Standard_Boolean Standard_Dump::splitKeyToValue (const TCollection_AsciiString& theStreamStr, |
449 | Standard_Integer theStartIndex, |
450 | Standard_Integer& theNextIndex, |
451 | NCollection_IndexedDataMap<TCollection_AsciiString, Standard_DumpValue>& theValues) |
452 | { |
453 | // find key value: "key" |
454 | Standard_Integer aStartIndex = theStartIndex; |
455 | Standard_Integer aCloseIndex = nextClosePosition (theStreamStr, aStartIndex + 1, Standard_JsonKey_None, Standard_JsonKey_Quote); |
456 | if (aCloseIndex == 0) |
457 | return Standard_False; |
458 | |
459 | TCollection_AsciiString aSplitKey = theStreamStr.SubString (aStartIndex, aCloseIndex - 1); |
460 | |
461 | // key to value |
462 | aStartIndex = aCloseIndex + 1; |
463 | Standard_JsonKey aKey = Standard_JsonKey_None; |
464 | if (!jsonKey (theStreamStr, aStartIndex, aCloseIndex, aKey)) |
465 | return Standard_False; |
466 | |
467 | // find value |
468 | aStartIndex = aCloseIndex; |
469 | aKey = Standard_JsonKey_None; |
470 | jsonKey (theStreamStr, aStartIndex, aCloseIndex, aKey); |
471 | aStartIndex = aCloseIndex; |
472 | |
473 | TCollection_AsciiString aSplitValue; |
474 | theNextIndex = -1; |
475 | switch (aKey) |
476 | { |
477 | case Standard_JsonKey_OpenChild: |
478 | { |
479 | aCloseIndex = nextClosePosition (theStreamStr, aStartIndex, Standard_JsonKey_OpenChild, Standard_JsonKey_CloseChild); |
480 | if (aCloseIndex > aStartIndex) |
481 | aSplitValue = theStreamStr.SubString (aStartIndex, aCloseIndex); |
482 | theNextIndex = aCloseIndex + 1; |
483 | break; |
484 | } |
485 | case Standard_JsonKey_OpenContainer: |
486 | { |
487 | aCloseIndex = nextClosePosition (theStreamStr, aStartIndex, Standard_JsonKey_OpenContainer, Standard_JsonKey_CloseContainer); |
488 | if (aCloseIndex > aStartIndex) |
489 | aSplitValue = theStreamStr.SubString (aStartIndex, aCloseIndex - 1); |
490 | theNextIndex = aCloseIndex + 1; |
491 | break; |
492 | } |
493 | case Standard_JsonKey_Quote: |
494 | { |
495 | Standard_JsonKey aKeyTmp = Standard_JsonKey_None; |
496 | if (jsonKey (theStreamStr, aStartIndex, aCloseIndex, aKeyTmp) && aKeyTmp == Standard_JsonKey_Quote) // emptyValue |
497 | { |
498 | aSplitValue = ""; |
499 | theNextIndex = aCloseIndex; |
500 | } |
501 | else |
502 | { |
503 | aCloseIndex = nextClosePosition (theStreamStr, aStartIndex + 1, Standard_JsonKey_None, Standard_JsonKey_Quote); |
504 | aSplitValue = theStreamStr.SubString (aStartIndex, aCloseIndex - 1); |
505 | theNextIndex = aCloseIndex + 1; |
506 | } |
507 | break; |
508 | } |
509 | case Standard_JsonKey_None: |
510 | { |
511 | if (aStartIndex == theStreamStr.Length()) |
512 | { |
513 | aSplitValue = aStartIndex <= aCloseIndex ? theStreamStr.SubString (aStartIndex, aCloseIndex) : ""; |
514 | aSplitValue = theStreamStr.SubString (aStartIndex, aCloseIndex); |
515 | aCloseIndex = aStartIndex; |
516 | } |
517 | else |
518 | { |
519 | Standard_Integer aCloseIndex1 = nextClosePosition (theStreamStr, aStartIndex, Standard_JsonKey_None, Standard_JsonKey_CloseChild) - 1; |
520 | Standard_Integer aCloseIndex2 = nextClosePosition (theStreamStr, aStartIndex, Standard_JsonKey_None, Standard_JsonKey_SeparatorValueToValue) - 1; |
521 | aCloseIndex = aCloseIndex1 < aCloseIndex2 ? aCloseIndex1 : aCloseIndex2; |
522 | aSplitValue = aStartIndex <= aCloseIndex ? theStreamStr.SubString (aStartIndex, aCloseIndex) : ""; |
523 | } |
524 | theNextIndex = aCloseIndex + 1; |
525 | break; |
526 | } |
527 | default: |
528 | return Standard_False; |
529 | } |
530 | |
531 | Standard_DumpValue aValue; |
532 | if (theValues.FindFromKey (aSplitKey, aValue)) |
533 | { |
534 | Standard_Integer anIndex = 1; |
535 | // increment key until the new key does not exist in the container |
536 | TCollection_AsciiString anIndexedSuffix = TCollection_AsciiString ("_") + TCollection_AsciiString (anIndex); |
537 | while (theValues.FindFromKey (TCollection_AsciiString (aSplitKey + anIndexedSuffix), aValue)) |
538 | { |
539 | anIndex++; |
540 | anIndexedSuffix = TCollection_AsciiString ("_") + TCollection_AsciiString (anIndex); |
541 | } |
542 | aSplitKey = aSplitKey + anIndexedSuffix; |
543 | } |
544 | |
545 | theValues.Add (aSplitKey, Standard_DumpValue (aSplitValue, aStartIndex)); |
546 | return Standard_True; |
547 | } |
548 | |
549 | // ======================================================================= |
550 | // jsonKey |
551 | // ======================================================================= |
552 | Standard_Boolean Standard_Dump::jsonKey (const TCollection_AsciiString& theStreamStr, |
553 | Standard_Integer theStartIndex, |
554 | Standard_Integer& theNextIndex, |
555 | Standard_JsonKey& theKey) |
556 | { |
557 | TCollection_AsciiString aSubStreamStr = theStreamStr.SubString (theStartIndex, theStreamStr.Length()); |
558 | for (Standard_Integer aKeyId = (Standard_Integer)Standard_JsonKey_OpenChild; aKeyId <= Standard_JsonKey_SeparatorValueToValue; aKeyId++) |
559 | { |
560 | Standard_JsonKey aKey = (Standard_JsonKey)aKeyId; |
561 | Standard_CString aKeyToStr = JsonKeyToString (aKey); |
562 | if (!aSubStreamStr.StartsWith (aKeyToStr)) |
563 | continue; |
564 | |
565 | theNextIndex = theStartIndex + Standard_Integer (JsonKeyLength (aKey)); |
566 | theKey = aKey; |
567 | return Standard_True; |
568 | } |
569 | return Standard_False; |
570 | } |
571 | |
572 | // ======================================================================= |
573 | // HasChildKey |
574 | // ======================================================================= |
575 | Standard_Boolean Standard_Dump::HasChildKey (const TCollection_AsciiString& theSourceValue) |
576 | { |
577 | return theSourceValue.Search (JsonKeyToString (Standard_JsonKey_SeparatorKeyToValue)) >= 0; |
578 | } |
579 | |
580 | // ======================================================================= |
581 | // JsonKeyToString |
582 | // ======================================================================= |
583 | Standard_CString Standard_Dump::JsonKeyToString (const Standard_JsonKey theKey) |
584 | { |
585 | switch (theKey) |
586 | { |
587 | case Standard_JsonKey_None: return ""; |
588 | case Standard_JsonKey_OpenChild: return "{"; |
589 | case Standard_JsonKey_CloseChild: return "}"; |
590 | case Standard_JsonKey_OpenContainer: return "["; |
591 | case Standard_JsonKey_CloseContainer: return "]"; |
592 | case Standard_JsonKey_Quote: return "\""; |
593 | case Standard_JsonKey_SeparatorKeyToValue: return ": "; |
594 | case Standard_JsonKey_SeparatorValueToValue: return ", "; |
595 | } |
596 | |
597 | return ""; |
598 | } |
599 | |
600 | // ======================================================================= |
601 | // JsonKeyLength |
602 | // ======================================================================= |
603 | Standard_Integer Standard_Dump::JsonKeyLength (const Standard_JsonKey theKey) |
604 | { |
605 | return (Standard_Integer)strlen (JsonKeyToString (theKey)); |
606 | } |
607 | |
608 | // ======================================================================= |
609 | // nextClosePosition |
610 | // ======================================================================= |
611 | Standard_Integer Standard_Dump::nextClosePosition (const TCollection_AsciiString& theSourceValue, |
612 | const Standard_Integer theStartPosition, |
613 | const Standard_JsonKey theOpenKey, |
614 | const Standard_JsonKey theCloseKey) |
615 | { |
616 | Standard_CString anOpenKey = JsonKeyToString (theOpenKey); |
617 | Standard_CString aCloseKeyStr = JsonKeyToString (theCloseKey); |
618 | |
619 | Standard_Integer aStartPos = theStartPosition; |
620 | Standard_Integer aDepthKey = 0; |
621 | |
622 | while (aStartPos < theSourceValue.Length()) |
623 | { |
624 | Standard_Integer anOpenKeyPos = theSourceValue.Location (anOpenKey, aStartPos, theSourceValue.Length()); |
625 | Standard_Integer aCloseKeyPos = theSourceValue.Location (aCloseKeyStr, aStartPos, theSourceValue.Length()); |
626 | if (aCloseKeyPos == 0) |
627 | break; |
628 | |
629 | if (anOpenKeyPos != 0 && anOpenKeyPos <= aCloseKeyPos) |
630 | { |
631 | aDepthKey++; |
632 | aStartPos = anOpenKeyPos + 1; |
633 | } |
634 | else |
635 | { |
636 | if (aDepthKey == 0) |
637 | return aCloseKeyPos; |
638 | else |
639 | { |
640 | aDepthKey--; |
641 | aStartPos = aCloseKeyPos + 1; |
642 | } |
643 | } |
644 | } |
645 | return theSourceValue.Length(); |
646 | } |