/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ var POW_8 = Math.pow(2, 8); var POW_16 = Math.pow(2, 16); var POW_24 = Math.pow(2, 24); var POW_32 = Math.pow(2, 32); var POW_40 = Math.pow(2, 40); var POW_48 = Math.pow(2, 48); var POW_52 = Math.pow(2, 52); var POW_1022 = Math.pow(2, 1022); exports.readByte = function(b){ return b > 127 ? b-256 : b; }; exports.readI16 = function(buff, off) { off = off || 0; var v = buff[off + 1]; v += buff[off] << 8; if (buff[off] & 128) { v -= POW_16; } return v; }; exports.readI32 = function(buff, off) { off = off || 0; var v = buff[off + 3]; v += buff[off + 2] << 8; v += buff[off + 1] << 16; v += buff[off] * POW_24; if (buff[off] & 0x80) { v -= POW_32; } return v; }; exports.writeI16 = function(buff, v) { buff[1] = v & 0xff; v >>= 8; buff[0] = v & 0xff; return buff; }; exports.writeI32 = function(buff, v) { buff[3] = v & 0xff; v >>= 8; buff[2] = v & 0xff; v >>= 8; buff[1] = v & 0xff; v >>= 8; buff[0] = v & 0xff; return buff; }; exports.readDouble = function(buff, off) { off = off || 0; var signed = buff[off] & 0x80; var e = (buff[off+1] & 0xF0) >> 4; e += (buff[off] & 0x7F) << 4; var m = buff[off+7]; m += buff[off+6] << 8; m += buff[off+5] << 16; m += buff[off+4] * POW_24; m += buff[off+3] * POW_32; m += buff[off+2] * POW_40; m += (buff[off+1] & 0x0F) * POW_48; switch (e) { case 0: e = -1022; break; case 2047: return m ? NaN : (signed ? -Infinity : Infinity); default: m += POW_52; e -= 1023; } if (signed) { m *= -1; } return m * Math.pow(2, e - 52); }; /* * Based on code from the jspack module: * http://code.google.com/p/jspack/ */ exports.writeDouble = function(buff, v) { var m, e, c; buff[0] = (v < 0 ? 0x80 : 0x00); v = Math.abs(v); if (v !== v) { // NaN, use QNaN IEEE format m = 2251799813685248; e = 2047; } else if (v === Infinity) { m = 0; e = 2047; } else { e = Math.floor(Math.log(v) / Math.LN2); c = Math.pow(2, -e); if (v * c < 1) { e--; c *= 2; } if (e + 1023 >= 2047) { // Overflow m = 0; e = 2047; } else if (e + 1023 >= 1) { // Normalized - term order matters, as Math.pow(2, 52-e) and v*Math.pow(2, 52) can overflow m = (v*c-1) * POW_52; e += 1023; } else { // Denormalized - also catches the '0' case, somewhat by chance m = (v * POW_1022) * POW_52; e = 0; } } buff[1] = (e << 4) & 0xf0; buff[0] |= (e >> 4) & 0x7f; buff[7] = m & 0xff; m = Math.floor(m / POW_8); buff[6] = m & 0xff; m = Math.floor(m / POW_8); buff[5] = m & 0xff; m = Math.floor(m / POW_8); buff[4] = m & 0xff; m >>= 8; buff[3] = m & 0xff; m >>= 8; buff[2] = m & 0xff; m >>= 8; buff[1] |= m & 0x0f; return buff; };