0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Standard / Standard_Dump.cxx
CommitLineData
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 22void 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//=======================================================================
35void 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//=======================================================================
47void 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//=======================================================================
64void 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//=======================================================================
81Standard_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//=======================================================================
112Standard_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//=======================================================================
143Standard_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//=======================================================================
181Standard_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// =======================================================================
210TCollection_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// =======================================================================
223TCollection_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 249TCollection_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// =======================================================================
285TCollection_AsciiString Standard_Dump::Text (const Standard_SStream& theStream)
286{
287 return TCollection_AsciiString (theStream.str().c_str());
288}
289
290// =======================================================================
291// FormatJson
292// =======================================================================
293TCollection_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// =======================================================================
384Standard_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// =======================================================================
432NCollection_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// =======================================================================
448Standard_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// =======================================================================
552Standard_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// =======================================================================
575Standard_Boolean Standard_Dump::HasChildKey (const TCollection_AsciiString& theSourceValue)
576{
577 return theSourceValue.Search (JsonKeyToString (Standard_JsonKey_SeparatorKeyToValue)) >= 0;
578}
579
580// =======================================================================
581// JsonKeyToString
582// =======================================================================
583Standard_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// =======================================================================
603Standard_Integer Standard_Dump::JsonKeyLength (const Standard_JsonKey theKey)
604{
605 return (Standard_Integer)strlen (JsonKeyToString (theKey));
606}
607
608// =======================================================================
609// nextClosePosition
610// =======================================================================
611Standard_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}