Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
BitWriter.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "CoreTypes.h"
7#include "Math/UnrealMathUtility.h"
8#include "Misc/AssertionMacros.h"
9#include "Misc/Build.h"
10#include "Serialization/BitArchive.h"
11
12class FArchive;
13
14/*-----------------------------------------------------------------------------
15 FBitWriter.
16-----------------------------------------------------------------------------*/
17
18//
19// Writes bitstreams.
20//
21struct FBitWriter : public FBitArchive
22{
23 friend struct FBitWriterMark;
24
25public:
26 /** Default constructor. Zeros everything. */
28
29 /**
30 * Constructor using known size the buffer needs to be
31 */
32 FBitWriter( int64 InMaxBits, bool AllowResize = false );
33
34 FBitWriter(const FBitWriter&) = default;
35 FBitWriter& operator=(const FBitWriter&) = default;
36 FBitWriter(FBitWriter&&) = default;
38
39 virtual void SerializeBits( void* Src, int64 LengthBits ) override;
40
41 virtual void SerializeBitsWithOffset( void* Src, int32 SourceBit, int64 LengthBits ) override;
42
43 /**
44 * Serializes a compressed integer - Value must be < Max
45 *
46 * @param Value The value to serialize, must be < Max
47 * @param Max The maximum allowed value - good to aim for power-of-two
48 */
49 virtual void SerializeInt(uint32& Value, uint32 Max) override;
50
51 virtual void SerializeIntPacked(uint32& Value) override;
52
53 /**
54 * Serializes the specified Value, but does not bounds check against ValueMax;
55 * instead, it will wrap around if the value exceeds ValueMax (this differs from SerializeInt, which clamps)
56 *
57 * @param Value The value to serialize
58 * @param ValueMax The maximum value to write; wraps Value if it exceeds this
59 */
60 void WriteIntWrapped(uint32 Value, uint32 ValueMax);
61
62 void WriteBit( uint8 In );
63 virtual void Serialize( void* Src, int64 LengthBytes ) override;
64
65 /**
66 * Returns a pointer to our internal buffer.
67 */
68 FORCEINLINE uint8* GetData(void)
69 {
71 // If this happens, your code has insufficient IsError() checks.
72 check(!IsError());
73#endif
74
75 return Buffer.GetData();
76 }
77
78 FORCEINLINE const uint8* GetData(void) const
79 {
81 // If this happens, your code has insufficient IsError() checks.
82 check(!IsError());
83#endif
84
85 return Buffer.GetData();
86 }
87
88 FORCEINLINE const TArray<uint8>* GetBuffer(void) const
89 {
91 // If this happens, your code has insufficient IsError() checks.
92 check(!IsError());
93#endif
94
95 return &Buffer;
96 }
97
98 /**
99 * Returns the number of bytes written.
100 */
101 FORCEINLINE int64 GetNumBytes(void) const
102 {
103 return (Num+7)>>3;
104 }
105
106 /**
107 * Returns the number of bits written.
108 */
109 FORCEINLINE int64 GetNumBits(void) const
110 {
111 return Num;
112 }
113
114 /**
115 * Returns the number of bits the buffer supports.
116 */
117 FORCEINLINE int64 GetMaxBits(void) const
118 {
119 return Max;
120 }
121
122 /**
123 * Marks this bit writer as overflowed.
124 *
125 * @param LengthBits The number of bits being written at the time of overflow
126 */
127 void SetOverflowed(int32 LengthBits);
128
129 /**
130 * Sets whether or not this writer intentionally allows overflows (to avoid logspam)
131 */
132 FORCEINLINE void SetAllowOverflow(bool bInAllow)
133 {
134 bAllowOverflow = bInAllow;
135 }
136
137 FORCEINLINE bool AllowAppend(int64 LengthBits)
138 {
139 //@TODO: FLOATPRECISION: This class pretends it is 64-bit aware, e.g., in the type of LengthBits and the Num/Max members, but it is not as the inner Buffer is a 32 bit TArray, etc...
140
141 if (Num+LengthBits > Max)
142 {
143 if (bAllowResize)
144 {
145 // Resize our buffer. The common case for resizing bitwriters is hitting the max and continuing to add a lot of small segments of data
146 // Though we could just allow the TArray buffer to handle the slack and resizing, we would still constantly hit the FBitWriter's max
147 // and cause this block to be executed, as well as constantly zeroing out memory inside AddZeroes (though the memory would be allocated
148 // in chunks).
149
150 Max = FMath::Max<int64>(Max<<1,Num+LengthBits);
151 int64 ByteMax = (Max+7)>>3;
152 Buffer.AddZeroed((int32)(ByteMax - Buffer.Num()));
153 check((Max+7)>>3== Buffer.Num());
154 return true;
155 }
156 else
157 {
158 return false;
159 }
160 }
161 return true;
162 }
163
164 FORCEINLINE void SetAllowResize(bool NewResize)
165 {
166 bAllowResize = NewResize;
167 }
168
169 /**
170 * Resets the bit writer back to its initial state
171 */
172 void Reset() override;
173
175 {
176 Num = ( Num + 7 ) & ( ~0x07 );
177 }
178
179 /** Counts the in-memory bytes used by this object */
180 virtual void CountMemory(FArchive& Ar) const;
181
182private:
184 int64 Num;
185 int64 Max;
187
188 /** Whether or not overflowing is allowed (overflows silently) */
190};
191
192
193//
194// For pushing and popping FBitWriter positions.
195//
197{
198public:
199
201 : Overflowed(false)
202 , Num(0)
203 { }
204
206 {
207 Init(Writer);
208 }
209
211 {
212 return Num;
213 }
214
216 {
217 Num = Writer.Num;
218 Overflowed = Writer.IsError();
219 }
220
221 void Reset()
222 {
223 Overflowed = false;
224 Num = 0;
225 }
226
227 void Pop( FBitWriter& Writer );
228 void Copy( FBitWriter& Writer, TArray<uint8> &Buffer );
229
230 /** Pops the BitWriter back to the start but doesn't clear what was written. */
232 {
233 Writer.Num = Num;
234 }
235
236private:
237
239 int64 Num;
240};
#define check(expr)
#define UE_BUILD_SHIPPING
Definition Build.h:4
#define FORCEINLINE_DEBUGGABLE
#define FORCEINLINE
Definition Platform.h:644
FORCEINLINE bool IsError() const
Definition Archive.h:337
virtual void CountMemory(FArchive &Ar) const
FORCEINLINE uint8 * GetData(void)
Definition BitWriter.h:68
FORCEINLINE const TArray< uint8 > * GetBuffer(void) const
Definition BitWriter.h:88
TArray< uint8 > Buffer
Definition BitWriter.h:183
int64 Max
Definition BitWriter.h:185
FBitWriter(const FBitWriter &)=default
virtual void SerializeBitsWithOffset(void *Src, int32 SourceBit, int64 LengthBits) override
virtual void SerializeIntPacked(uint32 &Value) override
int64 Num
Definition BitWriter.h:184
void WriteBit(uint8 In)
FORCEINLINE int64 GetNumBits(void) const
Definition BitWriter.h:109
FORCEINLINE bool AllowAppend(int64 LengthBits)
Definition BitWriter.h:137
FORCEINLINE int64 GetNumBytes(void) const
Definition BitWriter.h:101
virtual void Serialize(void *Src, int64 LengthBytes) override
void SetOverflowed(int32 LengthBits)
FORCEINLINE void SetAllowResize(bool NewResize)
Definition BitWriter.h:164
FBitWriter(FBitWriter &&)=default
FBitWriter(int64 InMaxBits, bool AllowResize=false)
FORCEINLINE void WriteAlign()
Definition BitWriter.h:174
bool bAllowOverflow
Definition BitWriter.h:189
void Reset() override
FORCEINLINE const uint8 * GetData(void) const
Definition BitWriter.h:78
FBitWriter & operator=(FBitWriter &&)=default
FBitWriter(void)
FBitWriter & operator=(const FBitWriter &)=default
virtual void SerializeBits(void *Src, int64 LengthBits) override
void WriteIntWrapped(uint32 Value, uint32 ValueMax)
bool bAllowResize
Definition BitWriter.h:186
FORCEINLINE int64 GetMaxBits(void) const
Definition BitWriter.h:117
virtual void SerializeInt(uint32 &Value, uint32 Max) override
FORCEINLINE void SetAllowOverflow(bool bInAllow)
Definition BitWriter.h:132
FORCEINLINE_DEBUGGABLE void PopWithoutClear(FBitWriter &Writer)
Definition BitWriter.h:231
FORCEINLINE_DEBUGGABLE void Init(FBitWriter &Writer)
Definition BitWriter.h:215
FBitWriterMark(FBitWriter &Writer)
Definition BitWriter.h:205
void Copy(FBitWriter &Writer, TArray< uint8 > &Buffer)
void Pop(FBitWriter &Writer)
FORCEINLINE_DEBUGGABLE int64 GetNumBits() const
Definition BitWriter.h:210