Repository navigation
Expand file tree
/
Copy pathLEB128.pas
More file actions
103 lines (87 loc) · 2.42 KB
/
Copy pathLEB128.pas
File metadata and controls
103 lines (87 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unit LEB128;
interface
uses System.Classes;
const MAXIMUMSIZE4BYTE:Int64 = 64 * 128 * 128 * 128 - 1;
function ReadLEB128(const reader:TBinaryReader):Int64;
function ReadInt(const br:TBinaryReader):Integer;
function ReadShort(const br:TBinaryReader):Int16;
function ReadSByte(const br:TBinaryReader):Int8;
function ReadUint(const br:TBinaryReader):UInt32;
function ReadUShort(const br:TBinaryReader):UInt16;
function ReadByte(const br:TBinaryReader):UInt8;
function GetLength(value:Int64) :Int8;
procedure Write(var stream: TMemoryStream; value, maximumSize: Int64);
implementation
uses System.Math;
function GetLength(value:Int64) :Int8;
begin
Result := 1;
value := value shr 6;
while value > 0 do
begin
value := value shr 7;
Inc(Result);
end;
end;
procedure Write(var stream: TMemoryStream; value, maximumSize: Int64);
var
currentByte : UInt8;
bw : TBinaryWriter;
begin
bw := TBinaryWriter.Create(stream);
while (True) do
begin
currentByte := value and $7F;
if ((maximumSize shr 6) = 0) or ((maximumSize shr 6) = -1) then
begin
bw.Write(currentByte);
bw.Free;
Exit;
end;
bw.Write(currentByte or $80);
value := value shr 7;
maximumSize := maximumSize shr 7;
end;
end;
function ReadLEB128(const reader:TBinaryReader):Int64;
var
currentshift : Integer;
currentbyte : Byte;
shift : Integer;
begin
Result := 0;
currentshift := 0;
repeat
currentbyte := reader.ReadByte;
Result := Result or (Int64((currentbyte and $7F) shl currentshift));
currentshift := currentshift + 7;
until ((currentbyte and $80)=0);
shift := 64 - currentshift;
if shift > 0 then
Result := (Result shl shift) shr shift;
end;
function ReadInt(const br:TBinaryReader):Integer;
begin
Result := Integer(Min(Max(ReadLEB128(br), Low(Integer)),High(Integer)));
end;
function ReadShort(const br:TBinaryReader):Int16;
begin
Result := Int16(Min(Max(ReadLEB128(br), Low(Int16)),High(Int16)));
end;
function ReadSByte(const br:TBinaryReader):Int8;
begin
Result := Int8(Min(Max(ReadLEB128(br), Low(Int8)),High(Int8)));
end;
function ReadUint(const br:TBinaryReader):UInt32;
begin
Result := UInt32(Min(Max(ReadLEB128(br), 0),High(Uint32)));
end;
function ReadUShort(const br:TBinaryReader):UInt16;
begin
Result := UInt16(Min(Max(ReadLEB128(br), 0),High(Uint16)));
end;
function ReadByte(const br:TBinaryReader):UInt8;
begin
Result := UInt8(Min(Max(ReadLEB128(br), 0),High(Uint8)));
end;
end.