AMXX-BG.INFO DataPacks.inc Raw include

DataPacks.inc

Original include source with line numbers.

Back Download .inc
1 /**
2 * These stocks are meant to mimic Sourcemod's data packs functionality,
3 * and complement CellTrie/CellArray, allowing heterogeneous data in the same container to be accessed by index.
4 * Storage is done in nested CellArrays, and there are no size limits other than those imposed by them, if any.
5 * They'll be specially usefull to pass data to/from callbacks and forwards.
6
7 * Changelog:
8 * ----------
9 * 22/03/2009 - Initial Release
10 * 23/03/2009 - Fixed DataPack_GetString not returning the proper string length
11 * Fixed accidental removal of stock modifier from functions
12 * ----------
13 *
14 * Discussion Thread:
15 * [http://forums.alliedmods.net/showthread.php?t=88304]
16 */
17
18 #if defined __DATAPACK_INCLUDED
19 #endinput
20 #endif
21 #define __DATAPACK_INCLUDED
22
23 #include <string>
24 #include <cellarray>
25
26 /**
27 * Creation / Destruction functions
28 */
29
30 /**
31 * Creates a datapack for use.
32 *
33 * @param iReserve [optional] How many entries to reserve beforehand (they're not usable though)
34 * @return Handle to the DataPack Array
35 **/
36 stock Array:DataPack_Create(iReserve = 1)
37 {
38 return ArrayCreate(2, iReserve)
39 }
40
41 /**
42 * Destroys a DataPack, freeing all of it's sub-arrays.
43 * You MUST use this instead of ArrayDestroy or you'll end up with a memory leak
44 *
45 * @param hDataPack DataPack Handle
46 * @return void, meaningless
47 **/
48 stock DataPack_Free(&Array:hDataPack)
49 {
50 if(!hDataPack)
51 return
52
53 new iSize = ArraySize(hDataPack)
54 new iArray[2]
55
56 for(new i=0; i < iSize; i++)
57 {
58 if(ArrayGetArray(hDataPack, i, iArray) && iArray[0] != DPACK_CELL)
59 ArrayDestroy(Array:iArray[1])
60 }
61
62 ArrayDestroy(hDataPack)
63 }
64
65 /**
66 * Informational functions
67 */
68
69 /**
70 * Returns the number of entries in a DataPack.
71 *
72 * @param hDataPack DataPack Handle
73 * @return Number of entries
74 **/
75 stock DataPack_GetSize(Array:hDataPack)
76 {
77 return ArraySize(hDataPack)
78 }
79
80 /**
81 * Returns the type of an entry on a DataPack.
82 * Types are defined below, and are self-explanatory with one exception:
83 * Anything higher than 0 corresponds to an array's size.
84 *
85 * @param hDataPack DataPack handle
86 * @param iIndex Entry index
87 * @return Integer from the enum below, or > 0 for an array size.
88 **/
89 enum {DPACK_INVALID = -2, DPACK_CELL = -1, DPACK_STRING = 0}
90 stock DataPack_GetItemType(Array:hDataPack, iIndex)
91 {
92 new iArray[2]
93 if( !hDataPack
94 || !(0 <= iIndex < ArraySize(hDataPack))
95 || !ArrayGetArray(hDataPack, iIndex, iArray) )
96 {
97 return DPACK_INVALID
98 }
99
100 return iArray[0]
101 }
102
103 /**
104 * Insertion Functions
105 */
106
107 /**
108 * Pushes a single cell into an DataPack
109 *
110 * @param hDataPack DataPack handle
111 * @param cCell Cell holding the data
112 * @return Boolean: success/fail
113 */
114 stock bool:DataPack_PushCell(Array:hDataPack, any:cCell)
115 {
116 if(!hDataPack)
117 return false
118
119 new any:iArray[2]
120 iArray[0] = DPACK_CELL
121 iArray[1] = cCell
122
123 ArrayPushArray(hDataPack, iArray)
124 return true
125 }
126
127 /**
128 * Pushes an array into a DataPack.
129 * The array size WILL be enforced on retrieval and MUST match the one passed on insertion,
130 * so make sure your array sizes match.
131 *
132 * @param hDataPack DataPack handle
133 * @param cArray[] Array containing the datapack
134 * @param iArraySize Size of the data array. MUST BE MATCHED ON RETRIEVAL
135 * @return Boolean: success/fail
136 */
137 stock bool:DataPack_PushArray(Array:hDataPack, any:cArray[], iArraySize)
138 {
139 if(!hDataPack || iArraySize < 1)
140 return false
141
142 new Array:hDataArray = ArrayCreate(iArraySize)
143 if(!hDataArray)
144 return false
145
146 ArrayPushArray(hDataArray, cArray)
147
148 new iArray[2]
149 iArray[0] = iArraySize
150 iArray[1] = hDataArray
151
152 ArrayPushArray(hDataPack, iArray)
153 return true
154 }
155 /**
156 * Push a string into a DataPack.
157 * Be careful with your string sizes on retrieval to avoid data loss.
158 *
159 * @param hDataPack DataPack handle
160 * @param szString[] String to instert
161 * @param iLen [optional] Max. length to read from the string
162 * @return Actual length of the inserted string, 0 on fail
163 */
164 stock DataPack_PushString(Array:hDataPack, szString[], iLen=-1)
165 {
166 if(hDataPack)
167 return 0
168
169 new iStrLen = iLen
170 if(iStrLen < 0)
171 iStrLen = strlen(szstring)
172
173 new Array:hStringArray = ArrayCreate(iStrLen + 1)
174 if(!hStringArray)
175 return 0
176
177 ArrayPushString(hStringArray, szString)
178
179 new iArray[2]
180 iArray[0] = DPACK_STRING
181 iArray[1] = _:hStringArray
182
183 ArrayPushArray(hDataPack, iArray)
184 return iStrLen
185 }
186
187 /**
188 * Retrieval Functions
189 */
190
191 /**
192 * Retrieve a cell from a DataPack.
193 * Result passed byref to allow fail check.
194 *
195 * @param hDataPack DataPack handle
196 * @param iIndex Entry index
197 * @param &cResult Cell to store the data into
198 * @return Boolean: success/fail
199 */
200 stock bool:DataPack_GetCell(Array:hDataPack, iIndex, &any:cResult)
201 {
202 new iArray[2]
203 if( !hDataPack
204 || !(0 <= iIndex < ArraySize(hDataPack))
205 || (!ArrayGetArray(hDataPack, iIndex, iArray) || iArray[0] != DPACK_CELL)
206 )
207 {
208 return false
209 }
210
211 cResult = iArray[1]
212 return true
213 }
214 /**
215 * Retrieve an array from a DataPack.
216 * Passed size MUST match with one used for insertion, or the function will fail
217 *
218 * @param hDataPack DataPack handle
219 * @param iIndex Entry index
220 * @param cArray[] Array to store the data into
221 * @param iArraySize Size of the data array. MUST MATCH INSERTION SIZE
222 * @return Boolean: success/fail
223 */
224 stock bool:DataPack_GetArray(Array:hDataPack, iIndex, any:cArray[], iArraySize)
225 {
226 new iArray[2], _iArraySize
227 if( iArraySize < 1 || !hDataPack
228 || !(0 <= iIndex < ArraySize(hDataPack))
229 || (!ArrayGetArray(hDataPack, iIndex, iArray))
230 || (iArray[0] != iArraySize)
231 )
232 {
233 return false
234 }
235
236 new Array:hArrayArray = Array:iArray[1]
237 return ArraySize(hArrayArray) ? bool:ArrayGetArray(hArrayArray, 0, cArray) : false
238 }
239 /**
240 * Retrieve a string from a DataPack.
241 *
242 * @param hDataPack DataPack handle
243 * @param iIndex Entry index
244 * @param szResult[] String to store the data into
245 * @param iMaxLen Max. length of the result string
246 * @return length of the retrieved string
247 */
248 stock DataPack_GetString(Array:hDataPack, iIndex, szResult[], iMaxLen)
249 {
250 new iArray[2]
251 if( !hDataPack
252 || !(0 <= iIndex < ArraySize(hDataPack))
253 || (!ArrayGetArray(hDataPack, iIndex, iArray) || iArray[0] != DPACK_STRING)
254 )
255 {
256 return 0
257 }
258
259 new Array:hStringArray = Array:iArray[1]
260 if(ArraySize(hStringArray))
261 {
262 ArrayGetString(hStringArray, 0, szResult, iMaxLen)
263 return strlen(szResult)
264 }
265 return 0
266 }