20 NBT_Scanner(
void) =
delete;
22 ~NBT_Scanner(
void) =
delete;
26 enum class Control : uint8_t
36 switch (enResultControl)
41 default:
return Control::Error;
break;
46 enum ErrCode : uint8_t
62 constexpr static inline const char *
const errReason[] =
69 "ListElementTypeError",
77 static_assert(
sizeof(errReason) /
sizeof(errReason[0]) == ERRCODE_END,
"errReason array out sync");
79 template <
typename InputStream,
typename Visitor,
typename... Args>
82 const ErrCode errCode,
83 const InputStream &tData,
85 const std::format_string<Args...> fmt,
89 if (errCode >= ERRCODE_END)
96 tVisitor.VisitError(lvl,
"Scan Err[{}]: {}\n", (uint8_t)errCode, errReason[errCode]);
99 tVisitor.VisitError(lvl,
"Extra Info: \"");
100 tVisitor.VisitError(lvl, std::move(fmt), std::forward<Args>(args)...);
101 tVisitor.VisitError(lvl,
"\"\n\n");
104#define VIEW_PRE (4 * 8 + 3)
105#define VIEW_SUF (4 * 8 + 5)
106 size_t rangeBeg = (tData.Index() > VIEW_PRE) ? (tData.Index() - VIEW_PRE) : (0);
107 size_t rangeEnd = ((tData.Index() + VIEW_SUF) < tData.Size()) ? (tData.Index() + VIEW_SUF) : (tData.Size());
115 "Current: 0x{:02X}({})\n"\
116 "Data Size: 0x{:02X}({})\n"\
117 "Data Range: [0x{:02X}({}),0x{:02X}({})):\n",
119 (uint64_t)tData.Index(), tData.Index(),
120 (uint64_t)tData.Size(), tData.Size(),
121 (uint64_t)rangeBeg, rangeBeg,
122 (uint64_t)rangeEnd, rangeEnd
126 for (
size_t i = rangeBeg; i < rangeEnd; ++i)
128 if ((i - rangeBeg) % 8 == 0)
132 tVisitor.VisitError(lvl,
"\n");
134 tVisitor.VisitError(lvl,
"0x{:02X}: ", (uint64_t)i);
137 if (i != tData.Index())
139 tVisitor.VisitError(lvl,
" {:02X} ", (uint8_t)tData[i]);
143 tVisitor.VisitError(lvl,
"[{:02X}]", (uint8_t)tData[i]);
148 tVisitor.VisitError(lvl,
"\nSkip err data and return...\n\n");
153#define _RP___FUNCTION__ __FUNCTION__
155#define _RP___LINE__ _RP_STRLING(__LINE__)
156#define _RP_STRLING(l) STRLING(l)
159#define STACK_TRACEBACK(fmt, ...) tVisitor.VisitError(NBT_Print_Level::Err, "In [{}] Line:[" _RP___LINE__ "]: \n" fmt "\n\n", _RP___FUNCTION__ __VA_OPT__(,) __VA_ARGS__);
160#define CHECK_STACK_DEPTH(depth, ret) \
163 Error(StackDepthExceeded, tData, tVisitor, "{}: NBT nesting depth exceeded maximum call stack limit", _RP___FUNCTION__);\
164 STACK_TRACEBACK(#depth " == 0");\
168#define UNKNOWN_CONTROL_CODE(func, ret) \
170 Error(UnknownControlCode, tData, tVisitor, "Function [" #func "] return unknown control code");\
171 STACK_TRACEBACK("ControlCode Test");\
175#define CALL_FUNC_RET_CONTROL(name, val) \
178 Control controlRet = ResultControlToControl(val);\
179 if (controlRet == Control::Error)\
181 Error(UnknownControlCode, tData, tVisitor, "Function [" #name "] return unknown control code");\
182 STACK_TRACEBACK("ControlCode Test");\
191#define MYCATCH(ret) \
193catch(const std::bad_alloc &e)\
195 Error(OutOfMemoryError, tData, tVisitor, "{}: Info:[{}]", _RP___FUNCTION__, e.what());\
196 STACK_TRACEBACK("catch(std::bad_alloc)");\
199catch(const std::exception &e)\
201 Error(StdException, tData, tVisitor, "{}: Info:[{}]", _RP___FUNCTION__, e.what());\
202 STACK_TRACEBACK("catch(std::exception)");\
207 Error(UnknownError, tData, tVisitor, "{}: Info:[Unknown Exception]", _RP___FUNCTION__);\
208 STACK_TRACEBACK("catch(...)");\
212 template<
bool bNoCheck = false,
typename T,
typename InputStream,
typename Visitor>
213 requires std::integral<T>
214 static inline std::conditional_t<bNoCheck, void, bool> ReadBigEndian(InputStream &tData, T &tVal, Visitor &tVisitor)
noexcept
216 if constexpr (!bNoCheck)
218 if (!tData.HasAvailData(
sizeof(T)))
220 Error(OutOfRangeError, tData, tVisitor,
"tData size [{}], current index [{}], remaining data size [{}], but try to read [{}]",
221 tData.Size(), tData.Index(), tData.Size() - tData.Index(),
sizeof(T));
222 STACK_TRACEBACK(
"HasAvailData Test");
228 tData.GetRange((
void *)&BigEndianVal,
sizeof(BigEndianVal));
231 if constexpr (!bNoCheck)
237 template<
typename InputStream,
typename Visitor>
238 static bool GetName(InputStream &tData,
NBT_Type::String &tName, Visitor &tVisitor)
noexcept
243 if (!ReadBigEndian(tData, wStringLength, tVisitor))
245 STACK_TRACEBACK(
"wStringLength Read");
249 using ValueType = NBT_Type::String::value_type;
250 size_t szStringLength = (size_t)wStringLength;
251 size_t szStringSize = szStringLength *
sizeof(ValueType);
254 if (!tData.HasAvailData(szStringSize))
256 Error(OutOfRangeError, tData, tVisitor,
"{}:\n(Index[{}] + szStringLength[{}])[{}] > DataSize[{}]", __FUNCTION__,
257 tData.Index(), szStringLength, tData.Index() + szStringLength, tData.Size());
258 STACK_TRACEBACK(
"HasAvailData Test");
263 tName.resize(szStringLength);
264 tData.GetRange((
void *)tName.data(), szStringSize);
270 template<
typename InputStream,
typename Visitor>
271 static bool SkipName(InputStream &tData, Visitor &tVisitor)
noexcept
275 if (!ReadBigEndian(tData, wStringLength, tVisitor))
277 STACK_TRACEBACK(
"wStringLength Read");
281 size_t szSkipSize = (size_t)wStringLength *
sizeof(NBT_Type::String::value_type);
284 if (!tData.HasAvailData(szSkipSize))
286 Error(OutOfRangeError, tData, tVisitor,
"{}:\n(Index[{}] + szSkipSize[{}])[{}] > DataSize[{}]", __FUNCTION__,
287 tData.Index(), szSkipSize, tData.Index() + szSkipSize, tData.Size());
288 STACK_TRACEBACK(
"HasAvailData Test");
293 tData.SkipData(szSkipSize);
297 template<
typename InputStream,
typename Visitor>
298 static Control ScanEndType(InputStream &tData, Visitor &tVisitor)
noexcept
301 return ResultControlToControl(tVisitor.VisitListEnd());
302 MYCATCH(Control::Error);
305 template<
typename InputStream,
typename Visitor>
306 static bool SkipEndType(InputStream &tData, Visitor &tVisitor)
noexcept
312 template<
typename T,
typename InputStream,
typename Visitor>
313 static Control ScanBuiltInType(InputStream &tData, Visitor &tVisitor)
noexcept
316 RAW_DATA_T tTmpRawData = 0;
317 if (!ReadBigEndian(tData, tTmpRawData, tVisitor))
319 STACK_TRACEBACK(
"tTmpRawData Read");
320 return Control::Error;
324 CALL_FUNC_RET_CONTROL(tVisitor.VisitNumericResult<T>, tVisitor.template VisitNumericResult<T>(std::bit_cast<T>(tTmpRawData)));
325 MYCATCH(Control::Error);
328 template<
typename T,
typename InputStream,
typename Visitor>
329 static bool SkipBuiltInType(InputStream &tData, Visitor &tVisitor)
noexcept
332 size_t szSkipSize =
sizeof(RAW_DATA_T);
334 if (!tData.HasAvailData(szSkipSize))
336 Error(OutOfRangeError, tData, tVisitor,
"{}:\n(Index[{}] + szSkipSize[{}])[{}] > DataSize[{}]", __FUNCTION__,
337 tData.Index(), szSkipSize, tData.Index() + szSkipSize, tData.Size());
338 STACK_TRACEBACK(
"HasAvailData Test");
343 tData.SkipData(szSkipSize);
347 template<
typename T,
typename InputStream,
typename Visitor>
348 static Control ScanArrayType(InputStream &tData, Visitor &tVisitor)
noexcept
353 if (!ReadBigEndian(tData, iArrayLength, tVisitor))
355 STACK_TRACEBACK(
"iArrayLength Read");
356 return Control::Error;
360 if (iArrayLength < 0)
362 Error(OutOfRangeError, tData, tVisitor,
":\niArrayLength[{}] < 0", __FUNCTION__, iArrayLength);
363 STACK_TRACEBACK(
"iArrayLength Test");
364 return Control::Error;
368 using ValueType =
typename T::value_type;
369 size_t szArrayLength = (size_t)iArrayLength;
370 size_t szArraySize = szArrayLength *
sizeof(ValueType);
373 if (!tData.HasAvailData(szArraySize))
375 Error(OutOfRangeError, tData, tVisitor,
"{}:\n(Index[{}] + szArraySize[{}])[{}] > DataSize[{}]", __FUNCTION__,
376 tData.Index(), szArrayLength, tData.Index() + szArraySize, tData.Size());
377 STACK_TRACEBACK(
"HasAvailData Test");
378 return Control::Error;
383 tArray.reserve(szArrayLength);
386 for (
size_t i = 0; i < szArrayLength; ++i)
388 ValueType tTmpData{};
389 ReadBigEndian<true>(tData, tTmpData, tVisitor);
390 tArray.emplace_back(std::move(tTmpData));
393 CALL_FUNC_RET_CONTROL(tVisitor.VisitArrayResult<T>, tVisitor.template VisitArrayResult<T>(std::move(tArray)));
394 MYCATCH(Control::Error);
397 template<
typename T,
typename InputStream,
typename Visitor>
398 static bool SkipArrayType(InputStream &tData, Visitor &tVisitor)
noexcept
402 if (!ReadBigEndian(tData, iArrayLength, tVisitor))
404 STACK_TRACEBACK(
"iArrayLength Read");
409 if (iArrayLength < 0)
411 Error(OutOfRangeError, tData, tVisitor,
":\niArrayLength[{}] < 0", __FUNCTION__, iArrayLength);
412 STACK_TRACEBACK(
"iArrayLength Test");
416 size_t szSkipSize = (size_t)iArrayLength *
sizeof(
typename T::value_type);
418 if (!tData.HasAvailData(szSkipSize))
420 Error(OutOfRangeError, tData, tVisitor,
"{}:\n(Index[{}] + szSkipSize[{}])[{}] > DataSize[{}]", __FUNCTION__,
421 tData.Index(), szSkipSize, tData.Index() + szSkipSize, tData.Size());
422 STACK_TRACEBACK(
"HasAvailData Test");
426 tData.SkipData(szSkipSize);
430 template<
typename InputStream,
typename Visitor>
431 static Control ScanStringType(InputStream &tData, Visitor &tVisitor)
noexcept
434 if (!GetName(tData, tString, tVisitor))
436 STACK_TRACEBACK(
"GetString");
437 return Control::Error;
441 CALL_FUNC_RET_CONTROL(tVisitor.VisitStringResult, tVisitor.VisitStringResult(std::move(tString)));
442 MYCATCH(Control::Error);
445 template<
typename InputStream,
typename Visitor>
446 static bool SkipStringType(InputStream &tData, Visitor &tVisitor)
noexcept
448 if (!SkipName(tData, tVisitor))
450 STACK_TRACEBACK(
"SkipString");
457 template<
typename InputStream,
typename Visitor>
458 static Control ScanListType(InputStream &tData, Visitor &tVisitor,
size_t szStackDepth)
noexcept
462 CHECK_STACK_DEPTH(szStackDepth, Control::Error);
466 if (!ReadBigEndian(tData, u8ListElementTag, tVisitor))
468 STACK_TRACEBACK(
"u8ListElementTag Read");
469 return Control::Error;
475 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nList NBT Type:Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
477 STACK_TRACEBACK(
"u8ListElementTag Test");
478 return Control::Error;
486 if (!ReadBigEndian(tData, iListLength, tVisitor))
488 STACK_TRACEBACK(
"iListLength Read");
489 return Control::Error;
495 Error(OutOfRangeError, tData, tVisitor,
":\niListLength[{}] < 0", __FUNCTION__, iListLength);
496 STACK_TRACEBACK(
"iListLength Test");
497 return Control::Error;
501 size_t szListLength = (size_t)iListLength;
504 if (enListElementTag ==
NBT_TAG::End && szListLength != 0)
506 Error(ListElementTypeError, tData, tVisitor,
"{}:\nThe list with TAG_End[0x00] tag must be empty, but [{}] elements were found", __FUNCTION__,
508 STACK_TRACEBACK(
"enListElementTag And szListLength Test");
509 return Control::Error;
513 if (szListLength == 0 && enListElementTag !=
NBT_TAG::End)
522 switch (tVisitor.VisitListBegin(enListElementTag, szListLength))
528 UNKNOWN_CONTROL_CODE(tVisitor.VisitListBegin, Control::Error);
533 for (; i < szListLength; ++i)
536 switch (tVisitor.VisitListElementBegin(enListElementTag, i))
541 if (!SkipSwitch(tData, enListElementTag, tVisitor, szStackDepth - 1))
543 STACK_TRACEBACK(
"SkipSwitch Error, Size: [{}] Index: [{}]", szListLength, i);
544 return Control::Error;
552 UNKNOWN_CONTROL_CODE(tVisitor.VisitListElementBegin, Control::Error);
557 switch (ScanSwitch(tData, enListElementTag, tVisitor, szStackDepth - 1))
559 case Control::Continue:
break;
560 case Control::Break:
goto skip_any;
break;
561 case Control::Stop:
return Control::Stop;
break;
563 STACK_TRACEBACK(
"ScanSwitch Error, Size: [{}] Index: [{}]", szListLength, i);
564 return Control::Error;
567 UNKNOWN_CONTROL_CODE(ScanSwitch, Control::Error);
572 switch (tVisitor.VisitListElementEnd(enListElementTag, i))
578 UNKNOWN_CONTROL_CODE(tVisitor.VisitListElementEnd, Control::Error);
584 for (
size_t j = i; j < szListLength; ++j)
586 if (!SkipSwitch(tData, enListElementTag, tVisitor, szStackDepth - 1))
588 STACK_TRACEBACK(
"SkipSwitch Error, Size: [{}] Index: [{}]", szListLength, j);
589 return Control::Error;
594 CALL_FUNC_RET_CONTROL(tVisitor.VisitListEnd, tVisitor.VisitListEnd());
595 MYCATCH(Control::Error);
598 template<
typename InputStream,
typename Visitor>
599 static bool SkipListType(InputStream &tData, Visitor &tVisitor,
size_t szStackDepth)
noexcept
602 CHECK_STACK_DEPTH(szStackDepth,
false);
605 if (!ReadBigEndian(tData, u8ListElementTag, tVisitor))
607 STACK_TRACEBACK(
"u8ListElementTag Read");
613 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nList NBT Type:Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
615 STACK_TRACEBACK(
"u8ListElementTag Test");
622 if (!ReadBigEndian(tData, iListLength, tVisitor))
624 STACK_TRACEBACK(
"iListLength Read");
630 Error(OutOfRangeError, tData, tVisitor,
":\niListLength[{}] < 0", __FUNCTION__, iListLength);
631 STACK_TRACEBACK(
"iListLength Test");
635 size_t szListLength = (size_t)iListLength;
637 if (enListElementTag ==
NBT_TAG::End && szListLength != 0)
639 Error(ListElementTypeError, tData, tVisitor,
"{}:\nThe list with TAG_End[0x00] tag must be empty, but [{}] elements were found", __FUNCTION__,
641 STACK_TRACEBACK(
"enListElementTag And szListLength Test");
645 if (szListLength == 0 && enListElementTag !=
NBT_TAG::End)
650 size_t szSkipLength = szListLength;
652 for (
size_t i = 0; i < szSkipLength; ++i)
654 if (!SkipSwitch(tData, enListElementTag, tVisitor, szStackDepth - 1))
656 STACK_TRACEBACK(
"SkipSwitch Error, Size: [{}] Index: [{}]", szListLength, i);
664 template<
bool bRoot,
typename InputStream,
typename Visitor>
665 static Control ScanCompoundType(InputStream &tData, Visitor &tVisitor,
size_t szStackDepth)
noexcept
669 CHECK_STACK_DEPTH(szStackDepth, Control::Error);
671 if constexpr (!bRoot)
673 switch (tVisitor.VisitCompoundBegin())
679 UNKNOWN_CONTROL_CODE(tVisitor.VisitCompoundBegin, Control::Error);
685 tVisitor.VisitBegin();
694 if constexpr (!bRoot)
696 Error(OutOfRangeError, tData, tVisitor,
"{}:\nIndex[{}] >= DataSize()[{}]", __FUNCTION__,
697 tData.Index(), tData.Size());
698 STACK_TRACEBACK(
"HasAvailData Test");
699 return Control::Error;
703 return Control::Stop;
717 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nNBT Tag switch default: Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
718 u8CompoundEntryTag, u8CompoundEntryTag);
719 STACK_TRACEBACK(
"u8CompoundEntryTag Test");
720 return Control::Error;
727 switch (tVisitor.VisitCompoundNextEntryType(enCompoundEntryTag))
734 if (!SkipName(tData, tVisitor))
737 return Control::Error;
741 if (!SkipSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
744 return Control::Error;
752 if (!SkipName(tData, tVisitor))
755 return Control::Error;
759 if (!SkipSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
762 return Control::Error;
771 UNKNOWN_CONTROL_CODE(tVisitor.VisitCompoundNextEntryType, Control::Error);
777 if (!GetName(tData, sName, tVisitor))
780 return Control::Error;
784 switch (tVisitor.VisitCompoundEntryBegin(enCompoundEntryTag, std::move(sName)))
791 if (!SkipSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
794 return Control::Error;
803 if (!SkipSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
806 return Control::Error;
815 UNKNOWN_CONTROL_CODE(tVisitor.VisitCompoundEntryBegin, Control::Error);
820 switch (ScanSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
822 case Control::Continue:
break;
823 case Control::Break:
goto skip_any;
break;
824 case Control::Stop:
return Control::Stop;
break;
826 STACK_TRACEBACK(
"ScanSwitch Error, Type: [NBT_Type::{}]",
NBT_Type::GetTypeName(enCompoundEntryTag));
827 return Control::Error;
830 UNKNOWN_CONTROL_CODE(ScanSwitch, Control::Error);
835 switch (tVisitor.VisitCompoundEntryEnd(enCompoundEntryTag, std::move(sName)))
841 UNKNOWN_CONTROL_CODE(tVisitor.VisitCompoundEntryEnd, Control::Error);
853 if constexpr (!bRoot)
855 Error(OutOfRangeError, tData, tVisitor,
"{}:\nIndex[{}] >= DataSize()[{}]", __FUNCTION__,
856 tData.Index(), tData.Size());
857 STACK_TRACEBACK(
"HasAvailData Test");
858 return Control::Error;
862 return Control::Stop;
875 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nNBT Tag switch default: Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
876 u8CompoundEntryTag, u8CompoundEntryTag);
877 STACK_TRACEBACK(
"u8CompoundEntryTag Test");
878 return Control::Error;
883 if (!SkipName(tData, tVisitor))
886 return Control::Error;
889 if (!SkipSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
892 return Control::Error;
897 if constexpr (!bRoot)
899 CALL_FUNC_RET_CONTROL(tVisitor.VisitCompoundEnd, tVisitor.VisitCompoundEnd());
904 return Control::Stop;
906 MYCATCH(Control::Error);
909 template<
typename InputStream,
typename Visitor>
910 static bool SkipCompoundType(InputStream &tData, Visitor &tVisitor,
size_t szStackDepth)
noexcept
913 CHECK_STACK_DEPTH(szStackDepth,
false);
920 Error(OutOfRangeError, tData, tVisitor,
"{}:\nIndex[{}] >= DataSize()[{}]", __FUNCTION__,
921 tData.Index(), tData.Size());
922 STACK_TRACEBACK(
"HasAvailData Test");
935 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nNBT Tag switch default: Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
936 u8CompoundEntryTag, u8CompoundEntryTag);
937 STACK_TRACEBACK(
"u8CompoundEntryTag Test");
943 if (!SkipName(tData, tVisitor))
949 if (!SkipSwitch(tData, enCompoundEntryTag, tVisitor, szStackDepth - 1))
959 template<
typename InputStream,
typename Visitor>
960 static Control ScanSwitch(InputStream &tData,
NBT_TAG tagNbt, Visitor &tVisitor,
size_t szStackDepth)
noexcept
967 retControl = ScanEndType(tData, tVisitor);
973 retControl = ScanBuiltInType<CurType>(tData, tVisitor);
979 retControl = ScanBuiltInType<CurType>(tData, tVisitor);
985 retControl = ScanBuiltInType<CurType>(tData, tVisitor);
991 retControl = ScanBuiltInType<CurType>(tData, tVisitor);
997 retControl = ScanBuiltInType<CurType>(tData, tVisitor);
1003 retControl = ScanBuiltInType<CurType>(tData, tVisitor);
1009 retControl = ScanArrayType<CurType>(tData, tVisitor);
1014 retControl = ScanStringType(tData, tVisitor);
1019 retControl = ScanListType(tData, tVisitor, szStackDepth);
1024 retControl = ScanCompoundType<false>(tData, tVisitor, szStackDepth);
1030 retControl = ScanArrayType<CurType>(tData, tVisitor);
1036 retControl = ScanArrayType<CurType>(tData, tVisitor);
1041 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nNBT Tag switch error: Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
1043 retControl = Control::Error;
1048 if (retControl == Control::Error)
1050 STACK_TRACEBACK(
"Tag[0x{:02X}({})] read error!",
1057 template<
typename InputStream,
typename Visitor>
1058 static bool SkipSwitch(InputStream &tData,
NBT_TAG tagNbt, Visitor &tVisitor,
size_t szStackDepth)
noexcept
1065 bRet = SkipEndType(tData, tVisitor);
1071 bRet = SkipBuiltInType<CurType>(tData, tVisitor);
1077 bRet = SkipBuiltInType<CurType>(tData, tVisitor);
1083 bRet = SkipBuiltInType<CurType>(tData, tVisitor);
1089 bRet = SkipBuiltInType<CurType>(tData, tVisitor);
1095 bRet = SkipBuiltInType<CurType>(tData, tVisitor);
1101 bRet = SkipBuiltInType<CurType>(tData, tVisitor);
1107 bRet = SkipArrayType<CurType>(tData, tVisitor);
1112 bRet = SkipStringType(tData, tVisitor);
1117 bRet = SkipListType(tData, tVisitor, szStackDepth);
1122 bRet = SkipCompoundType(tData, tVisitor, szStackDepth);
1128 bRet = SkipArrayType<CurType>(tData, tVisitor);
1134 bRet = SkipArrayType<CurType>(tData, tVisitor);
1139 Error(NbtTypeTagError, tData, tVisitor,
"{}:\nNBT Tag switch error: Unknown Type Tag[0x{:02X}({})]", __FUNCTION__,
1148 STACK_TRACEBACK(
"Tag[0x{:02X}({})] read error!",
1166 template<
typename InputStream,
typename Visitor>
1168 static bool ScanNBT(InputStream &IptStream, Visitor &tVisitor,
size_t szStackDepth = 512)
noexcept
1170 return ScanCompoundType<true>(IptStream, tVisitor, szStackDepth) != Control::Error;
1182 template<
typename DataType = std::vector<u
int8_t>,
typename Visitor>
1184 static bool ScanNBT(
const DataType &tDataInput,
size_t szStartIdx, Visitor &tVisitor,
size_t szStackDepth = 512)
noexcept
1187 return ScanCompoundType<true>(IptStream, tVisitor, szStackDepth) != Control::Error;
1190#ifdef CJF2_NBT_CPP_USE_ZLIB
1201 template <
typename Visitor,
typename InfoFunc = NBT_Pr
int>
1203 static bool SimpleScanNbtFile(
const std::filesystem::path &pathFileName, Visitor &tVisitor, InfoFunc funcInfo = InfoFunc{})
noexcept
1206 std::vector<uint8_t> vFileData;
1214 std::vector<uint8_t> vNbtData;
1218 vNbtData = std::move(vFileData);
1223 vFileData.shrink_to_fit();
1226 if (!
ScanNBT(vNbtData, 0, tVisitor, 512))
1239#undef CALL_FUNC_RET_CONTROL
1240#undef UNKNOWN_CONTROL_CODE
1241#undef CHECK_STACK_DEPTH
1242#undef STACK_TRACEBACK
1246#undef _RP___FUNCTION__