blob: 6cbb8ac28f84235c4d9bb5223529512c255b94ae [file] [log] [blame]
Jeff Thompson47eecfc2013-07-07 22:56:46 -07001/**
Jeff Thompson7687dc02013-09-13 11:54:07 -07002 * Copyright (C) 2013 Regents of the University of California.
3 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompsone5b37a52013-07-08 15:39:01 -07004 * Derived from BinaryXMLDecoder.js by Meki Cheraoui.
Jeff Thompson47eecfc2013-07-07 22:56:46 -07005 * See COPYING for copyright and distribution information.
Jeff Thompson76317aa2013-06-25 19:11:48 -07006 */
7
Jeff Thompson53412192013-08-06 13:35:50 -07008#include "binary-xml.h"
9#include "binary-xml-decoder.h"
Jeff Thompson76317aa2013-06-25 19:11:48 -070010
Jeff Thompsonb4ee4002013-06-28 13:41:43 -070011/**
12 * Return the octet at self->offset, converting to unsigned int. Increment self->offset.
13 * This does not check for reading past the end of the input, so this is called "unsafe".
14 */
Jeff Thompsonf0fea002013-07-30 17:22:42 -070015static inline unsigned int unsafeReadOctet(struct ndn_BinaryXmlDecoder *self)
Jeff Thompsonb4ee4002013-06-28 13:41:43 -070016{
17 return (unsigned int)(self->input[self->offset++] & 0xff);
18}
19
20/**
21 * Return the octet at self->offset, converting to unsigned int. Do not increment self->offset.
22 * This does not check for reading past the end of the input, so this is called "unsafe".
23 */
Jeff Thompsonf0fea002013-07-30 17:22:42 -070024static inline unsigned int unsafeGetOctet(struct ndn_BinaryXmlDecoder *self)
Jeff Thompsonb4ee4002013-06-28 13:41:43 -070025{
26 return (unsigned int)(self->input[self->offset] & 0xff);
27}
28
Jeff Thompson167ca5a2013-07-07 20:45:43 -070029/**
30 * Parse the value as a decimal unsigned integer. This does not check for whitespace or + sign.
31 * If valueLength is 0, this succeeds with resultOut 0.
32 * @param value
33 * @param valueLength
34 * @param resultOut output the parsed integer.
Jeff Thompson8b666002013-07-08 01:16:26 -070035 * @return 0 for success, else an error code, including if an element of value is not a decimal digit.
Jeff Thompson167ca5a2013-07-07 20:45:43 -070036 */
Jeff Thompson97223af2013-09-24 17:01:27 -070037static ndn_Error parseUnsignedDecimalInt(uint8_t *value, size_t valueLength, unsigned int *resultOut)
Jeff Thompson167ca5a2013-07-07 20:45:43 -070038{
39 unsigned int result = 0;
40
Jeff Thompson97223af2013-09-24 17:01:27 -070041 size_t i;
Jeff Thompson167ca5a2013-07-07 20:45:43 -070042 for (i = 0; i < valueLength; ++i) {
Jeff Thompson10ad12a2013-09-24 16:19:11 -070043 uint8_t digit = value[i];
Jeff Thompson167ca5a2013-07-07 20:45:43 -070044 if (!(digit >= '0' && digit <= '9'))
Jeff Thompson8b666002013-07-08 01:16:26 -070045 return NDN_ERROR_element_of_value_is_not_a_decimal_digit;
Jeff Thompson167ca5a2013-07-07 20:45:43 -070046
47 result *= 10;
48 result += (unsigned int)(digit - '0');
49 }
50
51 *resultOut = result;
Jeff Thompsonadaf9232013-08-08 14:30:29 -070052 return NDN_ERROR_success;
Jeff Thompson167ca5a2013-07-07 20:45:43 -070053}
54
Jeff Thompsonf0fea002013-07-30 17:22:42 -070055ndn_Error ndn_BinaryXmlDecoder_decodeTypeAndValue(struct ndn_BinaryXmlDecoder *self, unsigned int *type, unsigned int *valueOut)
Jeff Thompson82222e82013-06-26 19:32:59 -070056{
Jeff Thompson76317aa2013-06-25 19:11:48 -070057 unsigned int value = 0;
Jeff Thompson38cbd572013-06-28 14:01:10 -070058 int gotFirstOctet = 0;
Jeff Thompson76317aa2013-06-25 19:11:48 -070059
Jeff Thompsona0d18c92013-08-06 13:55:32 -070060 while (1) {
Jeff Thompsonf7316692013-06-26 21:31:42 -070061 if (self->offset >= self->inputLength)
Jeff Thompson8b666002013-07-08 01:16:26 -070062 return NDN_ERROR_read_past_the_end_of_the_input;
Jeff Thompson76317aa2013-06-25 19:11:48 -070063
Jeff Thompsona0d18c92013-08-06 13:55:32 -070064 unsigned int octet = unsafeReadOctet(self);
65
Jeff Thompson38cbd572013-06-28 14:01:10 -070066 if (!gotFirstOctet) {
67 if (octet == 0)
Jeff Thompson8b666002013-07-08 01:16:26 -070068 return NDN_ERROR_the_first_header_octet_may_not_be_zero;
Jeff Thompson38cbd572013-06-28 14:01:10 -070069
70 gotFirstOctet = 1;
71 }
72
Jeff Thompsona0d18c92013-08-06 13:55:32 -070073 if (octet & ndn_BinaryXml_TT_FINAL) {
Jeff Thompson76317aa2013-06-25 19:11:48 -070074 // Finished.
Jeff Thompsona0d18c92013-08-06 13:55:32 -070075 *type = octet & ndn_BinaryXml_TT_MASK;
76 value = (value << ndn_BinaryXml_TT_VALUE_BITS) | ((octet >> ndn_BinaryXml_TT_BITS) & ndn_BinaryXml_TT_VALUE_MASK);
Jeff Thompson76317aa2013-06-25 19:11:48 -070077 break;
Jeff Thompsona0d18c92013-08-06 13:55:32 -070078 }
79
80 value = (value << ndn_BinaryXml_REGULAR_VALUE_BITS) | (octet & ndn_BinaryXml_REGULAR_VALUE_MASK);
81 }
Jeff Thompson76317aa2013-06-25 19:11:48 -070082
Jeff Thompsona0d18c92013-08-06 13:55:32 -070083 *valueOut = value;
Jeff Thompsonadaf9232013-08-08 14:30:29 -070084 return NDN_ERROR_success;
Jeff Thompson76317aa2013-06-25 19:11:48 -070085}
Jeff Thompson179d0502013-06-28 11:36:00 -070086
Jeff Thompsonf0fea002013-07-30 17:22:42 -070087ndn_Error ndn_BinaryXmlDecoder_readElementStartDTag(struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag)
Jeff Thompson179d0502013-06-28 11:36:00 -070088{
Jeff Thompson8b666002013-07-08 01:16:26 -070089 ndn_Error error;
Jeff Thompson179d0502013-06-28 11:36:00 -070090 unsigned int type;
91 unsigned int value;
Jeff Thompson94ddc272013-08-08 14:17:38 -070092 if ((error = ndn_BinaryXmlDecoder_decodeTypeAndValue(self, &type, &value)))
Jeff Thompson179d0502013-06-28 11:36:00 -070093 return error;
94
Jeff Thompsonf0fea002013-07-30 17:22:42 -070095 if (type != ndn_BinaryXml_DTAG)
Jeff Thompson8b666002013-07-08 01:16:26 -070096 return NDN_ERROR_header_type_is_not_a_DTAG;
Jeff Thompson179d0502013-06-28 11:36:00 -070097
Jeff Thompson74ab0812013-06-28 12:25:04 -070098 if (value != expectedTag)
Jeff Thompson8b666002013-07-08 01:16:26 -070099 return NDN_ERROR_did_not_get_the_expected_DTAG;
Jeff Thompson179d0502013-06-28 11:36:00 -0700100
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700101 return NDN_ERROR_success;
Jeff Thompson74ab0812013-06-28 12:25:04 -0700102}
103
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700104ndn_Error ndn_BinaryXmlDecoder_readElementClose(struct ndn_BinaryXmlDecoder *self)
Jeff Thompson74ab0812013-06-28 12:25:04 -0700105{
106 if (self->offset >= self->inputLength)
Jeff Thompson8b666002013-07-08 01:16:26 -0700107 return NDN_ERROR_read_past_the_end_of_the_input;
Jeff Thompson74ab0812013-06-28 12:25:04 -0700108
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700109 if (unsafeReadOctet(self) != ndn_BinaryXml_CLOSE)
Jeff Thompson8b666002013-07-08 01:16:26 -0700110 return NDN_ERROR_did_not_get_the_expected_element_close;
Jeff Thompson74ab0812013-06-28 12:25:04 -0700111
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700112 return NDN_ERROR_success;
Jeff Thompson74ab0812013-06-28 12:25:04 -0700113}
114
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700115ndn_Error ndn_BinaryXmlDecoder_peekDTag(struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int *gotExpectedTag)
Jeff Thompson74ab0812013-06-28 12:25:04 -0700116{
117 // Default to 0.
118 *gotExpectedTag = 0;
Jeff Thompson6d17b6e2013-06-28 14:04:01 -0700119
120 // First check if it is an element close (which cannot be the expected tag).
121 if (self->offset >= self->inputLength)
Jeff Thompson8b666002013-07-08 01:16:26 -0700122 return NDN_ERROR_read_past_the_end_of_the_input;
Jeff Thompson6d17b6e2013-06-28 14:04:01 -0700123 if (unsafeGetOctet(self) == 0)
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700124 return NDN_ERROR_success;
Jeff Thompson6d17b6e2013-06-28 14:04:01 -0700125
Jeff Thompson74ab0812013-06-28 12:25:04 -0700126 unsigned int type;
127 unsigned int value;
Jeff Thompson97223af2013-09-24 17:01:27 -0700128 size_t saveOffset = self->offset;
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700129 ndn_Error error = ndn_BinaryXmlDecoder_decodeTypeAndValue(self, &type, &value);
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700130 // Restore offset.
Jeff Thompson74ab0812013-06-28 12:25:04 -0700131 self->offset = saveOffset;
132
133 if (error)
134 return error;
135
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700136 if (type == ndn_BinaryXml_DTAG && value == expectedTag)
Jeff Thompson74ab0812013-06-28 12:25:04 -0700137 *gotExpectedTag = 1;
138
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700139 return NDN_ERROR_success;
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700140}
141
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700142ndn_Error ndn_BinaryXmlDecoder_readBinaryDTagElement
Jeff Thompson97223af2013-09-24 17:01:27 -0700143 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, uint8_t **value, size_t *valueLength)
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700144{
Jeff Thompson8b666002013-07-08 01:16:26 -0700145 ndn_Error error;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700146 if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(self, expectedTag)))
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700147 return error;
148
149 if (allowNull) {
150 if (self->offset >= self->inputLength)
Jeff Thompson8b666002013-07-08 01:16:26 -0700151 return NDN_ERROR_read_past_the_end_of_the_input;
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700152
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700153 if (unsafeGetOctet(self) == ndn_BinaryXml_CLOSE) {
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700154 // The binary item is missing, and this is allowed, so read the element close and return a null value.
155 ++self->offset;
156 *value = 0;
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700157 *valueLength = 0;
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700158 return NDN_ERROR_success;
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700159 }
160 }
161
162 unsigned int itemType;
Jeff Thompson97223af2013-09-24 17:01:27 -0700163 unsigned int uintValueLength;
164 if ((error = ndn_BinaryXmlDecoder_decodeTypeAndValue(self, &itemType, &uintValueLength)))
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700165 return error;
166 // Ignore itemType.
167 *value = self->input + self->offset;
Jeff Thompson97223af2013-09-24 17:01:27 -0700168 *valueLength = (size_t)uintValueLength;
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700169 self->offset += *valueLength;
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700170
Jeff Thompson94ddc272013-08-08 14:17:38 -0700171 if ((error = ndn_BinaryXmlDecoder_readElementClose(self)))
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700172 return error;
173
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700174 return NDN_ERROR_success;
Jeff Thompsonb4ee4002013-06-28 13:41:43 -0700175}
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700176
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700177ndn_Error ndn_BinaryXmlDecoder_readOptionalBinaryDTagElement
Jeff Thompson97223af2013-09-24 17:01:27 -0700178 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int allowNull, uint8_t **value, size_t *valueLength)
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700179{
180 ndn_Error error;
181 int gotExpectedTag;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700182 if ((error = ndn_BinaryXmlDecoder_peekDTag(self, expectedTag, &gotExpectedTag)))
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700183 return error;
184 if (gotExpectedTag) {
Jeff Thompson94ddc272013-08-08 14:17:38 -0700185 if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(self, expectedTag, allowNull, value, valueLength)))
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700186 return error;
187 }
188 else {
189 *value = 0;
190 *valueLength = 0;
191 }
192
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700193 return NDN_ERROR_success;
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700194}
195
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700196ndn_Error ndn_BinaryXmlDecoder_readUDataDTagElement
Jeff Thompson97223af2013-09-24 17:01:27 -0700197 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, uint8_t **value, size_t *valueLength)
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700198{
Jeff Thompson8b666002013-07-08 01:16:26 -0700199 ndn_Error error;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700200 if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(self, expectedTag)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700201 return error;
202
203 unsigned int itemType;
Jeff Thompson97223af2013-09-24 17:01:27 -0700204 unsigned int uintValueLength;
205 if ((error = ndn_BinaryXmlDecoder_decodeTypeAndValue(self, &itemType, &uintValueLength)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700206 return error;
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700207 if (itemType != ndn_BinaryXml_UDATA)
Jeff Thompson8b666002013-07-08 01:16:26 -0700208 return NDN_ERROR_item_is_not_UDATA;
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700209 *value = self->input + self->offset;
Jeff Thompson97223af2013-09-24 17:01:27 -0700210 *valueLength = uintValueLength;
Jeff Thompson033d7fd2013-07-11 10:44:03 -0700211 self->offset += *valueLength;
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700212
Jeff Thompson94ddc272013-08-08 14:17:38 -0700213 if ((error = ndn_BinaryXmlDecoder_readElementClose(self)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700214 return error;
215
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700216 return NDN_ERROR_success;
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700217}
218
Jeff Thompson57be78e2013-08-27 13:40:23 -0700219ndn_Error ndn_BinaryXmlDecoder_readOptionalUDataDTagElement
Jeff Thompson97223af2013-09-24 17:01:27 -0700220 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, uint8_t **value, size_t *valueLength)
Jeff Thompson57be78e2013-08-27 13:40:23 -0700221{
222 ndn_Error error;
223 int gotExpectedTag;
224 if ((error = ndn_BinaryXmlDecoder_peekDTag(self, expectedTag, &gotExpectedTag)))
225 return error;
226 if (gotExpectedTag) {
227 if ((error = ndn_BinaryXmlDecoder_readUDataDTagElement(self, expectedTag, value, valueLength)))
228 return error;
229 }
230 else {
231 *value = 0;
232 *valueLength = 0;
233 }
234
235 return NDN_ERROR_success;
236}
237
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700238ndn_Error ndn_BinaryXmlDecoder_readUnsignedIntegerDTagElement
239 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, unsigned int *value)
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700240{
Jeff Thompson10ad12a2013-09-24 16:19:11 -0700241 uint8_t *udataValue;
Jeff Thompson97223af2013-09-24 17:01:27 -0700242 size_t udataValueLength;
Jeff Thompson8b666002013-07-08 01:16:26 -0700243 ndn_Error error;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700244 if ((error = ndn_BinaryXmlDecoder_readUDataDTagElement(self, expectedTag, &udataValue, &udataValueLength)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700245 return error;
246
Jeff Thompson94ddc272013-08-08 14:17:38 -0700247 if ((error = parseUnsignedDecimalInt(udataValue, udataValueLength, value)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700248 return error;
249
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700250 return NDN_ERROR_success;
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700251}
252
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700253ndn_Error ndn_BinaryXmlDecoder_readOptionalUnsignedIntegerDTagElement
254 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, int *value)
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700255{
256 int gotExpectedTag;
Jeff Thompson8b666002013-07-08 01:16:26 -0700257 ndn_Error error;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700258 if ((error = ndn_BinaryXmlDecoder_peekDTag(self, expectedTag, &gotExpectedTag)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700259 return error;
260
261 if (!gotExpectedTag) {
Jeff Thompson5abaaca2013-07-07 21:16:04 -0700262 *value = -1;
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700263 return NDN_ERROR_success;
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700264 }
265
266 unsigned int unsignedValue;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700267 if ((error = ndn_BinaryXmlDecoder_readUnsignedIntegerDTagElement(self, expectedTag, &unsignedValue)))
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700268 return error;
269
270 *value = (int)unsignedValue;
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700271 return NDN_ERROR_success;
Jeff Thompson167ca5a2013-07-07 20:45:43 -0700272}
Jeff Thompson5abaaca2013-07-07 21:16:04 -0700273
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700274ndn_Error ndn_BinaryXmlDecoder_readTimeMillisecondsDTagElement
275 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, double *milliseconds)
Jeff Thompson9693d392013-07-11 14:58:53 -0700276{
277 ndn_Error error;
Jeff Thompson10ad12a2013-09-24 16:19:11 -0700278 uint8_t *bytes;
Jeff Thompson97223af2013-09-24 17:01:27 -0700279 size_t bytesLength;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700280 if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(self, expectedTag, 0, &bytes, &bytesLength)))
Jeff Thompson9693d392013-07-11 14:58:53 -0700281 return error;
282
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700283 *milliseconds = 1000.0 * ndn_BinaryXmlDecoder_unsignedBigEndianToDouble(bytes, bytesLength) / 4096.0;
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700284 return NDN_ERROR_success;
Jeff Thompson9693d392013-07-11 14:58:53 -0700285}
286
Jeff Thompsonf0fea002013-07-30 17:22:42 -0700287ndn_Error ndn_BinaryXmlDecoder_readOptionalTimeMillisecondsDTagElement
288 (struct ndn_BinaryXmlDecoder *self, unsigned int expectedTag, double *milliseconds)
Jeff Thompson9693d392013-07-11 14:58:53 -0700289{
290 int gotExpectedTag;
291 ndn_Error error;
Jeff Thompson94ddc272013-08-08 14:17:38 -0700292 if ((error = ndn_BinaryXmlDecoder_peekDTag(self, expectedTag, &gotExpectedTag)))
Jeff Thompson9693d392013-07-11 14:58:53 -0700293 return error;
294
295 if (!gotExpectedTag) {
Jeff Thompsone32dc5d2013-07-11 17:56:57 -0700296 *milliseconds = -1.0;
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700297 return NDN_ERROR_success;
Jeff Thompson9693d392013-07-11 14:58:53 -0700298 }
299
Jeff Thompson94ddc272013-08-08 14:17:38 -0700300 if ((error = ndn_BinaryXmlDecoder_readTimeMillisecondsDTagElement(self, expectedTag, milliseconds)))
Jeff Thompson9693d392013-07-11 14:58:53 -0700301 return error;
302
Jeff Thompsonadaf9232013-08-08 14:30:29 -0700303 return NDN_ERROR_success;
Jeff Thompson9693d392013-07-11 14:58:53 -0700304}
305
Jeff Thompson97223af2013-09-24 17:01:27 -0700306double ndn_BinaryXmlDecoder_unsignedBigEndianToDouble(uint8_t *bytes, size_t bytesLength)
Jeff Thompson5abaaca2013-07-07 21:16:04 -0700307{
Jeff Thompson5553d992013-07-11 14:35:45 -0700308 double result = 0.0;
Jeff Thompson97223af2013-09-24 17:01:27 -0700309 size_t i;
Jeff Thompson5abaaca2013-07-07 21:16:04 -0700310 for (i = 0; i < bytesLength; ++i) {
Jeff Thompson5553d992013-07-11 14:35:45 -0700311 result *= 256.0;
312 result += (double)bytes[i];
Jeff Thompson5abaaca2013-07-07 21:16:04 -0700313 }
314
315 return result;
316}