UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
Deserializer.hpp
[詳解]
1//
2// デシリアライザ実装部
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
10#include <vector>
11#include <limits.h>
12
16#include <Udon/Types/Float.hpp>
21
22namespace Udon
23{
24 namespace Impl
25 {
26
28 {
29
30 size_t popIndex = 0; // 次に抽出するインデックス(バッファの先端からのオフセット)
31 uint8_t boolCount = 0; // bool の抽出回数
32 size_t boolPopIndex = 0; // bool を抽出中であるインデックス(バッファの先端からのオフセット)
33
34 ArrayView<const uint8_t> buffer; // デシリアライズするバイト列への参照
35
36 public:
37 using ResultType = void;
38
42 : buffer(buffer)
43 {
44 }
45
49 template <typename... Args>
50 void operator()(const Args&... args) const
51 {
52 argsUnpack(args...);
53 }
54
55 private:
57 template <typename Head, typename... Tails>
58 void argsUnpack(const Head& head, const Tails&... tails) const
59 {
60 const_cast<Deserializer&>(*this).deserialize(const_cast<Head&>(head));
61 // enumerate 関数は引数に一時オブジェクトを受けられる、かつconstexprである必要があるため "const Serializer& enumerator" になっている
62 // その関係で、operator()、本関数はconstな関数となり、thisポインタはconstなポインタになる。そのため const を外す。
63
64 argsUnpack(tails...);
65 }
66
68 void argsUnpack() const {}
69
71 template <typename Bool, EnableIfNullptrT<IsBool<RemoveCVRefT<Bool>>::value> = nullptr>
72 void deserialize(Bool& rhs)
73 {
74 rhs = popBool();
75 }
76
78 template <typename IntegralNotBool, EnableIfNullptrT<IsIntegralNotBool<RemoveCVRefT<IntegralNotBool>>::value> = nullptr>
79 void deserialize(IntegralNotBool& rhs)
80 {
81 rhs = popArithmetic<IntegralNotBool>();
82 }
83
85 template <typename FloatingPoint, EnableIfNullptrT<IsFloatingPoint<RemoveCVRefT<FloatingPoint>>::value> = nullptr>
86 void deserialize(FloatingPoint& rhs)
87 {
88 rhs = popArithmetic<Udon::Float32>();
89 }
90
92 template <typename Enum, EnableIfNullptrT<IsEnum<RemoveCVRefT<Enum>>::value> = nullptr>
93 void deserialize(Enum& rhs)
94 {
95 rhs = static_cast<Enum>(popArithmetic<typename std::underlying_type<Enum>::type>());
96 }
97
99 template <typename Array, EnableIfNullptrT<IsArray<RemoveCVRefT<Array>>::value> = nullptr>
100 void deserialize(Array& rhs)
101 {
102 for (auto& element : rhs)
103 {
104 deserialize(element);
105 }
106 }
107
109 template <typename Enumerable, EnableIfNullptrT<HasMemberFunctionEnumerate<RemoveCVRefT<Enumerable>>::value> = nullptr>
110 void deserialize(Enumerable& rhs)
111 {
112 rhs.enumerate(*this);
113 }
114
116 template <typename Arithmetic>
117 Arithmetic popArithmetic()
118 {
119 Arithmetic object;
120
121 constexpr auto size = sizeof(Arithmetic);
122
123 // 逆シリアル化されたオブジェクトをバイト列から抽出
124 // リトルエンディアン環境でのバイト列の並びを順とする
125#if UDON_PLATFORM_ENDIANNESS == UDON_PLATFORM_LITTLE_ENDIAN
126
127 // buffer をオブジェクトとして解釈
128 memcpy(
129 std::addressof(object),
130 buffer.data() + popIndex,
131 size);
132
133#elif UDON_PLATFORM_ENDIANNESS == UDON_PLATFORM_BIG_ENDIAN
134
135 // リトルエンディアンが基準なので、逆順のバイト列を作成
136 uint8_t reversedBuffer[size];
137 std::reverse_copy(
138 buffer.cbegin() + popIndex,
139 buffer.cbegin() + popIndex + size,
140 reversedBuffer);
141
142 // reversedBuffer をオブジェクトとして解釈
143 memcpy(
144 std::addressof(object),
145 reversedBuffer,
146 size);
147
148#endif
149
150 // 抽出したオブジェクトのバイト数分インデックスを進める
151 popIndex += size;
152
153 return object;
154 }
155
157 bool popBool()
158 {
159 if (boolCount == 0)
160 {
161 boolPopIndex = popIndex++;
162 }
163
164 const auto unpacked = Udon::BitRead(buffer.at(boolPopIndex), boolCount);
165
166 if (++boolCount >= CHAR_BIT)
167 {
168 boolCount = 0;
169 }
170
171 return unpacked;
172 }
173 };
174 } // namespace Impl
175
176} // namespace Udon
配列参照クラス
Definition ArrayView.hpp:27
const_iterator cbegin() const
Definition ArrayView.hpp:262
pointer data()
Definition ArrayView.hpp:95
reference at(const size_type index)
Definition ArrayView.hpp:113
Definition Deserializer.hpp:28
Deserializer(ArrayView< const uint8_t > buffer)
コンストラクタ
Definition Deserializer.hpp:41
void ResultType
Definition Deserializer.hpp:37
void operator()(const Args &... args) const
デシリアライズ
Definition Deserializer.hpp:50
Definition Bit.hpp:12
bool BitRead(const Ty &rhs, uint8_t bit)
特定のビットを読み取る
Definition Bit.hpp:20