-
Notifications
You must be signed in to change notification settings - Fork 19
/
Serialize.ahk
executable file
·104 lines (91 loc) · 3.61 KB
/
Serialize.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
99
100
101
102
103
104
#NoEnv
;wip: support objects as keys
/*
[
uint *Key
uint *Value
]
uint 0
[
char KeyType
str Key
]
[
uint ValueLength
blob Value
]
*/
;creates a binary representation of an object
SaveObject(InputObject,ByRef SerializedObject,SizeOnly = 0)
{
IsANSI := !A_IsUnicode
;calculate the size of the serialized object, including its keys and values
ObjectSize := 0, TableSize := 0, KeySize := 0
For Key In InputObject
{
TableSize += 8, KeySize += 1 + ((StrLen(Key) + 1) << IsANSI) ;sum the sizes of the table entry, sum the sizes of the keys
If IsObject(InputObject[Key])
{
}
Else ;value is a string or a number
{
CurrentSize := ObjGetCapacity(InputObject,Key)
If (CurrentSize = "")
InputObject[Key] .= "", CurrentSize := ObjGetCapacity(InputObject,Key)
}
ObjectSize += 4 +
}
ObjectSize += TableSize + 4 + KeySize
VarSetCapacity(SerializedObject,ObjectSize) ;set the capacity of the storage structure
MsgBox % ObjectSize
NumPut(0,SerializedObject,TableSize,"UInt") ;insert the table end indicator
TableOffset := 0, KeyOffset := 4 + TableSize, ValueOffset := KeyOffset + KeySize
For Key In InputObject
{
;store the table entry in the structure
NumPut(KeyOffset,SerializedObject,TableOffset,"UInt"), TableOffset += 4
NumPut(ValueOffset,SerializedObject,TableOffset,"UInt"), TableOffset += 4
;store the key in the structure
CurrentSize := StrLen(Key) + 1 ;length of the string and its null terminator
NumPut(0,SerializedObject,KeyOffset,"UChar"), KeyOffset ++ ;0 means the key is a string, 1 means that the key is a number ;wip: need to be able to tell if the key is an integer or not
StrPut(Key,&SerializedObject + KeyOffset,"","UTF-16"), KeyOffset += CurrentSize << IsANSI
;store the value in the structure
If IsObject(InputObject[Key])
{
CurrentSize := SaveObject(Value,SerializedNestedObject)
NumPut(CurrentSize,SerializedObject,ValueOffset,"UInt"), ValueOffset += 4
DllCall("RtlMoveMemory","UPtr",&SerializedObject + ValueOffset,"UPtr",&SerializedNestedObject,"UInt",CurrentSize), ValueOffset += CurrentSize ;wip: not sure if UInt should be used for length
}
Else ;value is a string or a number
{
CurrentSize := ObjGetCapacity(InputObject,Key)
If (CurrentSize = "") ;value is a number
InputObject[Key] .= "", CurrentSize := ObjGetCapacity(InputObject,Key) ;convert it to a string and retrieve the size again
NumPut(CurrentSize,SerializedObject,ValueOffset,"UInt"), ValueOffset += 4
DllCall("RtlMoveMemory","UPtr",&SerializedObject + ValueOffset,"UPtr",ObjGetAddress(InputObject,Key),"UInt",CurrentSize)
ValueOffset += CurrentSize ;wip: not sure if UInt should be used for length
}
}
Return, ObjectSize
}
LoadObject(ByRef SerializedObject,ObjectSize)
{
OutputObject := Object(), TableOffset := 0
Loop
{
KeyOffset := NumGet(SerializedObject,TableOffset,"UInt"), TableOffset += 4
If (KeyOffset = 0)
Break
ValueOffset := NumGet(SerializedObject,TableOffset,"UInt"), TableOffset += 4
;retrieve the key from the structure
KeyType := NumGet(SerializedObject,KeyOffset,"UChar"), KeyOffset ++
Key := StrGet(&SerializedObject + KeyOffset,"","UTF-16")
;wip: handle the key being a number type
ObjInsert(OutputObject,Key,"")
ValueLength := NumGet(SerializedObject,ValueOffset,"UInt"), ValueOffset += 4
MsgBox % ValueOffset
ObjSetCapacity(OutputObject,Key,ValueLength)
DllCall("RtlMoveMemory","UPtr",ObjGetAddress(OutputObject,Key),"UPtr",&SerializedObject + ValueOffset,"UInt",ValueLength) ;wip: not sure if UInt should be used for length
}
Return, OutputObject
}