Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
CompactBinaryValue.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/StringView.h"
6#include "HAL/PlatformMemory.h"
7#include "IO/IoHash.h"
8#include "Memory/MemoryView.h"
9#include "Misc/ByteSwap.h"
10#include "Misc/Guid.h"
11#include "Serialization/CompactBinary.h"
12#include "Serialization/VarInt.h"
13
14/**
15 * A type that provides unchecked access to compact binary values.
16 *
17 * The main purpose of the type is to efficiently switch on field type. For every other use case,
18 * prefer to use the field, array, and object types directly. The accessors here do not check the
19 * type before reading the value, which means they can read out of bounds even on a valid compact
20 * binary value if the wrong accessor is used.
21 */
23{
24public:
25 FCbValue(ECbFieldType Type, const void* Value);
26
29
30 FMemoryView AsBinary() const;
31 /** Access as a string. Checks for range errors and uses the default if OutError is not null. */
32 FUtf8StringView AsString(ECbFieldError* OutError = nullptr, FUtf8StringView Default = FUtf8StringView()) const;
33
34 /**
35 * Access as an integer, with both positive and negative values returned as unsigned.
36 *
37 * Checks for range errors and uses the default if OutError is not null.
38 */
39 uint64 AsInteger(UE::CompactBinary::Private::FIntegerParams Params, ECbFieldError* OutError = nullptr, uint64 Default = 0) const;
40
41 uint64 AsIntegerPositive() const;
42 int64 AsIntegerNegative() const;
43
44 float AsFloat32() const;
45 double AsFloat64() const;
46
47 bool AsBool() const;
48
49 FORCEINLINE FIoHash AsObjectAttachment() const { return AsHash(); }
50 FORCEINLINE FIoHash AsBinaryAttachment() const { return AsHash(); }
51 FORCEINLINE FIoHash AsAttachment() const { return AsHash(); }
52
53 FIoHash AsHash() const;
54 FGuid AsUuid() const;
55
56 int64 AsDateTimeTicks() const;
57 int64 AsTimeSpanTicks() const;
58
59 FCbObjectId AsObjectId() const;
60
63
65 FORCEINLINE const void* GetData() const { return Data; }
66
67private:
68 const void* Data;
70};
71
74 , Value(InValue.GetData())
75{
76}
77
79{
81}
82
83FORCEINLINE FCbValue::FCbValue(ECbFieldType InType, const void* InValue)
84 : Data(InValue)
85 , Type(InType)
86{
87}
88
90{
91 return FCbObjectView(*this);
92}
93
95{
96 return FCbArrayView(*this);
97}
98
100{
101 const uint8* const Bytes = static_cast<const uint8*>(Data);
102 uint32 ValueSizeByteCount;
103 const uint64 ValueSize = ReadVarUInt(Bytes, ValueSizeByteCount);
104 return MakeMemoryView(Bytes + ValueSizeByteCount, ValueSize);
105}
106
107FORCEINLINE FUtf8StringView FCbValue::AsString(ECbFieldError* OutError, FUtf8StringView Default) const
108{
109 const UTF8CHAR* const Chars = static_cast<const UTF8CHAR*>(Data);
110 uint32 ValueSizeByteCount;
111 const uint64 ValueSize = ReadVarUInt(Chars, ValueSizeByteCount);
112
113 if (OutError)
114 {
115 if (ValueSize >= (uint64(1) << 31))
116 {
117 *OutError = ECbFieldError::RangeError;
118 return Default;
119 }
120 *OutError = ECbFieldError::None;
121 }
122
123 return FUtf8StringView(Chars + ValueSizeByteCount, int32(ValueSize));
124}
125
126FORCEINLINE uint64 FCbValue::AsInteger(UE::CompactBinary::Private::FIntegerParams Params, ECbFieldError* OutError, uint64 Default) const
127{
128 // A shift of a 64-bit value by 64 is undefined so shift by one less because magnitude is never zero.
129 const uint64 OutOfRangeMask = uint64(-2) << (Params.MagnitudeBits - 1);
130 const uint64 IsNegative = uint8(Type) & 1;
131
132 uint32 MagnitudeByteCount;
133 const uint64 Magnitude = ReadVarUInt(Data, MagnitudeByteCount);
134 const uint64 Value = Magnitude ^ -int64(IsNegative);
135
136 if (OutError)
137 {
138 const uint64 IsInRange = (!(Magnitude & OutOfRangeMask)) & ((!IsNegative) | Params.IsSigned);
139 *OutError = IsInRange ? ECbFieldError::None : ECbFieldError::RangeError;
140
141 const uint64 UseValueMask = -int64(IsInRange);
142 return (Value & UseValueMask) | (Default & ~UseValueMask);
143 }
144
145 return Value;
146}
147
149{
150 uint32 MagnitudeByteCount;
151 return ReadVarUInt(Data, MagnitudeByteCount);
152}
153
155{
156 uint32 MagnitudeByteCount;
157 return int64(ReadVarUInt(Data, MagnitudeByteCount)) ^ -int64(1);
158}
159
161{
162 const uint32 Value = NETWORK_ORDER32(FPlatformMemory::ReadUnaligned<uint32>(Data));
163 return reinterpret_cast<const float&>(Value);
164}
165
167{
168 const uint64 Value = NETWORK_ORDER64(FPlatformMemory::ReadUnaligned<uint64>(Data));
169 return reinterpret_cast<const double&>(Value);
170}
171
173{
174 return uint8(Type) & 1;
175}
176
178{
179 return FIoHash(*static_cast<const FIoHash::ByteArray*>(Data));
180}
181
183{
184 FGuid Value = FPlatformMemory::ReadUnaligned<FGuid>(Data);
185 Value.A = NETWORK_ORDER32(Value.A);
186 Value.B = NETWORK_ORDER32(Value.B);
187 Value.C = NETWORK_ORDER32(Value.C);
188 Value.D = NETWORK_ORDER32(Value.D);
189 return Value;
190}
191
193{
194 return NETWORK_ORDER64(FPlatformMemory::ReadUnaligned<int64>(Data));
195}
196
198{
199 return NETWORK_ORDER64(FPlatformMemory::ReadUnaligned<int64>(Data));
200}
201
203{
204 return FCbObjectId(MakeMemoryView(Data, sizeof(FCbObjectId)));
205}
206
208{
209 const uint8* Bytes = static_cast<const uint8*>(Data);
210 uint32 DataSizeByteCount;
211 const uint64 DataSize = ReadVarUInt(Bytes, DataSizeByteCount);
212 Bytes += DataSizeByteCount;
213
214 FCbCustomById Value;
215 uint32 TypeIdByteCount;
216 Value.Id = ReadVarUInt(Bytes, TypeIdByteCount);
217 Value.Data = MakeMemoryView(Bytes + TypeIdByteCount, DataSize - TypeIdByteCount);
218 return Value;
219}
220
222{
223 const uint8* Bytes = static_cast<const uint8*>(Data);
224 uint32 DataSizeByteCount;
225 const uint64 DataSize = ReadVarUInt(Bytes, DataSizeByteCount);
226 Bytes += DataSizeByteCount;
227
228 uint32 TypeNameLenByteCount;
229 const uint64 TypeNameLen = ReadVarUInt(Bytes, TypeNameLenByteCount);
230 Bytes += TypeNameLenByteCount;
231
232 FCbCustomByName Value;
233 Value.Name = FUtf8StringView(
234 reinterpret_cast<const UTF8CHAR*>(Bytes),
235 static_cast<int32>(TypeNameLen));
236 Value.Data = MakeMemoryView(Bytes + TypeNameLen, DataSize - TypeNameLen - TypeNameLenByteCount);
237 return Value;
238}
#define NETWORK_ORDER32(x)
Definition ByteSwap.h:145
#define NETWORK_ORDER64(x)
Definition ByteSwap.h:147
ECbFieldError
ECbFieldType
#define FORCEINLINE
Definition Platform.h:644
FORCEINLINE uint64 ReadVarUInt(const void *InData, uint32 &OutByteCount)
Definition VarInt.h:103
FWindowsPlatformMemory FPlatformMemory
static constexpr ECbFieldType GetType(ECbFieldType Type)
ECbFieldType TypeWithFlags
FCbValue GetValue() const
const void * Value
FCbFieldView(const FCbValue &Value)
FORCEINLINE FIoHash AsBinaryAttachment() const
bool AsBool() const
FCbCustomById AsCustomById() const
double AsFloat64() const
ECbFieldType Type
int64 AsTimeSpanTicks() const
FIoHash AsHash() const
FCbObjectId AsObjectId() const
int64 AsDateTimeTicks() const
float AsFloat32() const
const void * Data
uint64 AsIntegerPositive() const
FORCEINLINE const void * GetData() const
int64 AsIntegerNegative() const
FUtf8StringView AsString(ECbFieldError *OutError=nullptr, FUtf8StringView Default=FUtf8StringView()) const
FORCEINLINE ECbFieldType GetType() const
FMemoryView AsBinary() const
FORCEINLINE FIoHash AsObjectAttachment() const
FGuid AsUuid() const
uint64 AsInteger(UE::CompactBinary::Private::FIntegerParams Params, ECbFieldError *OutError=nullptr, uint64 Default=0) const
FCbCustomByName AsCustomByName() const
FCbValue(ECbFieldType Type, const void *Value)
FCbObjectView AsObjectView() const
FORCEINLINE FIoHash AsAttachment() const
FCbArrayView AsArrayView() const
Definition Vector.h:40
Definition Guid.h:108
uint32 D
Definition Guid.h:398
uint32 C
Definition Guid.h:395
uint32 A
Definition Guid.h:389
uint32 B
Definition Guid.h:392