Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/libANGLE/BinaryStream.h
1693 views
1
//
2
// Copyright 2012 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
// BinaryStream.h: Provides binary serialization of simple types.
8
9
#ifndef LIBANGLE_BINARYSTREAM_H_
10
#define LIBANGLE_BINARYSTREAM_H_
11
12
#include <stdint.h>
13
#include <cstddef>
14
#include <string>
15
#include <vector>
16
17
#include "common/angleutils.h"
18
#include "common/mathutil.h"
19
20
namespace gl
21
{
22
template <typename IntT>
23
struct PromotedIntegerType
24
{
25
using type = typename std::conditional<
26
std::is_signed<IntT>::value,
27
typename std::conditional<sizeof(IntT) <= 4, int32_t, int64_t>::type,
28
typename std::conditional<sizeof(IntT) <= 4, uint32_t, uint64_t>::type>::type;
29
};
30
31
class BinaryInputStream : angle::NonCopyable
32
{
33
public:
34
BinaryInputStream(const void *data, size_t length)
35
{
36
mError = false;
37
mOffset = 0;
38
mData = static_cast<const uint8_t *>(data);
39
mLength = length;
40
}
41
42
// readInt will generate an error for bool types
43
template <class IntT>
44
IntT readInt()
45
{
46
static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use readBool");
47
using PromotedIntT = typename PromotedIntegerType<IntT>::type;
48
PromotedIntT value = 0;
49
read(&value);
50
ASSERT(angle::IsValueInRangeForNumericType<IntT>(value));
51
return static_cast<IntT>(value);
52
}
53
54
template <class IntT>
55
void readInt(IntT *outValue)
56
{
57
*outValue = readInt<IntT>();
58
}
59
60
template <class IntT, class VectorElementT>
61
void readIntVector(std::vector<VectorElementT> *param)
62
{
63
size_t size = readInt<size_t>();
64
for (size_t index = 0; index < size; ++index)
65
{
66
param->push_back(readInt<IntT>());
67
}
68
}
69
70
template <class EnumT>
71
EnumT readEnum()
72
{
73
using UnderlyingType = typename std::underlying_type<EnumT>::type;
74
return static_cast<EnumT>(readInt<UnderlyingType>());
75
}
76
77
template <class EnumT>
78
void readEnum(EnumT *outValue)
79
{
80
*outValue = readEnum<EnumT>();
81
}
82
83
bool readBool()
84
{
85
int value = 0;
86
read(&value);
87
return (value > 0);
88
}
89
90
void readBool(bool *outValue) { *outValue = readBool(); }
91
92
void readBytes(unsigned char outArray[], size_t count) { read<unsigned char>(outArray, count); }
93
94
std::string readString()
95
{
96
std::string outString;
97
readString(&outString);
98
return outString;
99
}
100
101
void readString(std::string *v)
102
{
103
size_t length;
104
readInt(&length);
105
106
if (mError)
107
{
108
return;
109
}
110
111
angle::CheckedNumeric<size_t> checkedOffset(mOffset);
112
checkedOffset += length;
113
114
if (!checkedOffset.IsValid() || mOffset + length > mLength)
115
{
116
mError = true;
117
return;
118
}
119
120
v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
121
mOffset = checkedOffset.ValueOrDie();
122
}
123
124
float readFloat()
125
{
126
float f;
127
read(&f, 1);
128
return f;
129
}
130
131
void skip(size_t length)
132
{
133
angle::CheckedNumeric<size_t> checkedOffset(mOffset);
134
checkedOffset += length;
135
136
if (!checkedOffset.IsValid() || mOffset + length > mLength)
137
{
138
mError = true;
139
return;
140
}
141
142
mOffset = checkedOffset.ValueOrDie();
143
}
144
145
size_t offset() const { return mOffset; }
146
size_t remainingSize() const
147
{
148
ASSERT(mLength >= mOffset);
149
return mLength - mOffset;
150
}
151
152
bool error() const { return mError; }
153
154
bool endOfStream() const { return mOffset == mLength; }
155
156
const uint8_t *data() { return mData; }
157
158
private:
159
bool mError;
160
size_t mOffset;
161
const uint8_t *mData;
162
size_t mLength;
163
164
template <typename T>
165
void read(T *v, size_t num)
166
{
167
static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
168
169
angle::CheckedNumeric<size_t> checkedLength(num);
170
checkedLength *= sizeof(T);
171
if (!checkedLength.IsValid())
172
{
173
mError = true;
174
return;
175
}
176
177
angle::CheckedNumeric<size_t> checkedOffset(mOffset);
178
checkedOffset += checkedLength;
179
180
if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength)
181
{
182
mError = true;
183
return;
184
}
185
186
memcpy(v, mData + mOffset, checkedLength.ValueOrDie());
187
mOffset = checkedOffset.ValueOrDie();
188
}
189
190
template <typename T>
191
void read(T *v)
192
{
193
read(v, 1);
194
}
195
};
196
197
class BinaryOutputStream : angle::NonCopyable
198
{
199
public:
200
BinaryOutputStream();
201
~BinaryOutputStream();
202
203
// writeInt also handles bool types
204
template <class IntT>
205
void writeInt(IntT param)
206
{
207
static_assert(std::is_integral<IntT>::value, "Not an integral type");
208
static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use writeBool");
209
using PromotedIntT = typename PromotedIntegerType<IntT>::type;
210
ASSERT(angle::IsValueInRangeForNumericType<PromotedIntT>(param));
211
PromotedIntT intValue = static_cast<PromotedIntT>(param);
212
write(&intValue, 1);
213
}
214
215
// Specialized writeInt for values that can also be exactly -1.
216
template <class UintT>
217
void writeIntOrNegOne(UintT param)
218
{
219
if (param == static_cast<UintT>(-1))
220
{
221
writeInt(-1);
222
}
223
else
224
{
225
writeInt(param);
226
}
227
}
228
229
template <class IntT>
230
void writeIntVector(const std::vector<IntT> &param)
231
{
232
writeInt(param.size());
233
for (IntT element : param)
234
{
235
writeIntOrNegOne(element);
236
}
237
}
238
239
template <class EnumT>
240
void writeEnum(EnumT param)
241
{
242
using UnderlyingType = typename std::underlying_type<EnumT>::type;
243
writeInt<UnderlyingType>(static_cast<UnderlyingType>(param));
244
}
245
246
void writeString(const std::string &v)
247
{
248
writeInt(v.length());
249
write(v.c_str(), v.length());
250
}
251
252
void writeBytes(const unsigned char *bytes, size_t count) { write(bytes, count); }
253
254
void writeBool(bool value)
255
{
256
int intValue = value ? 1 : 0;
257
write(&intValue, 1);
258
}
259
260
void writeFloat(float value) { write(&value, 1); }
261
262
size_t length() const { return mData.size(); }
263
264
const void *data() const { return mData.size() ? &mData[0] : nullptr; }
265
266
const std::vector<uint8_t> &getData() const { return mData; }
267
268
private:
269
template <typename T>
270
void write(const T *v, size_t num)
271
{
272
static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
273
const char *asBytes = reinterpret_cast<const char *>(v);
274
mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
275
}
276
277
std::vector<uint8_t> mData;
278
};
279
280
inline BinaryOutputStream::BinaryOutputStream() {}
281
282
inline BinaryOutputStream::~BinaryOutputStream() = default;
283
284
} // namespace gl
285
286
#endif // LIBANGLE_BINARYSTREAM_H_
287
288