27 NBT_Helper(
void) =
delete;
29 ~NBT_Helper(
void) =
delete;
39 template<
bool bAscending = true>
59 template<
typename SortPolicy = DefaultCompoundSort<true>,
typename Pr
intFunc = NBT_Pr
int>
62 PrintSwitch<true, SortPolicy>(nRoot, szPaddingStartLevel, strLevelPadding, funcPrint);
72 template<
typename SortPolicy = DefaultCompoundSort<true>,
bool bHexNumType = true,
bool bSnbtType = false>
75 std::conditional_t<bSnbtType, NBT_Type::String, std::string> sRet{};
76 SerializeSwitch<true, SortPolicy, bHexNumType, bSnbtType>(nRoot, sRet);
80#ifdef CJF2_NBT_CPP_USE_XXHASH
102 template<
typename SortPolicy = DefaultCompoundSort<true>,
typename TB = DefaultFuncType,
typename TA = DefaultFuncType>
106 HashSwitch<true, SortPolicy>(nRoot, nbtHash);
112 static_assert(std::is_invocable_v<TB,
decltype(nbtHash)&>,
"TB is not a callable object or parameter type mismatch.");
113 static_assert(std::is_invocable_v<TA,
decltype(nbtHash)&>,
"TA is not a callable object or parameter type mismatch.");
119 template<
typename Pr
intFunc>
120 static void PrintPadding(
size_t szLevel,
bool bSubLevel,
bool bNewLine,
const std::string &strLevelPadding, PrintFunc &funcPrint)
122 if (szLevel == (
size_t)-1)
132 for (
size_t i = 0; i < szLevel; ++i)
134 funcPrint(
"{}", strLevelPadding);
139 funcPrint(
"{}", strLevelPadding);
144 requires(std::is_arithmetic_v<T>)
145 static void NumericToHexString(
const T &value, std::string &result)
148 static constexpr char hex_chars[] =
"0123456789ABCDEF";
154 using Raw_T =
decltype([](void) ->
auto
165 Raw_T uintVal = std::bit_cast<Raw_T>(value);
167 for (
size_t i = 0; i <
sizeof(T); ++i)
169 uint8_t u8Byte = (uintVal >> 8 * (
sizeof(T) - i - 1)) & 0xFF;
171 result += hex_chars[(u8Byte >> 4) & 0x0F];
172 result += hex_chars[(u8Byte >> 0) & 0x0F];
176 template<
typename T,
typename STR_T>
178 static void NumericToDecString(
const T &value, STR_T &result)
183 tmp = std::format(
"{:.{}g}", value, std::numeric_limits<T>::max_digits10);
187 tmp = std::format(
"{:d}", value);
191 static_assert(
false,
"T type unknown");
194 if constexpr (std::is_same_v<STR_T, NBT_Type::String>)
198 else if constexpr(std::is_same_v<STR_T, std::string>)
204 static_assert(
false,
"STR_T type unknown");
212 template<
bool bRoot,
typename SortPolicy,
typename Pr
intFunc = NBT_Pr
int>
213 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)
215 static auto PrintArray = [](
const std::string strBeg,
const auto &vArr,
const std::string strEnd, PrintFunc &funcPrint) ->
void
217 funcPrint(
"{}", strBeg);
219 for (
const auto &it : vArr)
228 funcPrint(
",{}", it);
231 funcPrint(
"{}", strEnd);
235 auto tag = nRoot.
GetTag();
245 funcPrint(
"{}B", nRoot.template Get<NBT_Type::Byte>());
250 funcPrint(
"{}S", nRoot.template Get<NBT_Type::Short>());
255 funcPrint(
"{}I", nRoot.template Get<NBT_Type::Int>());
260 funcPrint(
"{}L", nRoot.template Get<NBT_Type::Long>());
265 funcPrint(
"{}F", nRoot.template Get<NBT_Type::Float>());
270 funcPrint(
"{}D", nRoot.template Get<NBT_Type::Double>());
275 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
276 PrintArray(
"[B;", arr,
"]", funcPrint);
281 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
282 PrintArray(
"[I;", arr,
"]", funcPrint);
287 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
288 PrintArray(
"[L;", arr,
"]", funcPrint);
293 funcPrint(
"\"{}\"", nRoot.template Get<NBT_Type::String>().ToCharTypeUTF8());
298 const auto &list = nRoot.template Get<NBT_Type::List>();
299 PrintPadding(szLevel,
false, !bRoot, strLevelPadding, funcPrint);
303 for (
const auto &it : list)
315 PrintSwitch<false, SortPolicy, PrintFunc>(it, szLevel + 1, strLevelPadding, funcPrint);
318 if (list.Size() != 0)
320 PrintPadding(szLevel,
false,
true, strLevelPadding, funcPrint);
328 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
329 PrintPadding(szLevel,
false, !bRoot, strLevelPadding, funcPrint);
332 if constexpr (std::is_same_v<SortPolicy, NoSortCompound>)
335 for (
const auto &it : cpd)
346 PrintPadding(szLevel,
true,
true, strLevelPadding, funcPrint);
347 funcPrint(
"\"{}\":", it.first.ToCharTypeUTF8());
348 PrintSwitch<false, SortPolicy, PrintFunc>(it.second, szLevel + 1, strLevelPadding, funcPrint);
353 std::vector<NBT_Type::Compound::Const_Iterator> vSort = SortPolicy{}(cpd);
356 for (
const auto &it : vSort)
367 PrintPadding(szLevel,
true,
true, strLevelPadding, funcPrint);
368 funcPrint(
"\"{}\":", it->first.ToCharTypeUTF8());
369 PrintSwitch<false, SortPolicy, PrintFunc>(it->second, szLevel + 1, strLevelPadding, funcPrint);
375 PrintPadding(szLevel,
false,
true, strLevelPadding, funcPrint);
390 template<
bool bRoot,
typename SortPolicy,
bool bHexNumType,
bool bSnbtType>
391 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)
393 auto tag = nRoot.
GetTag();
398 if constexpr (bSnbtType)
410 if constexpr (bSnbtType || !bHexNumType)
412 NumericToDecString(nRoot.template Get<NBT_Type::Byte>(), sRet);
416 NumericToHexString(nRoot.template Get<NBT_Type::Byte>(), sRet);
423 if constexpr (bSnbtType || !bHexNumType)
425 NumericToDecString(nRoot.template Get<NBT_Type::Short>(), sRet);
429 NumericToHexString(nRoot.template Get<NBT_Type::Short>(), sRet);
436 if constexpr (bSnbtType || !bHexNumType)
438 NumericToDecString(nRoot.template Get<NBT_Type::Int>(), sRet);
442 NumericToHexString(nRoot.template Get<NBT_Type::Int>(), sRet);
449 if constexpr (bSnbtType || !bHexNumType)
451 NumericToDecString(nRoot.template Get<NBT_Type::Long>(), sRet);
455 NumericToHexString(nRoot.template Get<NBT_Type::Long>(), sRet);
462 if constexpr (bSnbtType || !bHexNumType)
464 NumericToDecString(nRoot.template Get<NBT_Type::Float>(), sRet);
468 NumericToHexString(nRoot.template Get<NBT_Type::Float>(), sRet);
475 if constexpr (bSnbtType || !bHexNumType)
477 NumericToDecString(nRoot.template Get<NBT_Type::Double>(), sRet);
481 NumericToHexString(nRoot.template Get<NBT_Type::Double>(), sRet);
488 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
490 if constexpr (bSnbtType)
499 for (
const auto &it : arr)
501 if constexpr (bSnbtType || !bHexNumType)
503 NumericToDecString(it, sRet);
507 NumericToHexString(it, sRet);
521 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
523 if constexpr (bSnbtType)
532 for (
const auto &it : arr)
534 if constexpr (bSnbtType || !bHexNumType)
536 NumericToDecString(it, sRet);
540 NumericToHexString(it, sRet);
554 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
556 if constexpr (bSnbtType)
565 for (
const auto &it : arr)
567 if constexpr (bSnbtType || !bHexNumType)
569 NumericToDecString(it, sRet);
573 NumericToHexString(it, sRet);
588 if constexpr (bSnbtType)
590 sRet += nRoot.template Get<NBT_Type::String>();
594 sRet += nRoot.template Get<NBT_Type::String>().ToCharTypeUTF8();
601 const auto &list = nRoot.template Get<NBT_Type::List>();
603 for (
const auto &it : list)
605 SerializeSwitch<false, SortPolicy, bHexNumType, bSnbtType>(it, sRet);
609 if (list.Size() != 0)
618 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
621 if constexpr (std::is_same_v<SortPolicy, NoSortCompound>)
623 for (
const auto &it : cpd)
626 if constexpr (bSnbtType)
633 sRet += it.first.ToCharTypeUTF8();
636 SerializeSwitch<false, SortPolicy, bHexNumType, bSnbtType>(it.second, sRet);
642 std::vector<NBT_Type::Compound::Const_Iterator> vSort = SortPolicy{}(cpd);
644 for (
const auto &it : vSort)
647 if constexpr (bSnbtType)
654 sRet += it->first.ToCharTypeUTF8();
657 SerializeSwitch<false, SortPolicy, bHexNumType, bSnbtType>(it->second, sRet);
671 if constexpr (bSnbtType)
677 sRet +=
"[Unknown NBT Tag Type [";
686#ifdef CJF2_NBT_CPP_USE_XXHASH
687 template<
bool bRoot,
typename SortPolicy>
688 static void HashSwitch(std::conditional_t<bRoot,
const NBT_Node_View<true> &,
const NBT_Node &>nRoot, NBT_Hash &nbtHash)
690 auto tag = nRoot.
GetTag();
694 const auto &tmp = tag;
708 const auto &tmp = nRoot.template Get<NBT_Type::Byte>();
714 const auto &tmp = nRoot.template Get<NBT_Type::Short>();
720 const auto &tmp = nRoot.template Get<NBT_Type::Int>();
726 const auto &tmp = nRoot.template Get<NBT_Type::Long>();
732 const auto &tmp = nRoot.template Get<NBT_Type::Float>();
738 const auto &tmp = nRoot.template Get<NBT_Type::Double>();
744 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
745 for (
const auto &it : arr)
747 const auto &tmp = it;
754 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
755 for (
const auto &it : arr)
757 const auto &tmp = it;
764 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
765 for (
const auto &it : arr)
767 const auto &tmp = it;
774 const auto &tmp = nRoot.template Get<NBT_Type::String>();
775 nbtHash.
Update(tmp.data(), tmp.size());
780 const auto &list = nRoot.template Get<NBT_Type::List>();
781 for (
const auto &it : list)
783 HashSwitch<false, SortPolicy>(it, nbtHash);
789 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
791 if constexpr (std::is_same_v<SortPolicy, NoSortCompound>)
793 for (
const auto &it : cpd)
795 const auto &tmp = it.first;
796 nbtHash.
Update(tmp.data(), tmp.size());
797 HashSwitch<false, SortPolicy>(it.second, nbtHash);
802 std::vector<NBT_Type::Compound::Const_Iterator> vSort = SortPolicy{}(cpd);
805 for (
const auto &it : vSort)
807 const auto &tmp = it->first;
808 nbtHash.
Update(tmp.data(), tmp.size());
809 HashSwitch<false, SortPolicy>(it->second, nbtHash);