15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)'use strict'; 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @constructor 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {ArrayBuffer} arrayBuffer // TODO(JSDOC). 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_offset // TODO(JSDOC). 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_length // TODO(JSDOC). 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function ByteReader(arrayBuffer, opt_offset, opt_length) { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_offset = opt_offset || 0; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_length = opt_length || (arrayBuffer.byteLength - opt_offset); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.view_ = new DataView(arrayBuffer, opt_offset, opt_length); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ = 0; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.seekStack_ = []; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.setByteOrder(ByteReader.BIG_ENDIAN); 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Static constants and methods. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Intel, 0x1234 is [0x34, 0x12] 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number} 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ByteReader.LITTLE_ENDIAN = 0; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Motorola, 0x1234 is [0x12, 0x34] 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number} 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ByteReader.BIG_ENDIAN = 1; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Seek relative to the beginning of the buffer. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ByteReader.SEEK_BEG = 0; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Seek relative to the current position. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ByteReader.SEEK_CUR = 1; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Seek relative to the end of the buffer. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number} 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ByteReader.SEEK_END = 2; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Throw an error if (0 > pos >= end) or if (pos + size > end). 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Static utility function. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} end // TODO(JSDOC). 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.validateRead = function(pos, size, end) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos < 0 || pos >= end) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Error('Invalid read position'); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos + size > end) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Error('Read past end of buffer'); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of characters, returning them as a single string. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a static utility function. There is a member function with the 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * same name which side-effects the current read position. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {DataView} dataView // TODO(JSDOC). 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.readString = function(dataView, pos, size, opt_end) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteReader.validateRead(pos, size, opt_end || dataView.byteLength); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var codes = []; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < size; ++i) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codes.push(dataView.getUint8(pos + i)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return String.fromCharCode.apply(null, codes); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of characters, returning them as a single string. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a static utility function. There is a member function with the 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * same name which side-effects the current read position. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {DataView} dataView // TODO(JSDOC). 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.readNullTerminatedString = function(dataView, pos, size, opt_end) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteReader.validateRead(pos, size, opt_end || dataView.byteLength); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var codes = []; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < size; ++i) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var code = dataView.getUint8(pos + i); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (code == 0) break; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codes.push(code); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return String.fromCharCode.apply(null, codes); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of UTF16 characters, returning them as a single string. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a static utility function. There is a member function with the 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * same name which side-effects the current read position. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {DataView} dataView // TODO(JSDOC). 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} bom // TODO(JSDOC). 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.readNullTerminatedStringUTF16 = function( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dataView, pos, bom, size, opt_end) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteReader.validateRead(pos, size, opt_end || dataView.byteLength); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var littleEndian = false; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var start = 0; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bom) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) littleEndian = (dataView.getUint8(pos) == 0xFF); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = 2; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var codes = []; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = start; i < size; i += 2) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var code = dataView.getUint16(pos + i, littleEndian); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (code == 0) break; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) codes.push(code); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return String.fromCharCode.apply(null, codes); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {Array.<string>} 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @private 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.base64Alphabet_ = 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'). 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) split(''); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of bytes, returning them as a single base64 encoded 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a static utility function. There is a member function with the 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * same name which side-effects the current read position. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {DataView} dataView // TODO(JSDOC). 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.readBase64 = function(dataView, pos, size, opt_end) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteReader.validateRead(pos, size, opt_end || dataView.byteLength); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = []; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var chars = []; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var padding = 0; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < size; /* incremented inside */) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var bits = dataView.getUint8(pos + (i++)) << 16; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < size) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bits |= dataView.getUint8(pos + (i++)) << 8; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < size) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bits |= dataView.getUint8(pos + (i++)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding = 1; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding = 2; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars[3] = ByteReader.base64Alphabet_[bits & 63]; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars[2] = ByteReader.base64Alphabet_[(bits >> 6) & 63]; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars[1] = ByteReader.base64Alphabet_[(bits >> 12) & 63]; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chars[0] = ByteReader.base64Alphabet_[(bits >> 18) & 63]; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv.push.apply(rv, chars); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (padding > 0) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv[rv.length - 1] = '='; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (padding > 1) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv[rv.length - 2] = '='; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv.join(''); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as an image encoded in a data url. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a static utility function. There is a member function with the 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * same name which side-effects the current read position. 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {DataView} dataView // TODO(JSDOC). 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.readImage = function(dataView, pos, size, opt_end) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_end = opt_end || dataView.byteLength; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteReader.validateRead(pos, size, opt_end); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Two bytes is enough to identify the mime type. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var prefixToMime = { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '\x89P' : 'png', 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '\xFF\xD8' : 'jpeg', 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'BM' : 'bmp', 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'GI' : 'gif' 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var prefix = ByteReader.readString(dataView, pos, 2, opt_end); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var mime = prefixToMime[prefix] || 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dataView.getUint16(pos, false).toString(16); // For debugging. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var b64 = ByteReader.readBase64(dataView, pos, size, opt_end); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 'data:image/' + mime + ';base64,' + b64; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instance methods. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return true if the requested number of bytes can be read from the buffer. 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} // TODO(JSDOC). 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.canRead = function(size) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.pos_ + size <= this.view_.byteLength; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return true if the current position is past the end of the buffer. 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} // TODO(JSDOC). 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.eof = function() { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.pos_ >= this.view_.byteLength; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return true if the current position is before the beginning of the buffer. 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} // TODO(JSDOC). 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.bof = function() { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.pos_ < 0; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return true if the current position is outside the buffer. 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} // TODO(JSDOC). 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.beof = function() { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.pos_ >= this.view_.byteLength || this.pos_ < 0; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set the expected byte ordering for future reads. 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} order // TODO(JSDOC). 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.setByteOrder = function(order) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.littleEndian_ = order == ByteReader.LITTLE_ENDIAN; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Throw an error if the reader is at an invalid position, or if a read a read 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of |size| would put it in one. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * You may optionally pass opt_end to override what is considered to be the 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * end of the buffer. 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.validateRead = function(size, opt_end) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (typeof opt_end == 'undefined') 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_end = this.view_.byteLength; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ByteReader.validateRead(this.view_, this.pos_, size, opt_end); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} width // TODO(JSDOC). 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean=} opt_signed // TODO(JSDOC). 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readScalar = function(width, opt_signed, opt_end) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var method = opt_signed ? 'getInt' : 'getUint'; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (width) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method += '8'; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method += '16'; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method += '32'; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method += '64'; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Error('Invalid width: ' + width); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.validateRead(width, opt_end); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = this.view_[method](this.pos_, this.littleEndian_); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += width; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of characters, returning them as a single string. 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the current position on success. Throws an exception if the 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read would go past the end of the buffer. 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readString = function(size, opt_end) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = ByteReader.readString(this.view_, this.pos_, size, opt_end); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += size; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of characters, returning them as a single string. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the current position on success. Throws an exception if the 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read would go past the end of the buffer. 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readNullTerminatedString = function(size, opt_end) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = ByteReader.readNullTerminatedString(this.view_, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size, 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_end); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += rv.length; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv.length < size) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we've stopped reading because we found '0' but didn't hit size limit 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then we should skip additional '0' character 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_++; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of UTF16 characters, returning them as a single string. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the current position on success. Throws an exception if the 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read would go past the end of the buffer. 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} bom // TODO(JSDOC). 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readNullTerminatedStringUTF16 = 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function(bom, size, opt_end) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = ByteReader.readNullTerminatedStringUTF16( 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.view_, this.pos_, bom, size, opt_end); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bom) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the BOM word was present advance the position. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += 2; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += rv.length; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv.length < size) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we've stopped reading because we found '0' but didn't hit size limit 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then we should skip additional '0' character 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += 2; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as an array of numbers. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the current position on success. Throws an exception if the 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read would go past the end of the buffer. 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {function(new:Array.<*>)=} opt_arrayConstructor // TODO(JSDOC). 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {Array.<*>} // TODO(JSDOC). 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readSlice = function(size, opt_end, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_arrayConstructor) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this.validateRead(size, opt_end); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var arrayConstructor = opt_arrayConstructor || Uint8Array; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var slice = new arrayConstructor( 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.view_.buffer, this.view_.byteOffset + this.pos, size); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += size; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return slice; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read as a sequence of bytes, returning them as a single base64 encoded 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string. 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the current position on success. Throws an exception if the 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read would go past the end of the buffer. 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readBase64 = function(size, opt_end) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = ByteReader.readBase64(this.view_, this.pos_, size, opt_end); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += size; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read an image returning it as a data url. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Adjusts the current position on success. Throws an exception if the 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read would go past the end of the buffer. 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} size // TODO(JSDOC). 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} // TODO(JSDOC). 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.readImage = function(size, opt_end) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var rv = ByteReader.readImage(this.view_, this.pos_, size, opt_end); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ += size; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Seek to a give position relative to opt_seekStart. 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_seekStart // TODO(JSDOC). 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_end // TODO(JSDOC). 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.seek = function(pos, opt_seekStart, opt_end) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) opt_end = opt_end || this.view_.byteLength; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var newPos; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opt_seekStart == ByteReader.SEEK_CUR) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newPos = this.pos_ + pos; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (opt_seekStart == ByteReader.SEEK_END) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newPos = opt_end + pos; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newPos = pos; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newPos < 0 || newPos > this.view_.byteLength) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) throw new Error('Seek outside of buffer: ' + (newPos - opt_end)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.pos_ = newPos; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Seek to a given position relative to opt_seekStart, saving the current 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * position. 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Recover the current position with a call to seekPop. 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} pos // TODO(JSDOC). 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number=} opt_seekStart // TODO(JSDOC). 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.pushSeek = function(pos, opt_seekStart) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var oldPos = this.pos_; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.seek(pos, opt_seekStart); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Alter the seekStack_ after the call to seek(), in case it throws. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.seekStack_.push(oldPos); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Undo a previous seekPush. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.popSeek = function() { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this.seek(this.seekStack_.pop()); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the current read position. 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {number} // TODO(JSDOC). 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ByteReader.prototype.tell = function() { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this.pos_; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 536