-
Notifications
You must be signed in to change notification settings - Fork 72
/
class_ScanningBuffer.ahk
98 lines (83 loc) · 2.26 KB
/
class_ScanningBuffer.ahk
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
class _TypeSizes {
__Get(Key) {
return (Key != "") ? (TypeSizes[Key] := TypeSizes.GetTypeSize(Key)) : (0)
}
}
class TypeSizes extends _TypeSizes {
GetTypeSize(TypeName) {
static TestBuffer
static _ := VarSetCapacity(TestBuffer, 8, 0)
return NumPut(0, &TestBuffer + 0, 0, TypeName) - (&TestBuffer)
}
}
class ManagedScanningBuffer extends ScanningBuffer {
static hProcessHeap := DllCall("GetProcessHeap")
__New(Length) {
static HEAP_ZERO_MEMORY := 0x00000008
this.pBuffer := DllCall("HeapAlloc", "Ptr", ManagedScanningBuffer.hProcessHeap, "UInt", HEAP_ZERO_MEMORY, "UInt", Length)
ScanningBuffer.__New.Call(this, this.pBuffer, Length)
}
__Delete() {
DllCall("HeapFree", "Ptr", ManagedScanningBuffer.hProcessHeap, "UInt", 0, "Ptr", this.pBuffer)
}
}
class ScanningBuffer {
IsScanningBuffer() {
return true
}
__New(pBuffer, Length) {
this.Start := pBuffer
this.Current := this.Start
this.End := this.Start + Length
}
Tell() {
return this.Current - this.Start
}
CheckBounds(TypeName) {
NewCurrent := this.Current + TypeSizes[TypeName]
if (NewCurrent > this.End || NewCurrent < this.Start) {
Throw, Exception("Reading/Writing a " TypeName " will over/under-run the ScanningBuffer at " this.Start ".")
}
else {
return NewCurrent
}
}
_ReadType(TypeName) {
NewCurrent := this.CheckBounds(TypeName)
return (NumGet(this.Current + 0, 0, TypeName), this.Current := NewCurrent)
}
_WriteType(TypeName, Value) {
NewCurrent := this.CheckBounds(TypeName)
return (NumPut(Value, this.Current + 0, 0, TypeName), this.Current := NewCurrent)
}
SeekCurrent(Offset) {
this.Current += Offset
try {
this.CheckBounds("")
}
catch {
Throw, Exception("Invalid SeekCurrent using offset " Offset)
this.Current -= Offset
}
}
SeekStart(Offset) {
OldCurrent := this.Current
this.Current := this.Start + Offset
try {
this.CheckBounds("")
}
catch {
Throw, Exception("Invalid SeekStart using offset " Offset)
this.Current := OldCurrent
}
}
__Call(Key, Params*) {
Base := ObjGetBase(this)
if (SubStr(Key, 1, 4) = "Read") {
return Base._ReadType.Call(this, SubStr(Key, 5), Params*)
}
else if (SubStr(Key, 1, 5) = "Write") {
return Base._WriteType.Call(this, SubStr(Key, 6), Params*)
}
}
}