UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
VarInt.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "HAL/PlatformMath.h"
7
8// Variable-Length Integer Encoding
9//
10// ZigZag encoding is used to convert signed integers into unsigned integers in a way that allows
11// integers with a small magnitude to have a smaller encoded representation.
12//
13// An unsigned integer is encoded into 1-9 bytes based on its magnitude. The first byte indicates
14// how many additional bytes are used by the number of leading 1-bits that it has. The additional
15// bytes are stored in big endian order, and the most significant bits of the value are stored in
16// the remaining bits in the first byte. The encoding of the first byte allows the reader to skip
17// over the encoded integer without consuming its bytes individually.
18//
19// Encoded unsigned integers sort the same in a byte-wise comparison as when their decoded values
20// are compared. The same property does not hold for signed integers due to ZigZag encoding.
21//
22// 32-bit inputs encode to 1-5 bytes.
23// 64-bit inputs encode to 1-9 bytes.
24//
25// 0x0000'0000'0000'0000 - 0x0000'0000'0000'007f : 0b0_______ 1 byte
26// 0x0000'0000'0000'0080 - 0x0000'0000'0000'3fff : 0b10______ 2 bytes
27// 0x0000'0000'0000'4000 - 0x0000'0000'001f'ffff : 0b110_____ 3 bytes
28// 0x0000'0000'0020'0000 - 0x0000'0000'0fff'ffff : 0b1110____ 4 bytes
29// 0x0000'0000'1000'0000 - 0x0000'0007'ffff'ffff : 0b11110___ 5 bytes
30// 0x0000'0008'0000'0000 - 0x0000'03ff'ffff'ffff : 0b111110__ 6 bytes
31// 0x0000'0400'0000'0000 - 0x0001'ffff'ffff'ffff : 0b1111110_ 7 bytes
32// 0x0002'0000'0000'0000 - 0x00ff'ffff'ffff'ffff : 0b11111110 8 bytes
33// 0x0100'0000'0000'0000 - 0xffff'ffff'ffff'ffff : 0b11111111 9 bytes
34//
35// Encoding Examples
36// -42 => ZigZag => 0x53 => 0x53
37// 42 => ZigZag => 0x54 => 0x54
38// 0x1 => 0x01
39// 0x12 => 0x12
40// 0x123 => 0x81 0x23
41// 0x1234 => 0x92 0x34
42// 0x12345 => 0xc1 0x23 0x45
43// 0x123456 => 0xd2 0x34 0x56
44// 0x1234567 => 0xe1 0x23 0x45 0x67
45// 0x12345678 => 0xf0 0x12 0x34 0x56 0x78
46// 0x123456789 => 0xf1 0x23 0x45 0x67 0x89
47// 0x123456789a => 0xf8 0x12 0x34 0x56 0x78 0x9a
48// 0x123456789ab => 0xfb 0x23 0x45 0x67 0x89 0xab
49// 0x123456789abc => 0xfc 0x12 0x34 0x56 0x78 0x9a 0xbc
50// 0x123456789abcd => 0xfd 0x23 0x45 0x67 0x89 0xab 0xcd
51// 0x123456789abcde => 0xfe 0x12 0x34 0x56 0x78 0x9a 0xbc 0xde
52// 0x123456789abcdef => 0xff 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef
53// 0x123456789abcdef0 => 0xff 0x12 0x34 0x56 0x78 0x9a 0xbc 0xde 0xf0
54
62{
63 return FPlatformMath::CountLeadingZeros(uint8(~*static_cast<const uint8*>(InData))) - 23;
64}
65
71
74{
75 return uint32(int32(FPlatformMath::FloorLog2(InValue)) / 7 + 1);
76}
77
80{
81 return uint32(FPlatformMath::Min(int32(FPlatformMath::FloorLog2_64(InValue)) / 7 + 1, 9));
82}
83
89
95
104{
105 const uint32 ByteCount = MeasureVarUInt(InData);
106 OutByteCount = ByteCount;
107
108 const uint8* InBytes = static_cast<const uint8*>(InData);
109 uint64 Value = *InBytes++ & uint8(0xff >> ByteCount);
110 switch (ByteCount - 1)
111 {
112 case 8: Value <<= 8; Value |= *InBytes++;
113 case 7: Value <<= 8; Value |= *InBytes++;
114 case 6: Value <<= 8; Value |= *InBytes++;
115 case 5: Value <<= 8; Value |= *InBytes++;
116 case 4: Value <<= 8; Value |= *InBytes++;
117 case 3: Value <<= 8; Value |= *InBytes++;
118 case 2: Value <<= 8; Value |= *InBytes++;
119 case 1: Value <<= 8; Value |= *InBytes++;
120 default:
121 return Value;
122 }
123}
124
133{
135 return -int64(Value & 1) ^ int64(Value >> 1);
136}
137
146{
147 const uint32 ByteCount = MeasureVarUInt(InValue);
148 uint8* OutBytes = static_cast<uint8*>(OutData) + ByteCount - 1;
149 switch (ByteCount - 1)
150 {
151 case 4: *OutBytes-- = uint8(InValue); InValue >>= 8;
152 case 3: *OutBytes-- = uint8(InValue); InValue >>= 8;
153 case 2: *OutBytes-- = uint8(InValue); InValue >>= 8;
154 case 1: *OutBytes-- = uint8(InValue); InValue >>= 8;
155 default: break;
156 }
157 *OutBytes = uint8(0xff << (9 - ByteCount)) | uint8(InValue);
158 return ByteCount;
159}
160
169{
170 const uint32 ByteCount = MeasureVarUInt(InValue);
171 uint8* OutBytes = static_cast<uint8*>(OutData) + ByteCount - 1;
172 switch (ByteCount - 1)
173 {
174 case 8: *OutBytes-- = uint8(InValue); InValue >>= 8;
175 case 7: *OutBytes-- = uint8(InValue); InValue >>= 8;
176 case 6: *OutBytes-- = uint8(InValue); InValue >>= 8;
177 case 5: *OutBytes-- = uint8(InValue); InValue >>= 8;
178 case 4: *OutBytes-- = uint8(InValue); InValue >>= 8;
179 case 3: *OutBytes-- = uint8(InValue); InValue >>= 8;
180 case 2: *OutBytes-- = uint8(InValue); InValue >>= 8;
181 case 1: *OutBytes-- = uint8(InValue); InValue >>= 8;
182 default: break;
183 }
184 *OutBytes = uint8(0xff << (9 - ByteCount)) | uint8(InValue);
185 return ByteCount;
186}
187
190{
191 const uint32 Value = uint32((InValue >> 31) ^ (InValue << 1));
192 return WriteVarUInt(Value, OutData);
193}
194
197{
198 const uint64 Value = uint64((InValue >> 63) ^ (InValue << 1));
199 return WriteVarUInt(Value, OutData);
200}
201
202class FArchive;
203
207
#define FORCEINLINE
Definition AndroidPlatform.h:140
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
CORE_API void SerializeVarUInt(FArchive &Ar, uint64 &Value)
Definition VarInt.cpp:50
CORE_API int64 ReadVarIntFromArchive(FArchive &Ar)
Definition VarInt.cpp:8
CORE_API void WriteVarIntToArchive(FArchive &Ar, int64 Value)
Definition VarInt.cpp:14
CORE_API void SerializeVarInt(FArchive &Ar, int64 &Value)
Definition VarInt.cpp:19
FORCEINLINE uint32 MeasureVarUInt(const void *InData)
Definition VarInt.h:61
FORCEINLINE uint32 WriteVarUInt(uint32 InValue, void *OutData)
Definition VarInt.h:145
CORE_API uint64 ReadVarUIntFromArchive(FArchive &Ar)
Definition VarInt.cpp:31
CORE_API void WriteVarUIntToArchive(FArchive &Ar, uint64 Value)
Definition VarInt.cpp:43
FORCEINLINE uint64 ReadVarUInt(const void *InData, uint32 &OutByteCount)
Definition VarInt.h:103
FORCEINLINE uint32 MeasureVarInt(const void *InData)
Definition VarInt.h:67
FORCEINLINE int64 ReadVarInt(const void *InData, uint32 &OutByteCount)
Definition VarInt.h:132
FORCEINLINE uint32 WriteVarInt(int32 InValue, void *OutData)
Definition VarInt.h:189
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208