blob: 23fcc8d91d9cff8022811bb6fc816b079769bd53
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: pack_utils.c,v 1.2.2.1 2005/05/04 18:21:23 hubbe Exp $ |
3 | * |
4 | * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM |
5 | * Portions Copyright (c) 1995-2005 RealNetworks, Inc. |
6 | * All Rights Reserved. |
7 | * |
8 | * The contents of this file, and the files included with this file, |
9 | * are subject to the current version of the Real Format Source Code |
10 | * Porting and Optimization License, available at |
11 | * https://helixcommunity.org/2005/license/realformatsource (unless |
12 | * RealNetworks otherwise expressly agrees in writing that you are |
13 | * subject to a different license). You may also obtain the license |
14 | * terms directly from RealNetworks. You may not use this file except |
15 | * in compliance with the Real Format Source Code Porting and |
16 | * Optimization License. There are no redistribution rights for the |
17 | * source code of this file. Please see the Real Format Source Code |
18 | * Porting and Optimization License for the rights, obligations and |
19 | * limitations governing use of the contents of the file. |
20 | * |
21 | * RealNetworks is the developer of the Original Code and owns the |
22 | * copyrights in the portions it created. |
23 | * |
24 | * This file, and the files included with this file, is distributed and |
25 | * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, |
26 | * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL |
27 | * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF |
28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT |
29 | * OR NON-INFRINGEMENT. |
30 | * |
31 | * Technology Compatibility Kit Test Suite(s) Location: |
32 | * https://rarvcode-tck.helixcommunity.org |
33 | * |
34 | * Contributor(s): |
35 | * |
36 | * ***** END LICENSE BLOCK ***** */ |
37 | |
38 | #include <memory.h> |
39 | #include "helix_types.h" |
40 | #include "helix_result.h" |
41 | #include "rm_memory.h" |
42 | #include "memory_utils.h" |
43 | #include "pack_utils.h" |
44 | |
45 | void rm_pack32(UINT32 ulValue, BYTE** ppBuf, UINT32* pulLen) |
46 | { |
47 | if (ppBuf && pulLen && *pulLen >= 4) { |
48 | BYTE* pBuf = *ppBuf; |
49 | pBuf[0] = (BYTE)((ulValue & 0xFF000000) >> 24); |
50 | pBuf[1] = (BYTE)((ulValue & 0x00FF0000) >> 16); |
51 | pBuf[2] = (BYTE)((ulValue & 0x0000FF00) >> 8); |
52 | pBuf[3] = (BYTE)(ulValue & 0x000000FF); |
53 | *ppBuf += 4; |
54 | *pulLen -= 4; |
55 | } |
56 | } |
57 | |
58 | void rm_pack32_le(UINT32 ulValue, BYTE** ppBuf, UINT32* pulLen) |
59 | { |
60 | if (ppBuf && pulLen && *pulLen >= 4) { |
61 | BYTE* pBuf = *ppBuf; |
62 | pBuf[0] = (BYTE)(ulValue & 0x000000FF); |
63 | pBuf[1] = (BYTE)((ulValue & 0x0000FF00) >> 8); |
64 | pBuf[2] = (BYTE)((ulValue & 0x00FF0000) >> 16); |
65 | pBuf[3] = (BYTE)((ulValue & 0xFF000000) >> 24); |
66 | *ppBuf += 4; |
67 | *pulLen -= 4; |
68 | } |
69 | } |
70 | |
71 | void rm_pack16(UINT16 usValue, BYTE** ppBuf, UINT32* pulLen) |
72 | { |
73 | if (ppBuf && pulLen && *pulLen >= 2) { |
74 | BYTE* pBuf = *ppBuf; |
75 | pBuf[0] = (BYTE)((usValue & 0x0000FF00) >> 8); |
76 | pBuf[1] = (BYTE)(usValue & 0x000000FF); |
77 | *ppBuf += 2; |
78 | *pulLen -= 2; |
79 | } |
80 | } |
81 | |
82 | void rm_pack16_le(UINT16 usValue, BYTE** ppBuf, UINT32* pulLen) |
83 | { |
84 | if (ppBuf && pulLen && *pulLen >= 2) { |
85 | BYTE* pBuf = *ppBuf; |
86 | pBuf[0] = (BYTE)(usValue & 0x000000FF); |
87 | pBuf[1] = (BYTE)((usValue & 0x0000FF00) >> 8); |
88 | *ppBuf += 2; |
89 | *pulLen -= 2; |
90 | } |
91 | } |
92 | |
93 | void rm_pack8(BYTE ucValue, BYTE** ppBuf, UINT32* pulLen) |
94 | { |
95 | if (ppBuf && pulLen && *pulLen > 0) { |
96 | BYTE* pBuf = *ppBuf; |
97 | pBuf[0] = (BYTE) ucValue; |
98 | *ppBuf += 1; |
99 | *pulLen -= 1; |
100 | } |
101 | } |
102 | |
103 | UINT32 rm_unpack32(BYTE** ppBuf, UINT32* pulLen) |
104 | { |
105 | UINT32 ulRet = 0; |
106 | |
107 | if (ppBuf && pulLen && *pulLen >= 4) { |
108 | BYTE* pBuf = *ppBuf; |
109 | ulRet = (pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]; |
110 | *ppBuf += 4; |
111 | *pulLen -= 4; |
112 | } |
113 | |
114 | return ulRet; |
115 | } |
116 | |
117 | UINT16 rm_unpack16(BYTE** ppBuf, UINT32* pulLen) |
118 | { |
119 | UINT16 usRet = 0; |
120 | |
121 | if (ppBuf && pulLen && *pulLen >= 2) { |
122 | BYTE* pBuf = *ppBuf; |
123 | usRet = (pBuf[0] << 8) | pBuf[1]; |
124 | *ppBuf += 2; |
125 | *pulLen -= 2; |
126 | } |
127 | |
128 | return usRet; |
129 | } |
130 | |
131 | UINT32 rm_unpack32_nse(BYTE* pBuf, UINT32 ulLen) |
132 | { |
133 | UINT32 ulRet = 0; |
134 | |
135 | if (pBuf && ulLen >= 4) { |
136 | ulRet = (pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]; |
137 | } |
138 | |
139 | return ulRet; |
140 | } |
141 | |
142 | UINT16 rm_unpack16_nse(BYTE* pBuf, UINT32 ulLen) |
143 | { |
144 | UINT16 usRet = 0; |
145 | |
146 | if (pBuf && ulLen >= 2) { |
147 | usRet = (pBuf[0] << 8) | pBuf[1]; |
148 | } |
149 | |
150 | return usRet; |
151 | } |
152 | |
153 | BYTE rm_unpack8(BYTE** ppBuf, UINT32* pulLen) |
154 | { |
155 | BYTE ucRet = 0; |
156 | |
157 | if (ppBuf && pulLen && *pulLen > 0) { |
158 | BYTE* pBuf = *ppBuf; |
159 | ucRet = pBuf[0]; |
160 | *ppBuf += 1; |
161 | *pulLen -= 1; |
162 | } |
163 | |
164 | return ucRet; |
165 | } |
166 | |
167 | HX_RESULT rm_unpack_string(BYTE** ppBuf, |
168 | UINT32* pulLen, |
169 | UINT32 ulStrLen, |
170 | char** ppStr, |
171 | void* pUserMem, |
172 | rm_malloc_func_ptr fpMalloc, |
173 | rm_free_func_ptr fpFree) |
174 | { |
175 | HX_RESULT retVal = HXR_FAIL; |
176 | |
177 | if (ppBuf && pulLen && *pulLen >= ulStrLen && ppStr && fpMalloc && fpFree) { |
178 | /* Clear the return value */ |
179 | retVal = HXR_OK; |
180 | /* Do we actually have a string to unpack? */ |
181 | if (ulStrLen) { |
182 | /* If the string is already allocated, free it */ |
183 | if (*ppStr) { |
184 | fpFree(pUserMem, *ppStr); |
185 | *ppStr = HXNULL; |
186 | } |
187 | /* Allocate a buffer that it one more byte than the length */ |
188 | *ppStr = (char*) fpMalloc(pUserMem, ulStrLen + 1); |
189 | if (*ppStr) { |
190 | /* Copy the string buffer in */ |
191 | memcpy(*ppStr, *ppBuf, ulStrLen); |
192 | /* Put a NULL terminator on the end */ |
193 | (*ppStr)[ulStrLen] = '\0'; |
194 | /* Update the parsing buffer counters */ |
195 | *ppBuf += ulStrLen; |
196 | *pulLen -= ulStrLen; |
197 | } else { |
198 | retVal = HXR_OUTOFMEMORY; |
199 | } |
200 | } |
201 | } |
202 | |
203 | return retVal; |
204 | } |
205 | |
206 | HX_RESULT rm_unpack_buffer(BYTE** ppBuf, |
207 | UINT32* pulLen, |
208 | UINT32 ulBufLen, |
209 | BYTE** ppUnPackBuf, |
210 | void* pUserMem, |
211 | rm_malloc_func_ptr fpMalloc, |
212 | rm_free_func_ptr fpFree) |
213 | { |
214 | HX_RESULT retVal = HXR_FAIL; |
215 | |
216 | if (ppBuf && pulLen && *pulLen >= ulBufLen && ppUnPackBuf && fpMalloc && fpFree) { |
217 | /* Clear the return value */ |
218 | retVal = HXR_OK; |
219 | /* Do we have a buffer? */ |
220 | if (ulBufLen) { |
221 | /* If the string is already allocated, free it */ |
222 | if (*ppUnPackBuf) { |
223 | fpFree(pUserMem, *ppUnPackBuf); |
224 | *ppUnPackBuf = HXNULL; |
225 | } |
226 | /* Allocate a buffer that it one more byte than the length */ |
227 | *ppUnPackBuf = (BYTE*) fpMalloc(pUserMem, ulBufLen); |
228 | if (*ppUnPackBuf) { |
229 | /* Copy the string buffer in */ |
230 | memcpy(*ppUnPackBuf, *ppBuf, ulBufLen); |
231 | /* Update the parsing buffer counters */ |
232 | *ppBuf += ulBufLen; |
233 | *pulLen -= ulBufLen; |
234 | } else { |
235 | retVal = HXR_OUTOFMEMORY; |
236 | } |
237 | } |
238 | } |
239 | |
240 | return retVal; |
241 | } |
242 | |
243 | HX_RESULT rm_unpack_array(BYTE** ppBuf, |
244 | UINT32* pulLen, |
245 | UINT32 ulNumElem, |
246 | UINT32 ulElemSize, |
247 | void** ppArr, |
248 | void* pUserMem, |
249 | rm_malloc_func_ptr fpMalloc, |
250 | rm_free_func_ptr fpFree) |
251 | { |
252 | HX_RESULT retVal = HXR_FAIL; |
253 | |
254 | if (ppBuf && pulLen && *pulLen >= ulNumElem * ulElemSize && |
255 | ppArr && fpMalloc && fpFree) { |
256 | /* Clear the return value */ |
257 | retVal = HXR_OK; |
258 | /* Do we have any elements? */ |
259 | if (ulNumElem) { |
260 | /* If the array is already allocated, then free it */ |
261 | if (*ppArr) { |
262 | fpFree(pUserMem, *ppArr); |
263 | *ppArr = HXNULL; |
264 | } |
265 | /* Allocate space for the array */ |
266 | *ppArr = fpMalloc(pUserMem, ulNumElem * ulElemSize); |
267 | if (*ppArr) { |
268 | /* Is this a UINT32 or a UINT16? */ |
269 | UINT32 i = 0; |
270 | if (ulElemSize == sizeof(UINT32)) { |
271 | /* Unpack UINT32s */ |
272 | UINT32* pArr32 = (UINT32*) * ppArr; |
273 | for (i = 0; i < ulNumElem; i++) { |
274 | pArr32[i] = rm_unpack32(ppBuf, pulLen); |
275 | } |
276 | } else if (ulElemSize == sizeof(UINT16)) { |
277 | /* Unpack UINT16s */ |
278 | UINT16* pArr16 = (UINT16*) * ppArr; |
279 | for (i = 0; i < ulNumElem; i++) { |
280 | pArr16[i] = rm_unpack16(ppBuf, pulLen); |
281 | } |
282 | } |
283 | /* Clear the return value */ |
284 | retVal = HXR_OK; |
285 | } else { |
286 | retVal = HXR_OUTOFMEMORY; |
287 | } |
288 | } |
289 | } |
290 | |
291 | return retVal; |
292 | } |
293 | |
294 | UINT32 rm_unpack32_from_byte_string(BYTE** ppBuf, UINT32* pulLen) |
295 | { |
296 | UINT32 ulRet = 0; |
297 | |
298 | if (ppBuf && *ppBuf && pulLen && *pulLen) { |
299 | UINT32 ulStrLen = rm_unpack8(ppBuf, pulLen); |
300 | if (ulStrLen == 4 && *pulLen >= ulStrLen) { |
301 | ulRet = rm_unpack32(ppBuf, pulLen); |
302 | } |
303 | } |
304 | |
305 | return ulRet; |
306 | } |
307 |