27 NBT_Helper(
void) =
delete;
29 ~NBT_Helper(
void) =
delete;
39 template<
bool bSortCompound = true,
typename Pr
intFunc = NBT_Pr
int>
42 PrintSwitch<true, bSortCompound>(nRoot, szPaddingStartLevel, strLevelPadding, funcPrint);
52 template<
bool bSortCompound = true,
bool bHexNumType = true,
bool bSnbtType = false>
55 std::conditional_t<bSnbtType, NBT_Type::String, std::string> sRet{};
56 SerializeSwitch<true, bSortCompound, bHexNumType, bSnbtType>(nRoot, sRet);
60#ifdef CJF2_NBT_CPP_USE_XXHASH
82 template<
bool bSortCompound = true,
typename TB = DefaultFuncType,
typename TA = DefaultFuncType>
86 HashSwitch<true, bSortCompound>(nRoot, nbtHash);
92 static_assert(std::is_invocable_v<TB,
decltype(nbtHash)&>,
"TB is not a callable object or parameter type mismatch.");
93 static_assert(std::is_invocable_v<TA,
decltype(nbtHash)&>,
"TA is not a callable object or parameter type mismatch.");
99 template<
typename Pr
intFunc>
100 static void PrintPadding(
size_t szLevel,
bool bSubLevel,
bool bNewLine,
const std::string &strLevelPadding, PrintFunc &funcPrint)
102 if (szLevel == (
size_t)-1)
112 for (
size_t i = 0; i < szLevel; ++i)
114 funcPrint(
"{}", strLevelPadding);
119 funcPrint(
"{}", strLevelPadding);
124 requires(std::is_arithmetic_v<T>)
125 static void NumericToHexString(
const T &value, std::string &result)
128 static constexpr char hex_chars[] =
"0123456789ABCDEF";
134 using Raw_T =
decltype([](void) ->
auto
145 Raw_T uintVal = std::bit_cast<Raw_T>(value);
147 for (
size_t i = 0; i <
sizeof(T); ++i)
149 uint8_t u8Byte = (uintVal >> 8 * (
sizeof(T) - i - 1)) & 0xFF;
151 result += hex_chars[(u8Byte >> 4) & 0x0F];
152 result += hex_chars[(u8Byte >> 0) & 0x0F];
156 template<
typename T,
typename STR_T>
158 static void NumericToDecString(
const T &value, STR_T &result)
163 tmp = std::format(
"{:.{}g}", value, std::numeric_limits<T>::max_digits10);
167 tmp = std::format(
"{:d}", value);
171 static_assert(
false,
"T type unknown");
174 if constexpr (std::is_same_v<STR_T, NBT_Type::String>)
178 else if constexpr(std::is_same_v<STR_T, std::string>)
184 static_assert(
false,
"STR_T type unknown");
192 template<
bool bRoot,
bool bSortCompound,
typename Pr
intFunc = NBT_Pr
int>
193 static void PrintSwitch(std::conditional_t<bRoot,
const NBT_Node_View<true> &,
const NBT_Node &>nRoot,
size_t szLevel,
const std::string &strLevelPadding, PrintFunc &funcPrint)
195 static auto PrintArray = [](
const std::string strBeg,
const auto &vArr,
const std::string strEnd, PrintFunc &funcPrint) ->
void
197 funcPrint(
"{}", strBeg);
199 for (
const auto &it : vArr)
206 funcPrint(
",{}", it);
208 funcPrint(
"{}", strEnd);
212 auto tag = nRoot.
GetTag();
222 funcPrint(
"{}B", nRoot.template Get<NBT_Type::Byte>());
227 funcPrint(
"{}S", nRoot.template Get<NBT_Type::Short>());
232 funcPrint(
"{}I", nRoot.template Get<NBT_Type::Int>());
237 funcPrint(
"{}L", nRoot.template Get<NBT_Type::Long>());
242 funcPrint(
"{}F", nRoot.template Get<NBT_Type::Float>());
247 funcPrint(
"{}D", nRoot.template Get<NBT_Type::Double>());
252 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
253 PrintArray(
"[B;", arr,
"]", funcPrint);
258 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
259 PrintArray(
"[I;", arr,
"]", funcPrint);
264 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
265 PrintArray(
"[L;", arr,
"]", funcPrint);
270 funcPrint(
"\"{}\"", nRoot.template Get<NBT_Type::String>().ToCharTypeUTF8());
275 const auto &list = nRoot.template Get<NBT_Type::List>();
276 PrintPadding(szLevel,
false, !bRoot, strLevelPadding, funcPrint);
280 for (
const auto &it : list)
292 PrintSwitch<false, bSortCompound, PrintFunc>(it, szLevel + 1, strLevelPadding, funcPrint);
295 if (list.Size() != 0)
297 PrintPadding(szLevel,
false,
true, strLevelPadding, funcPrint);
305 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
306 PrintPadding(szLevel,
false, !bRoot, strLevelPadding, funcPrint);
309 if constexpr (!bSortCompound)
312 for (
const auto &it : cpd)
323 PrintPadding(szLevel,
true,
true, strLevelPadding, funcPrint);
324 funcPrint(
"\"{}\":", it.first.ToCharTypeUTF8());
325 PrintSwitch<false, bSortCompound, PrintFunc>(it.second, szLevel + 1, strLevelPadding, funcPrint);
330 auto vSort = cpd.KeySortIt();
333 for (
const auto &it : vSort)
344 PrintPadding(szLevel,
true,
true, strLevelPadding, funcPrint);
345 funcPrint(
"\"{}\":", it->first.ToCharTypeUTF8());
346 PrintSwitch<false, bSortCompound, PrintFunc>(it->second, szLevel + 1, strLevelPadding, funcPrint);
352 PrintPadding(szLevel,
false,
true, strLevelPadding, funcPrint);
367 template<
bool bRoot,
bool bSortCompound,
bool bHexNumType,
bool bSnbtType>
368 static void SerializeSwitch(std::conditional_t<bRoot,
const NBT_Node_View<true> &,
const NBT_Node &>nRoot, std::conditional_t<bSnbtType, NBT_Type::String, std::string> &sRet)
370 auto tag = nRoot.
GetTag();
375 if constexpr (bSnbtType)
387 if constexpr (bSnbtType || !bHexNumType)
389 NumericToDecString(nRoot.template Get<NBT_Type::Byte>(), sRet);
393 NumericToHexString(nRoot.template Get<NBT_Type::Byte>(), sRet);
400 if constexpr (bSnbtType || !bHexNumType)
402 NumericToDecString(nRoot.template Get<NBT_Type::Short>(), sRet);
406 NumericToHexString(nRoot.template Get<NBT_Type::Short>(), sRet);
413 if constexpr (bSnbtType || !bHexNumType)
415 NumericToDecString(nRoot.template Get<NBT_Type::Int>(), sRet);
419 NumericToHexString(nRoot.template Get<NBT_Type::Int>(), sRet);
426 if constexpr (bSnbtType || !bHexNumType)
428 NumericToDecString(nRoot.template Get<NBT_Type::Long>(), sRet);
432 NumericToHexString(nRoot.template Get<NBT_Type::Long>(), sRet);
439 if constexpr (bSnbtType || !bHexNumType)
441 NumericToDecString(nRoot.template Get<NBT_Type::Float>(), sRet);
445 NumericToHexString(nRoot.template Get<NBT_Type::Float>(), sRet);
452 if constexpr (bSnbtType || !bHexNumType)
454 NumericToDecString(nRoot.template Get<NBT_Type::Double>(), sRet);
458 NumericToHexString(nRoot.template Get<NBT_Type::Double>(), sRet);
465 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
467 if constexpr (bSnbtType)
476 for (
const auto &it : arr)
478 if constexpr (bSnbtType || !bHexNumType)
480 NumericToDecString(it, sRet);
484 NumericToHexString(it, sRet);
498 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
500 if constexpr (bSnbtType)
509 for (
const auto &it : arr)
511 if constexpr (bSnbtType || !bHexNumType)
513 NumericToDecString(it, sRet);
517 NumericToHexString(it, sRet);
531 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
533 if constexpr (bSnbtType)
542 for (
const auto &it : arr)
544 if constexpr (bSnbtType || !bHexNumType)
546 NumericToDecString(it, sRet);
550 NumericToHexString(it, sRet);
565 if constexpr (bSnbtType)
567 sRet += nRoot.template Get<NBT_Type::String>();
571 sRet += nRoot.template Get<NBT_Type::String>().ToCharTypeUTF8();
578 const auto &list = nRoot.template Get<NBT_Type::List>();
580 for (
const auto &it : list)
582 SerializeSwitch<false, bSortCompound, bHexNumType, bSnbtType>(it, sRet);
586 if (list.Size() != 0)
595 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
598 if constexpr (!bSortCompound)
600 for (
const auto &it : cpd)
603 if constexpr (bSnbtType)
610 sRet += it.first.ToCharTypeUTF8();
613 SerializeSwitch<false, bSortCompound, bHexNumType, bSnbtType>(it.second, sRet);
619 auto vSort = cpd.KeySortIt();
621 for (
const auto &it : vSort)
624 if constexpr (bSnbtType)
631 sRet += it->first.ToCharTypeUTF8();
634 SerializeSwitch<false, bSortCompound, bHexNumType, bSnbtType>(it->second, sRet);
648 if constexpr (bSnbtType)
654 sRet +=
"[Unknown NBT Tag Type [";
663#ifdef CJF2_NBT_CPP_USE_XXHASH
664 template<
bool bRoot,
bool bSortCompound>
665 static void HashSwitch(std::conditional_t<bRoot,
const NBT_Node_View<true> &,
const NBT_Node &>nRoot, NBT_Hash &nbtHash)
667 auto tag = nRoot.
GetTag();
671 const auto &tmp = tag;
685 const auto &tmp = nRoot.template Get<NBT_Type::Byte>();
691 const auto &tmp = nRoot.template Get<NBT_Type::Short>();
697 const auto &tmp = nRoot.template Get<NBT_Type::Int>();
703 const auto &tmp = nRoot.template Get<NBT_Type::Long>();
709 const auto &tmp = nRoot.template Get<NBT_Type::Float>();
715 const auto &tmp = nRoot.template Get<NBT_Type::Double>();
721 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
722 for (
const auto &it : arr)
724 const auto &tmp = it;
731 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
732 for (
const auto &it : arr)
734 const auto &tmp = it;
741 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
742 for (
const auto &it : arr)
744 const auto &tmp = it;
751 const auto &tmp = nRoot.template Get<NBT_Type::String>();
752 nbtHash.
Update(tmp.data(), tmp.size());
757 const auto &list = nRoot.template Get<NBT_Type::List>();
758 for (
const auto &it : list)
760 HashSwitch<false, bSortCompound>(it, nbtHash);
766 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
768 if constexpr (!bSortCompound)
770 for (
const auto &it : cpd)
772 const auto &tmp = it.first;
773 nbtHash.
Update(tmp.data(), tmp.size());
774 HashSwitch<false, bSortCompound>(it.second, nbtHash);
779 auto vSort = cpd.KeySortIt();
782 for (
const auto &it : vSort)
784 const auto &tmp = it->first;
785 nbtHash.
Update(tmp.data(), tmp.size());
786 HashSwitch<false, bSortCompound>(it->second, nbtHash);