UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
BitReader.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 "HAL/UnrealMemory.h"
10
11class FArchive;
12
13CORE_API void appBitsCpy( uint8* Dest, int32 DestBit, uint8* Src, int32 SrcBit, int32 BitCount );
14
15/*-----------------------------------------------------------------------------
16 FBitReader.
17-----------------------------------------------------------------------------*/
18
19//@TODO: FLOATPRECISION: Public API assumes it can have > 2 GB of bits, but internally uses int32 based TArray for bytes and also has uint32 clamping on bit counts in various places
20
21//
22// Reads bitstreams.
23//
24struct FBitReader : public FBitArchive
25{
26 friend struct FBitReaderMark;
27
28public:
29 CORE_API FBitReader( const uint8* Src = nullptr, int64 CountBits = 0 );
31
36
37 CORE_API void SetData( FBitReader& Src, int64 CountBits );
38 CORE_API void SetData( uint8* Src, int64 CountBits );
39 CORE_API void SetData( TArray<uint8>&& Src, int64 CountBits );
40
43
44// Disable false positive buffer overrun warning during pgoprofile linking step
46 inline void SerializeBits( void* Dest, int64 LengthBits )
47 {
48 //@TODO: FLOATPRECISION: This function/class pretends it is 64-bit aware, e.g., in the type of LengthBits and the Pos member, but it is not as appBitsCpy is only 32 bits, the inner Buffer is a 32 bit TArray, etc...
49 if ( IsError() || Pos+LengthBits > Num)
50 {
51 if (!IsError())
52 {
54 //UE_LOG( LogNetSerialization, Error, TEXT( "FBitReader::SerializeBits: Pos + LengthBits > Num" ) );
55 }
56 FMemory::Memzero( Dest, (LengthBits+7)>>3 );
57 return;
58 }
59 //for( int32 i=0; i<LengthBits; i++,Pos++ )
60 // if( Buffer(Pos>>3) & GShift[Pos&7] )
61 // ((uint8*)Dest)[i>>3] |= GShift[i&7];
62 if( LengthBits == 1 )
63 {
64 ((uint8*)Dest)[0] = 0;
65 if( Buffer[(int32)(Pos>>3)] & Shift(Pos&7) )
66 ((uint8*)Dest)[0] |= 0x01;
67 Pos++;
68 }
69 else if (LengthBits != 0)
70 {
71 ((uint8*)Dest)[((LengthBits+7)>>3) - 1] = 0;
73 Pos += LengthBits;
74 }
75 }
77
78 CORE_API virtual void SerializeBitsWithOffset( void* Dest, int32 DestBit, int64 LengthBits ) override;
79
80 // OutValue < ValueMax
81 inline void SerializeInt(uint32& OutValue, uint32 ValueMax)
82 {
83 if (!IsError())
84 {
85 // Use local variable to avoid Load-Hit-Store
86 uint32 Value = 0;
88 const int64 LocalNum = Num;
89
90 for (uint32 Mask=1; (Value + Mask) < ValueMax && Mask; Mask *= 2, LocalPos++)
91 {
92 if (LocalPos >= LocalNum)
93 {
95 break;
96 }
97
98 if (Buffer[(int32)(LocalPos >> 3)] & Shift(LocalPos & 7))
99 {
100 Value |= Mask;
101 }
102 }
103
104 // Now write back
105 Pos = LocalPos;
106 OutValue = Value;
107 }
108 }
109
110 CORE_API virtual void SerializeIntPacked(uint32& Value) override;
111
113 {
114 uint32 Value = 0;
115
117
118 return Value;
119 }
120
121 inline uint8 ReadBit()
122 {
123 uint8 Bit=0;
124 //SerializeBits( &Bit, 1 );
125 if ( !IsError() )
126 {
128 const int64 LocalNum = Num;
129 if (LocalPos >= LocalNum)
130 {
131 SetOverflowed(1);
132 //UE_LOG( LogNetSerialization, Error, TEXT( "FBitReader::SerializeInt: LocalPos >= LocalNum" ) );
133 }
134 else
135 {
136 Bit = !!(Buffer[(int32)(LocalPos>>3)] & Shift(LocalPos&7));
137 Pos++;
138 }
139 }
140 return Bit;
141 }
142
144 {
145 SerializeBits( Dest, LengthBytes*8 );
146 }
147
149 {
150 return Buffer.GetData();
151 }
152
154 {
155 return Buffer.GetData();
156 }
157
159 {
160 return Buffer;
161 }
162
164 {
165 check(Pos % 8 == 0);
166 return &Buffer[(int32)(Pos >> 3)];
167 }
168
170 {
171 return ((Num - Pos) + 7) >> 3;
172 }
174 {
175 return (Num - Pos);
176 }
178 {
179 return IsError() || Pos>=Num;
180 }
182 {
183 return (Num+7)>>3;
184 }
186 {
187 return Num;
188 }
190 {
191 return Pos;
192 }
193 inline void EatByteAlign()
194 {
195 int64 PrePos = Pos;
196
197 // Skip over remaining bits in current byte
198 Pos = (Pos+7) & (~0x07);
199
200 if ( Pos > Num )
201 {
202 //UE_LOG( LogNetSerialization, Error, TEXT( "FBitReader::EatByteAlign: Pos > Num" ) );
204 }
205 }
206 inline void Skip(int32 BitCount)
207 {
208 if (Pos + BitCount > Num)
209 {
211 }
212 else
213 {
214 Pos += BitCount;
215 }
216 }
217
224
226 void SetAtEnd() { Pos = Num; }
227
231
233 CORE_API virtual void CountMemory(FArchive& Ar) const;
234
235protected:
236
240
243
244private:
245
247 {
248 return (uint8)(1<<Cnt);
249 }
250
251};
252
253
254//
255// For pushing and popping FBitWriter positions.
256//
258{
259public:
260
262 : Pos(0)
263 { }
264
266 : Pos(Reader.Pos)
267 { }
268
270 {
271 return Pos;
272 }
273
275 {
276 Reader.Pos = Pos;
277 }
278
279 CORE_API void Copy( FBitReader& Reader, TArray<uint8> &Buffer );
280
281private:
282
283 int64 Pos;
284};
#define check(expr)
Definition AssertionMacros.h:314
CORE_API void appBitsCpy(uint8 *Dest, int32 DestBit, uint8 *Src, int32 SrcBit, int32 BitCount)
Definition BitReader.cpp:39
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define PGO_LINK_DISABLE_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:71
#define PGO_LINK_ENABLE_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:75
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
UE_FORCEINLINE_HINT bool IsError() const
Definition Archive.h:362
Definition BitArchive.h:13
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT ElementType * GetData() UE_LIFETIMEBOUND
Definition Array.h:1027
Definition BitReader.h:258
FBitReaderMark()
Definition BitReader.h:261
UE_FORCEINLINE_HINT int64 GetPos() const
Definition BitReader.h:269
UE_FORCEINLINE_HINT void Pop(FBitReader &Reader)
Definition BitReader.h:274
FBitReaderMark(FBitReader &Reader)
Definition BitReader.h:265
Definition BitReader.h:25
UE_FORCEINLINE_HINT int64 GetPosBits() const
Definition BitReader.h:189
CORE_API void ResetData(FBitReader &Src, int64 CountBits, int64 CountBitsWithSlack=0)
Definition BitReader.cpp:220
void Skip(int32 BitCount)
Definition BitReader.h:206
uint32 ReadInt(uint32 Max)
Definition BitReader.h:112
uint8 ReadBit()
Definition BitReader.h:121
int64 Pos
Definition BitReader.h:239
UE_FORCEINLINE_HINT int64 GetNumBytes() const
Definition BitReader.h:181
void SerializeInt(uint32 &OutValue, uint32 ValueMax)
Definition BitReader.h:81
CORE_API FBitReader & operator=(const FBitReader &)
UE_FORCEINLINE_HINT int64 GetBitsLeft() const
Definition BitReader.h:173
PGO_LINK_DISABLE_WARNINGS void SerializeBits(void *Dest, int64 LengthBits)
Definition BitReader.h:46
void EatByteAlign()
Definition BitReader.h:193
CORE_API void SetData(FBitReader &Src, int64 CountBits)
Definition BitReader.cpp:206
void SetAtEnd()
Definition BitReader.h:226
CORE_API FBitReader(const FBitReader &)
CORE_API void SetNetVersionsFromArchive(FArchive &Source)
Definition BitReader.cpp:354
virtual CORE_API void SerializeIntPacked(uint32 &Value) override
Definition BitReader.cpp:313
UE_FORCEINLINE_HINT const TArray< uint8 > & GetBuffer() const
Definition BitReader.h:158
UE_FORCEINLINE_HINT bool AtEnd()
Definition BitReader.h:177
CORE_API void AppendTo(TArray< uint8 > &Buffer)
Definition BitReader.cpp:260
int64 Num
Definition BitReader.h:238
UE_FORCEINLINE_HINT int64 GetBytesLeft() const
Definition BitReader.h:169
UE_FORCEINLINE_HINT int64 GetNumBits() const
Definition BitReader.h:185
CORE_API ~FBitReader()
UE_FORCEINLINE_HINT void Serialize(void *Dest, int64 LengthBytes)
Definition BitReader.h:143
UE_FORCEINLINE_HINT uint8 * GetData()
Definition BitReader.h:148
CORE_API FBitReader(FBitReader &&)
uint8 * GetDataPosChecked()
Definition BitReader.h:163
UE_FORCEINLINE_HINT const uint8 * GetData() const
Definition BitReader.h:153
CORE_API FBitReader & operator=(FBitReader &&)
TArray< uint8 > Buffer
Definition BitReader.h:237
CORE_API void SetOverflowed(int64 LengthBits)
Definition BitReader.cpp:271
PGO_LINK_ENABLE_WARNINGS virtual CORE_API void SerializeBitsWithOffset(void *Dest, int32 DestBit, int64 LengthBits) override
Definition BitReader.cpp:294
CORE_API void AppendDataFromChecked(FBitReader &Src)
Definition BitReader.cpp:237
virtual CORE_API void CountMemory(FArchive &Ar) const
Definition BitReader.cpp:265
static UE_FORCEINLINE_HINT void * Memzero(void *Dest, SIZE_T Count)
Definition UnrealMemory.h:131