chenjunfu2-nbt-cpp v2.1.3
一个基于CPP20的NBT(Named Binary Tag)库
载入中...
搜索中...
未找到
NBT_Helper.hpp
浏览该文件的文档.
1#pragma once
2
3#include <bit>
4#include <concepts>
5#include <iterator>
6#include <algorithm>
7
8#include "NBT_Print.hpp"//打印输出
9#include "NBT_Endian.hpp"
10#include "NBT_Node.hpp"
11#include "NBT_Node_View.hpp"
12
13#include "vcpkg_config.h"//包含vcpkg生成的配置以确认库安装情况
14
15#ifdef CJF2_NBT_CPP_USE_XXHASH
16#include "NBT_Hash.hpp"
17#endif
18
21
24class NBT_Helper
25{
27 NBT_Helper(void) = delete;
29 ~NBT_Helper(void) = delete;
30
31public:
35 {};
36
39 template<bool bAscending = true>
41 {
46 std::vector<NBT_Type::Compound::Const_Iterator> operator()(const NBT_Type::Compound &cpdSort)
47 {
48 return cpdSort.KeySortIt<bAscending>();
49 }
50 };
51
59 template<typename SortPolicy = DefaultCompoundSort<true>, typename PrintFunc = NBT_Print>
60 static void Print(const NBT_Node_View<true> nRoot, size_t szPaddingStartLevel = 0, const std::string & strLevelPadding = " ", PrintFunc funcPrint = NBT_Print{})
61 {
62 PrintSwitch<true, SortPolicy>(nRoot, szPaddingStartLevel, strLevelPadding, funcPrint);
63 }
64
72 template<typename SortPolicy = DefaultCompoundSort<true>, bool bHexNumType = true, bool bSnbtType = false>
73 static std::conditional_t<bSnbtType, NBT_Type::String, std::string> Serialize(const NBT_Node_View<true> nRoot)
74 {
75 std::conditional_t<bSnbtType, NBT_Type::String, std::string> sRet{};
76 SerializeSwitch<true, SortPolicy, bHexNumType, bSnbtType>(nRoot, sRet);
77 return sRet;
78 }
79
80#ifdef CJF2_NBT_CPP_USE_XXHASH
84 static void DefaultFunc(NBT_Hash &nbtHash)
85 {
86 return;
87 }
88
90 using DefaultFuncType = std::decay_t<decltype(DefaultFunc)>;
91
102 template<typename SortPolicy = DefaultCompoundSort<true>, typename TB = DefaultFuncType, typename TA = DefaultFuncType>//两个函数,分别在前后调用,可以用于插入哈希数据
103 static NBT_Hash::HASH_T Hash(const NBT_Node_View<true> nRoot, NBT_Hash nbtHash, TB funBefore = DefaultFunc, TA funAfter = DefaultFunc)
104 {
105 funBefore(nbtHash);
106 HashSwitch<true, SortPolicy>(nRoot, nbtHash);
107 funAfter(nbtHash);
108
109 return nbtHash.Digest();
110
111 //调用可行性检测
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.");
114 }
115#endif
116
117protected:
119 template<typename PrintFunc>
120 static void PrintPadding(size_t szLevel, bool bSubLevel, bool bNewLine, const std::string &strLevelPadding, PrintFunc &funcPrint)//bSubLevel会让缩进多一层
121 {
122 if (szLevel == (size_t)-1)//跳过打印
123 {
124 return;
125 }
126
127 if (bNewLine)
128 {
129 funcPrint("\n");
130 }
131
132 for (size_t i = 0; i < szLevel; ++i)
133 {
134 funcPrint("{}", strLevelPadding);
135 }
136
137 if (bSubLevel)
138 {
139 funcPrint("{}", strLevelPadding);
140 }
141 }
142
143 template<typename T>
144 requires(std::is_arithmetic_v<T>)
145 static void NumericToHexString(const T &value, std::string &result)
146 {
147 //映射
148 static constexpr char hex_chars[] = "0123456789ABCDEF";
149
150 //前缀
151 result += "0x";
152
153 //按照原始字节序处理
154 using Raw_T = decltype([](void) -> auto
155 {
156 if constexpr (NBT_Type::IsNumericType_V<T>)
157 {
159 }
160 else
161 {
162 return T{};
163 }
164 }());
165 Raw_T uintVal = std::bit_cast<Raw_T>(value);
166
167 for (size_t i = 0; i < sizeof(T); ++i)
168 {
169 uint8_t u8Byte = (uintVal >> 8 * (sizeof(T) - i - 1)) & 0xFF;//遍历字节,从高到低
170
171 result += hex_chars[(u8Byte >> 4) & 0x0F];//高4
172 result += hex_chars[(u8Byte >> 0) & 0x0F];//低4
173 }
174 }
175
176 template<typename T, typename STR_T>
177 requires(NBT_Type::IsNumericType_V<T> && (std::is_same_v<STR_T, NBT_Type::String> || std::is_same_v<STR_T, std::string>))
178 static void NumericToDecString(const T &value, STR_T &result)
179 {
180 std::string tmp{};
181 if constexpr (NBT_Type::IsFloatingType_V<T>)
182 {
183 tmp = std::format("{:.{}g}", value, std::numeric_limits<T>::max_digits10);
184 }
185 else if constexpr (NBT_Type::IsIntegerType_V<T>)
186 {
187 tmp = std::format("{:d}", value);
188 }
189 else
190 {
191 static_assert(false,"T type unknown");
192 }
193
194 if constexpr (std::is_same_v<STR_T, NBT_Type::String>)
195 {
196 result += (NBT_Type::String)tmp;//转换为NBT字符串
197 }
198 else if constexpr(std::is_same_v<STR_T, std::string>)
199 {
200 result += tmp;
201 }
202 else
203 {
204 static_assert(false, "STR_T type unknown");
205 }
206 }
208
209protected:
211 //首次调用默认为true,二次调用开始内部主动变为false
212 template<bool bRoot, typename SortPolicy, typename PrintFunc = NBT_Print>//首次使用NBT_Node_View解包,后续直接使用NBT_Node引用免除额外初始化开销
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)
214 {
215 static auto PrintArray = [](const std::string strBeg, const auto &vArr, const std::string strEnd, PrintFunc &funcPrint) -> void
216 {
217 funcPrint("{}", strBeg);
218 bool bFirst = true;
219 for (const auto &it : vArr)
220 {
221 if (bFirst)
222 {
223 bFirst = false;
224 funcPrint("{}", it);
225 }
226 else
227 {
228 funcPrint(",{}", it);
229 }
230 }
231 funcPrint("{}", strEnd);
232 };
233
234
235 auto tag = nRoot.GetTag();
236 switch (tag)
237 {
238 case NBT_TAG::End:
239 {
240 funcPrint("[End]");
241 }
242 break;
243 case NBT_TAG::Byte:
244 {
245 funcPrint("{}B", nRoot.template Get<NBT_Type::Byte>());
246 }
247 break;
248 case NBT_TAG::Short:
249 {
250 funcPrint("{}S", nRoot.template Get<NBT_Type::Short>());
251 }
252 break;
253 case NBT_TAG::Int:
254 {
255 funcPrint("{}I", nRoot.template Get<NBT_Type::Int>());
256 }
257 break;
258 case NBT_TAG::Long:
259 {
260 funcPrint("{}L", nRoot.template Get<NBT_Type::Long>());
261 }
262 break;
263 case NBT_TAG::Float:
264 {
265 funcPrint("{}F", nRoot.template Get<NBT_Type::Float>());
266 }
267 break;
268 case NBT_TAG::Double:
269 {
270 funcPrint("{}D", nRoot.template Get<NBT_Type::Double>());
271 }
272 break;
274 {
275 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
276 PrintArray("[B;", arr, "]", funcPrint);
277 }
278 break;
280 {
281 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
282 PrintArray("[I;", arr, "]", funcPrint);
283 }
284 break;
286 {
287 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
288 PrintArray("[L;", arr, "]", funcPrint);
289 }
290 break;
291 case NBT_TAG::String:
292 {
293 funcPrint("\"{}\"", nRoot.template Get<NBT_Type::String>().ToCharTypeUTF8());
294 }
295 break;
296 case NBT_TAG::List://需要打印缩进的地方
297 {
298 const auto &list = nRoot.template Get<NBT_Type::List>();
299 PrintPadding(szLevel, false, !bRoot, strLevelPadding, funcPrint);//不是根部则打印开头换行
300 funcPrint("[");
301
302 bool bFirst = true;
303 for (const auto &it : list)
304 {
305 if (bFirst)
306 {
307 bFirst = false;
308 }
309 else
310 {
311 funcPrint(",");
312 }
313
314 PrintPadding(szLevel, true, it.GetTag() != NBT_TAG::Compound && it.GetTag() != NBT_TAG::List, strLevelPadding, funcPrint);
315 PrintSwitch<false, SortPolicy, PrintFunc>(it, szLevel + 1, strLevelPadding, funcPrint);
316 }
317
318 if (list.Size() != 0)//空列表无需换行以及对齐
319 {
320 PrintPadding(szLevel, false, true, strLevelPadding, funcPrint);
321 }
322
323 funcPrint("]");
324 }
325 break;
326 case NBT_TAG::Compound://需要打印缩进的地方
327 {
328 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
329 PrintPadding(szLevel, false, !bRoot, strLevelPadding, funcPrint);//不是根部则打印开头换行
330 funcPrint("{{");//大括号转义
331
332 if constexpr (std::is_same_v<SortPolicy, NoSortCompound>)
333 {
334 bool bFirst = true;
335 for (const auto &it : cpd)
336 {
337 if (bFirst)
338 {
339 bFirst = false;
340 }
341 else
342 {
343 funcPrint(",");
344 }
345
346 PrintPadding(szLevel, true, true, strLevelPadding, funcPrint);
347 funcPrint("\"{}\":", it.first.ToCharTypeUTF8());
348 PrintSwitch<false, SortPolicy, PrintFunc>(it.second, szLevel + 1, strLevelPadding, funcPrint);
349 }
350 }
351 else
352 {
353 std::vector<NBT_Type::Compound::Const_Iterator> vSort = SortPolicy{}(cpd);
354
355 bool bFirst = true;
356 for (const auto &it : vSort)
357 {
358 if (bFirst)
359 {
360 bFirst = false;
361 }
362 else
363 {
364 funcPrint(",");
365 }
366
367 PrintPadding(szLevel, true, true, strLevelPadding, funcPrint);
368 funcPrint("\"{}\":", it->first.ToCharTypeUTF8());
369 PrintSwitch<false, SortPolicy, PrintFunc>(it->second, szLevel + 1, strLevelPadding, funcPrint);
370 }
371 }
372
373 if (cpd.Size() != 0)//空集合无需换行以及对齐
374 {
375 PrintPadding(szLevel, false, true, strLevelPadding, funcPrint);
376 }
377
378 funcPrint("}}");//大括号转义
379 }
380 break;
381 default:
382 {
383 funcPrint("[Unknown NBT Tag Type [{:02X}({})]]", (NBT_TAG_RAW_TYPE)tag, (NBT_TAG_RAW_TYPE)tag);
384 }
385 break;
386 }
387 }
388
389 //首次调用默认为true,二次调用开始内部主动变为false
390 template<bool bRoot, typename SortPolicy, bool bHexNumType, bool bSnbtType>//首次使用NBT_Node_View解包,后续直接使用NBT_Node引用免除额外初始化开销
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)
392 {
393 auto tag = nRoot.GetTag();
394 switch (tag)
395 {
396 case NBT_TAG::End:
397 {
398 if constexpr (bSnbtType)
399 {
400 sRet += MU8STR("[End]");
401 }
402 else
403 {
404 sRet += "[End]";
405 }
406 }
407 break;
408 case NBT_TAG::Byte:
409 {
410 if constexpr (bSnbtType || !bHexNumType)//snbt必须是dec
411 {
412 NumericToDecString(nRoot.template Get<NBT_Type::Byte>(), sRet);
413 }
414 else
415 {
416 NumericToHexString(nRoot.template Get<NBT_Type::Byte>(), sRet);
417 }
418 sRet += 'B';
419 }
420 break;
421 case NBT_TAG::Short:
422 {
423 if constexpr (bSnbtType || !bHexNumType)
424 {
425 NumericToDecString(nRoot.template Get<NBT_Type::Short>(), sRet);
426 }
427 else
428 {
429 NumericToHexString(nRoot.template Get<NBT_Type::Short>(), sRet);
430 }
431 sRet += 'S';
432 }
433 break;
434 case NBT_TAG::Int:
435 {
436 if constexpr (bSnbtType || !bHexNumType)
437 {
438 NumericToDecString(nRoot.template Get<NBT_Type::Int>(), sRet);
439 }
440 else
441 {
442 NumericToHexString(nRoot.template Get<NBT_Type::Int>(), sRet);
443 }
444 sRet += 'I';
445 }
446 break;
447 case NBT_TAG::Long:
448 {
449 if constexpr (bSnbtType || !bHexNumType)
450 {
451 NumericToDecString(nRoot.template Get<NBT_Type::Long>(), sRet);
452 }
453 else
454 {
455 NumericToHexString(nRoot.template Get<NBT_Type::Long>(), sRet);
456 }
457 sRet += 'L';
458 }
459 break;
460 case NBT_TAG::Float:
461 {
462 if constexpr (bSnbtType || !bHexNumType)
463 {
464 NumericToDecString(nRoot.template Get<NBT_Type::Float>(), sRet);
465 }
466 else
467 {
468 NumericToHexString(nRoot.template Get<NBT_Type::Float>(), sRet);
469 }
470 sRet += 'F';
471 }
472 break;
473 case NBT_TAG::Double:
474 {
475 if constexpr (bSnbtType || !bHexNumType)
476 {
477 NumericToDecString(nRoot.template Get<NBT_Type::Double>(), sRet);
478 }
479 else
480 {
481 NumericToHexString(nRoot.template Get<NBT_Type::Double>(), sRet);
482 }
483 sRet += 'D';
484 }
485 break;
487 {
488 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
489
490 if constexpr (bSnbtType)
491 {
492 sRet += MU8STR("[B;");
493 }
494 else
495 {
496 sRet += "[B;";
497 }
498
499 for (const auto &it : arr)
500 {
501 if constexpr (bSnbtType || !bHexNumType)
502 {
503 NumericToDecString(it, sRet);
504 }
505 else
506 {
507 NumericToHexString(it, sRet);
508 }
509 sRet += ',';
510 }
511 if (arr.size() != 0)
512 {
513 sRet.pop_back();//删掉最后一个逗号
514 }
515
516 sRet += ']';
517 }
518 break;
520 {
521 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
522
523 if constexpr (bSnbtType)
524 {
525 sRet += MU8STR("[I;");
526 }
527 else
528 {
529 sRet += "[I;";
530 }
531
532 for (const auto &it : arr)
533 {
534 if constexpr (bSnbtType || !bHexNumType)
535 {
536 NumericToDecString(it, sRet);
537 }
538 else
539 {
540 NumericToHexString(it, sRet);
541 }
542 sRet += ',';
543 }
544 if (arr.size() != 0)
545 {
546 sRet.pop_back();//删掉最后一个逗号
547 }
548
549 sRet += ']';
550 }
551 break;
553 {
554 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
555
556 if constexpr (bSnbtType)
557 {
558 sRet += MU8STR("[L;");
559 }
560 else
561 {
562 sRet += "[L;";
563 }
564
565 for (const auto &it : arr)
566 {
567 if constexpr (bSnbtType || !bHexNumType)
568 {
569 NumericToDecString(it, sRet);
570 }
571 else
572 {
573 NumericToHexString(it, sRet);
574 }
575 sRet += ',';
576 }
577 if (arr.size() != 0)
578 {
579 sRet.pop_back();//删掉最后一个逗号
580 }
581
582 sRet += ']';
583 }
584 break;
585 case NBT_TAG::String:
586 {
587 sRet += '\"';
588 if constexpr (bSnbtType)
589 {
590 sRet += nRoot.template Get<NBT_Type::String>();
591 }
592 else
593 {
594 sRet += nRoot.template Get<NBT_Type::String>().ToCharTypeUTF8();
595 }
596 sRet += '\"';
597 }
598 break;
599 case NBT_TAG::List:
600 {
601 const auto &list = nRoot.template Get<NBT_Type::List>();
602 sRet += '[';
603 for (const auto &it : list)
604 {
605 SerializeSwitch<false, SortPolicy, bHexNumType, bSnbtType>(it, sRet);
606 sRet += ',';
607 }
608
609 if (list.Size() != 0)
610 {
611 sRet.pop_back();//删掉最后一个逗号
612 }
613 sRet += ']';
614 }
615 break;
616 case NBT_TAG::Compound://需要打印缩进的地方
617 {
618 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
619 sRet += '{';
620
621 if constexpr (std::is_same_v<SortPolicy, NoSortCompound>)
622 {
623 for (const auto &it : cpd)
624 {
625 sRet += '\"';
626 if constexpr (bSnbtType)
627 {
628 sRet += it.first;
629 sRet += MU8STR("\":");
630 }
631 else
632 {
633 sRet += it.first.ToCharTypeUTF8();
634 sRet += "\":";
635 }
636 SerializeSwitch<false, SortPolicy, bHexNumType, bSnbtType>(it.second, sRet);
637 sRet += ',';
638 }
639 }
640 else
641 {
642 std::vector<NBT_Type::Compound::Const_Iterator> vSort = SortPolicy{}(cpd);
643
644 for (const auto &it : vSort)
645 {
646 sRet += '\"';
647 if constexpr (bSnbtType)
648 {
649 sRet += it->first;
650 sRet += MU8STR("\":");
651 }
652 else
653 {
654 sRet += it->first.ToCharTypeUTF8();
655 sRet += "\":";
656 }
657 SerializeSwitch<false, SortPolicy, bHexNumType, bSnbtType>(it->second, sRet);
658 sRet += ',';
659 }
660 }
661
662 if (cpd.Size() != 0)
663 {
664 sRet.pop_back();//删掉最后一个逗号
665 }
666 sRet += '}';
667 }
668 break;
669 default:
670 {
671 if constexpr (bSnbtType)
672 {
673 //Ignore Error
674 }
675 else
676 {
677 sRet += "[Unknown NBT Tag Type [";
678 NumericToHexString((NBT_TAG_RAW_TYPE)tag, sRet);
679 sRet += "]]";
680 }
681 }
682 break;
683 }
684 }
685
686#ifdef CJF2_NBT_CPP_USE_XXHASH
687 template<bool bRoot, typename SortPolicy>//首次使用NBT_Node_View解包,后续直接使用NBT_Node引用免除额外初始化开销
688 static void HashSwitch(std::conditional_t<bRoot, const NBT_Node_View<true> &, const NBT_Node &>nRoot, NBT_Hash &nbtHash)
689 {
690 auto tag = nRoot.GetTag();
691
692 //把tag本身作为数据
693 {
694 const auto &tmp = tag;
695 nbtHash.Update(tmp);
696 }
697
698 //再读出实际内容作为数据
699 switch (tag)
700 {
701 case NBT_TAG::End:
702 {
703 //end类型无负载,所以什么也不做
704 }
705 break;
706 case NBT_TAG::Byte:
707 {
708 const auto &tmp = nRoot.template Get<NBT_Type::Byte>();
709 nbtHash.Update(tmp);
710 }
711 break;
712 case NBT_TAG::Short:
713 {
714 const auto &tmp = nRoot.template Get<NBT_Type::Short>();
715 nbtHash.Update(tmp);
716 }
717 break;
718 case NBT_TAG::Int:
719 {
720 const auto &tmp = nRoot.template Get<NBT_Type::Int>();
721 nbtHash.Update(tmp);
722 }
723 break;
724 case NBT_TAG::Long:
725 {
726 const auto &tmp = nRoot.template Get<NBT_Type::Long>();
727 nbtHash.Update(tmp);
728 }
729 break;
730 case NBT_TAG::Float:
731 {
732 const auto &tmp = nRoot.template Get<NBT_Type::Float>();
733 nbtHash.Update(tmp);
734 }
735 break;
736 case NBT_TAG::Double:
737 {
738 const auto &tmp = nRoot.template Get<NBT_Type::Double>();
739 nbtHash.Update(tmp);
740 }
741 break;
743 {
744 const auto &arr = nRoot.template Get<NBT_Type::ByteArray>();
745 for (const auto &it : arr)
746 {
747 const auto &tmp = it;
748 nbtHash.Update(tmp);
749 }
750 }
751 break;
753 {
754 const auto &arr = nRoot.template Get<NBT_Type::IntArray>();
755 for (const auto &it : arr)
756 {
757 const auto &tmp = it;
758 nbtHash.Update(tmp);
759 }
760 }
761 break;
763 {
764 const auto &arr = nRoot.template Get<NBT_Type::LongArray>();
765 for (const auto &it : arr)
766 {
767 const auto &tmp = it;
768 nbtHash.Update(tmp);
769 }
770 }
771 break;
772 case NBT_TAG::String:
773 {
774 const auto &tmp = nRoot.template Get<NBT_Type::String>();
775 nbtHash.Update(tmp.data(), tmp.size());
776 }
777 break;
778 case NBT_TAG::List:
779 {
780 const auto &list = nRoot.template Get<NBT_Type::List>();
781 for (const auto &it : list)
782 {
783 HashSwitch<false, SortPolicy>(it, nbtHash);
784 }
785 }
786 break;
787 case NBT_TAG::Compound://需要打印缩进的地方
788 {
789 const auto &cpd = nRoot.template Get<NBT_Type::Compound>();
790
791 if constexpr (std::is_same_v<SortPolicy, NoSortCompound>)
792 {
793 for (const auto &it : cpd)
794 {
795 const auto &tmp = it.first;
796 nbtHash.Update(tmp.data(), tmp.size());
797 HashSwitch<false, SortPolicy>(it.second, nbtHash);
798 }
799 }
800 else//对compound迭代器进行排序,以使得hash获得一致性结果
801 {
802 std::vector<NBT_Type::Compound::Const_Iterator> vSort = SortPolicy{}(cpd);
803
804 //遍历有序结构
805 for (const auto &it : vSort)
806 {
807 const auto &tmp = it->first;
808 nbtHash.Update(tmp.data(), tmp.size());
809 HashSwitch<false, SortPolicy>(it->second, nbtHash);
810 }
811 }
812 }
813 break;
814 default:
815 {}
816 break;
817 }
818 }
819#endif
821
822};
端序工具集
哈希工具集
NBT节点类型,支持存储所有NBT类型的变体
#define MU8STR(charLiteralString)
从C风格字符串获取M-UTF-8的字符串
定义 NBT_Node.hpp:21
NBT节点类型的视图,支持指向所有NBT类型的变体视图,不持有对象
用于处理NBT信息打印的默认实现
uint8_t NBT_TAG_RAW_TYPE
NBT_TAG的原始类型,用于二进制读写或判断等
定义 NBT_TAG.hpp:12
@ Int
对应NBT_Type::Int
定义 NBT_TAG.hpp:21
@ Float
对应NBT_Type::Float
定义 NBT_TAG.hpp:23
@ Compound
对应NBT_Type::Compound
定义 NBT_TAG.hpp:28
@ String
对应NBT_Type::String
定义 NBT_TAG.hpp:26
@ ByteArray
对应NBT_Type::ByteArray
定义 NBT_TAG.hpp:25
@ Short
对应NBT_Type::Short
定义 NBT_TAG.hpp:20
@ List
对应NBT_Type::List
定义 NBT_TAG.hpp:27
@ Long
对应NBT_Type::Long
定义 NBT_TAG.hpp:22
@ End
对应NBT_Type::End
定义 NBT_TAG.hpp:18
@ LongArray
对应NBT_Type::LongArray
定义 NBT_TAG.hpp:30
@ Byte
对应NBT_Type::Byte
定义 NBT_TAG.hpp:19
@ IntArray
对应NBT_Type::IntArray
定义 NBT_TAG.hpp:29
@ Double
对应NBT_Type::Double
定义 NBT_TAG.hpp:24
std::vector< typename Compound::iterator > KeySortIt(void)
获取按键名排序的迭代器向量(非常量版本)
定义 NBT_Compound.hpp:182
一个封装xxhash调用的用于计算哈希的辅助类
定义 NBT_Hash.hpp:12
XXH64_hash_t HASH_T
类型别名,xxhash类型封装,类型必须是uint64_t
定义 NBT_Hash.hpp:15
HASH_T Digest(void) const
根据之前已添加的数据,获取当前的哈希值
定义 NBT_Hash.hpp:71
void Update(const void *pData, size_t szSize)
添加指针指向的数据更新哈希
定义 NBT_Hash.hpp:80
static NBT_Hash::HASH_T Hash(const NBT_Node_View< true > nRoot, NBT_Hash nbtHash, TB funBefore=DefaultFunc, TA funAfter=DefaultFunc)
对NBT对象进行递归计算哈希
定义 NBT_Helper.hpp:103
static void DefaultFunc(NBT_Hash &nbtHash)
用于插入哈希的示例函数
定义 NBT_Helper.hpp:84
static std::conditional_t< bSnbtType, NBT_Type::String, std::string > Serialize(const NBT_Node_View< true > nRoot)
直接序列化,按照一定规则输出为String并返回
定义 NBT_Helper.hpp:73
static void Print(const NBT_Node_View< true > nRoot, size_t szPaddingStartLevel=0, const std::string &strLevelPadding=" ", PrintFunc funcPrint=NBT_Print{})
格式化对齐打印NBT对象
定义 NBT_Helper.hpp:60
std::decay_t< decltype(DefaultFunc)> DefaultFuncType
函数的类型,用于模板默认值
定义 NBT_Helper.hpp:90
NBT节点的视图,用于指向而不持有对象,类似于标准库的std::string与std::string_view的关系
定义 NBT_Node_View.hpp:24
NBT_TAG GetTag() const noexcept
获取当前视图指向的NBT类型的枚举值
定义 NBT_Node_View.hpp:369
一个用于打印信息到指定的C文件对象的工具类,作为库内大部分存在信息输出接口的默认实现。 实际可被使用此类为默认值参数的函数的调用方,以类似此类的仿函数参数重写的其它类型替换, 比如调用方实现了一个My_...
定义 NBT_Print.hpp:24
static constexpr bool IsNumericType_V
判断类型是否为NBT数值类型(包含所有整数和浮点数类型)
定义 NBT_Type.hpp:261
static constexpr bool IsIntegerType_V
判断类型是否为NBT整数类型(包含所有整数类型)
定义 NBT_Type.hpp:273
NBT_String< MUTF8_String, MUTF8_String_View > String
字符串类型,存储Java M-UTF-8字符串
定义 NBT_Type.hpp:65
NBT_Compound< std::unordered_map< String, NBT_Node > > Compound
集合类型,可存储任意不同的NBT类型,通过名称映射值
定义 NBT_Type.hpp:73
typename BuiltinRawType< T >::Type BuiltinRawType_T
映射内建类型到方便读写的raw类型:编译期获得内建类型到可以进行二进制读写的原始类型
定义 NBT_Type.hpp:345
static constexpr bool IsFloatingType_V
判断类型是否为NBT浮点数类型(包含所有浮点数类型)
定义 NBT_Type.hpp:283
默认排序策略,提供按键的字符串字典序升序或降序排列。
定义 NBT_Helper.hpp:41
std::vector< NBT_Type::Compound::Const_Iterator > operator()(const NBT_Type::Compound &cpdSort)
对给定的 Compound 对象进行排序,返回指向其元素的迭代器向量。
定义 NBT_Helper.hpp:46
提示性类型,表示在写出 Compound 时不对键值对进行任何排序。
定义 NBT_Helper.hpp:35
根据已安装的可选依赖提供定义