-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BigMask.au3
293 lines (194 loc) · 8.73 KB
/
BigMask.au3
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.16.1
Author(s): Zvend
Discord(s): zvend
Script Functions:
_BigMask_Init(Const $nCapacity = 32, Const $bDefaultSet = False) -> BigMask
_BigMask_IsBigMask(Const ByRef $aBigMask) -> Bool
_BigMask_IsValidIndex(Const ByRef $aBigMask, Const $nIndex, Const $bSkipBigMaskCheck = False) -> Bool
_BigMask_IsValidGroup(Const ByRef $aBigMask, Const $nGroup, Const $bSkipBigMaskCheck = False) -> Bool
_BigMask_GetFlag(Const ByRef $aBigMask, Const $nIndex) -> Bool
_BigMask_SetFlag(ByRef $aBigMask, Const $nIndex, Const $bBool) -> Bool
_BigMask_SetGroup(ByRef $aBigMask, Const $nGroup, Const $nBitMask) -> Bool
_BigMask_GetGroup(Const ByRef $aBigMask, Const $nGroup) -> UInt32
_BigMask_GetSize(Const ByRef $aBigMask) -> UInt32
_BigMask_GetGroupSize(Const ByRef $aBigMask) -> UInt32
_BigMask_ToBinary(Const ByRef $aBigMask) -> Binary
_BigMask_ToString(Const ByRef $aBigMask, Const $bIncludeGroups = False) -> String
Internal Functions:
__BigMask_GetGroupFlag(Const $nFlagMask, Const $nIndex) -> Bool
__BigMask_GetBitMask(Const $nIndex) -> UInt32
__BigMask_ConvertToGroup(Const $nIndex) -> UInt32
Description:
The BigMask is a very storage efficient BitMask, that contain unlimited bits for
setting & getting flags.
The main reason i made this class is for storing bitmasks into packets or
getting bitmasks from received packets. No matter if its socket or inter
process communication.
Can also be used for any other flagging system.
#ce ----------------------------------------------------------------------------
#include-once
Global Enum _
$BIGMASK_ERR_NONE , _
$BIGMASK_ERR_BAD_SIZE , _
$BIGMASK_ERR_BAD_BIGMASK , _
$BIGMASK_ERR_BAD_FLAG , _
$BIGMASK_ERR_INVALID_INDEX, _
$BIGMASK_ERR_INVALID_GROUP, _
$__BIGMASK_ERR_COUNT
Global Enum _
$__BIGMASK_IDENTIFIER, _
$__BIGMASK_CAPACITY, _
$__BIGMASK_BUFFER , _
$__BIGMASK_PARAMS
Func _BigMask_Init(Const $nCapacity = 32, Const $bDefaultSet = False) ;-> BigMask
If Not IsInt($nCapacity) Or $nCapacity <= 0 Then
Return SetError($BIGMASK_ERR_BAD_SIZE, 0, Null)
EndIf
;~ Calculate the size of the array
Local $nGroups = __BigMask_ConvertToGroup($nCapacity - 1) + 1
Local $aContainer[$nGroups]
For $i = 0 To $nGroups - 1
$aContainer[$i] = Int(0 - Int($bDefaultSet = True, 1), 1)
Next
Local $aBigMask[$__BIGMASK_PARAMS]
$aBigMask[$__BIGMASK_IDENTIFIER] = "BigMask"
$aBigMask[$__BIGMASK_CAPACITY] = $nCapacity
$aBigMask[$__BIGMASK_BUFFER] = $aContainer
Return $aBigMask
EndFunc
Func _BigMask_IsBigMask(Const ByRef $aBigMask) ;-> Bool
If Not IsArray($aBigMask) Then
Return SetError($BIGMASK_ERR_BAD_BIGMASK, 0, 0)
EndIf
If UBound($aBigMask) <> $__BIGMASK_PARAMS Then
Return SetError($BIGMASK_ERR_BAD_BIGMASK, 0, 0)
EndIf
If Not ($aBigMask[$__BIGMASK_IDENTIFIER] == "BigMask") Then
Return SetError($BIGMASK_ERR_BAD_BIGMASK, 0, 0)
EndIf
Return 1
EndFunc
Func _BigMask_IsValidIndex(Const ByRef $aBigMask, Const $nIndex, Const $bSkipBigMaskCheck = False) ;-> Bool
If Not $bSkipBigMaskCheck And Not _BigMask_IsBigMask($aBigMask) Then
Return SetError(@error, 0, 0)
EndIf
If Not IsInt($nIndex) Or $nIndex < 0 Or $nIndex >= $aBigMask[$__BIGMASK_CAPACITY] Then
Return SetError($BIGMASK_ERR_INVALID_INDEX, 0, 0)
EndIf
Return 1
EndFunc
Func _BigMask_IsValidGroup(Const ByRef $aBigMask, Const $nGroup, Const $bSkipBigMaskCheck = False) ;-> Bool
If Not $bSkipBigMaskCheck And Not _BigMask_IsBigMask($aBigMask) Then
Return SetError(@error, 0, 0)
EndIf
Local $aContainer = $aBigMask[$__BIGMASK_BUFFER]
If Not IsInt($nGroup) Or $nGroup < 0 Or $nGroup >= UBound($aContainer) Then
Return SetError($BIGMASK_ERR_INVALID_GROUP, 0, 0)
EndIf
Return 1
EndFunc
Func _BigMask_GetFlag(Const ByRef $aBigMask, Const $nIndex) ;-> Bool
If Not _BigMask_IsValidIndex($aBigMask, $nIndex, False) Then
Return SetError(@error, 0, 0)
EndIf
Local $nGroup = __BigMask_ConvertToGroup($nIndex)
Local $aContainer = $aBigMask[$__BIGMASK_BUFFER]
Return Int(__BigMask_GetGroupFlag($aContainer[$nGroup], $nIndex), 1)
EndFunc
Func _BigMask_SetFlag(ByRef $aBigMask, Const $nIndex, Const $bBool) ;-> Bool
If Not _BigMask_IsValidIndex($aBigMask, $nIndex, False) Then
Return SetError(@error, 0, 0)
EndIf
If Not (IsBool($bBool) Or IsInt($bBool)) Then
Return SetError($BIGMASK_ERR_BAD_FLAG, 0, 0)
EndIf
Local $nGroup = __BigMask_ConvertToGroup($nIndex)
Local $nBitMask = __BigMask_GetBitMask($nIndex)
Local $aContainer = $aBigMask[$__BIGMASK_BUFFER]
If $bBool Then
$aContainer[$nGroup] = BitOR($aContainer[$nGroup], $nBitMask)
Else
$aContainer[$nGroup] = BitAND($aContainer[$nGroup], BitNOT($nBitMask))
EndIf
$aBigMask[$__BIGMASK_BUFFER] = $aContainer
Return 1
EndFunc
Func _BigMask_SetGroup(ByRef $aBigMask, Const $nGroup, Const $nBitMask) ;-> Bool
If Not _BigMask_IsValidGroup($aBigMask, $nGroup, False) Then
Return SetError(@error, 0, 0)
EndIf
If Not IsInt($nBitMask) And Not IsPtr($nBitMask) Then
Return SetError($BIGMASK_ERR_BAD_FLAG, 0, 0)
EndIf
Local $aContainer = $aBigMask[$__BIGMASK_BUFFER]
$aContainer[$nGroup] = Int($nBitMask, 1)
$aBigMask[$__BIGMASK_BUFFER] = $aContainer
Return 1
EndFunc
Func _BigMask_GetGroup(Const ByRef $aBigMask, Const $nGroup) ;-> UInt32
If Not _BigMask_IsValidGroup($aBigMask, $nGroup, False) Then
Return SetError(@error, 0, 0)
EndIf
Local $aContainer = $aBigMask[$__BIGMASK_BUFFER]
Return $aContainer[$nGroup]
EndFunc
Func _BigMask_GetSize(Const ByRef $aBigMask) ;-> UInt32
If Not _BigMask_IsBigMask($aBigMask) Then
Return SetError(@error, 0, 0)
EndIf
Return $aBigMask[$__BIGMASK_CAPACITY]
EndFunc
Func _BigMask_GetGroupSize(Const ByRef $aBigMask) ;-> UInt32
If Not _BigMask_IsBigMask($aBigMask) Then
Return SetError(@error, 0, 0)
EndIf
Return UBound($aBigMask[$__BIGMASK_BUFFER])
EndFunc
Func _BigMask_ToBinary(Const ByRef $aBigMask) ;-> Binary
If Not _BigMask_IsBigMask($aBigMask) Then
Return SetError(@error, 0, Binary("0x00"))
EndIf
Local $tStruct = DllStructCreate("DWORD[" & _BigMask_GetGroupSize($aBigMask) & "];")
For $i = 0 To _BigMask_GetGroupSize($aBigMask) - 1
DllStructSetData($tStruct, 1, _BigMask_GetGroup($aBigMask, $i), $i + 1)
Next
Local $nSize = Ceiling(_BigMask_GetSize($aBigMask) / 8)
Local $tBytes = DllStructCreate("BYTE[" & $nSize & "];", DllStructGetPtr($tStruct))
Return DllStructGetData($tBytes, 1)
EndFunc
Func _BigMask_ToString(Const ByRef $aBigMask, Const $bIncludeGroups = False) ;-> String
If Not _BigMask_IsBigMask($aBigMask) Then
Return SetError(@error, 0, 0)
EndIf
Local $sOut = ""
If $bIncludeGroups Then
$sOut = "[BigMask] [Size: " & _BigMask_GetSize($aBigMask) & ", Groups: " & _BigMask_GetGroupSize($aBigMask) & "]" & @LF
$sOut &= StringFormat("Group %d: 0x%08X = {", 0, _BigMask_GetGroup($aBigMask, 0))
EndIf
For $i = 0 To $aBigMask[$__BIGMASK_CAPACITY] - 1
$sOut &= StringFormat("%1d ", _BigMask_GetFlag($aBigMask, $i))
If $i = $aBigMask[$__BIGMASK_CAPACITY] - 1 Then
ExitLoop
ElseIf $bIncludeGroups And Mod($i + 1, 32) = 0 Then
Local $nGroupIndex = __BigMask_ConvertToGroup($i + 1)
$sOut = StringTrimRight($sOut, 1) & "}" & @LF
$sOut &= StringFormat("Group %d: 0x%08X = {", $nGroupIndex, _BigMask_GetGroup($aBigMask, $nGroupIndex))
ElseIf $bIncludeGroups And Mod($i + 1, 8) = 0 Then
$sOut &= " "
EndIf
Next
If $bIncludeGroups Then
$sOut = StringStripWS($sOut, 2) & "}" & @LF
EndIf
Return $sOut
EndFunc
Func __BigMask_GetGroupFlag(Const $nFlagMask, Const $nIndex) ;-> Bool
Return BitAnd($nFlagMask, BitShift(1, - Mod($nIndex, 32))) <> 0
EndFunc
Func __BigMask_GetBitMask(Const $nIndex) ;-> UInt32
Return BitShift(1, - Mod($nIndex, 32))
EndFunc
Func __BigMask_ConvertToGroup(Const $nIndex) ;-> UInt32
Return Floor($nIndex / 32)
EndFunc