]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | var POW_8 = Math.pow(2, 8); | |
21 | var POW_16 = Math.pow(2, 16); | |
22 | var POW_24 = Math.pow(2, 24); | |
23 | var POW_32 = Math.pow(2, 32); | |
24 | var POW_40 = Math.pow(2, 40); | |
25 | var POW_48 = Math.pow(2, 48); | |
26 | var POW_52 = Math.pow(2, 52); | |
27 | var POW_1022 = Math.pow(2, 1022); | |
28 | ||
29 | exports.readByte = function(b){ | |
30 | return b > 127 ? b-256 : b; | |
31 | }; | |
32 | ||
33 | exports.readI16 = function(buff, off) { | |
34 | off = off || 0; | |
35 | var v = buff[off + 1]; | |
36 | v += buff[off] << 8; | |
37 | if (buff[off] & 128) { | |
38 | v -= POW_16; | |
39 | } | |
40 | return v; | |
41 | }; | |
42 | ||
43 | exports.readI32 = function(buff, off) { | |
44 | off = off || 0; | |
45 | var v = buff[off + 3]; | |
46 | v += buff[off + 2] << 8; | |
47 | v += buff[off + 1] << 16; | |
48 | v += buff[off] * POW_24; | |
49 | if (buff[off] & 0x80) { | |
50 | v -= POW_32; | |
51 | } | |
52 | return v; | |
53 | }; | |
54 | ||
55 | exports.writeI16 = function(buff, v) { | |
56 | buff[1] = v & 0xff; | |
57 | v >>= 8; | |
58 | buff[0] = v & 0xff; | |
59 | return buff; | |
60 | }; | |
61 | ||
62 | exports.writeI32 = function(buff, v) { | |
63 | buff[3] = v & 0xff; | |
64 | v >>= 8; | |
65 | buff[2] = v & 0xff; | |
66 | v >>= 8; | |
67 | buff[1] = v & 0xff; | |
68 | v >>= 8; | |
69 | buff[0] = v & 0xff; | |
70 | return buff; | |
71 | }; | |
72 | ||
73 | exports.readDouble = function(buff, off) { | |
74 | off = off || 0; | |
75 | var signed = buff[off] & 0x80; | |
76 | var e = (buff[off+1] & 0xF0) >> 4; | |
77 | e += (buff[off] & 0x7F) << 4; | |
78 | ||
79 | var m = buff[off+7]; | |
80 | m += buff[off+6] << 8; | |
81 | m += buff[off+5] << 16; | |
82 | m += buff[off+4] * POW_24; | |
83 | m += buff[off+3] * POW_32; | |
84 | m += buff[off+2] * POW_40; | |
85 | m += (buff[off+1] & 0x0F) * POW_48; | |
86 | ||
87 | switch (e) { | |
88 | case 0: | |
89 | e = -1022; | |
90 | break; | |
91 | case 2047: | |
92 | return m ? NaN : (signed ? -Infinity : Infinity); | |
93 | default: | |
94 | m += POW_52; | |
95 | e -= 1023; | |
96 | } | |
97 | ||
98 | if (signed) { | |
99 | m *= -1; | |
100 | } | |
101 | ||
102 | return m * Math.pow(2, e - 52); | |
103 | }; | |
104 | ||
105 | /* | |
106 | * Based on code from the jspack module: | |
107 | * http://code.google.com/p/jspack/ | |
108 | */ | |
109 | exports.writeDouble = function(buff, v) { | |
110 | var m, e, c; | |
111 | ||
112 | buff[0] = (v < 0 ? 0x80 : 0x00); | |
113 | ||
114 | v = Math.abs(v); | |
115 | if (v !== v) { | |
116 | // NaN, use QNaN IEEE format | |
117 | m = 2251799813685248; | |
118 | e = 2047; | |
119 | } else if (v === Infinity) { | |
120 | m = 0; | |
121 | e = 2047; | |
122 | } else { | |
123 | e = Math.floor(Math.log(v) / Math.LN2); | |
124 | c = Math.pow(2, -e); | |
125 | if (v * c < 1) { | |
126 | e--; | |
127 | c *= 2; | |
128 | } | |
129 | ||
130 | if (e + 1023 >= 2047) | |
131 | { | |
132 | // Overflow | |
133 | m = 0; | |
134 | e = 2047; | |
135 | } | |
136 | else if (e + 1023 >= 1) | |
137 | { | |
138 | // Normalized - term order matters, as Math.pow(2, 52-e) and v*Math.pow(2, 52) can overflow | |
139 | m = (v*c-1) * POW_52; | |
140 | e += 1023; | |
141 | } | |
142 | else | |
143 | { | |
144 | // Denormalized - also catches the '0' case, somewhat by chance | |
145 | m = (v * POW_1022) * POW_52; | |
146 | e = 0; | |
147 | } | |
148 | } | |
149 | ||
150 | buff[1] = (e << 4) & 0xf0; | |
151 | buff[0] |= (e >> 4) & 0x7f; | |
152 | ||
153 | buff[7] = m & 0xff; | |
154 | m = Math.floor(m / POW_8); | |
155 | buff[6] = m & 0xff; | |
156 | m = Math.floor(m / POW_8); | |
157 | buff[5] = m & 0xff; | |
158 | m = Math.floor(m / POW_8); | |
159 | buff[4] = m & 0xff; | |
160 | m >>= 8; | |
161 | buff[3] = m & 0xff; | |
162 | m >>= 8; | |
163 | buff[2] = m & 0xff; | |
164 | m >>= 8; | |
165 | buff[1] |= m & 0x0f; | |
166 | ||
167 | return buff; | |
168 | }; |