├── index.js ├── package.json └── public ├── axios.min.js ├── bytebuffer.js ├── index.html ├── long.js ├── message.proto └── protobuf.js /index.js: -------------------------------------------------------------------------------- 1 | let path = require('path') 2 | let express = require('express') 3 | let app = express() 4 | let messages = [ 5 | {text: 'hey', lang: 'english'}, 6 | {text: 'isänme', lang: 'tatar'}, 7 | {text: 'hej', lang: 'swedish'} 8 | ] 9 | let publicFolderName = 'public' 10 | app.use(express.static(publicFolderName)) 11 | app.use (function(req, res, next) { 12 | if (!req.is('application/octet-stream')) return next() 13 | var data = [] // List of Buffer objects 14 | req.on('data', function(chunk) { 15 | data.push(chunk) // Append Buffer object 16 | }) 17 | req.on('end', function() { 18 | if (data.length <= 0 ) return next() 19 | data = Buffer.concat(data) // Make one large Buffer of it 20 | console.log('Received buffer', data) 21 | req.raw = data 22 | next() 23 | }) 24 | }) 25 | let ProtoBuf = require('protobufjs') 26 | let builder = ProtoBuf.loadProtoFile( 27 | path.join(__dirname, 28 | publicFolderName, 29 | 'message.proto') 30 | ) 31 | let Message = builder.build('Message') 32 | 33 | app.get('/api/messages', (req, res, next)=>{ 34 | let msg = new Message(messages[Math.round(Math.random()*2)]) 35 | console.log('Encode and decode: ', 36 | Message.decode(msg.encode().toBuffer())) 37 | console.log('Buffer we are sending: ', msg.encode().toBuffer()) 38 | // res.end(msg.encode().toBuffer(), 'binary') // alternative 39 | res.send(msg.encode().toBuffer()) 40 | // res.end(Buffer.from(msg.toArrayBuffer()), 'binary') // alternative 41 | }) 42 | 43 | app.post('/api/messages', (req, res, next)=>{ 44 | if (req.raw) { 45 | try { 46 | // Decode the Message 47 | var msg = Message.decode(req.raw) 48 | console.log('Received "%s" in %s', msg.text, msg.lang) 49 | } catch (err) { 50 | console.log('Processing failed:', err) 51 | next(err) 52 | } 53 | } else { 54 | console.log("Not binary data") 55 | } 56 | }) 57 | 58 | app.all('*', (req, res)=>{ 59 | res.status(400).send('Not supported') 60 | }) 61 | 62 | app.listen(3000) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "proto-buffer-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Azat Mardan", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.13.4", 13 | "protobufjs": "^5.0.1" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /public/axios.min.js: -------------------------------------------------------------------------------- 1 | /* axios v0.11.1 | (c) 2016 by Matt Zabriskie */ 2 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";function n(e){this.defaults=i.merge({},e),this.interceptors={request:new u,response:new u}}var o=r(2),i=r(3),s=r(4),u=r(13),a=r(14),c=r(15),f=r(16),p=r(8);n.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,this.defaults,{method:"get"},e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.withCredentials=e.withCredentials||this.defaults.withCredentials,e.data=p(e.data,e.headers,e.transformRequest),e.headers=i.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),i.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=[s,void 0],r=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)r=r.then(t.shift(),t.shift());return r};var d=new n(o),l=e.exports=f(n.prototype.request,d);e.exports.Axios=n,l.defaults=d.defaults,l.interceptors=d.interceptors,l.create=function(e){return new n(e)},l.all=function(e){return Promise.all(e)},l.spread=r(17),i.forEach(["delete","get","head"],function(e){n.prototype[e]=function(t,r){return this.request(i.merge(r||{},{method:e,url:t}))},l[e]=f(n.prototype[e],d)}),i.forEach(["post","put","patch"],function(e){n.prototype[e]=function(t,r,n){return this.request(i.merge(n||{},{method:e,url:t,data:r}))},l[e]=f(n.prototype[e],d)})},function(e,t,r){"use strict";var n=r(3),o=/^\)\]\}',?\n/,i={"Content-Type":"application/x-www-form-urlencoded"};e.exports={transformRequest:[function(e,t){return n.isFormData(e)||n.isArrayBuffer(e)||n.isStream(e)?e:n.isArrayBufferView(e)?e.buffer:!n.isObject(e)||n.isFile(e)||n.isBlob(e)?e:(n.isUndefined(t)||(n.forEach(t,function(e,r){"content-type"===r.toLowerCase()&&(t["Content-Type"]=e)}),n.isUndefined(t["Content-Type"])&&(t["Content-Type"]="application/json;charset=utf-8")),JSON.stringify(e))}],transformResponse:[function(e){if("string"==typeof e){e=e.replace(o,"");try{e=JSON.parse(e)}catch(t){}}return e}],headers:{common:{Accept:"application/json, text/plain, */*"},patch:n.merge(i),post:n.merge(i),put:n.merge(i)},timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&300>e}}},function(e,t){"use strict";function r(e){return"[object Array]"===v.call(e)}function n(e){return"[object ArrayBuffer]"===v.call(e)}function o(e){return"undefined"!=typeof FormData&&e instanceof FormData}function i(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function s(e){return"string"==typeof e}function u(e){return"number"==typeof e}function a(e){return"undefined"==typeof e}function c(e){return null!==e&&"object"==typeof e}function f(e){return"[object Date]"===v.call(e)}function p(e){return"[object File]"===v.call(e)}function d(e){return"[object Blob]"===v.call(e)}function l(e){return"[object Function]"===v.call(e)}function h(e){return c(e)&&l(e.pipe)}function m(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function y(){return"undefined"!=typeof window&&"undefined"!=typeof document&&"function"==typeof document.createElement}function w(e,t){if(null!==e&&"undefined"!=typeof e)if("object"==typeof e||r(e)||(e=[e]),r(e))for(var n=0,o=e.length;o>n;n++)t.call(null,e[n],n,e);else for(var i in e)e.hasOwnProperty(i)&&t.call(null,e[i],i,e)}function g(){function e(e,r){"object"==typeof t[r]&&"object"==typeof e?t[r]=g(t[r],e):t[r]=e}for(var t={},r=0,n=arguments.length;n>r;r++)w(arguments[r],e);return t}var v=Object.prototype.toString;e.exports={isArray:r,isArrayBuffer:n,isFormData:o,isArrayBufferView:i,isString:s,isNumber:u,isObject:c,isUndefined:a,isDate:f,isFile:p,isBlob:d,isFunction:l,isStream:h,isStandardBrowserEnv:y,forEach:w,merge:g,trim:m}},function(e,t,r){"use strict";e.exports=function(e){return new Promise(function(t,n){try{var o;"function"==typeof e.adapter?o=e.adapter:"undefined"!=typeof XMLHttpRequest?o=r(5):"undefined"!=typeof process&&(o=r(5)),"function"==typeof o&&o(t,n,e)}catch(i){n(i)}})}},function(e,t,r){"use strict";var n=r(3),o=r(6),i=r(7),s=r(8),u=r(9),a="undefined"!=typeof window&&window.btoa||r(10),c=r(11);e.exports=function(e,t,f){var p=f.data,d=f.headers;n.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(f.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),f.auth){var y=f.auth.username||"",w=f.auth.password||"";d.Authorization="Basic "+a(y+":"+w)}if(l.open(f.method.toUpperCase(),o(f.url,f.params,f.paramsSerializer),!0),l.timeout=f.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&0!==l.status){var r="getAllResponseHeaders"in l?i(l.getAllResponseHeaders()):null,n=f.responseType&&"text"!==f.responseType?l.response:l.responseText,o={data:s(n,r,f.transformResponse),status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:r,config:f,request:l};c(e,t,o),l=null}},l.onerror=function(){t(new Error("Network Error")),l=null},l.ontimeout=function(){var e=new Error("timeout of "+f.timeout+"ms exceeded");e.timeout=f.timeout,e.code="ECONNABORTED",t(e),l=null},n.isStandardBrowserEnv()){var g=r(12),v=f.withCredentials||u(f.url)?g.read(f.xsrfCookieName):void 0;v&&(d[f.xsrfHeaderName]=v)}if("setRequestHeader"in l&&n.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),f.withCredentials&&(l.withCredentials=!0),f.responseType)try{l.responseType=f.responseType}catch(x){if("json"!==l.responseType)throw x}f.progress&&("post"===f.method||"put"===f.method?l.upload.addEventListener("progress",f.progress):"get"===f.method&&l.addEventListener("progress",f.progress)),void 0===p&&(p=null),l.send(p)}},function(e,t,r){"use strict";function n(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=r(3);e.exports=function(e,t,r){if(!t)return e;var i;if(r)i=r(t);else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)&&(t+="[]"),o.isArray(e)||(e=[e]),o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(n(t)+"="+n(e))}))}),i=s.join("&")}return i&&(e+=(-1===e.indexOf("?")?"?":"&")+i),e}},function(e,t,r){"use strict";var n=r(3);e.exports=function(e){var t,r,o,i={};return e?(n.forEach(e.split("\n"),function(e){o=e.indexOf(":"),t=n.trim(e.substr(0,o)).toLowerCase(),r=n.trim(e.substr(o+1)),t&&(i[t]=i[t]?i[t]+", "+r:r)}),i):i}},function(e,t,r){"use strict";var n=r(3);e.exports=function(e,t,r){return n.forEach(r,function(r){e=r(e,t)}),e}},function(e,t,r){"use strict";var n=r(3);e.exports=n.isStandardBrowserEnv()?function(){function e(e){var t=e;return r&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,r=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(r){var o=n.isString(r)?e(r):r;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function r(){this.message="String contains an invalid character"}function n(e){for(var t,n,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(n=i.charCodeAt(u+=.75),n>255)throw new r;t=t<<8|n}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";r.prototype=new Error,r.prototype.code=5,r.prototype.name="InvalidCharacterError",e.exports=n},function(e,t){"use strict";e.exports=function(e,t,r){var n=r.config.validateStatus;r.status&&n&&!n(r.status)?t(r):e(r)}},function(e,t,r){"use strict";var n=r(3);e.exports=n.isStandardBrowserEnv()?function(){return{write:function(e,t,r,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),n.isNumber(r)&&u.push("expires="+new Date(r).toGMTString()),n.isString(o)&&u.push("path="+o),n.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,r){"use strict";function n(){this.handlers=[]}var o=r(3);n.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},n.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},n.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=n},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,"")}},function(e,t){"use strict";e.exports=function(e,t){return function(){for(var r=new Array(arguments.length),n=0;n 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | * @license bytebuffer.js (c) 2015 Daniel Wirtz 19 | * Backing buffer: ArrayBuffer, Accessor: Uint8Array 20 | * Released under the Apache License, Version 2.0 21 | * see: https://github.com/dcodeIO/bytebuffer.js for details 22 | */ 23 | (function(global, factory) { 24 | 25 | /* AMD */ if (typeof define === 'function' && define["amd"]) 26 | define(["long"], factory); 27 | /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) 28 | module['exports'] = (function() { 29 | var Long; try { Long = require("long"); } catch (e) {} 30 | return factory(Long); 31 | })(); 32 | /* Global */ else 33 | (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]); 34 | 35 | })(this, function(Long) { 36 | "use strict"; 37 | 38 | /** 39 | * Constructs a new ByteBuffer. 40 | * @class The swiss army knife for binary data in JavaScript. 41 | * @exports ByteBuffer 42 | * @constructor 43 | * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. 44 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 45 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 46 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to 47 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 48 | * @expose 49 | */ 50 | var ByteBuffer = function(capacity, littleEndian, noAssert) { 51 | if (typeof capacity === 'undefined') 52 | capacity = ByteBuffer.DEFAULT_CAPACITY; 53 | if (typeof littleEndian === 'undefined') 54 | littleEndian = ByteBuffer.DEFAULT_ENDIAN; 55 | if (typeof noAssert === 'undefined') 56 | noAssert = ByteBuffer.DEFAULT_NOASSERT; 57 | if (!noAssert) { 58 | capacity = capacity | 0; 59 | if (capacity < 0) 60 | throw RangeError("Illegal capacity"); 61 | littleEndian = !!littleEndian; 62 | noAssert = !!noAssert; 63 | } 64 | 65 | /** 66 | * Backing ArrayBuffer. 67 | * @type {!ArrayBuffer} 68 | * @expose 69 | */ 70 | this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity); 71 | 72 | /** 73 | * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`. 74 | * @type {?Uint8Array} 75 | * @expose 76 | */ 77 | this.view = capacity === 0 ? null : new Uint8Array(this.buffer); 78 | 79 | /** 80 | * Absolute read/write offset. 81 | * @type {number} 82 | * @expose 83 | * @see ByteBuffer#flip 84 | * @see ByteBuffer#clear 85 | */ 86 | this.offset = 0; 87 | 88 | /** 89 | * Marked offset. 90 | * @type {number} 91 | * @expose 92 | * @see ByteBuffer#mark 93 | * @see ByteBuffer#reset 94 | */ 95 | this.markedOffset = -1; 96 | 97 | /** 98 | * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation. 99 | * @type {number} 100 | * @expose 101 | * @see ByteBuffer#flip 102 | * @see ByteBuffer#clear 103 | */ 104 | this.limit = capacity; 105 | 106 | /** 107 | * Whether to use little endian byte order, defaults to `false` for big endian. 108 | * @type {boolean} 109 | * @expose 110 | */ 111 | this.littleEndian = littleEndian; 112 | 113 | /** 114 | * Whether to skip assertions of offsets and values, defaults to `false`. 115 | * @type {boolean} 116 | * @expose 117 | */ 118 | this.noAssert = noAssert; 119 | }; 120 | 121 | /** 122 | * ByteBuffer version. 123 | * @type {string} 124 | * @const 125 | * @expose 126 | */ 127 | ByteBuffer.VERSION = "5.0.1"; 128 | 129 | /** 130 | * Little endian constant that can be used instead of its boolean value. Evaluates to `true`. 131 | * @type {boolean} 132 | * @const 133 | * @expose 134 | */ 135 | ByteBuffer.LITTLE_ENDIAN = true; 136 | 137 | /** 138 | * Big endian constant that can be used instead of its boolean value. Evaluates to `false`. 139 | * @type {boolean} 140 | * @const 141 | * @expose 142 | */ 143 | ByteBuffer.BIG_ENDIAN = false; 144 | 145 | /** 146 | * Default initial capacity of `16`. 147 | * @type {number} 148 | * @expose 149 | */ 150 | ByteBuffer.DEFAULT_CAPACITY = 16; 151 | 152 | /** 153 | * Default endianess of `false` for big endian. 154 | * @type {boolean} 155 | * @expose 156 | */ 157 | ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN; 158 | 159 | /** 160 | * Default no assertions flag of `false`. 161 | * @type {boolean} 162 | * @expose 163 | */ 164 | ByteBuffer.DEFAULT_NOASSERT = false; 165 | 166 | /** 167 | * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded 168 | * and int64 support is not available. 169 | * @type {?Long} 170 | * @const 171 | * @see https://github.com/dcodeIO/long.js 172 | * @expose 173 | */ 174 | ByteBuffer.Long = Long || null; 175 | 176 | /** 177 | * @alias ByteBuffer.prototype 178 | * @inner 179 | */ 180 | var ByteBufferPrototype = ByteBuffer.prototype; 181 | 182 | /** 183 | * An indicator used to reliably determine if an object is a ByteBuffer or not. 184 | * @type {boolean} 185 | * @const 186 | * @expose 187 | * @private 188 | */ 189 | ByteBufferPrototype.__isByteBuffer__; 190 | 191 | Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", { 192 | value: true, 193 | enumerable: false, 194 | configurable: false 195 | }); 196 | 197 | // helpers 198 | 199 | /** 200 | * @type {!ArrayBuffer} 201 | * @inner 202 | */ 203 | var EMPTY_BUFFER = new ArrayBuffer(0); 204 | 205 | /** 206 | * String.fromCharCode reference for compile-time renaming. 207 | * @type {function(...number):string} 208 | * @inner 209 | */ 210 | var stringFromCharCode = String.fromCharCode; 211 | 212 | /** 213 | * Creates a source function for a string. 214 | * @param {string} s String to read from 215 | * @returns {function():number|null} Source function returning the next char code respectively `null` if there are 216 | * no more characters left. 217 | * @throws {TypeError} If the argument is invalid 218 | * @inner 219 | */ 220 | function stringSource(s) { 221 | var i=0; return function() { 222 | return i < s.length ? s.charCodeAt(i++) : null; 223 | }; 224 | } 225 | 226 | /** 227 | * Creates a destination function for a string. 228 | * @returns {function(number=):undefined|string} Destination function successively called with the next char code. 229 | * Returns the final string when called without arguments. 230 | * @inner 231 | */ 232 | function stringDestination() { 233 | var cs = [], ps = []; return function() { 234 | if (arguments.length === 0) 235 | return ps.join('')+stringFromCharCode.apply(String, cs); 236 | if (cs.length + arguments.length > 1024) 237 | ps.push(stringFromCharCode.apply(String, cs)), 238 | cs.length = 0; 239 | Array.prototype.push.apply(cs, arguments); 240 | }; 241 | } 242 | 243 | /** 244 | * Gets the accessor type. 245 | * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes) 246 | * @expose 247 | */ 248 | ByteBuffer.accessor = function() { 249 | return Uint8Array; 250 | }; 251 | /** 252 | * Allocates a new ByteBuffer backed by a buffer of the specified capacity. 253 | * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. 254 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 255 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 256 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to 257 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 258 | * @returns {!ByteBuffer} 259 | * @expose 260 | */ 261 | ByteBuffer.allocate = function(capacity, littleEndian, noAssert) { 262 | return new ByteBuffer(capacity, littleEndian, noAssert); 263 | }; 264 | 265 | /** 266 | * Concatenates multiple ByteBuffers into one. 267 | * @param {!Array.} buffers Buffers to concatenate 268 | * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary", 269 | * defaults to "utf8") 270 | * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults 271 | * to {@link ByteBuffer.DEFAULT_ENDIAN}. 272 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to 273 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 274 | * @returns {!ByteBuffer} Concatenated ByteBuffer 275 | * @expose 276 | */ 277 | ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) { 278 | if (typeof encoding === 'boolean' || typeof encoding !== 'string') { 279 | noAssert = littleEndian; 280 | littleEndian = encoding; 281 | encoding = undefined; 282 | } 283 | var capacity = 0; 284 | for (var i=0, k=buffers.length, length; i 0) capacity += length; 289 | } 290 | if (capacity === 0) 291 | return new ByteBuffer(0, littleEndian, noAssert); 292 | var bb = new ByteBuffer(capacity, littleEndian, noAssert), 293 | bi; 294 | i=0; while (i} buffer Anything that can be wrapped 327 | * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to 328 | * "utf8") 329 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 330 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 331 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to 332 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 333 | * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer` 334 | * @expose 335 | */ 336 | ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) { 337 | if (typeof encoding !== 'string') { 338 | noAssert = littleEndian; 339 | littleEndian = encoding; 340 | encoding = undefined; 341 | } 342 | if (typeof buffer === 'string') { 343 | if (typeof encoding === 'undefined') 344 | encoding = "utf8"; 345 | switch (encoding) { 346 | case "base64": 347 | return ByteBuffer.fromBase64(buffer, littleEndian); 348 | case "hex": 349 | return ByteBuffer.fromHex(buffer, littleEndian); 350 | case "binary": 351 | return ByteBuffer.fromBinary(buffer, littleEndian); 352 | case "utf8": 353 | return ByteBuffer.fromUTF8(buffer, littleEndian); 354 | case "debug": 355 | return ByteBuffer.fromDebug(buffer, littleEndian); 356 | default: 357 | throw Error("Unsupported encoding: "+encoding); 358 | } 359 | } 360 | if (buffer === null || typeof buffer !== 'object') 361 | throw TypeError("Illegal buffer"); 362 | var bb; 363 | if (ByteBuffer.isByteBuffer(buffer)) { 364 | bb = ByteBufferPrototype.clone.call(buffer); 365 | bb.markedOffset = -1; 366 | return bb; 367 | } 368 | if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array 369 | bb = new ByteBuffer(0, littleEndian, noAssert); 370 | if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER 371 | bb.buffer = buffer.buffer; 372 | bb.offset = buffer.byteOffset; 373 | bb.limit = buffer.byteOffset + buffer.byteLength; 374 | bb.view = new Uint8Array(buffer.buffer); 375 | } 376 | } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer 377 | bb = new ByteBuffer(0, littleEndian, noAssert); 378 | if (buffer.byteLength > 0) { 379 | bb.buffer = buffer; 380 | bb.offset = 0; 381 | bb.limit = buffer.byteLength; 382 | bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null; 383 | } 384 | } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets 385 | bb = new ByteBuffer(buffer.length, littleEndian, noAssert); 386 | bb.limit = buffer.length; 387 | for (var i=0; i} value Array of booleans to write 397 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. 398 | * @returns {!ByteBuffer} 399 | * @expose 400 | */ 401 | ByteBufferPrototype.writeBitSet = function(value, offset) { 402 | var relative = typeof offset === 'undefined'; 403 | if (relative) offset = this.offset; 404 | if (!this.noAssert) { 405 | if (!(value instanceof Array)) 406 | throw TypeError("Illegal BitSet: Not an array"); 407 | if (typeof offset !== 'number' || offset % 1 !== 0) 408 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 409 | offset >>>= 0; 410 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 411 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 412 | } 413 | 414 | var start = offset, 415 | bits = value.length, 416 | bytes = (bits >> 3), 417 | bit = 0, 418 | k; 419 | 420 | offset += this.writeVarint32(bits,offset); 421 | 422 | while(bytes--) { 423 | k = (!!value[bit++] & 1) | 424 | ((!!value[bit++] & 1) << 1) | 425 | ((!!value[bit++] & 1) << 2) | 426 | ((!!value[bit++] & 1) << 3) | 427 | ((!!value[bit++] & 1) << 4) | 428 | ((!!value[bit++] & 1) << 5) | 429 | ((!!value[bit++] & 1) << 6) | 430 | ((!!value[bit++] & 1) << 7); 431 | this.writeByte(k,offset++); 432 | } 433 | 434 | if(bit < bits) { 435 | var m = 0; k = 0; 436 | while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++)); 437 | this.writeByte(k,offset++); 438 | } 439 | 440 | if (relative) { 441 | this.offset = offset; 442 | return this; 443 | } 444 | return offset - start; 445 | } 446 | 447 | /** 448 | * Reads a BitSet as an array of booleans. 449 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. 450 | * @returns {Array 451 | * @expose 452 | */ 453 | ByteBufferPrototype.readBitSet = function(offset) { 454 | var relative = typeof offset === 'undefined'; 455 | if (relative) offset = this.offset; 456 | 457 | var ret = this.readVarint32(offset), 458 | bits = ret.value, 459 | bytes = (bits >> 3), 460 | bit = 0, 461 | value = [], 462 | k; 463 | 464 | offset += ret.length; 465 | 466 | while(bytes--) { 467 | k = this.readByte(offset++); 468 | value[bit++] = !!(k & 0x01); 469 | value[bit++] = !!(k & 0x02); 470 | value[bit++] = !!(k & 0x04); 471 | value[bit++] = !!(k & 0x08); 472 | value[bit++] = !!(k & 0x10); 473 | value[bit++] = !!(k & 0x20); 474 | value[bit++] = !!(k & 0x40); 475 | value[bit++] = !!(k & 0x80); 476 | } 477 | 478 | if(bit < bits) { 479 | var m = 0; 480 | k = this.readByte(offset++); 481 | while(bit < bits) value[bit++] = !!((k >> (m++)) & 1); 482 | } 483 | 484 | if (relative) { 485 | this.offset = offset; 486 | } 487 | return value; 488 | } 489 | /** 490 | * Reads the specified number of bytes. 491 | * @param {number} length Number of bytes to read 492 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. 493 | * @returns {!ByteBuffer} 494 | * @expose 495 | */ 496 | ByteBufferPrototype.readBytes = function(length, offset) { 497 | var relative = typeof offset === 'undefined'; 498 | if (relative) offset = this.offset; 499 | if (!this.noAssert) { 500 | if (typeof offset !== 'number' || offset % 1 !== 0) 501 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 502 | offset >>>= 0; 503 | if (offset < 0 || offset + length > this.buffer.byteLength) 504 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); 505 | } 506 | var slice = this.slice(offset, offset + length); 507 | if (relative) this.offset += length; 508 | return slice; 509 | }; 510 | 511 | /** 512 | * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}. 513 | * @function 514 | * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets 515 | * will be modified according to the performed read operation. 516 | * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") 517 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 518 | * written if omitted. 519 | * @returns {!ByteBuffer} this 520 | * @expose 521 | */ 522 | ByteBufferPrototype.writeBytes = ByteBufferPrototype.append; 523 | 524 | // types/ints/int8 525 | 526 | /** 527 | * Writes an 8bit signed integer. 528 | * @param {number} value Value to write 529 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 530 | * @returns {!ByteBuffer} this 531 | * @expose 532 | */ 533 | ByteBufferPrototype.writeInt8 = function(value, offset) { 534 | var relative = typeof offset === 'undefined'; 535 | if (relative) offset = this.offset; 536 | if (!this.noAssert) { 537 | if (typeof value !== 'number' || value % 1 !== 0) 538 | throw TypeError("Illegal value: "+value+" (not an integer)"); 539 | value |= 0; 540 | if (typeof offset !== 'number' || offset % 1 !== 0) 541 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 542 | offset >>>= 0; 543 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 544 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 545 | } 546 | offset += 1; 547 | var capacity0 = this.buffer.byteLength; 548 | if (offset > capacity0) 549 | this.resize((capacity0 *= 2) > offset ? capacity0 : offset); 550 | offset -= 1; 551 | this.view[offset] = value; 552 | if (relative) this.offset += 1; 553 | return this; 554 | }; 555 | 556 | /** 557 | * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}. 558 | * @function 559 | * @param {number} value Value to write 560 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 561 | * @returns {!ByteBuffer} this 562 | * @expose 563 | */ 564 | ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8; 565 | 566 | /** 567 | * Reads an 8bit signed integer. 568 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 569 | * @returns {number} Value read 570 | * @expose 571 | */ 572 | ByteBufferPrototype.readInt8 = function(offset) { 573 | var relative = typeof offset === 'undefined'; 574 | if (relative) offset = this.offset; 575 | if (!this.noAssert) { 576 | if (typeof offset !== 'number' || offset % 1 !== 0) 577 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 578 | offset >>>= 0; 579 | if (offset < 0 || offset + 1 > this.buffer.byteLength) 580 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); 581 | } 582 | var value = this.view[offset]; 583 | if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed 584 | if (relative) this.offset += 1; 585 | return value; 586 | }; 587 | 588 | /** 589 | * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}. 590 | * @function 591 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 592 | * @returns {number} Value read 593 | * @expose 594 | */ 595 | ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8; 596 | 597 | /** 598 | * Writes an 8bit unsigned integer. 599 | * @param {number} value Value to write 600 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 601 | * @returns {!ByteBuffer} this 602 | * @expose 603 | */ 604 | ByteBufferPrototype.writeUint8 = function(value, offset) { 605 | var relative = typeof offset === 'undefined'; 606 | if (relative) offset = this.offset; 607 | if (!this.noAssert) { 608 | if (typeof value !== 'number' || value % 1 !== 0) 609 | throw TypeError("Illegal value: "+value+" (not an integer)"); 610 | value >>>= 0; 611 | if (typeof offset !== 'number' || offset % 1 !== 0) 612 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 613 | offset >>>= 0; 614 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 615 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 616 | } 617 | offset += 1; 618 | var capacity1 = this.buffer.byteLength; 619 | if (offset > capacity1) 620 | this.resize((capacity1 *= 2) > offset ? capacity1 : offset); 621 | offset -= 1; 622 | this.view[offset] = value; 623 | if (relative) this.offset += 1; 624 | return this; 625 | }; 626 | 627 | /** 628 | * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}. 629 | * @function 630 | * @param {number} value Value to write 631 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 632 | * @returns {!ByteBuffer} this 633 | * @expose 634 | */ 635 | ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8; 636 | 637 | /** 638 | * Reads an 8bit unsigned integer. 639 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 640 | * @returns {number} Value read 641 | * @expose 642 | */ 643 | ByteBufferPrototype.readUint8 = function(offset) { 644 | var relative = typeof offset === 'undefined'; 645 | if (relative) offset = this.offset; 646 | if (!this.noAssert) { 647 | if (typeof offset !== 'number' || offset % 1 !== 0) 648 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 649 | offset >>>= 0; 650 | if (offset < 0 || offset + 1 > this.buffer.byteLength) 651 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); 652 | } 653 | var value = this.view[offset]; 654 | if (relative) this.offset += 1; 655 | return value; 656 | }; 657 | 658 | /** 659 | * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}. 660 | * @function 661 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. 662 | * @returns {number} Value read 663 | * @expose 664 | */ 665 | ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8; 666 | 667 | // types/ints/int16 668 | 669 | /** 670 | * Writes a 16bit signed integer. 671 | * @param {number} value Value to write 672 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 673 | * @throws {TypeError} If `offset` or `value` is not a valid number 674 | * @throws {RangeError} If `offset` is out of bounds 675 | * @expose 676 | */ 677 | ByteBufferPrototype.writeInt16 = function(value, offset) { 678 | var relative = typeof offset === 'undefined'; 679 | if (relative) offset = this.offset; 680 | if (!this.noAssert) { 681 | if (typeof value !== 'number' || value % 1 !== 0) 682 | throw TypeError("Illegal value: "+value+" (not an integer)"); 683 | value |= 0; 684 | if (typeof offset !== 'number' || offset % 1 !== 0) 685 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 686 | offset >>>= 0; 687 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 688 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 689 | } 690 | offset += 2; 691 | var capacity2 = this.buffer.byteLength; 692 | if (offset > capacity2) 693 | this.resize((capacity2 *= 2) > offset ? capacity2 : offset); 694 | offset -= 2; 695 | if (this.littleEndian) { 696 | this.view[offset+1] = (value & 0xFF00) >>> 8; 697 | this.view[offset ] = value & 0x00FF; 698 | } else { 699 | this.view[offset] = (value & 0xFF00) >>> 8; 700 | this.view[offset+1] = value & 0x00FF; 701 | } 702 | if (relative) this.offset += 2; 703 | return this; 704 | }; 705 | 706 | /** 707 | * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}. 708 | * @function 709 | * @param {number} value Value to write 710 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 711 | * @throws {TypeError} If `offset` or `value` is not a valid number 712 | * @throws {RangeError} If `offset` is out of bounds 713 | * @expose 714 | */ 715 | ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16; 716 | 717 | /** 718 | * Reads a 16bit signed integer. 719 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 720 | * @returns {number} Value read 721 | * @throws {TypeError} If `offset` is not a valid number 722 | * @throws {RangeError} If `offset` is out of bounds 723 | * @expose 724 | */ 725 | ByteBufferPrototype.readInt16 = function(offset) { 726 | var relative = typeof offset === 'undefined'; 727 | if (relative) offset = this.offset; 728 | if (!this.noAssert) { 729 | if (typeof offset !== 'number' || offset % 1 !== 0) 730 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 731 | offset >>>= 0; 732 | if (offset < 0 || offset + 2 > this.buffer.byteLength) 733 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); 734 | } 735 | var value = 0; 736 | if (this.littleEndian) { 737 | value = this.view[offset ]; 738 | value |= this.view[offset+1] << 8; 739 | } else { 740 | value = this.view[offset ] << 8; 741 | value |= this.view[offset+1]; 742 | } 743 | if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed 744 | if (relative) this.offset += 2; 745 | return value; 746 | }; 747 | 748 | /** 749 | * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}. 750 | * @function 751 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 752 | * @returns {number} Value read 753 | * @throws {TypeError} If `offset` is not a valid number 754 | * @throws {RangeError} If `offset` is out of bounds 755 | * @expose 756 | */ 757 | ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16; 758 | 759 | /** 760 | * Writes a 16bit unsigned integer. 761 | * @param {number} value Value to write 762 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 763 | * @throws {TypeError} If `offset` or `value` is not a valid number 764 | * @throws {RangeError} If `offset` is out of bounds 765 | * @expose 766 | */ 767 | ByteBufferPrototype.writeUint16 = function(value, offset) { 768 | var relative = typeof offset === 'undefined'; 769 | if (relative) offset = this.offset; 770 | if (!this.noAssert) { 771 | if (typeof value !== 'number' || value % 1 !== 0) 772 | throw TypeError("Illegal value: "+value+" (not an integer)"); 773 | value >>>= 0; 774 | if (typeof offset !== 'number' || offset % 1 !== 0) 775 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 776 | offset >>>= 0; 777 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 778 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 779 | } 780 | offset += 2; 781 | var capacity3 = this.buffer.byteLength; 782 | if (offset > capacity3) 783 | this.resize((capacity3 *= 2) > offset ? capacity3 : offset); 784 | offset -= 2; 785 | if (this.littleEndian) { 786 | this.view[offset+1] = (value & 0xFF00) >>> 8; 787 | this.view[offset ] = value & 0x00FF; 788 | } else { 789 | this.view[offset] = (value & 0xFF00) >>> 8; 790 | this.view[offset+1] = value & 0x00FF; 791 | } 792 | if (relative) this.offset += 2; 793 | return this; 794 | }; 795 | 796 | /** 797 | * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}. 798 | * @function 799 | * @param {number} value Value to write 800 | * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 801 | * @throws {TypeError} If `offset` or `value` is not a valid number 802 | * @throws {RangeError} If `offset` is out of bounds 803 | * @expose 804 | */ 805 | ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16; 806 | 807 | /** 808 | * Reads a 16bit unsigned integer. 809 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 810 | * @returns {number} Value read 811 | * @throws {TypeError} If `offset` is not a valid number 812 | * @throws {RangeError} If `offset` is out of bounds 813 | * @expose 814 | */ 815 | ByteBufferPrototype.readUint16 = function(offset) { 816 | var relative = typeof offset === 'undefined'; 817 | if (relative) offset = this.offset; 818 | if (!this.noAssert) { 819 | if (typeof offset !== 'number' || offset % 1 !== 0) 820 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 821 | offset >>>= 0; 822 | if (offset < 0 || offset + 2 > this.buffer.byteLength) 823 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); 824 | } 825 | var value = 0; 826 | if (this.littleEndian) { 827 | value = this.view[offset ]; 828 | value |= this.view[offset+1] << 8; 829 | } else { 830 | value = this.view[offset ] << 8; 831 | value |= this.view[offset+1]; 832 | } 833 | if (relative) this.offset += 2; 834 | return value; 835 | }; 836 | 837 | /** 838 | * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}. 839 | * @function 840 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. 841 | * @returns {number} Value read 842 | * @throws {TypeError} If `offset` is not a valid number 843 | * @throws {RangeError} If `offset` is out of bounds 844 | * @expose 845 | */ 846 | ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16; 847 | 848 | // types/ints/int32 849 | 850 | /** 851 | * Writes a 32bit signed integer. 852 | * @param {number} value Value to write 853 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 854 | * @expose 855 | */ 856 | ByteBufferPrototype.writeInt32 = function(value, offset) { 857 | var relative = typeof offset === 'undefined'; 858 | if (relative) offset = this.offset; 859 | if (!this.noAssert) { 860 | if (typeof value !== 'number' || value % 1 !== 0) 861 | throw TypeError("Illegal value: "+value+" (not an integer)"); 862 | value |= 0; 863 | if (typeof offset !== 'number' || offset % 1 !== 0) 864 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 865 | offset >>>= 0; 866 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 867 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 868 | } 869 | offset += 4; 870 | var capacity4 = this.buffer.byteLength; 871 | if (offset > capacity4) 872 | this.resize((capacity4 *= 2) > offset ? capacity4 : offset); 873 | offset -= 4; 874 | if (this.littleEndian) { 875 | this.view[offset+3] = (value >>> 24) & 0xFF; 876 | this.view[offset+2] = (value >>> 16) & 0xFF; 877 | this.view[offset+1] = (value >>> 8) & 0xFF; 878 | this.view[offset ] = value & 0xFF; 879 | } else { 880 | this.view[offset ] = (value >>> 24) & 0xFF; 881 | this.view[offset+1] = (value >>> 16) & 0xFF; 882 | this.view[offset+2] = (value >>> 8) & 0xFF; 883 | this.view[offset+3] = value & 0xFF; 884 | } 885 | if (relative) this.offset += 4; 886 | return this; 887 | }; 888 | 889 | /** 890 | * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}. 891 | * @param {number} value Value to write 892 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 893 | * @expose 894 | */ 895 | ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32; 896 | 897 | /** 898 | * Reads a 32bit signed integer. 899 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 900 | * @returns {number} Value read 901 | * @expose 902 | */ 903 | ByteBufferPrototype.readInt32 = function(offset) { 904 | var relative = typeof offset === 'undefined'; 905 | if (relative) offset = this.offset; 906 | if (!this.noAssert) { 907 | if (typeof offset !== 'number' || offset % 1 !== 0) 908 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 909 | offset >>>= 0; 910 | if (offset < 0 || offset + 4 > this.buffer.byteLength) 911 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); 912 | } 913 | var value = 0; 914 | if (this.littleEndian) { 915 | value = this.view[offset+2] << 16; 916 | value |= this.view[offset+1] << 8; 917 | value |= this.view[offset ]; 918 | value += this.view[offset+3] << 24 >>> 0; 919 | } else { 920 | value = this.view[offset+1] << 16; 921 | value |= this.view[offset+2] << 8; 922 | value |= this.view[offset+3]; 923 | value += this.view[offset ] << 24 >>> 0; 924 | } 925 | value |= 0; // Cast to signed 926 | if (relative) this.offset += 4; 927 | return value; 928 | }; 929 | 930 | /** 931 | * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}. 932 | * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted. 933 | * @returns {number} Value read 934 | * @expose 935 | */ 936 | ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32; 937 | 938 | /** 939 | * Writes a 32bit unsigned integer. 940 | * @param {number} value Value to write 941 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 942 | * @expose 943 | */ 944 | ByteBufferPrototype.writeUint32 = function(value, offset) { 945 | var relative = typeof offset === 'undefined'; 946 | if (relative) offset = this.offset; 947 | if (!this.noAssert) { 948 | if (typeof value !== 'number' || value % 1 !== 0) 949 | throw TypeError("Illegal value: "+value+" (not an integer)"); 950 | value >>>= 0; 951 | if (typeof offset !== 'number' || offset % 1 !== 0) 952 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 953 | offset >>>= 0; 954 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 955 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 956 | } 957 | offset += 4; 958 | var capacity5 = this.buffer.byteLength; 959 | if (offset > capacity5) 960 | this.resize((capacity5 *= 2) > offset ? capacity5 : offset); 961 | offset -= 4; 962 | if (this.littleEndian) { 963 | this.view[offset+3] = (value >>> 24) & 0xFF; 964 | this.view[offset+2] = (value >>> 16) & 0xFF; 965 | this.view[offset+1] = (value >>> 8) & 0xFF; 966 | this.view[offset ] = value & 0xFF; 967 | } else { 968 | this.view[offset ] = (value >>> 24) & 0xFF; 969 | this.view[offset+1] = (value >>> 16) & 0xFF; 970 | this.view[offset+2] = (value >>> 8) & 0xFF; 971 | this.view[offset+3] = value & 0xFF; 972 | } 973 | if (relative) this.offset += 4; 974 | return this; 975 | }; 976 | 977 | /** 978 | * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}. 979 | * @function 980 | * @param {number} value Value to write 981 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 982 | * @expose 983 | */ 984 | ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32; 985 | 986 | /** 987 | * Reads a 32bit unsigned integer. 988 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 989 | * @returns {number} Value read 990 | * @expose 991 | */ 992 | ByteBufferPrototype.readUint32 = function(offset) { 993 | var relative = typeof offset === 'undefined'; 994 | if (relative) offset = this.offset; 995 | if (!this.noAssert) { 996 | if (typeof offset !== 'number' || offset % 1 !== 0) 997 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 998 | offset >>>= 0; 999 | if (offset < 0 || offset + 4 > this.buffer.byteLength) 1000 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); 1001 | } 1002 | var value = 0; 1003 | if (this.littleEndian) { 1004 | value = this.view[offset+2] << 16; 1005 | value |= this.view[offset+1] << 8; 1006 | value |= this.view[offset ]; 1007 | value += this.view[offset+3] << 24 >>> 0; 1008 | } else { 1009 | value = this.view[offset+1] << 16; 1010 | value |= this.view[offset+2] << 8; 1011 | value |= this.view[offset+3]; 1012 | value += this.view[offset ] << 24 >>> 0; 1013 | } 1014 | if (relative) this.offset += 4; 1015 | return value; 1016 | }; 1017 | 1018 | /** 1019 | * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}. 1020 | * @function 1021 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 1022 | * @returns {number} Value read 1023 | * @expose 1024 | */ 1025 | ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32; 1026 | 1027 | // types/ints/int64 1028 | 1029 | if (Long) { 1030 | 1031 | /** 1032 | * Writes a 64bit signed integer. 1033 | * @param {number|!Long} value Value to write 1034 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1035 | * @returns {!ByteBuffer} this 1036 | * @expose 1037 | */ 1038 | ByteBufferPrototype.writeInt64 = function(value, offset) { 1039 | var relative = typeof offset === 'undefined'; 1040 | if (relative) offset = this.offset; 1041 | if (!this.noAssert) { 1042 | if (typeof value === 'number') 1043 | value = Long.fromNumber(value); 1044 | else if (typeof value === 'string') 1045 | value = Long.fromString(value); 1046 | else if (!(value && value instanceof Long)) 1047 | throw TypeError("Illegal value: "+value+" (not an integer or Long)"); 1048 | if (typeof offset !== 'number' || offset % 1 !== 0) 1049 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1050 | offset >>>= 0; 1051 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1052 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1053 | } 1054 | if (typeof value === 'number') 1055 | value = Long.fromNumber(value); 1056 | else if (typeof value === 'string') 1057 | value = Long.fromString(value); 1058 | offset += 8; 1059 | var capacity6 = this.buffer.byteLength; 1060 | if (offset > capacity6) 1061 | this.resize((capacity6 *= 2) > offset ? capacity6 : offset); 1062 | offset -= 8; 1063 | var lo = value.low, 1064 | hi = value.high; 1065 | if (this.littleEndian) { 1066 | this.view[offset+3] = (lo >>> 24) & 0xFF; 1067 | this.view[offset+2] = (lo >>> 16) & 0xFF; 1068 | this.view[offset+1] = (lo >>> 8) & 0xFF; 1069 | this.view[offset ] = lo & 0xFF; 1070 | offset += 4; 1071 | this.view[offset+3] = (hi >>> 24) & 0xFF; 1072 | this.view[offset+2] = (hi >>> 16) & 0xFF; 1073 | this.view[offset+1] = (hi >>> 8) & 0xFF; 1074 | this.view[offset ] = hi & 0xFF; 1075 | } else { 1076 | this.view[offset ] = (hi >>> 24) & 0xFF; 1077 | this.view[offset+1] = (hi >>> 16) & 0xFF; 1078 | this.view[offset+2] = (hi >>> 8) & 0xFF; 1079 | this.view[offset+3] = hi & 0xFF; 1080 | offset += 4; 1081 | this.view[offset ] = (lo >>> 24) & 0xFF; 1082 | this.view[offset+1] = (lo >>> 16) & 0xFF; 1083 | this.view[offset+2] = (lo >>> 8) & 0xFF; 1084 | this.view[offset+3] = lo & 0xFF; 1085 | } 1086 | if (relative) this.offset += 8; 1087 | return this; 1088 | }; 1089 | 1090 | /** 1091 | * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}. 1092 | * @param {number|!Long} value Value to write 1093 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1094 | * @returns {!ByteBuffer} this 1095 | * @expose 1096 | */ 1097 | ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64; 1098 | 1099 | /** 1100 | * Reads a 64bit signed integer. 1101 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1102 | * @returns {!Long} 1103 | * @expose 1104 | */ 1105 | ByteBufferPrototype.readInt64 = function(offset) { 1106 | var relative = typeof offset === 'undefined'; 1107 | if (relative) offset = this.offset; 1108 | if (!this.noAssert) { 1109 | if (typeof offset !== 'number' || offset % 1 !== 0) 1110 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1111 | offset >>>= 0; 1112 | if (offset < 0 || offset + 8 > this.buffer.byteLength) 1113 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); 1114 | } 1115 | var lo = 0, 1116 | hi = 0; 1117 | if (this.littleEndian) { 1118 | lo = this.view[offset+2] << 16; 1119 | lo |= this.view[offset+1] << 8; 1120 | lo |= this.view[offset ]; 1121 | lo += this.view[offset+3] << 24 >>> 0; 1122 | offset += 4; 1123 | hi = this.view[offset+2] << 16; 1124 | hi |= this.view[offset+1] << 8; 1125 | hi |= this.view[offset ]; 1126 | hi += this.view[offset+3] << 24 >>> 0; 1127 | } else { 1128 | hi = this.view[offset+1] << 16; 1129 | hi |= this.view[offset+2] << 8; 1130 | hi |= this.view[offset+3]; 1131 | hi += this.view[offset ] << 24 >>> 0; 1132 | offset += 4; 1133 | lo = this.view[offset+1] << 16; 1134 | lo |= this.view[offset+2] << 8; 1135 | lo |= this.view[offset+3]; 1136 | lo += this.view[offset ] << 24 >>> 0; 1137 | } 1138 | var value = new Long(lo, hi, false); 1139 | if (relative) this.offset += 8; 1140 | return value; 1141 | }; 1142 | 1143 | /** 1144 | * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}. 1145 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1146 | * @returns {!Long} 1147 | * @expose 1148 | */ 1149 | ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64; 1150 | 1151 | /** 1152 | * Writes a 64bit unsigned integer. 1153 | * @param {number|!Long} value Value to write 1154 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1155 | * @returns {!ByteBuffer} this 1156 | * @expose 1157 | */ 1158 | ByteBufferPrototype.writeUint64 = function(value, offset) { 1159 | var relative = typeof offset === 'undefined'; 1160 | if (relative) offset = this.offset; 1161 | if (!this.noAssert) { 1162 | if (typeof value === 'number') 1163 | value = Long.fromNumber(value); 1164 | else if (typeof value === 'string') 1165 | value = Long.fromString(value); 1166 | else if (!(value && value instanceof Long)) 1167 | throw TypeError("Illegal value: "+value+" (not an integer or Long)"); 1168 | if (typeof offset !== 'number' || offset % 1 !== 0) 1169 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1170 | offset >>>= 0; 1171 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1172 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1173 | } 1174 | if (typeof value === 'number') 1175 | value = Long.fromNumber(value); 1176 | else if (typeof value === 'string') 1177 | value = Long.fromString(value); 1178 | offset += 8; 1179 | var capacity7 = this.buffer.byteLength; 1180 | if (offset > capacity7) 1181 | this.resize((capacity7 *= 2) > offset ? capacity7 : offset); 1182 | offset -= 8; 1183 | var lo = value.low, 1184 | hi = value.high; 1185 | if (this.littleEndian) { 1186 | this.view[offset+3] = (lo >>> 24) & 0xFF; 1187 | this.view[offset+2] = (lo >>> 16) & 0xFF; 1188 | this.view[offset+1] = (lo >>> 8) & 0xFF; 1189 | this.view[offset ] = lo & 0xFF; 1190 | offset += 4; 1191 | this.view[offset+3] = (hi >>> 24) & 0xFF; 1192 | this.view[offset+2] = (hi >>> 16) & 0xFF; 1193 | this.view[offset+1] = (hi >>> 8) & 0xFF; 1194 | this.view[offset ] = hi & 0xFF; 1195 | } else { 1196 | this.view[offset ] = (hi >>> 24) & 0xFF; 1197 | this.view[offset+1] = (hi >>> 16) & 0xFF; 1198 | this.view[offset+2] = (hi >>> 8) & 0xFF; 1199 | this.view[offset+3] = hi & 0xFF; 1200 | offset += 4; 1201 | this.view[offset ] = (lo >>> 24) & 0xFF; 1202 | this.view[offset+1] = (lo >>> 16) & 0xFF; 1203 | this.view[offset+2] = (lo >>> 8) & 0xFF; 1204 | this.view[offset+3] = lo & 0xFF; 1205 | } 1206 | if (relative) this.offset += 8; 1207 | return this; 1208 | }; 1209 | 1210 | /** 1211 | * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}. 1212 | * @function 1213 | * @param {number|!Long} value Value to write 1214 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1215 | * @returns {!ByteBuffer} this 1216 | * @expose 1217 | */ 1218 | ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64; 1219 | 1220 | /** 1221 | * Reads a 64bit unsigned integer. 1222 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1223 | * @returns {!Long} 1224 | * @expose 1225 | */ 1226 | ByteBufferPrototype.readUint64 = function(offset) { 1227 | var relative = typeof offset === 'undefined'; 1228 | if (relative) offset = this.offset; 1229 | if (!this.noAssert) { 1230 | if (typeof offset !== 'number' || offset % 1 !== 0) 1231 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1232 | offset >>>= 0; 1233 | if (offset < 0 || offset + 8 > this.buffer.byteLength) 1234 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); 1235 | } 1236 | var lo = 0, 1237 | hi = 0; 1238 | if (this.littleEndian) { 1239 | lo = this.view[offset+2] << 16; 1240 | lo |= this.view[offset+1] << 8; 1241 | lo |= this.view[offset ]; 1242 | lo += this.view[offset+3] << 24 >>> 0; 1243 | offset += 4; 1244 | hi = this.view[offset+2] << 16; 1245 | hi |= this.view[offset+1] << 8; 1246 | hi |= this.view[offset ]; 1247 | hi += this.view[offset+3] << 24 >>> 0; 1248 | } else { 1249 | hi = this.view[offset+1] << 16; 1250 | hi |= this.view[offset+2] << 8; 1251 | hi |= this.view[offset+3]; 1252 | hi += this.view[offset ] << 24 >>> 0; 1253 | offset += 4; 1254 | lo = this.view[offset+1] << 16; 1255 | lo |= this.view[offset+2] << 8; 1256 | lo |= this.view[offset+3]; 1257 | lo += this.view[offset ] << 24 >>> 0; 1258 | } 1259 | var value = new Long(lo, hi, true); 1260 | if (relative) this.offset += 8; 1261 | return value; 1262 | }; 1263 | 1264 | /** 1265 | * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}. 1266 | * @function 1267 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1268 | * @returns {!Long} 1269 | * @expose 1270 | */ 1271 | ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64; 1272 | 1273 | } // Long 1274 | 1275 | 1276 | // types/floats/float32 1277 | 1278 | /* 1279 | ieee754 - https://github.com/feross/ieee754 1280 | 1281 | The MIT License (MIT) 1282 | 1283 | Copyright (c) Feross Aboukhadijeh 1284 | 1285 | Permission is hereby granted, free of charge, to any person obtaining a copy 1286 | of this software and associated documentation files (the "Software"), to deal 1287 | in the Software without restriction, including without limitation the rights 1288 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1289 | copies of the Software, and to permit persons to whom the Software is 1290 | furnished to do so, subject to the following conditions: 1291 | 1292 | The above copyright notice and this permission notice shall be included in 1293 | all copies or substantial portions of the Software. 1294 | 1295 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1296 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1297 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1298 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1299 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1300 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 1301 | THE SOFTWARE. 1302 | */ 1303 | 1304 | /** 1305 | * Reads an IEEE754 float from a byte array. 1306 | * @param {!Array} buffer 1307 | * @param {number} offset 1308 | * @param {boolean} isLE 1309 | * @param {number} mLen 1310 | * @param {number} nBytes 1311 | * @returns {number} 1312 | * @inner 1313 | */ 1314 | function ieee754_read(buffer, offset, isLE, mLen, nBytes) { 1315 | var e, m, 1316 | eLen = nBytes * 8 - mLen - 1, 1317 | eMax = (1 << eLen) - 1, 1318 | eBias = eMax >> 1, 1319 | nBits = -7, 1320 | i = isLE ? (nBytes - 1) : 0, 1321 | d = isLE ? -1 : 1, 1322 | s = buffer[offset + i]; 1323 | 1324 | i += d; 1325 | 1326 | e = s & ((1 << (-nBits)) - 1); 1327 | s >>= (-nBits); 1328 | nBits += eLen; 1329 | for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} 1330 | 1331 | m = e & ((1 << (-nBits)) - 1); 1332 | e >>= (-nBits); 1333 | nBits += mLen; 1334 | for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} 1335 | 1336 | if (e === 0) { 1337 | e = 1 - eBias; 1338 | } else if (e === eMax) { 1339 | return m ? NaN : ((s ? -1 : 1) * Infinity); 1340 | } else { 1341 | m = m + Math.pow(2, mLen); 1342 | e = e - eBias; 1343 | } 1344 | return (s ? -1 : 1) * m * Math.pow(2, e - mLen); 1345 | } 1346 | 1347 | /** 1348 | * Writes an IEEE754 float to a byte array. 1349 | * @param {!Array} buffer 1350 | * @param {number} value 1351 | * @param {number} offset 1352 | * @param {boolean} isLE 1353 | * @param {number} mLen 1354 | * @param {number} nBytes 1355 | * @inner 1356 | */ 1357 | function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) { 1358 | var e, m, c, 1359 | eLen = nBytes * 8 - mLen - 1, 1360 | eMax = (1 << eLen) - 1, 1361 | eBias = eMax >> 1, 1362 | rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), 1363 | i = isLE ? 0 : (nBytes - 1), 1364 | d = isLE ? 1 : -1, 1365 | s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; 1366 | 1367 | value = Math.abs(value); 1368 | 1369 | if (isNaN(value) || value === Infinity) { 1370 | m = isNaN(value) ? 1 : 0; 1371 | e = eMax; 1372 | } else { 1373 | e = Math.floor(Math.log(value) / Math.LN2); 1374 | if (value * (c = Math.pow(2, -e)) < 1) { 1375 | e--; 1376 | c *= 2; 1377 | } 1378 | if (e + eBias >= 1) { 1379 | value += rt / c; 1380 | } else { 1381 | value += rt * Math.pow(2, 1 - eBias); 1382 | } 1383 | if (value * c >= 2) { 1384 | e++; 1385 | c /= 2; 1386 | } 1387 | 1388 | if (e + eBias >= eMax) { 1389 | m = 0; 1390 | e = eMax; 1391 | } else if (e + eBias >= 1) { 1392 | m = (value * c - 1) * Math.pow(2, mLen); 1393 | e = e + eBias; 1394 | } else { 1395 | m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); 1396 | e = 0; 1397 | } 1398 | } 1399 | 1400 | for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} 1401 | 1402 | e = (e << mLen) | m; 1403 | eLen += mLen; 1404 | for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} 1405 | 1406 | buffer[offset + i - d] |= s * 128; 1407 | } 1408 | 1409 | /** 1410 | * Writes a 32bit float. 1411 | * @param {number} value Value to write 1412 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 1413 | * @returns {!ByteBuffer} this 1414 | * @expose 1415 | */ 1416 | ByteBufferPrototype.writeFloat32 = function(value, offset) { 1417 | var relative = typeof offset === 'undefined'; 1418 | if (relative) offset = this.offset; 1419 | if (!this.noAssert) { 1420 | if (typeof value !== 'number') 1421 | throw TypeError("Illegal value: "+value+" (not a number)"); 1422 | if (typeof offset !== 'number' || offset % 1 !== 0) 1423 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1424 | offset >>>= 0; 1425 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1426 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1427 | } 1428 | offset += 4; 1429 | var capacity8 = this.buffer.byteLength; 1430 | if (offset > capacity8) 1431 | this.resize((capacity8 *= 2) > offset ? capacity8 : offset); 1432 | offset -= 4; 1433 | ieee754_write(this.view, value, offset, this.littleEndian, 23, 4); 1434 | if (relative) this.offset += 4; 1435 | return this; 1436 | }; 1437 | 1438 | /** 1439 | * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}. 1440 | * @function 1441 | * @param {number} value Value to write 1442 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 1443 | * @returns {!ByteBuffer} this 1444 | * @expose 1445 | */ 1446 | ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32; 1447 | 1448 | /** 1449 | * Reads a 32bit float. 1450 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 1451 | * @returns {number} 1452 | * @expose 1453 | */ 1454 | ByteBufferPrototype.readFloat32 = function(offset) { 1455 | var relative = typeof offset === 'undefined'; 1456 | if (relative) offset = this.offset; 1457 | if (!this.noAssert) { 1458 | if (typeof offset !== 'number' || offset % 1 !== 0) 1459 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1460 | offset >>>= 0; 1461 | if (offset < 0 || offset + 4 > this.buffer.byteLength) 1462 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); 1463 | } 1464 | var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4); 1465 | if (relative) this.offset += 4; 1466 | return value; 1467 | }; 1468 | 1469 | /** 1470 | * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}. 1471 | * @function 1472 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. 1473 | * @returns {number} 1474 | * @expose 1475 | */ 1476 | ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32; 1477 | 1478 | // types/floats/float64 1479 | 1480 | /** 1481 | * Writes a 64bit float. 1482 | * @param {number} value Value to write 1483 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1484 | * @returns {!ByteBuffer} this 1485 | * @expose 1486 | */ 1487 | ByteBufferPrototype.writeFloat64 = function(value, offset) { 1488 | var relative = typeof offset === 'undefined'; 1489 | if (relative) offset = this.offset; 1490 | if (!this.noAssert) { 1491 | if (typeof value !== 'number') 1492 | throw TypeError("Illegal value: "+value+" (not a number)"); 1493 | if (typeof offset !== 'number' || offset % 1 !== 0) 1494 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1495 | offset >>>= 0; 1496 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1497 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1498 | } 1499 | offset += 8; 1500 | var capacity9 = this.buffer.byteLength; 1501 | if (offset > capacity9) 1502 | this.resize((capacity9 *= 2) > offset ? capacity9 : offset); 1503 | offset -= 8; 1504 | ieee754_write(this.view, value, offset, this.littleEndian, 52, 8); 1505 | if (relative) this.offset += 8; 1506 | return this; 1507 | }; 1508 | 1509 | /** 1510 | * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}. 1511 | * @function 1512 | * @param {number} value Value to write 1513 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1514 | * @returns {!ByteBuffer} this 1515 | * @expose 1516 | */ 1517 | ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64; 1518 | 1519 | /** 1520 | * Reads a 64bit float. 1521 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1522 | * @returns {number} 1523 | * @expose 1524 | */ 1525 | ByteBufferPrototype.readFloat64 = function(offset) { 1526 | var relative = typeof offset === 'undefined'; 1527 | if (relative) offset = this.offset; 1528 | if (!this.noAssert) { 1529 | if (typeof offset !== 'number' || offset % 1 !== 0) 1530 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1531 | offset >>>= 0; 1532 | if (offset < 0 || offset + 8 > this.buffer.byteLength) 1533 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); 1534 | } 1535 | var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8); 1536 | if (relative) this.offset += 8; 1537 | return value; 1538 | }; 1539 | 1540 | /** 1541 | * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}. 1542 | * @function 1543 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. 1544 | * @returns {number} 1545 | * @expose 1546 | */ 1547 | ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64; 1548 | 1549 | 1550 | // types/varints/varint32 1551 | 1552 | /** 1553 | * Maximum number of bytes required to store a 32bit base 128 variable-length integer. 1554 | * @type {number} 1555 | * @const 1556 | * @expose 1557 | */ 1558 | ByteBuffer.MAX_VARINT32_BYTES = 5; 1559 | 1560 | /** 1561 | * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer. 1562 | * @param {number} value Value to encode 1563 | * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES} 1564 | * @expose 1565 | */ 1566 | ByteBuffer.calculateVarint32 = function(value) { 1567 | // ref: src/google/protobuf/io/coded_stream.cc 1568 | value = value >>> 0; 1569 | if (value < 1 << 7 ) return 1; 1570 | else if (value < 1 << 14) return 2; 1571 | else if (value < 1 << 21) return 3; 1572 | else if (value < 1 << 28) return 4; 1573 | else return 5; 1574 | }; 1575 | 1576 | /** 1577 | * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding. 1578 | * @param {number} n Signed 32bit integer 1579 | * @returns {number} Unsigned zigzag encoded 32bit integer 1580 | * @expose 1581 | */ 1582 | ByteBuffer.zigZagEncode32 = function(n) { 1583 | return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h 1584 | }; 1585 | 1586 | /** 1587 | * Decodes a zigzag encoded signed 32bit integer. 1588 | * @param {number} n Unsigned zigzag encoded 32bit integer 1589 | * @returns {number} Signed 32bit integer 1590 | * @expose 1591 | */ 1592 | ByteBuffer.zigZagDecode32 = function(n) { 1593 | return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h 1594 | }; 1595 | 1596 | /** 1597 | * Writes a 32bit base 128 variable-length integer. 1598 | * @param {number} value Value to write 1599 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1600 | * written if omitted. 1601 | * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written 1602 | * @expose 1603 | */ 1604 | ByteBufferPrototype.writeVarint32 = function(value, offset) { 1605 | var relative = typeof offset === 'undefined'; 1606 | if (relative) offset = this.offset; 1607 | if (!this.noAssert) { 1608 | if (typeof value !== 'number' || value % 1 !== 0) 1609 | throw TypeError("Illegal value: "+value+" (not an integer)"); 1610 | value |= 0; 1611 | if (typeof offset !== 'number' || offset % 1 !== 0) 1612 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1613 | offset >>>= 0; 1614 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1615 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1616 | } 1617 | var size = ByteBuffer.calculateVarint32(value), 1618 | b; 1619 | offset += size; 1620 | var capacity10 = this.buffer.byteLength; 1621 | if (offset > capacity10) 1622 | this.resize((capacity10 *= 2) > offset ? capacity10 : offset); 1623 | offset -= size; 1624 | value >>>= 0; 1625 | while (value >= 0x80) { 1626 | b = (value & 0x7f) | 0x80; 1627 | this.view[offset++] = b; 1628 | value >>>= 7; 1629 | } 1630 | this.view[offset++] = value; 1631 | if (relative) { 1632 | this.offset = offset; 1633 | return this; 1634 | } 1635 | return size; 1636 | }; 1637 | 1638 | /** 1639 | * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer. 1640 | * @param {number} value Value to write 1641 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1642 | * written if omitted. 1643 | * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written 1644 | * @expose 1645 | */ 1646 | ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) { 1647 | return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset); 1648 | }; 1649 | 1650 | /** 1651 | * Reads a 32bit base 128 variable-length integer. 1652 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1653 | * written if omitted. 1654 | * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read 1655 | * and the actual number of bytes read. 1656 | * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available 1657 | * to fully decode the varint. 1658 | * @expose 1659 | */ 1660 | ByteBufferPrototype.readVarint32 = function(offset) { 1661 | var relative = typeof offset === 'undefined'; 1662 | if (relative) offset = this.offset; 1663 | if (!this.noAssert) { 1664 | if (typeof offset !== 'number' || offset % 1 !== 0) 1665 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1666 | offset >>>= 0; 1667 | if (offset < 0 || offset + 1 > this.buffer.byteLength) 1668 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); 1669 | } 1670 | var c = 0, 1671 | value = 0 >>> 0, 1672 | b; 1673 | do { 1674 | if (!this.noAssert && offset > this.limit) { 1675 | var err = Error("Truncated"); 1676 | err['truncated'] = true; 1677 | throw err; 1678 | } 1679 | b = this.view[offset++]; 1680 | if (c < 5) 1681 | value |= (b & 0x7f) << (7*c); 1682 | ++c; 1683 | } while ((b & 0x80) !== 0); 1684 | value |= 0; 1685 | if (relative) { 1686 | this.offset = offset; 1687 | return value; 1688 | } 1689 | return { 1690 | "value": value, 1691 | "length": c 1692 | }; 1693 | }; 1694 | 1695 | /** 1696 | * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer. 1697 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1698 | * written if omitted. 1699 | * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read 1700 | * and the actual number of bytes read. 1701 | * @throws {Error} If it's not a valid varint 1702 | * @expose 1703 | */ 1704 | ByteBufferPrototype.readVarint32ZigZag = function(offset) { 1705 | var val = this.readVarint32(offset); 1706 | if (typeof val === 'object') 1707 | val["value"] = ByteBuffer.zigZagDecode32(val["value"]); 1708 | else 1709 | val = ByteBuffer.zigZagDecode32(val); 1710 | return val; 1711 | }; 1712 | 1713 | // types/varints/varint64 1714 | 1715 | if (Long) { 1716 | 1717 | /** 1718 | * Maximum number of bytes required to store a 64bit base 128 variable-length integer. 1719 | * @type {number} 1720 | * @const 1721 | * @expose 1722 | */ 1723 | ByteBuffer.MAX_VARINT64_BYTES = 10; 1724 | 1725 | /** 1726 | * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer. 1727 | * @param {number|!Long} value Value to encode 1728 | * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES} 1729 | * @expose 1730 | */ 1731 | ByteBuffer.calculateVarint64 = function(value) { 1732 | if (typeof value === 'number') 1733 | value = Long.fromNumber(value); 1734 | else if (typeof value === 'string') 1735 | value = Long.fromString(value); 1736 | // ref: src/google/protobuf/io/coded_stream.cc 1737 | var part0 = value.toInt() >>> 0, 1738 | part1 = value.shiftRightUnsigned(28).toInt() >>> 0, 1739 | part2 = value.shiftRightUnsigned(56).toInt() >>> 0; 1740 | if (part2 == 0) { 1741 | if (part1 == 0) { 1742 | if (part0 < 1 << 14) 1743 | return part0 < 1 << 7 ? 1 : 2; 1744 | else 1745 | return part0 < 1 << 21 ? 3 : 4; 1746 | } else { 1747 | if (part1 < 1 << 14) 1748 | return part1 < 1 << 7 ? 5 : 6; 1749 | else 1750 | return part1 < 1 << 21 ? 7 : 8; 1751 | } 1752 | } else 1753 | return part2 < 1 << 7 ? 9 : 10; 1754 | }; 1755 | 1756 | /** 1757 | * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding. 1758 | * @param {number|!Long} value Signed long 1759 | * @returns {!Long} Unsigned zigzag encoded long 1760 | * @expose 1761 | */ 1762 | ByteBuffer.zigZagEncode64 = function(value) { 1763 | if (typeof value === 'number') 1764 | value = Long.fromNumber(value, false); 1765 | else if (typeof value === 'string') 1766 | value = Long.fromString(value, false); 1767 | else if (value.unsigned !== false) value = value.toSigned(); 1768 | // ref: src/google/protobuf/wire_format_lite.h 1769 | return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned(); 1770 | }; 1771 | 1772 | /** 1773 | * Decodes a zigzag encoded signed 64bit integer. 1774 | * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number 1775 | * @returns {!Long} Signed long 1776 | * @expose 1777 | */ 1778 | ByteBuffer.zigZagDecode64 = function(value) { 1779 | if (typeof value === 'number') 1780 | value = Long.fromNumber(value, false); 1781 | else if (typeof value === 'string') 1782 | value = Long.fromString(value, false); 1783 | else if (value.unsigned !== false) value = value.toSigned(); 1784 | // ref: src/google/protobuf/wire_format_lite.h 1785 | return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned(); 1786 | }; 1787 | 1788 | /** 1789 | * Writes a 64bit base 128 variable-length integer. 1790 | * @param {number|Long} value Value to write 1791 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1792 | * written if omitted. 1793 | * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. 1794 | * @expose 1795 | */ 1796 | ByteBufferPrototype.writeVarint64 = function(value, offset) { 1797 | var relative = typeof offset === 'undefined'; 1798 | if (relative) offset = this.offset; 1799 | if (!this.noAssert) { 1800 | if (typeof value === 'number') 1801 | value = Long.fromNumber(value); 1802 | else if (typeof value === 'string') 1803 | value = Long.fromString(value); 1804 | else if (!(value && value instanceof Long)) 1805 | throw TypeError("Illegal value: "+value+" (not an integer or Long)"); 1806 | if (typeof offset !== 'number' || offset % 1 !== 0) 1807 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1808 | offset >>>= 0; 1809 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1810 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1811 | } 1812 | if (typeof value === 'number') 1813 | value = Long.fromNumber(value, false); 1814 | else if (typeof value === 'string') 1815 | value = Long.fromString(value, false); 1816 | else if (value.unsigned !== false) value = value.toSigned(); 1817 | var size = ByteBuffer.calculateVarint64(value), 1818 | part0 = value.toInt() >>> 0, 1819 | part1 = value.shiftRightUnsigned(28).toInt() >>> 0, 1820 | part2 = value.shiftRightUnsigned(56).toInt() >>> 0; 1821 | offset += size; 1822 | var capacity11 = this.buffer.byteLength; 1823 | if (offset > capacity11) 1824 | this.resize((capacity11 *= 2) > offset ? capacity11 : offset); 1825 | offset -= size; 1826 | switch (size) { 1827 | case 10: this.view[offset+9] = (part2 >>> 7) & 0x01; 1828 | case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F; 1829 | case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F; 1830 | case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F; 1831 | case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F; 1832 | case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F; 1833 | case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F; 1834 | case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F; 1835 | case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F; 1836 | case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F; 1837 | } 1838 | if (relative) { 1839 | this.offset += size; 1840 | return this; 1841 | } else { 1842 | return size; 1843 | } 1844 | }; 1845 | 1846 | /** 1847 | * Writes a zig-zag encoded 64bit base 128 variable-length integer. 1848 | * @param {number|Long} value Value to write 1849 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1850 | * written if omitted. 1851 | * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. 1852 | * @expose 1853 | */ 1854 | ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) { 1855 | return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset); 1856 | }; 1857 | 1858 | /** 1859 | * Reads a 64bit base 128 variable-length integer. Requires Long.js. 1860 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1861 | * read if omitted. 1862 | * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and 1863 | * the actual number of bytes read. 1864 | * @throws {Error} If it's not a valid varint 1865 | * @expose 1866 | */ 1867 | ByteBufferPrototype.readVarint64 = function(offset) { 1868 | var relative = typeof offset === 'undefined'; 1869 | if (relative) offset = this.offset; 1870 | if (!this.noAssert) { 1871 | if (typeof offset !== 'number' || offset % 1 !== 0) 1872 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1873 | offset >>>= 0; 1874 | if (offset < 0 || offset + 1 > this.buffer.byteLength) 1875 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); 1876 | } 1877 | // ref: src/google/protobuf/io/coded_stream.cc 1878 | var start = offset, 1879 | part0 = 0, 1880 | part1 = 0, 1881 | part2 = 0, 1882 | b = 0; 1883 | b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) { 1884 | b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1885 | b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1886 | b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1887 | b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1888 | b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1889 | b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1890 | b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1891 | b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1892 | b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { 1893 | throw Error("Buffer overrun"); }}}}}}}}}} 1894 | var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false); 1895 | if (relative) { 1896 | this.offset = offset; 1897 | return value; 1898 | } else { 1899 | return { 1900 | 'value': value, 1901 | 'length': offset-start 1902 | }; 1903 | } 1904 | }; 1905 | 1906 | /** 1907 | * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js. 1908 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1909 | * read if omitted. 1910 | * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and 1911 | * the actual number of bytes read. 1912 | * @throws {Error} If it's not a valid varint 1913 | * @expose 1914 | */ 1915 | ByteBufferPrototype.readVarint64ZigZag = function(offset) { 1916 | var val = this.readVarint64(offset); 1917 | if (val && val['value'] instanceof Long) 1918 | val["value"] = ByteBuffer.zigZagDecode64(val["value"]); 1919 | else 1920 | val = ByteBuffer.zigZagDecode64(val); 1921 | return val; 1922 | }; 1923 | 1924 | } // Long 1925 | 1926 | 1927 | // types/strings/cstring 1928 | 1929 | /** 1930 | * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL 1931 | * characters itself. 1932 | * @param {string} str String to write 1933 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1934 | * contained in `str` + 1 if omitted. 1935 | * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written 1936 | * @expose 1937 | */ 1938 | ByteBufferPrototype.writeCString = function(str, offset) { 1939 | var relative = typeof offset === 'undefined'; 1940 | if (relative) offset = this.offset; 1941 | var i, 1942 | k = str.length; 1943 | if (!this.noAssert) { 1944 | if (typeof str !== 'string') 1945 | throw TypeError("Illegal str: Not a string"); 1946 | for (i=0; i>>= 0; 1953 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 1954 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 1955 | } 1956 | // UTF8 strings do not contain zero bytes in between except for the zero character, so: 1957 | k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; 1958 | offset += k+1; 1959 | var capacity12 = this.buffer.byteLength; 1960 | if (offset > capacity12) 1961 | this.resize((capacity12 *= 2) > offset ? capacity12 : offset); 1962 | offset -= k+1; 1963 | utfx.encodeUTF16toUTF8(stringSource(str), function(b) { 1964 | this.view[offset++] = b; 1965 | }.bind(this)); 1966 | this.view[offset++] = 0; 1967 | if (relative) { 1968 | this.offset = offset; 1969 | return this; 1970 | } 1971 | return k; 1972 | }; 1973 | 1974 | /** 1975 | * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters 1976 | * itself. 1977 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 1978 | * read if omitted. 1979 | * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string 1980 | * read and the actual number of bytes read. 1981 | * @expose 1982 | */ 1983 | ByteBufferPrototype.readCString = function(offset) { 1984 | var relative = typeof offset === 'undefined'; 1985 | if (relative) offset = this.offset; 1986 | if (!this.noAssert) { 1987 | if (typeof offset !== 'number' || offset % 1 !== 0) 1988 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 1989 | offset >>>= 0; 1990 | if (offset < 0 || offset + 1 > this.buffer.byteLength) 1991 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); 1992 | } 1993 | var start = offset, 1994 | temp; 1995 | // UTF8 strings do not contain zero bytes in between except for the zero character itself, so: 1996 | var sd, b = -1; 1997 | utfx.decodeUTF8toUTF16(function() { 1998 | if (b === 0) return null; 1999 | if (offset >= this.limit) 2000 | throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit); 2001 | b = this.view[offset++]; 2002 | return b === 0 ? null : b; 2003 | }.bind(this), sd = stringDestination(), true); 2004 | if (relative) { 2005 | this.offset = offset; 2006 | return sd(); 2007 | } else { 2008 | return { 2009 | "string": sd(), 2010 | "length": offset - start 2011 | }; 2012 | } 2013 | }; 2014 | 2015 | // types/strings/istring 2016 | 2017 | /** 2018 | * Writes a length as uint32 prefixed UTF8 encoded string. 2019 | * @param {string} str String to write 2020 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2021 | * written if omitted. 2022 | * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written 2023 | * @expose 2024 | * @see ByteBuffer#writeVarint32 2025 | */ 2026 | ByteBufferPrototype.writeIString = function(str, offset) { 2027 | var relative = typeof offset === 'undefined'; 2028 | if (relative) offset = this.offset; 2029 | if (!this.noAssert) { 2030 | if (typeof str !== 'string') 2031 | throw TypeError("Illegal str: Not a string"); 2032 | if (typeof offset !== 'number' || offset % 1 !== 0) 2033 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2034 | offset >>>= 0; 2035 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2036 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2037 | } 2038 | var start = offset, 2039 | k; 2040 | k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; 2041 | offset += 4+k; 2042 | var capacity13 = this.buffer.byteLength; 2043 | if (offset > capacity13) 2044 | this.resize((capacity13 *= 2) > offset ? capacity13 : offset); 2045 | offset -= 4+k; 2046 | if (this.littleEndian) { 2047 | this.view[offset+3] = (k >>> 24) & 0xFF; 2048 | this.view[offset+2] = (k >>> 16) & 0xFF; 2049 | this.view[offset+1] = (k >>> 8) & 0xFF; 2050 | this.view[offset ] = k & 0xFF; 2051 | } else { 2052 | this.view[offset ] = (k >>> 24) & 0xFF; 2053 | this.view[offset+1] = (k >>> 16) & 0xFF; 2054 | this.view[offset+2] = (k >>> 8) & 0xFF; 2055 | this.view[offset+3] = k & 0xFF; 2056 | } 2057 | offset += 4; 2058 | utfx.encodeUTF16toUTF8(stringSource(str), function(b) { 2059 | this.view[offset++] = b; 2060 | }.bind(this)); 2061 | if (offset !== start + 4 + k) 2062 | throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k)); 2063 | if (relative) { 2064 | this.offset = offset; 2065 | return this; 2066 | } 2067 | return offset - start; 2068 | }; 2069 | 2070 | /** 2071 | * Reads a length as uint32 prefixed UTF8 encoded string. 2072 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2073 | * read if omitted. 2074 | * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string 2075 | * read and the actual number of bytes read. 2076 | * @expose 2077 | * @see ByteBuffer#readVarint32 2078 | */ 2079 | ByteBufferPrototype.readIString = function(offset) { 2080 | var relative = typeof offset === 'undefined'; 2081 | if (relative) offset = this.offset; 2082 | if (!this.noAssert) { 2083 | if (typeof offset !== 'number' || offset % 1 !== 0) 2084 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2085 | offset >>>= 0; 2086 | if (offset < 0 || offset + 4 > this.buffer.byteLength) 2087 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); 2088 | } 2089 | var start = offset; 2090 | var len = this.readUint32(offset); 2091 | var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4); 2092 | offset += str['length']; 2093 | if (relative) { 2094 | this.offset = offset; 2095 | return str['string']; 2096 | } else { 2097 | return { 2098 | 'string': str['string'], 2099 | 'length': offset - start 2100 | }; 2101 | } 2102 | }; 2103 | 2104 | // types/strings/utf8string 2105 | 2106 | /** 2107 | * Metrics representing number of UTF8 characters. Evaluates to `c`. 2108 | * @type {string} 2109 | * @const 2110 | * @expose 2111 | */ 2112 | ByteBuffer.METRICS_CHARS = 'c'; 2113 | 2114 | /** 2115 | * Metrics representing number of bytes. Evaluates to `b`. 2116 | * @type {string} 2117 | * @const 2118 | * @expose 2119 | */ 2120 | ByteBuffer.METRICS_BYTES = 'b'; 2121 | 2122 | /** 2123 | * Writes an UTF8 encoded string. 2124 | * @param {string} str String to write 2125 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. 2126 | * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. 2127 | * @expose 2128 | */ 2129 | ByteBufferPrototype.writeUTF8String = function(str, offset) { 2130 | var relative = typeof offset === 'undefined'; 2131 | if (relative) offset = this.offset; 2132 | if (!this.noAssert) { 2133 | if (typeof offset !== 'number' || offset % 1 !== 0) 2134 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2135 | offset >>>= 0; 2136 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2137 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2138 | } 2139 | var k; 2140 | var start = offset; 2141 | k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; 2142 | offset += k; 2143 | var capacity14 = this.buffer.byteLength; 2144 | if (offset > capacity14) 2145 | this.resize((capacity14 *= 2) > offset ? capacity14 : offset); 2146 | offset -= k; 2147 | utfx.encodeUTF16toUTF8(stringSource(str), function(b) { 2148 | this.view[offset++] = b; 2149 | }.bind(this)); 2150 | if (relative) { 2151 | this.offset = offset; 2152 | return this; 2153 | } 2154 | return offset - start; 2155 | }; 2156 | 2157 | /** 2158 | * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}. 2159 | * @function 2160 | * @param {string} str String to write 2161 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. 2162 | * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. 2163 | * @expose 2164 | */ 2165 | ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String; 2166 | 2167 | /** 2168 | * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's 2169 | * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF. 2170 | * @param {string} str String to calculate 2171 | * @returns {number} Number of UTF8 characters 2172 | * @expose 2173 | */ 2174 | ByteBuffer.calculateUTF8Chars = function(str) { 2175 | return utfx.calculateUTF16asUTF8(stringSource(str))[0]; 2176 | }; 2177 | 2178 | /** 2179 | * Calculates the number of UTF8 bytes of a string. 2180 | * @param {string} str String to calculate 2181 | * @returns {number} Number of UTF8 bytes 2182 | * @expose 2183 | */ 2184 | ByteBuffer.calculateUTF8Bytes = function(str) { 2185 | return utfx.calculateUTF16asUTF8(stringSource(str))[1]; 2186 | }; 2187 | 2188 | /** 2189 | * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}. 2190 | * @function 2191 | * @param {string} str String to calculate 2192 | * @returns {number} Number of UTF8 bytes 2193 | * @expose 2194 | */ 2195 | ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes; 2196 | 2197 | /** 2198 | * Reads an UTF8 encoded string. 2199 | * @param {number} length Number of characters or bytes to read. 2200 | * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to 2201 | * {@link ByteBuffer.METRICS_CHARS}. 2202 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2203 | * read if omitted. 2204 | * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string 2205 | * read and the actual number of bytes read. 2206 | * @expose 2207 | */ 2208 | ByteBufferPrototype.readUTF8String = function(length, metrics, offset) { 2209 | if (typeof metrics === 'number') { 2210 | offset = metrics; 2211 | metrics = undefined; 2212 | } 2213 | var relative = typeof offset === 'undefined'; 2214 | if (relative) offset = this.offset; 2215 | if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS; 2216 | if (!this.noAssert) { 2217 | if (typeof length !== 'number' || length % 1 !== 0) 2218 | throw TypeError("Illegal length: "+length+" (not an integer)"); 2219 | length |= 0; 2220 | if (typeof offset !== 'number' || offset % 1 !== 0) 2221 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2222 | offset >>>= 0; 2223 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2224 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2225 | } 2226 | var i = 0, 2227 | start = offset, 2228 | sd; 2229 | if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser 2230 | sd = stringDestination(); 2231 | utfx.decodeUTF8(function() { 2232 | return i < length && offset < this.limit ? this.view[offset++] : null; 2233 | }.bind(this), function(cp) { 2234 | ++i; utfx.UTF8toUTF16(cp, sd); 2235 | }); 2236 | if (i !== length) 2237 | throw RangeError("Illegal range: Truncated data, "+i+" == "+length); 2238 | if (relative) { 2239 | this.offset = offset; 2240 | return sd(); 2241 | } else { 2242 | return { 2243 | "string": sd(), 2244 | "length": offset - start 2245 | }; 2246 | } 2247 | } else if (metrics === ByteBuffer.METRICS_BYTES) { 2248 | if (!this.noAssert) { 2249 | if (typeof offset !== 'number' || offset % 1 !== 0) 2250 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2251 | offset >>>= 0; 2252 | if (offset < 0 || offset + length > this.buffer.byteLength) 2253 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); 2254 | } 2255 | var k = offset + length; 2256 | utfx.decodeUTF8toUTF16(function() { 2257 | return offset < k ? this.view[offset++] : null; 2258 | }.bind(this), sd = stringDestination(), this.noAssert); 2259 | if (offset !== k) 2260 | throw RangeError("Illegal range: Truncated data, "+offset+" == "+k); 2261 | if (relative) { 2262 | this.offset = offset; 2263 | return sd(); 2264 | } else { 2265 | return { 2266 | 'string': sd(), 2267 | 'length': offset - start 2268 | }; 2269 | } 2270 | } else 2271 | throw TypeError("Unsupported metrics: "+metrics); 2272 | }; 2273 | 2274 | /** 2275 | * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}. 2276 | * @function 2277 | * @param {number} length Number of characters or bytes to read 2278 | * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to 2279 | * {@link ByteBuffer.METRICS_CHARS}. 2280 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2281 | * read if omitted. 2282 | * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string 2283 | * read and the actual number of bytes read. 2284 | * @expose 2285 | */ 2286 | ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String; 2287 | 2288 | // types/strings/vstring 2289 | 2290 | /** 2291 | * Writes a length as varint32 prefixed UTF8 encoded string. 2292 | * @param {string} str String to write 2293 | * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2294 | * written if omitted. 2295 | * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written 2296 | * @expose 2297 | * @see ByteBuffer#writeVarint32 2298 | */ 2299 | ByteBufferPrototype.writeVString = function(str, offset) { 2300 | var relative = typeof offset === 'undefined'; 2301 | if (relative) offset = this.offset; 2302 | if (!this.noAssert) { 2303 | if (typeof str !== 'string') 2304 | throw TypeError("Illegal str: Not a string"); 2305 | if (typeof offset !== 'number' || offset % 1 !== 0) 2306 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2307 | offset >>>= 0; 2308 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2309 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2310 | } 2311 | var start = offset, 2312 | k, l; 2313 | k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; 2314 | l = ByteBuffer.calculateVarint32(k); 2315 | offset += l+k; 2316 | var capacity15 = this.buffer.byteLength; 2317 | if (offset > capacity15) 2318 | this.resize((capacity15 *= 2) > offset ? capacity15 : offset); 2319 | offset -= l+k; 2320 | offset += this.writeVarint32(k, offset); 2321 | utfx.encodeUTF16toUTF8(stringSource(str), function(b) { 2322 | this.view[offset++] = b; 2323 | }.bind(this)); 2324 | if (offset !== start+k+l) 2325 | throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l)); 2326 | if (relative) { 2327 | this.offset = offset; 2328 | return this; 2329 | } 2330 | return offset - start; 2331 | }; 2332 | 2333 | /** 2334 | * Reads a length as varint32 prefixed UTF8 encoded string. 2335 | * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2336 | * read if omitted. 2337 | * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string 2338 | * read and the actual number of bytes read. 2339 | * @expose 2340 | * @see ByteBuffer#readVarint32 2341 | */ 2342 | ByteBufferPrototype.readVString = function(offset) { 2343 | var relative = typeof offset === 'undefined'; 2344 | if (relative) offset = this.offset; 2345 | if (!this.noAssert) { 2346 | if (typeof offset !== 'number' || offset % 1 !== 0) 2347 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2348 | offset >>>= 0; 2349 | if (offset < 0 || offset + 1 > this.buffer.byteLength) 2350 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); 2351 | } 2352 | var start = offset; 2353 | var len = this.readVarint32(offset); 2354 | var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']); 2355 | offset += str['length']; 2356 | if (relative) { 2357 | this.offset = offset; 2358 | return str['string']; 2359 | } else { 2360 | return { 2361 | 'string': str['string'], 2362 | 'length': offset - start 2363 | }; 2364 | } 2365 | }; 2366 | 2367 | 2368 | /** 2369 | * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended 2370 | * data's length. 2371 | * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets 2372 | * will be modified according to the performed read operation. 2373 | * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") 2374 | * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2375 | * written if omitted. 2376 | * @returns {!ByteBuffer} this 2377 | * @expose 2378 | * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|` 2379 | * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|` 2380 | */ 2381 | ByteBufferPrototype.append = function(source, encoding, offset) { 2382 | if (typeof encoding === 'number' || typeof encoding !== 'string') { 2383 | offset = encoding; 2384 | encoding = undefined; 2385 | } 2386 | var relative = typeof offset === 'undefined'; 2387 | if (relative) offset = this.offset; 2388 | if (!this.noAssert) { 2389 | if (typeof offset !== 'number' || offset % 1 !== 0) 2390 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2391 | offset >>>= 0; 2392 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2393 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2394 | } 2395 | if (!(source instanceof ByteBuffer)) 2396 | source = ByteBuffer.wrap(source, encoding); 2397 | var length = source.limit - source.offset; 2398 | if (length <= 0) return this; // Nothing to append 2399 | offset += length; 2400 | var capacity16 = this.buffer.byteLength; 2401 | if (offset > capacity16) 2402 | this.resize((capacity16 *= 2) > offset ? capacity16 : offset); 2403 | offset -= length; 2404 | this.view.set(source.view.subarray(source.offset, source.limit), offset); 2405 | source.offset += length; 2406 | if (relative) this.offset += length; 2407 | return this; 2408 | }; 2409 | 2410 | /** 2411 | * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the 2412 | specified offset up to the length of this ByteBuffer's data. 2413 | * @param {!ByteBuffer} target Target ByteBuffer 2414 | * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2415 | * read if omitted. 2416 | * @returns {!ByteBuffer} this 2417 | * @expose 2418 | * @see ByteBuffer#append 2419 | */ 2420 | ByteBufferPrototype.appendTo = function(target, offset) { 2421 | target.append(this, offset); 2422 | return this; 2423 | }; 2424 | 2425 | /** 2426 | * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to 2427 | * disable them if your code already makes sure that everything is valid. 2428 | * @param {boolean} assert `true` to enable assertions, otherwise `false` 2429 | * @returns {!ByteBuffer} this 2430 | * @expose 2431 | */ 2432 | ByteBufferPrototype.assert = function(assert) { 2433 | this.noAssert = !assert; 2434 | return this; 2435 | }; 2436 | 2437 | /** 2438 | * Gets the capacity of this ByteBuffer's backing buffer. 2439 | * @returns {number} Capacity of the backing buffer 2440 | * @expose 2441 | */ 2442 | ByteBufferPrototype.capacity = function() { 2443 | return this.buffer.byteLength; 2444 | }; 2445 | /** 2446 | * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the 2447 | * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}. 2448 | * @returns {!ByteBuffer} this 2449 | * @expose 2450 | */ 2451 | ByteBufferPrototype.clear = function() { 2452 | this.offset = 0; 2453 | this.limit = this.buffer.byteLength; 2454 | this.markedOffset = -1; 2455 | return this; 2456 | }; 2457 | 2458 | /** 2459 | * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset}, 2460 | * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}. 2461 | * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false` 2462 | * @returns {!ByteBuffer} Cloned instance 2463 | * @expose 2464 | */ 2465 | ByteBufferPrototype.clone = function(copy) { 2466 | var bb = new ByteBuffer(0, this.littleEndian, this.noAssert); 2467 | if (copy) { 2468 | bb.buffer = new ArrayBuffer(this.buffer.byteLength); 2469 | bb.view = new Uint8Array(bb.buffer); 2470 | } else { 2471 | bb.buffer = this.buffer; 2472 | bb.view = this.view; 2473 | } 2474 | bb.offset = this.offset; 2475 | bb.markedOffset = this.markedOffset; 2476 | bb.limit = this.limit; 2477 | return bb; 2478 | }; 2479 | 2480 | /** 2481 | * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes 2482 | * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and 2483 | * adapt {@link ByteBuffer#markedOffset} to the same relative position if set. 2484 | * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} 2485 | * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} 2486 | * @returns {!ByteBuffer} this 2487 | * @expose 2488 | */ 2489 | ByteBufferPrototype.compact = function(begin, end) { 2490 | if (typeof begin === 'undefined') begin = this.offset; 2491 | if (typeof end === 'undefined') end = this.limit; 2492 | if (!this.noAssert) { 2493 | if (typeof begin !== 'number' || begin % 1 !== 0) 2494 | throw TypeError("Illegal begin: Not an integer"); 2495 | begin >>>= 0; 2496 | if (typeof end !== 'number' || end % 1 !== 0) 2497 | throw TypeError("Illegal end: Not an integer"); 2498 | end >>>= 0; 2499 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 2500 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 2501 | } 2502 | if (begin === 0 && end === this.buffer.byteLength) 2503 | return this; // Already compacted 2504 | var len = end - begin; 2505 | if (len === 0) { 2506 | this.buffer = EMPTY_BUFFER; 2507 | this.view = null; 2508 | if (this.markedOffset >= 0) this.markedOffset -= begin; 2509 | this.offset = 0; 2510 | this.limit = 0; 2511 | return this; 2512 | } 2513 | var buffer = new ArrayBuffer(len); 2514 | var view = new Uint8Array(buffer); 2515 | view.set(this.view.subarray(begin, end)); 2516 | this.buffer = buffer; 2517 | this.view = view; 2518 | if (this.markedOffset >= 0) this.markedOffset -= begin; 2519 | this.offset = 0; 2520 | this.limit = len; 2521 | return this; 2522 | }; 2523 | 2524 | /** 2525 | * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and 2526 | * {@link ByteBuffer#limit}. 2527 | * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. 2528 | * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. 2529 | * @returns {!ByteBuffer} Copy 2530 | * @expose 2531 | */ 2532 | ByteBufferPrototype.copy = function(begin, end) { 2533 | if (typeof begin === 'undefined') begin = this.offset; 2534 | if (typeof end === 'undefined') end = this.limit; 2535 | if (!this.noAssert) { 2536 | if (typeof begin !== 'number' || begin % 1 !== 0) 2537 | throw TypeError("Illegal begin: Not an integer"); 2538 | begin >>>= 0; 2539 | if (typeof end !== 'number' || end % 1 !== 0) 2540 | throw TypeError("Illegal end: Not an integer"); 2541 | end >>>= 0; 2542 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 2543 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 2544 | } 2545 | if (begin === end) 2546 | return new ByteBuffer(0, this.littleEndian, this.noAssert); 2547 | var capacity = end - begin, 2548 | bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert); 2549 | bb.offset = 0; 2550 | bb.limit = capacity; 2551 | if (bb.markedOffset >= 0) bb.markedOffset -= begin; 2552 | this.copyTo(bb, 0, begin, end); 2553 | return bb; 2554 | }; 2555 | 2556 | /** 2557 | * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and 2558 | * {@link ByteBuffer#limit}. 2559 | * @param {!ByteBuffer} target Target ByteBuffer 2560 | * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset} 2561 | * by the number of bytes copied if omitted. 2562 | * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the 2563 | * number of bytes copied if omitted. 2564 | * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit} 2565 | * @returns {!ByteBuffer} this 2566 | * @expose 2567 | */ 2568 | ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) { 2569 | var relative, 2570 | targetRelative; 2571 | if (!this.noAssert) { 2572 | if (!ByteBuffer.isByteBuffer(target)) 2573 | throw TypeError("Illegal target: Not a ByteBuffer"); 2574 | } 2575 | targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0; 2576 | sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0; 2577 | sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0; 2578 | 2579 | if (targetOffset < 0 || targetOffset > target.buffer.byteLength) 2580 | throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength); 2581 | if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength) 2582 | throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength); 2583 | 2584 | var len = sourceLimit - sourceOffset; 2585 | if (len === 0) 2586 | return target; // Nothing to copy 2587 | 2588 | target.ensureCapacity(targetOffset + len); 2589 | 2590 | target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset); 2591 | 2592 | if (relative) this.offset += len; 2593 | if (targetRelative) target.offset += len; 2594 | 2595 | return this; 2596 | }; 2597 | 2598 | /** 2599 | * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the 2600 | * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity, 2601 | * the required capacity will be used instead. 2602 | * @param {number} capacity Required capacity 2603 | * @returns {!ByteBuffer} this 2604 | * @expose 2605 | */ 2606 | ByteBufferPrototype.ensureCapacity = function(capacity) { 2607 | var current = this.buffer.byteLength; 2608 | if (current < capacity) 2609 | return this.resize((current *= 2) > capacity ? current : capacity); 2610 | return this; 2611 | }; 2612 | 2613 | /** 2614 | * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between 2615 | * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. 2616 | * @param {number|string} value Byte value to fill with. If given as a string, the first character is used. 2617 | * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes 2618 | * written if omitted. defaults to {@link ByteBuffer#offset}. 2619 | * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. 2620 | * @returns {!ByteBuffer} this 2621 | * @expose 2622 | * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes 2623 | */ 2624 | ByteBufferPrototype.fill = function(value, begin, end) { 2625 | var relative = typeof begin === 'undefined'; 2626 | if (relative) begin = this.offset; 2627 | if (typeof value === 'string' && value.length > 0) 2628 | value = value.charCodeAt(0); 2629 | if (typeof begin === 'undefined') begin = this.offset; 2630 | if (typeof end === 'undefined') end = this.limit; 2631 | if (!this.noAssert) { 2632 | if (typeof value !== 'number' || value % 1 !== 0) 2633 | throw TypeError("Illegal value: "+value+" (not an integer)"); 2634 | value |= 0; 2635 | if (typeof begin !== 'number' || begin % 1 !== 0) 2636 | throw TypeError("Illegal begin: Not an integer"); 2637 | begin >>>= 0; 2638 | if (typeof end !== 'number' || end % 1 !== 0) 2639 | throw TypeError("Illegal end: Not an integer"); 2640 | end >>>= 0; 2641 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 2642 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 2643 | } 2644 | if (begin >= end) 2645 | return this; // Nothing to fill 2646 | while (begin < end) this.view[begin++] = value; 2647 | if (relative) this.offset = begin; 2648 | return this; 2649 | }; 2650 | 2651 | /** 2652 | * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and 2653 | * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete. 2654 | * @returns {!ByteBuffer} this 2655 | * @expose 2656 | */ 2657 | ByteBufferPrototype.flip = function() { 2658 | this.limit = this.offset; 2659 | this.offset = 0; 2660 | return this; 2661 | }; 2662 | /** 2663 | * Marks an offset on this ByteBuffer to be used later. 2664 | * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}. 2665 | * @returns {!ByteBuffer} this 2666 | * @throws {TypeError} If `offset` is not a valid number 2667 | * @throws {RangeError} If `offset` is out of bounds 2668 | * @see ByteBuffer#reset 2669 | * @expose 2670 | */ 2671 | ByteBufferPrototype.mark = function(offset) { 2672 | offset = typeof offset === 'undefined' ? this.offset : offset; 2673 | if (!this.noAssert) { 2674 | if (typeof offset !== 'number' || offset % 1 !== 0) 2675 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2676 | offset >>>= 0; 2677 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2678 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2679 | } 2680 | this.markedOffset = offset; 2681 | return this; 2682 | }; 2683 | /** 2684 | * Sets the byte order. 2685 | * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian 2686 | * @returns {!ByteBuffer} this 2687 | * @expose 2688 | */ 2689 | ByteBufferPrototype.order = function(littleEndian) { 2690 | if (!this.noAssert) { 2691 | if (typeof littleEndian !== 'boolean') 2692 | throw TypeError("Illegal littleEndian: Not a boolean"); 2693 | } 2694 | this.littleEndian = !!littleEndian; 2695 | return this; 2696 | }; 2697 | 2698 | /** 2699 | * Switches (to) little endian byte order. 2700 | * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian 2701 | * @returns {!ByteBuffer} this 2702 | * @expose 2703 | */ 2704 | ByteBufferPrototype.LE = function(littleEndian) { 2705 | this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true; 2706 | return this; 2707 | }; 2708 | 2709 | /** 2710 | * Switches (to) big endian byte order. 2711 | * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian 2712 | * @returns {!ByteBuffer} this 2713 | * @expose 2714 | */ 2715 | ByteBufferPrototype.BE = function(bigEndian) { 2716 | this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false; 2717 | return this; 2718 | }; 2719 | /** 2720 | * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the 2721 | * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer 2722 | * will be resized and its contents moved accordingly. 2723 | * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be 2724 | * modified according to the performed read operation. 2725 | * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") 2726 | * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes 2727 | * prepended if omitted. 2728 | * @returns {!ByteBuffer} this 2729 | * @expose 2730 | * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|` 2731 | * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|` 2732 | */ 2733 | ByteBufferPrototype.prepend = function(source, encoding, offset) { 2734 | if (typeof encoding === 'number' || typeof encoding !== 'string') { 2735 | offset = encoding; 2736 | encoding = undefined; 2737 | } 2738 | var relative = typeof offset === 'undefined'; 2739 | if (relative) offset = this.offset; 2740 | if (!this.noAssert) { 2741 | if (typeof offset !== 'number' || offset % 1 !== 0) 2742 | throw TypeError("Illegal offset: "+offset+" (not an integer)"); 2743 | offset >>>= 0; 2744 | if (offset < 0 || offset + 0 > this.buffer.byteLength) 2745 | throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); 2746 | } 2747 | if (!(source instanceof ByteBuffer)) 2748 | source = ByteBuffer.wrap(source, encoding); 2749 | var len = source.limit - source.offset; 2750 | if (len <= 0) return this; // Nothing to prepend 2751 | var diff = len - offset; 2752 | if (diff > 0) { // Not enough space before offset, so resize + move 2753 | var buffer = new ArrayBuffer(this.buffer.byteLength + diff); 2754 | var view = new Uint8Array(buffer); 2755 | view.set(this.view.subarray(offset, this.buffer.byteLength), len); 2756 | this.buffer = buffer; 2757 | this.view = view; 2758 | this.offset += diff; 2759 | if (this.markedOffset >= 0) this.markedOffset += diff; 2760 | this.limit += diff; 2761 | offset += diff; 2762 | } else { 2763 | var arrayView = new Uint8Array(this.buffer); 2764 | } 2765 | this.view.set(source.view.subarray(source.offset, source.limit), offset - len); 2766 | 2767 | source.offset = source.limit; 2768 | if (relative) 2769 | this.offset -= len; 2770 | return this; 2771 | }; 2772 | 2773 | /** 2774 | * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the 2775 | * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer 2776 | * will be resized and its contents moved accordingly. 2777 | * @param {!ByteBuffer} target Target ByteBuffer 2778 | * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes 2779 | * prepended if omitted. 2780 | * @returns {!ByteBuffer} this 2781 | * @expose 2782 | * @see ByteBuffer#prepend 2783 | */ 2784 | ByteBufferPrototype.prependTo = function(target, offset) { 2785 | target.prepend(this, offset); 2786 | return this; 2787 | }; 2788 | /** 2789 | * Prints debug information about this ByteBuffer's contents. 2790 | * @param {function(string)=} out Output function to call, defaults to console.log 2791 | * @expose 2792 | */ 2793 | ByteBufferPrototype.printDebug = function(out) { 2794 | if (typeof out !== 'function') out = console.log.bind(console); 2795 | out( 2796 | this.toString()+"\n"+ 2797 | "-------------------------------------------------------------------\n"+ 2798 | this.toDebug(/* columns */ true) 2799 | ); 2800 | }; 2801 | 2802 | /** 2803 | * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and 2804 | * {@link ByteBuffer#limit}, so this returns `limit - offset`. 2805 | * @returns {number} Remaining readable bytes. May be negative if `offset > limit`. 2806 | * @expose 2807 | */ 2808 | ByteBufferPrototype.remaining = function() { 2809 | return this.limit - this.offset; 2810 | }; 2811 | /** 2812 | * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark} 2813 | * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been 2814 | * marked, sets `offset = 0`. 2815 | * @returns {!ByteBuffer} this 2816 | * @see ByteBuffer#mark 2817 | * @expose 2818 | */ 2819 | ByteBufferPrototype.reset = function() { 2820 | if (this.markedOffset >= 0) { 2821 | this.offset = this.markedOffset; 2822 | this.markedOffset = -1; 2823 | } else { 2824 | this.offset = 0; 2825 | } 2826 | return this; 2827 | }; 2828 | /** 2829 | * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that 2830 | * large or larger. 2831 | * @param {number} capacity Capacity required 2832 | * @returns {!ByteBuffer} this 2833 | * @throws {TypeError} If `capacity` is not a number 2834 | * @throws {RangeError} If `capacity < 0` 2835 | * @expose 2836 | */ 2837 | ByteBufferPrototype.resize = function(capacity) { 2838 | if (!this.noAssert) { 2839 | if (typeof capacity !== 'number' || capacity % 1 !== 0) 2840 | throw TypeError("Illegal capacity: "+capacity+" (not an integer)"); 2841 | capacity |= 0; 2842 | if (capacity < 0) 2843 | throw RangeError("Illegal capacity: 0 <= "+capacity); 2844 | } 2845 | if (this.buffer.byteLength < capacity) { 2846 | var buffer = new ArrayBuffer(capacity); 2847 | var view = new Uint8Array(buffer); 2848 | view.set(this.view); 2849 | this.buffer = buffer; 2850 | this.view = view; 2851 | } 2852 | return this; 2853 | }; 2854 | /** 2855 | * Reverses this ByteBuffer's contents. 2856 | * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} 2857 | * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} 2858 | * @returns {!ByteBuffer} this 2859 | * @expose 2860 | */ 2861 | ByteBufferPrototype.reverse = function(begin, end) { 2862 | if (typeof begin === 'undefined') begin = this.offset; 2863 | if (typeof end === 'undefined') end = this.limit; 2864 | if (!this.noAssert) { 2865 | if (typeof begin !== 'number' || begin % 1 !== 0) 2866 | throw TypeError("Illegal begin: Not an integer"); 2867 | begin >>>= 0; 2868 | if (typeof end !== 'number' || end % 1 !== 0) 2869 | throw TypeError("Illegal end: Not an integer"); 2870 | end >>>= 0; 2871 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 2872 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 2873 | } 2874 | if (begin === end) 2875 | return this; // Nothing to reverse 2876 | Array.prototype.reverse.call(this.view.subarray(begin, end)); 2877 | return this; 2878 | }; 2879 | /** 2880 | * Skips the next `length` bytes. This will just advance 2881 | * @param {number} length Number of bytes to skip. May also be negative to move the offset back. 2882 | * @returns {!ByteBuffer} this 2883 | * @expose 2884 | */ 2885 | ByteBufferPrototype.skip = function(length) { 2886 | if (!this.noAssert) { 2887 | if (typeof length !== 'number' || length % 1 !== 0) 2888 | throw TypeError("Illegal length: "+length+" (not an integer)"); 2889 | length |= 0; 2890 | } 2891 | var offset = this.offset + length; 2892 | if (!this.noAssert) { 2893 | if (offset < 0 || offset > this.buffer.byteLength) 2894 | throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength); 2895 | } 2896 | this.offset = offset; 2897 | return this; 2898 | }; 2899 | 2900 | /** 2901 | * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`. 2902 | * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. 2903 | * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. 2904 | * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer} 2905 | * @expose 2906 | */ 2907 | ByteBufferPrototype.slice = function(begin, end) { 2908 | if (typeof begin === 'undefined') begin = this.offset; 2909 | if (typeof end === 'undefined') end = this.limit; 2910 | if (!this.noAssert) { 2911 | if (typeof begin !== 'number' || begin % 1 !== 0) 2912 | throw TypeError("Illegal begin: Not an integer"); 2913 | begin >>>= 0; 2914 | if (typeof end !== 'number' || end % 1 !== 0) 2915 | throw TypeError("Illegal end: Not an integer"); 2916 | end >>>= 0; 2917 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 2918 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 2919 | } 2920 | var bb = this.clone(); 2921 | bb.offset = begin; 2922 | bb.limit = end; 2923 | return bb; 2924 | }; 2925 | /** 2926 | * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between 2927 | * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. 2928 | * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if 2929 | * possible. Defaults to `false` 2930 | * @returns {!ArrayBuffer} Contents as an ArrayBuffer 2931 | * @expose 2932 | */ 2933 | ByteBufferPrototype.toBuffer = function(forceCopy) { 2934 | var offset = this.offset, 2935 | limit = this.limit; 2936 | if (!this.noAssert) { 2937 | if (typeof offset !== 'number' || offset % 1 !== 0) 2938 | throw TypeError("Illegal offset: Not an integer"); 2939 | offset >>>= 0; 2940 | if (typeof limit !== 'number' || limit % 1 !== 0) 2941 | throw TypeError("Illegal limit: Not an integer"); 2942 | limit >>>= 0; 2943 | if (offset < 0 || offset > limit || limit > this.buffer.byteLength) 2944 | throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength); 2945 | } 2946 | // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is 2947 | // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So: 2948 | if (!forceCopy && offset === 0 && limit === this.buffer.byteLength) 2949 | return this.buffer; 2950 | if (offset === limit) 2951 | return EMPTY_BUFFER; 2952 | var buffer = new ArrayBuffer(limit - offset); 2953 | new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0); 2954 | return buffer; 2955 | }; 2956 | 2957 | /** 2958 | * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between 2959 | * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}. 2960 | * @function 2961 | * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory. 2962 | * Defaults to `false` 2963 | * @returns {!ArrayBuffer} Contents as an ArrayBuffer 2964 | * @expose 2965 | */ 2966 | ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer; 2967 | 2968 | /** 2969 | * Converts the ByteBuffer's contents to a string. 2970 | * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows 2971 | * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with 2972 | * highlighted offsets. 2973 | * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset} 2974 | * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} 2975 | * @returns {string} String representation 2976 | * @throws {Error} If `encoding` is invalid 2977 | * @expose 2978 | */ 2979 | ByteBufferPrototype.toString = function(encoding, begin, end) { 2980 | if (typeof encoding === 'undefined') 2981 | return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")"; 2982 | if (typeof encoding === 'number') 2983 | encoding = "utf8", 2984 | begin = encoding, 2985 | end = begin; 2986 | switch (encoding) { 2987 | case "utf8": 2988 | return this.toUTF8(begin, end); 2989 | case "base64": 2990 | return this.toBase64(begin, end); 2991 | case "hex": 2992 | return this.toHex(begin, end); 2993 | case "binary": 2994 | return this.toBinary(begin, end); 2995 | case "debug": 2996 | return this.toDebug(); 2997 | case "columns": 2998 | return this.toColumns(); 2999 | default: 3000 | throw Error("Unsupported encoding: "+encoding); 3001 | } 3002 | }; 3003 | 3004 | // lxiv-embeddable 3005 | 3006 | /** 3007 | * lxiv-embeddable (c) 2014 Daniel Wirtz 3008 | * Released under the Apache License, Version 2.0 3009 | * see: https://github.com/dcodeIO/lxiv for details 3010 | */ 3011 | var lxiv = function() { 3012 | "use strict"; 3013 | 3014 | /** 3015 | * lxiv namespace. 3016 | * @type {!Object.} 3017 | * @exports lxiv 3018 | */ 3019 | var lxiv = {}; 3020 | 3021 | /** 3022 | * Character codes for output. 3023 | * @type {!Array.} 3024 | * @inner 3025 | */ 3026 | var aout = [ 3027 | 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 3028 | 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 3029 | 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 3030 | 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 3031 | ]; 3032 | 3033 | /** 3034 | * Character codes for input. 3035 | * @type {!Array.} 3036 | * @inner 3037 | */ 3038 | var ain = []; 3039 | for (var i=0, k=aout.length; i>2)&0x3f]); 3053 | t = (b&0x3)<<4; 3054 | if ((b = src()) !== null) { 3055 | t |= (b>>4)&0xf; 3056 | dst(aout[(t|((b>>4)&0xf))&0x3f]); 3057 | t = (b&0xf)<<2; 3058 | if ((b = src()) !== null) 3059 | dst(aout[(t|((b>>6)&0x3))&0x3f]), 3060 | dst(aout[b&0x3f]); 3061 | else 3062 | dst(aout[t&0x3f]), 3063 | dst(61); 3064 | } else 3065 | dst(aout[t&0x3f]), 3066 | dst(61), 3067 | dst(61); 3068 | } 3069 | }; 3070 | 3071 | /** 3072 | * Decodes base64 char codes to bytes. 3073 | * @param {!function():number|null} src Characters source as a function returning the next char code respectively 3074 | * `null` if there are no more characters left. 3075 | * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. 3076 | * @throws {Error} If a character code is invalid 3077 | */ 3078 | lxiv.decode = function(src, dst) { 3079 | var c, t1, t2; 3080 | function fail(c) { 3081 | throw Error("Illegal character code: "+c); 3082 | } 3083 | while ((c = src()) !== null) { 3084 | t1 = ain[c]; 3085 | if (typeof t1 === 'undefined') fail(c); 3086 | if ((c = src()) !== null) { 3087 | t2 = ain[c]; 3088 | if (typeof t2 === 'undefined') fail(c); 3089 | dst((t1<<2)>>>0|(t2&0x30)>>4); 3090 | if ((c = src()) !== null) { 3091 | t1 = ain[c]; 3092 | if (typeof t1 === 'undefined') 3093 | if (c === 61) break; else fail(c); 3094 | dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2); 3095 | if ((c = src()) !== null) { 3096 | t2 = ain[c]; 3097 | if (typeof t2 === 'undefined') 3098 | if (c === 61) break; else fail(c); 3099 | dst(((t1&0x3)<<6)>>>0|t2); 3100 | } 3101 | } 3102 | } 3103 | } 3104 | }; 3105 | 3106 | /** 3107 | * Tests if a string is valid base64. 3108 | * @param {string} str String to test 3109 | * @returns {boolean} `true` if valid, otherwise `false` 3110 | */ 3111 | lxiv.test = function(str) { 3112 | return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str); 3113 | }; 3114 | 3115 | return lxiv; 3116 | }(); 3117 | 3118 | // encodings/base64 3119 | 3120 | /** 3121 | * Encodes this ByteBuffer's contents to a base64 encoded string. 3122 | * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}. 3123 | * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}. 3124 | * @returns {string} Base64 encoded string 3125 | * @throws {RangeError} If `begin` or `end` is out of bounds 3126 | * @expose 3127 | */ 3128 | ByteBufferPrototype.toBase64 = function(begin, end) { 3129 | if (typeof begin === 'undefined') 3130 | begin = this.offset; 3131 | if (typeof end === 'undefined') 3132 | end = this.limit; 3133 | begin = begin | 0; end = end | 0; 3134 | if (begin < 0 || end > this.capacity || begin > end) 3135 | throw RangeError("begin, end"); 3136 | var sd; lxiv.encode(function() { 3137 | return begin < end ? this.view[begin++] : null; 3138 | }.bind(this), sd = stringDestination()); 3139 | return sd(); 3140 | }; 3141 | 3142 | /** 3143 | * Decodes a base64 encoded string to a ByteBuffer. 3144 | * @param {string} str String to decode 3145 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 3146 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 3147 | * @returns {!ByteBuffer} ByteBuffer 3148 | * @expose 3149 | */ 3150 | ByteBuffer.fromBase64 = function(str, littleEndian) { 3151 | if (typeof str !== 'string') 3152 | throw TypeError("str"); 3153 | var bb = new ByteBuffer(str.length/4*3, littleEndian), 3154 | i = 0; 3155 | lxiv.decode(stringSource(str), function(b) { 3156 | bb.view[i++] = b; 3157 | }); 3158 | bb.limit = i; 3159 | return bb; 3160 | }; 3161 | 3162 | /** 3163 | * Encodes a binary string to base64 like `window.btoa` does. 3164 | * @param {string} str Binary string 3165 | * @returns {string} Base64 encoded string 3166 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa 3167 | * @expose 3168 | */ 3169 | ByteBuffer.btoa = function(str) { 3170 | return ByteBuffer.fromBinary(str).toBase64(); 3171 | }; 3172 | 3173 | /** 3174 | * Decodes a base64 encoded string to binary like `window.atob` does. 3175 | * @param {string} b64 Base64 encoded string 3176 | * @returns {string} Binary string 3177 | * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob 3178 | * @expose 3179 | */ 3180 | ByteBuffer.atob = function(b64) { 3181 | return ByteBuffer.fromBase64(b64).toBinary(); 3182 | }; 3183 | 3184 | // encodings/binary 3185 | 3186 | /** 3187 | * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes. 3188 | * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}. 3189 | * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}. 3190 | * @returns {string} Binary encoded string 3191 | * @throws {RangeError} If `offset > limit` 3192 | * @expose 3193 | */ 3194 | ByteBufferPrototype.toBinary = function(begin, end) { 3195 | if (typeof begin === 'undefined') 3196 | begin = this.offset; 3197 | if (typeof end === 'undefined') 3198 | end = this.limit; 3199 | begin |= 0; end |= 0; 3200 | if (begin < 0 || end > this.capacity() || begin > end) 3201 | throw RangeError("begin, end"); 3202 | if (begin === end) 3203 | return ""; 3204 | var chars = [], 3205 | parts = []; 3206 | while (begin < end) { 3207 | chars.push(this.view[begin++]); 3208 | if (chars.length >= 1024) 3209 | parts.push(String.fromCharCode.apply(String, chars)), 3210 | chars = []; 3211 | } 3212 | return parts.join('') + String.fromCharCode.apply(String, chars); 3213 | }; 3214 | 3215 | /** 3216 | * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer. 3217 | * @param {string} str String to decode 3218 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 3219 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 3220 | * @returns {!ByteBuffer} ByteBuffer 3221 | * @expose 3222 | */ 3223 | ByteBuffer.fromBinary = function(str, littleEndian) { 3224 | if (typeof str !== 'string') 3225 | throw TypeError("str"); 3226 | var i = 0, 3227 | k = str.length, 3228 | charCode, 3229 | bb = new ByteBuffer(k, littleEndian); 3230 | while (i 0xff) 3233 | throw RangeError("illegal char code: "+charCode); 3234 | bb.view[i++] = charCode; 3235 | } 3236 | bb.limit = k; 3237 | return bb; 3238 | }; 3239 | 3240 | // encodings/debug 3241 | 3242 | /** 3243 | * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are: 3244 | * * `<` : offset, 3245 | * * `'` : markedOffset, 3246 | * * `>` : limit, 3247 | * * `|` : offset and limit, 3248 | * * `[` : offset and markedOffset, 3249 | * * `]` : markedOffset and limit, 3250 | * * `!` : offset, markedOffset and limit 3251 | * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false` 3252 | * @returns {string|!Array.} Debug string or array of lines if `asArray = true` 3253 | * @expose 3254 | * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3` 3255 | * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4` 3256 | * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1` 3257 | * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1` 3258 | */ 3259 | ByteBufferPrototype.toDebug = function(columns) { 3260 | var i = -1, 3261 | k = this.buffer.byteLength, 3262 | b, 3263 | hex = "", 3264 | asc = "", 3265 | out = ""; 3266 | while (i 32 && b < 127 ? String.fromCharCode(b) : '.'; 3273 | } 3274 | ++i; 3275 | if (columns) { 3276 | if (i > 0 && i % 16 === 0 && i !== k) { 3277 | while (hex.length < 3*16+3) hex += " "; 3278 | out += hex+asc+"\n"; 3279 | hex = asc = ""; 3280 | } 3281 | } 3282 | if (i === this.offset && i === this.limit) 3283 | hex += i === this.markedOffset ? "!" : "|"; 3284 | else if (i === this.offset) 3285 | hex += i === this.markedOffset ? "[" : "<"; 3286 | else if (i === this.limit) 3287 | hex += i === this.markedOffset ? "]" : ">"; 3288 | else 3289 | hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : ""); 3290 | } 3291 | if (columns && hex !== " ") { 3292 | while (hex.length < 3*16+3) 3293 | hex += " "; 3294 | out += hex + asc + "\n"; 3295 | } 3296 | return columns ? out : hex; 3297 | }; 3298 | 3299 | /** 3300 | * Decodes a hex encoded string with marked offsets to a ByteBuffer. 3301 | * @param {string} str Debug string to decode (not be generated with `columns = true`) 3302 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 3303 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 3304 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to 3305 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 3306 | * @returns {!ByteBuffer} ByteBuffer 3307 | * @expose 3308 | * @see ByteBuffer#toDebug 3309 | */ 3310 | ByteBuffer.fromDebug = function(str, littleEndian, noAssert) { 3311 | var k = str.length, 3312 | bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert); 3313 | var i = 0, j = 0, ch, b, 3314 | rs = false, // Require symbol next 3315 | ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)? 3316 | fail = false; 3317 | while (i': 3375 | if (!noAssert) { 3376 | if (hl) { 3377 | fail = true; 3378 | break; 3379 | } 3380 | hl = true; 3381 | } 3382 | bb.limit = j; 3383 | rs = false; 3384 | break; 3385 | case "'": 3386 | if (!noAssert) { 3387 | if (hm) { 3388 | fail = true; 3389 | break; 3390 | } 3391 | hm = true; 3392 | } 3393 | bb.markedOffset = j; 3394 | rs = false; 3395 | break; 3396 | case ' ': 3397 | rs = false; 3398 | break; 3399 | default: 3400 | if (!noAssert) { 3401 | if (rs) { 3402 | fail = true; 3403 | break; 3404 | } 3405 | } 3406 | b = parseInt(ch+str.charAt(i++), 16); 3407 | if (!noAssert) { 3408 | if (isNaN(b) || b < 0 || b > 255) 3409 | throw TypeError("Illegal str: Not a debug encoded string"); 3410 | } 3411 | bb.view[j++] = b; 3412 | rs = true; 3413 | } 3414 | if (fail) 3415 | throw TypeError("Illegal str: Invalid symbol at "+i); 3416 | } 3417 | if (!noAssert) { 3418 | if (!ho || !hl) 3419 | throw TypeError("Illegal str: Missing offset or limit"); 3420 | if (j>>= 0; 3442 | if (typeof end !== 'number' || end % 1 !== 0) 3443 | throw TypeError("Illegal end: Not an integer"); 3444 | end >>>= 0; 3445 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 3446 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 3447 | } 3448 | var out = new Array(end - begin), 3449 | b; 3450 | while (begin < end) { 3451 | b = this.view[begin++]; 3452 | if (b < 0x10) 3453 | out.push("0", b.toString(16)); 3454 | else out.push(b.toString(16)); 3455 | } 3456 | return out.join(''); 3457 | }; 3458 | 3459 | /** 3460 | * Decodes a hex encoded string to a ByteBuffer. 3461 | * @param {string} str String to decode 3462 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 3463 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 3464 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to 3465 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 3466 | * @returns {!ByteBuffer} ByteBuffer 3467 | * @expose 3468 | */ 3469 | ByteBuffer.fromHex = function(str, littleEndian, noAssert) { 3470 | if (!noAssert) { 3471 | if (typeof str !== 'string') 3472 | throw TypeError("Illegal str: Not a string"); 3473 | if (str.length % 2 !== 0) 3474 | throw TypeError("Illegal str: Length not a multiple of 2"); 3475 | } 3476 | var k = str.length, 3477 | bb = new ByteBuffer((k / 2) | 0, littleEndian), 3478 | b; 3479 | for (var i=0, j=0; i 255) 3483 | throw TypeError("Illegal str: Contains non-hex characters"); 3484 | bb.view[j++] = b; 3485 | } 3486 | bb.limit = j; 3487 | return bb; 3488 | }; 3489 | 3490 | // utfx-embeddable 3491 | 3492 | /** 3493 | * utfx-embeddable (c) 2014 Daniel Wirtz 3494 | * Released under the Apache License, Version 2.0 3495 | * see: https://github.com/dcodeIO/utfx for details 3496 | */ 3497 | var utfx = function() { 3498 | "use strict"; 3499 | 3500 | /** 3501 | * utfx namespace. 3502 | * @inner 3503 | * @type {!Object.} 3504 | */ 3505 | var utfx = {}; 3506 | 3507 | /** 3508 | * Maximum valid code point. 3509 | * @type {number} 3510 | * @const 3511 | */ 3512 | utfx.MAX_CODEPOINT = 0x10FFFF; 3513 | 3514 | /** 3515 | * Encodes UTF8 code points to UTF8 bytes. 3516 | * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point 3517 | * respectively `null` if there are no more code points left or a single numeric code point. 3518 | * @param {!function(number)} dst Bytes destination as a function successively called with the next byte 3519 | */ 3520 | utfx.encodeUTF8 = function(src, dst) { 3521 | var cp = null; 3522 | if (typeof src === 'number') 3523 | cp = src, 3524 | src = function() { return null; }; 3525 | while (cp !== null || (cp = src()) !== null) { 3526 | if (cp < 0x80) 3527 | dst(cp&0x7F); 3528 | else if (cp < 0x800) 3529 | dst(((cp>>6)&0x1F)|0xC0), 3530 | dst((cp&0x3F)|0x80); 3531 | else if (cp < 0x10000) 3532 | dst(((cp>>12)&0x0F)|0xE0), 3533 | dst(((cp>>6)&0x3F)|0x80), 3534 | dst((cp&0x3F)|0x80); 3535 | else 3536 | dst(((cp>>18)&0x07)|0xF0), 3537 | dst(((cp>>12)&0x3F)|0x80), 3538 | dst(((cp>>6)&0x3F)|0x80), 3539 | dst((cp&0x3F)|0x80); 3540 | cp = null; 3541 | } 3542 | }; 3543 | 3544 | /** 3545 | * Decodes UTF8 bytes to UTF8 code points. 3546 | * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there 3547 | * are no more bytes left. 3548 | * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. 3549 | * @throws {RangeError} If a starting byte is invalid in UTF8 3550 | * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the 3551 | * remaining bytes. 3552 | */ 3553 | utfx.decodeUTF8 = function(src, dst) { 3554 | var a, b, c, d, fail = function(b) { 3555 | b = b.slice(0, b.indexOf(null)); 3556 | var err = Error(b.toString()); 3557 | err.name = "TruncatedError"; 3558 | err['bytes'] = b; 3559 | throw err; 3560 | }; 3561 | while ((a = src()) !== null) { 3562 | if ((a&0x80) === 0) 3563 | dst(a); 3564 | else if ((a&0xE0) === 0xC0) 3565 | ((b = src()) === null) && fail([a, b]), 3566 | dst(((a&0x1F)<<6) | (b&0x3F)); 3567 | else if ((a&0xF0) === 0xE0) 3568 | ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), 3569 | dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); 3570 | else if ((a&0xF8) === 0xF0) 3571 | ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), 3572 | dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); 3573 | else throw RangeError("Illegal starting byte: "+a); 3574 | } 3575 | }; 3576 | 3577 | /** 3578 | * Converts UTF16 characters to UTF8 code points. 3579 | * @param {!function():number|null} src Characters source as a function returning the next char code respectively 3580 | * `null` if there are no more characters left. 3581 | * @param {!function(number)} dst Code points destination as a function successively called with each converted code 3582 | * point. 3583 | */ 3584 | utfx.UTF16toUTF8 = function(src, dst) { 3585 | var c1, c2 = null; 3586 | while (true) { 3587 | if ((c1 = c2 !== null ? c2 : src()) === null) 3588 | break; 3589 | if (c1 >= 0xD800 && c1 <= 0xDFFF) { 3590 | if ((c2 = src()) !== null) { 3591 | if (c2 >= 0xDC00 && c2 <= 0xDFFF) { 3592 | dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); 3593 | c2 = null; continue; 3594 | } 3595 | } 3596 | } 3597 | dst(c1); 3598 | } 3599 | if (c2 !== null) dst(c2); 3600 | }; 3601 | 3602 | /** 3603 | * Converts UTF8 code points to UTF16 characters. 3604 | * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point 3605 | * respectively `null` if there are no more code points left or a single numeric code point. 3606 | * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. 3607 | * @throws {RangeError} If a code point is out of range 3608 | */ 3609 | utfx.UTF8toUTF16 = function(src, dst) { 3610 | var cp = null; 3611 | if (typeof src === 'number') 3612 | cp = src, src = function() { return null; }; 3613 | while (cp !== null || (cp = src()) !== null) { 3614 | if (cp <= 0xFFFF) 3615 | dst(cp); 3616 | else 3617 | cp -= 0x10000, 3618 | dst((cp>>10)+0xD800), 3619 | dst((cp%0x400)+0xDC00); 3620 | cp = null; 3621 | } 3622 | }; 3623 | 3624 | /** 3625 | * Converts and encodes UTF16 characters to UTF8 bytes. 3626 | * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` 3627 | * if there are no more characters left. 3628 | * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. 3629 | */ 3630 | utfx.encodeUTF16toUTF8 = function(src, dst) { 3631 | utfx.UTF16toUTF8(src, function(cp) { 3632 | utfx.encodeUTF8(cp, dst); 3633 | }); 3634 | }; 3635 | 3636 | /** 3637 | * Decodes and converts UTF8 bytes to UTF16 characters. 3638 | * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there 3639 | * are no more bytes left. 3640 | * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. 3641 | * @throws {RangeError} If a starting byte is invalid in UTF8 3642 | * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. 3643 | */ 3644 | utfx.decodeUTF8toUTF16 = function(src, dst) { 3645 | utfx.decodeUTF8(src, function(cp) { 3646 | utfx.UTF8toUTF16(cp, dst); 3647 | }); 3648 | }; 3649 | 3650 | /** 3651 | * Calculates the byte length of an UTF8 code point. 3652 | * @param {number} cp UTF8 code point 3653 | * @returns {number} Byte length 3654 | */ 3655 | utfx.calculateCodePoint = function(cp) { 3656 | return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; 3657 | }; 3658 | 3659 | /** 3660 | * Calculates the number of UTF8 bytes required to store UTF8 code points. 3661 | * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively 3662 | * `null` if there are no more code points left. 3663 | * @returns {number} The number of UTF8 bytes required 3664 | */ 3665 | utfx.calculateUTF8 = function(src) { 3666 | var cp, l=0; 3667 | while ((cp = src()) !== null) 3668 | l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; 3669 | return l; 3670 | }; 3671 | 3672 | /** 3673 | * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. 3674 | * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively 3675 | * `null` if there are no more characters left. 3676 | * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. 3677 | */ 3678 | utfx.calculateUTF16asUTF8 = function(src) { 3679 | var n=0, l=0; 3680 | utfx.UTF16toUTF8(src, function(cp) { 3681 | ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; 3682 | }); 3683 | return [n,l]; 3684 | }; 3685 | 3686 | return utfx; 3687 | }(); 3688 | 3689 | // encodings/utf8 3690 | 3691 | /** 3692 | * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded 3693 | * string. 3694 | * @returns {string} Hex encoded string 3695 | * @throws {RangeError} If `offset > limit` 3696 | * @expose 3697 | */ 3698 | ByteBufferPrototype.toUTF8 = function(begin, end) { 3699 | if (typeof begin === 'undefined') begin = this.offset; 3700 | if (typeof end === 'undefined') end = this.limit; 3701 | if (!this.noAssert) { 3702 | if (typeof begin !== 'number' || begin % 1 !== 0) 3703 | throw TypeError("Illegal begin: Not an integer"); 3704 | begin >>>= 0; 3705 | if (typeof end !== 'number' || end % 1 !== 0) 3706 | throw TypeError("Illegal end: Not an integer"); 3707 | end >>>= 0; 3708 | if (begin < 0 || begin > end || end > this.buffer.byteLength) 3709 | throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); 3710 | } 3711 | var sd; try { 3712 | utfx.decodeUTF8toUTF16(function() { 3713 | return begin < end ? this.view[begin++] : null; 3714 | }.bind(this), sd = stringDestination()); 3715 | } catch (e) { 3716 | if (begin !== end) 3717 | throw RangeError("Illegal range: Truncated data, "+begin+" != "+end); 3718 | } 3719 | return sd(); 3720 | }; 3721 | 3722 | /** 3723 | * Decodes an UTF8 encoded string to a ByteBuffer. 3724 | * @param {string} str String to decode 3725 | * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to 3726 | * {@link ByteBuffer.DEFAULT_ENDIAN}. 3727 | * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to 3728 | * {@link ByteBuffer.DEFAULT_NOASSERT}. 3729 | * @returns {!ByteBuffer} ByteBuffer 3730 | * @expose 3731 | */ 3732 | ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) { 3733 | if (!noAssert) 3734 | if (typeof str !== 'string') 3735 | throw TypeError("Illegal str: Not a string"); 3736 | var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert), 3737 | i = 0; 3738 | utfx.encodeUTF16toUTF8(stringSource(str), function(b) { 3739 | bb.view[i++] = b; 3740 | }); 3741 | bb.limit = i; 3742 | return bb; 3743 | }; 3744 | 3745 | return ByteBuffer; 3746 | }); 3747 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

10 |     
11 |     
45 |   
46 | 


--------------------------------------------------------------------------------
/public/long.js:
--------------------------------------------------------------------------------
   1 | /*
   2 |  Copyright 2013 Daniel Wirtz 
   3 |  Copyright 2009 The Closure Library Authors. All Rights Reserved.
   4 | 
   5 |  Licensed under the Apache License, Version 2.0 (the "License");
   6 |  you may not use this file except in compliance with the License.
   7 |  You may obtain a copy of the License at
   8 | 
   9 |  http://www.apache.org/licenses/LICENSE-2.0
  10 | 
  11 |  Unless required by applicable law or agreed to in writing, software
  12 |  distributed under the License is distributed on an "AS-IS" BASIS,
  13 |  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 |  See the License for the specific language governing permissions and
  15 |  limitations under the License.
  16 |  */
  17 | 
  18 | /**
  19 |  * @license long.js (c) 2013 Daniel Wirtz 
  20 |  * Released under the Apache License, Version 2.0
  21 |  * see: https://github.com/dcodeIO/long.js for details
  22 |  */
  23 | (function(global, factory) {
  24 | 
  25 |     /* AMD */ if (typeof define === 'function' && define["amd"])
  26 |         define([], factory);
  27 |     /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
  28 |         module["exports"] = factory();
  29 |     /* Global */ else
  30 |         (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
  31 | 
  32 | })(this, function() {
  33 |     "use strict";
  34 | 
  35 |     /**
  36 |      * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
  37 |      *  See the from* functions below for more convenient ways of constructing Longs.
  38 |      * @exports Long
  39 |      * @class A Long class for representing a 64 bit two's-complement integer value.
  40 |      * @param {number} low The low (signed) 32 bits of the long
  41 |      * @param {number} high The high (signed) 32 bits of the long
  42 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  43 |      * @constructor
  44 |      */
  45 |     function Long(low, high, unsigned) {
  46 | 
  47 |         /**
  48 |          * The low 32 bits as a signed value.
  49 |          * @type {number}
  50 |          * @expose
  51 |          */
  52 |         this.low = low | 0;
  53 | 
  54 |         /**
  55 |          * The high 32 bits as a signed value.
  56 |          * @type {number}
  57 |          * @expose
  58 |          */
  59 |         this.high = high | 0;
  60 | 
  61 |         /**
  62 |          * Whether unsigned or not.
  63 |          * @type {boolean}
  64 |          * @expose
  65 |          */
  66 |         this.unsigned = !!unsigned;
  67 |     }
  68 | 
  69 |     // The internal representation of a long is the two given signed, 32-bit values.
  70 |     // We use 32-bit pieces because these are the size of integers on which
  71 |     // Javascript performs bit-operations.  For operations like addition and
  72 |     // multiplication, we split each number into 16 bit pieces, which can easily be
  73 |     // multiplied within Javascript's floating-point representation without overflow
  74 |     // or change in sign.
  75 |     //
  76 |     // In the algorithms below, we frequently reduce the negative case to the
  77 |     // positive case by negating the input(s) and then post-processing the result.
  78 |     // Note that we must ALWAYS check specially whether those values are MIN_VALUE
  79 |     // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
  80 |     // a positive number, it overflows back into a negative).  Not handling this
  81 |     // case would often result in infinite recursion.
  82 |     //
  83 |     // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
  84 |     // methods on which they depend.
  85 | 
  86 |     /**
  87 |      * An indicator used to reliably determine if an object is a Long or not.
  88 |      * @type {boolean}
  89 |      * @const
  90 |      * @expose
  91 |      * @private
  92 |      */
  93 |     Long.prototype.__isLong__;
  94 | 
  95 |     Object.defineProperty(Long.prototype, "__isLong__", {
  96 |         value: true,
  97 |         enumerable: false,
  98 |         configurable: false
  99 |     });
 100 | 
 101 |     /**
 102 |      * @function
 103 |      * @param {*} obj Object
 104 |      * @returns {boolean}
 105 |      * @inner
 106 |      */
 107 |     function isLong(obj) {
 108 |         return (obj && obj["__isLong__"]) === true;
 109 |     }
 110 | 
 111 |     /**
 112 |      * Tests if the specified object is a Long.
 113 |      * @function
 114 |      * @param {*} obj Object
 115 |      * @returns {boolean}
 116 |      * @expose
 117 |      */
 118 |     Long.isLong = isLong;
 119 | 
 120 |     /**
 121 |      * A cache of the Long representations of small integer values.
 122 |      * @type {!Object}
 123 |      * @inner
 124 |      */
 125 |     var INT_CACHE = {};
 126 | 
 127 |     /**
 128 |      * A cache of the Long representations of small unsigned integer values.
 129 |      * @type {!Object}
 130 |      * @inner
 131 |      */
 132 |     var UINT_CACHE = {};
 133 | 
 134 |     /**
 135 |      * @param {number} value
 136 |      * @param {boolean=} unsigned
 137 |      * @returns {!Long}
 138 |      * @inner
 139 |      */
 140 |     function fromInt(value, unsigned) {
 141 |         var obj, cachedObj, cache;
 142 |         if (unsigned) {
 143 |             value >>>= 0;
 144 |             if (cache = (0 <= value && value < 256)) {
 145 |                 cachedObj = UINT_CACHE[value];
 146 |                 if (cachedObj)
 147 |                     return cachedObj;
 148 |             }
 149 |             obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
 150 |             if (cache)
 151 |                 UINT_CACHE[value] = obj;
 152 |             return obj;
 153 |         } else {
 154 |             value |= 0;
 155 |             if (cache = (-128 <= value && value < 128)) {
 156 |                 cachedObj = INT_CACHE[value];
 157 |                 if (cachedObj)
 158 |                     return cachedObj;
 159 |             }
 160 |             obj = fromBits(value, value < 0 ? -1 : 0, false);
 161 |             if (cache)
 162 |                 INT_CACHE[value] = obj;
 163 |             return obj;
 164 |         }
 165 |     }
 166 | 
 167 |     /**
 168 |      * Returns a Long representing the given 32 bit integer value.
 169 |      * @function
 170 |      * @param {number} value The 32 bit integer in question
 171 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
 172 |      * @returns {!Long} The corresponding Long value
 173 |      * @expose
 174 |      */
 175 |     Long.fromInt = fromInt;
 176 | 
 177 |     /**
 178 |      * @param {number} value
 179 |      * @param {boolean=} unsigned
 180 |      * @returns {!Long}
 181 |      * @inner
 182 |      */
 183 |     function fromNumber(value, unsigned) {
 184 |         if (isNaN(value) || !isFinite(value))
 185 |             return unsigned ? UZERO : ZERO;
 186 |         if (unsigned) {
 187 |             if (value < 0)
 188 |                 return UZERO;
 189 |             if (value >= TWO_PWR_64_DBL)
 190 |                 return MAX_UNSIGNED_VALUE;
 191 |         } else {
 192 |             if (value <= -TWO_PWR_63_DBL)
 193 |                 return MIN_VALUE;
 194 |             if (value + 1 >= TWO_PWR_63_DBL)
 195 |                 return MAX_VALUE;
 196 |         }
 197 |         if (value < 0)
 198 |             return fromNumber(-value, unsigned).neg();
 199 |         return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
 200 |     }
 201 | 
 202 |     /**
 203 |      * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
 204 |      * @function
 205 |      * @param {number} value The number in question
 206 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
 207 |      * @returns {!Long} The corresponding Long value
 208 |      * @expose
 209 |      */
 210 |     Long.fromNumber = fromNumber;
 211 | 
 212 |     /**
 213 |      * @param {number} lowBits
 214 |      * @param {number} highBits
 215 |      * @param {boolean=} unsigned
 216 |      * @returns {!Long}
 217 |      * @inner
 218 |      */
 219 |     function fromBits(lowBits, highBits, unsigned) {
 220 |         return new Long(lowBits, highBits, unsigned);
 221 |     }
 222 | 
 223 |     /**
 224 |      * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
 225 |      *  assumed to use 32 bits.
 226 |      * @function
 227 |      * @param {number} lowBits The low 32 bits
 228 |      * @param {number} highBits The high 32 bits
 229 |      * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
 230 |      * @returns {!Long} The corresponding Long value
 231 |      * @expose
 232 |      */
 233 |     Long.fromBits = fromBits;
 234 | 
 235 |     /**
 236 |      * @function
 237 |      * @param {number} base
 238 |      * @param {number} exponent
 239 |      * @returns {number}
 240 |      * @inner
 241 |      */
 242 |     var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
 243 | 
 244 |     /**
 245 |      * @param {string} str
 246 |      * @param {(boolean|number)=} unsigned
 247 |      * @param {number=} radix
 248 |      * @returns {!Long}
 249 |      * @inner
 250 |      */
 251 |     function fromString(str, unsigned, radix) {
 252 |         if (str.length === 0)
 253 |             throw Error('empty string');
 254 |         if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
 255 |             return ZERO;
 256 |         if (typeof unsigned === 'number') {
 257 |             // For goog.math.long compatibility
 258 |             radix = unsigned,
 259 |             unsigned = false;
 260 |         } else {
 261 |             unsigned = !! unsigned;
 262 |         }
 263 |         radix = radix || 10;
 264 |         if (radix < 2 || 36 < radix)
 265 |             throw RangeError('radix');
 266 | 
 267 |         var p;
 268 |         if ((p = str.indexOf('-')) > 0)
 269 |             throw Error('interior hyphen');
 270 |         else if (p === 0) {
 271 |             return fromString(str.substring(1), unsigned, radix).neg();
 272 |         }
 273 | 
 274 |         // Do several (8) digits each time through the loop, so as to
 275 |         // minimize the calls to the very expensive emulated div.
 276 |         var radixToPower = fromNumber(pow_dbl(radix, 8));
 277 | 
 278 |         var result = ZERO;
 279 |         for (var i = 0; i < str.length; i += 8) {
 280 |             var size = Math.min(8, str.length - i),
 281 |                 value = parseInt(str.substring(i, i + size), radix);
 282 |             if (size < 8) {
 283 |                 var power = fromNumber(pow_dbl(radix, size));
 284 |                 result = result.mul(power).add(fromNumber(value));
 285 |             } else {
 286 |                 result = result.mul(radixToPower);
 287 |                 result = result.add(fromNumber(value));
 288 |             }
 289 |         }
 290 |         result.unsigned = unsigned;
 291 |         return result;
 292 |     }
 293 | 
 294 |     /**
 295 |      * Returns a Long representation of the given string, written using the specified radix.
 296 |      * @function
 297 |      * @param {string} str The textual representation of the Long
 298 |      * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
 299 |      * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
 300 |      * @returns {!Long} The corresponding Long value
 301 |      * @expose
 302 |      */
 303 |     Long.fromString = fromString;
 304 | 
 305 |     /**
 306 |      * @function
 307 |      * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
 308 |      * @returns {!Long}
 309 |      * @inner
 310 |      */
 311 |     function fromValue(val) {
 312 |         if (val /* is compatible */ instanceof Long)
 313 |             return val;
 314 |         if (typeof val === 'number')
 315 |             return fromNumber(val);
 316 |         if (typeof val === 'string')
 317 |             return fromString(val);
 318 |         // Throws for non-objects, converts non-instanceof Long:
 319 |         return fromBits(val.low, val.high, val.unsigned);
 320 |     }
 321 | 
 322 |     /**
 323 |      * Converts the specified value to a Long.
 324 |      * @function
 325 |      * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
 326 |      * @returns {!Long}
 327 |      * @expose
 328 |      */
 329 |     Long.fromValue = fromValue;
 330 | 
 331 |     // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
 332 |     // no runtime penalty for these.
 333 | 
 334 |     /**
 335 |      * @type {number}
 336 |      * @const
 337 |      * @inner
 338 |      */
 339 |     var TWO_PWR_16_DBL = 1 << 16;
 340 | 
 341 |     /**
 342 |      * @type {number}
 343 |      * @const
 344 |      * @inner
 345 |      */
 346 |     var TWO_PWR_24_DBL = 1 << 24;
 347 | 
 348 |     /**
 349 |      * @type {number}
 350 |      * @const
 351 |      * @inner
 352 |      */
 353 |     var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
 354 | 
 355 |     /**
 356 |      * @type {number}
 357 |      * @const
 358 |      * @inner
 359 |      */
 360 |     var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
 361 | 
 362 |     /**
 363 |      * @type {number}
 364 |      * @const
 365 |      * @inner
 366 |      */
 367 |     var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
 368 | 
 369 |     /**
 370 |      * @type {!Long}
 371 |      * @const
 372 |      * @inner
 373 |      */
 374 |     var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
 375 | 
 376 |     /**
 377 |      * @type {!Long}
 378 |      * @inner
 379 |      */
 380 |     var ZERO = fromInt(0);
 381 | 
 382 |     /**
 383 |      * Signed zero.
 384 |      * @type {!Long}
 385 |      * @expose
 386 |      */
 387 |     Long.ZERO = ZERO;
 388 | 
 389 |     /**
 390 |      * @type {!Long}
 391 |      * @inner
 392 |      */
 393 |     var UZERO = fromInt(0, true);
 394 | 
 395 |     /**
 396 |      * Unsigned zero.
 397 |      * @type {!Long}
 398 |      * @expose
 399 |      */
 400 |     Long.UZERO = UZERO;
 401 | 
 402 |     /**
 403 |      * @type {!Long}
 404 |      * @inner
 405 |      */
 406 |     var ONE = fromInt(1);
 407 | 
 408 |     /**
 409 |      * Signed one.
 410 |      * @type {!Long}
 411 |      * @expose
 412 |      */
 413 |     Long.ONE = ONE;
 414 | 
 415 |     /**
 416 |      * @type {!Long}
 417 |      * @inner
 418 |      */
 419 |     var UONE = fromInt(1, true);
 420 | 
 421 |     /**
 422 |      * Unsigned one.
 423 |      * @type {!Long}
 424 |      * @expose
 425 |      */
 426 |     Long.UONE = UONE;
 427 | 
 428 |     /**
 429 |      * @type {!Long}
 430 |      * @inner
 431 |      */
 432 |     var NEG_ONE = fromInt(-1);
 433 | 
 434 |     /**
 435 |      * Signed negative one.
 436 |      * @type {!Long}
 437 |      * @expose
 438 |      */
 439 |     Long.NEG_ONE = NEG_ONE;
 440 | 
 441 |     /**
 442 |      * @type {!Long}
 443 |      * @inner
 444 |      */
 445 |     var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
 446 | 
 447 |     /**
 448 |      * Maximum signed value.
 449 |      * @type {!Long}
 450 |      * @expose
 451 |      */
 452 |     Long.MAX_VALUE = MAX_VALUE;
 453 | 
 454 |     /**
 455 |      * @type {!Long}
 456 |      * @inner
 457 |      */
 458 |     var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
 459 | 
 460 |     /**
 461 |      * Maximum unsigned value.
 462 |      * @type {!Long}
 463 |      * @expose
 464 |      */
 465 |     Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
 466 | 
 467 |     /**
 468 |      * @type {!Long}
 469 |      * @inner
 470 |      */
 471 |     var MIN_VALUE = fromBits(0, 0x80000000|0, false);
 472 | 
 473 |     /**
 474 |      * Minimum signed value.
 475 |      * @type {!Long}
 476 |      * @expose
 477 |      */
 478 |     Long.MIN_VALUE = MIN_VALUE;
 479 | 
 480 |     /**
 481 |      * @alias Long.prototype
 482 |      * @inner
 483 |      */
 484 |     var LongPrototype = Long.prototype;
 485 | 
 486 |     /**
 487 |      * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
 488 |      * @returns {number}
 489 |      * @expose
 490 |      */
 491 |     LongPrototype.toInt = function toInt() {
 492 |         return this.unsigned ? this.low >>> 0 : this.low;
 493 |     };
 494 | 
 495 |     /**
 496 |      * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
 497 |      * @returns {number}
 498 |      * @expose
 499 |      */
 500 |     LongPrototype.toNumber = function toNumber() {
 501 |         if (this.unsigned)
 502 |             return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
 503 |         return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
 504 |     };
 505 | 
 506 |     /**
 507 |      * Converts the Long to a string written in the specified radix.
 508 |      * @param {number=} radix Radix (2-36), defaults to 10
 509 |      * @returns {string}
 510 |      * @override
 511 |      * @throws {RangeError} If `radix` is out of range
 512 |      * @expose
 513 |      */
 514 |     LongPrototype.toString = function toString(radix) {
 515 |         radix = radix || 10;
 516 |         if (radix < 2 || 36 < radix)
 517 |             throw RangeError('radix');
 518 |         if (this.isZero())
 519 |             return '0';
 520 |         if (this.isNegative()) { // Unsigned Longs are never negative
 521 |             if (this.eq(MIN_VALUE)) {
 522 |                 // We need to change the Long value before it can be negated, so we remove
 523 |                 // the bottom-most digit in this base and then recurse to do the rest.
 524 |                 var radixLong = fromNumber(radix),
 525 |                     div = this.div(radixLong),
 526 |                     rem1 = div.mul(radixLong).sub(this);
 527 |                 return div.toString(radix) + rem1.toInt().toString(radix);
 528 |             } else
 529 |                 return '-' + this.neg().toString(radix);
 530 |         }
 531 | 
 532 |         // Do several (6) digits each time through the loop, so as to
 533 |         // minimize the calls to the very expensive emulated div.
 534 |         var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
 535 |             rem = this;
 536 |         var result = '';
 537 |         while (true) {
 538 |             var remDiv = rem.div(radixToPower),
 539 |                 intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
 540 |                 digits = intval.toString(radix);
 541 |             rem = remDiv;
 542 |             if (rem.isZero())
 543 |                 return digits + result;
 544 |             else {
 545 |                 while (digits.length < 6)
 546 |                     digits = '0' + digits;
 547 |                 result = '' + digits + result;
 548 |             }
 549 |         }
 550 |     };
 551 | 
 552 |     /**
 553 |      * Gets the high 32 bits as a signed integer.
 554 |      * @returns {number} Signed high bits
 555 |      * @expose
 556 |      */
 557 |     LongPrototype.getHighBits = function getHighBits() {
 558 |         return this.high;
 559 |     };
 560 | 
 561 |     /**
 562 |      * Gets the high 32 bits as an unsigned integer.
 563 |      * @returns {number} Unsigned high bits
 564 |      * @expose
 565 |      */
 566 |     LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
 567 |         return this.high >>> 0;
 568 |     };
 569 | 
 570 |     /**
 571 |      * Gets the low 32 bits as a signed integer.
 572 |      * @returns {number} Signed low bits
 573 |      * @expose
 574 |      */
 575 |     LongPrototype.getLowBits = function getLowBits() {
 576 |         return this.low;
 577 |     };
 578 | 
 579 |     /**
 580 |      * Gets the low 32 bits as an unsigned integer.
 581 |      * @returns {number} Unsigned low bits
 582 |      * @expose
 583 |      */
 584 |     LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
 585 |         return this.low >>> 0;
 586 |     };
 587 | 
 588 |     /**
 589 |      * Gets the number of bits needed to represent the absolute value of this Long.
 590 |      * @returns {number}
 591 |      * @expose
 592 |      */
 593 |     LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
 594 |         if (this.isNegative()) // Unsigned Longs are never negative
 595 |             return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
 596 |         var val = this.high != 0 ? this.high : this.low;
 597 |         for (var bit = 31; bit > 0; bit--)
 598 |             if ((val & (1 << bit)) != 0)
 599 |                 break;
 600 |         return this.high != 0 ? bit + 33 : bit + 1;
 601 |     };
 602 | 
 603 |     /**
 604 |      * Tests if this Long's value equals zero.
 605 |      * @returns {boolean}
 606 |      * @expose
 607 |      */
 608 |     LongPrototype.isZero = function isZero() {
 609 |         return this.high === 0 && this.low === 0;
 610 |     };
 611 | 
 612 |     /**
 613 |      * Tests if this Long's value is negative.
 614 |      * @returns {boolean}
 615 |      * @expose
 616 |      */
 617 |     LongPrototype.isNegative = function isNegative() {
 618 |         return !this.unsigned && this.high < 0;
 619 |     };
 620 | 
 621 |     /**
 622 |      * Tests if this Long's value is positive.
 623 |      * @returns {boolean}
 624 |      * @expose
 625 |      */
 626 |     LongPrototype.isPositive = function isPositive() {
 627 |         return this.unsigned || this.high >= 0;
 628 |     };
 629 | 
 630 |     /**
 631 |      * Tests if this Long's value is odd.
 632 |      * @returns {boolean}
 633 |      * @expose
 634 |      */
 635 |     LongPrototype.isOdd = function isOdd() {
 636 |         return (this.low & 1) === 1;
 637 |     };
 638 | 
 639 |     /**
 640 |      * Tests if this Long's value is even.
 641 |      * @returns {boolean}
 642 |      * @expose
 643 |      */
 644 |     LongPrototype.isEven = function isEven() {
 645 |         return (this.low & 1) === 0;
 646 |     };
 647 | 
 648 |     /**
 649 |      * Tests if this Long's value equals the specified's.
 650 |      * @param {!Long|number|string} other Other value
 651 |      * @returns {boolean}
 652 |      * @expose
 653 |      */
 654 |     LongPrototype.equals = function equals(other) {
 655 |         if (!isLong(other))
 656 |             other = fromValue(other);
 657 |         if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
 658 |             return false;
 659 |         return this.high === other.high && this.low === other.low;
 660 |     };
 661 | 
 662 |     /**
 663 |      * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
 664 |      * @function
 665 |      * @param {!Long|number|string} other Other value
 666 |      * @returns {boolean}
 667 |      * @expose
 668 |      */
 669 |     LongPrototype.eq = LongPrototype.equals;
 670 | 
 671 |     /**
 672 |      * Tests if this Long's value differs from the specified's.
 673 |      * @param {!Long|number|string} other Other value
 674 |      * @returns {boolean}
 675 |      * @expose
 676 |      */
 677 |     LongPrototype.notEquals = function notEquals(other) {
 678 |         return !this.eq(/* validates */ other);
 679 |     };
 680 | 
 681 |     /**
 682 |      * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
 683 |      * @function
 684 |      * @param {!Long|number|string} other Other value
 685 |      * @returns {boolean}
 686 |      * @expose
 687 |      */
 688 |     LongPrototype.neq = LongPrototype.notEquals;
 689 | 
 690 |     /**
 691 |      * Tests if this Long's value is less than the specified's.
 692 |      * @param {!Long|number|string} other Other value
 693 |      * @returns {boolean}
 694 |      * @expose
 695 |      */
 696 |     LongPrototype.lessThan = function lessThan(other) {
 697 |         return this.comp(/* validates */ other) < 0;
 698 |     };
 699 | 
 700 |     /**
 701 |      * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
 702 |      * @function
 703 |      * @param {!Long|number|string} other Other value
 704 |      * @returns {boolean}
 705 |      * @expose
 706 |      */
 707 |     LongPrototype.lt = LongPrototype.lessThan;
 708 | 
 709 |     /**
 710 |      * Tests if this Long's value is less than or equal the specified's.
 711 |      * @param {!Long|number|string} other Other value
 712 |      * @returns {boolean}
 713 |      * @expose
 714 |      */
 715 |     LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
 716 |         return this.comp(/* validates */ other) <= 0;
 717 |     };
 718 | 
 719 |     /**
 720 |      * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
 721 |      * @function
 722 |      * @param {!Long|number|string} other Other value
 723 |      * @returns {boolean}
 724 |      * @expose
 725 |      */
 726 |     LongPrototype.lte = LongPrototype.lessThanOrEqual;
 727 | 
 728 |     /**
 729 |      * Tests if this Long's value is greater than the specified's.
 730 |      * @param {!Long|number|string} other Other value
 731 |      * @returns {boolean}
 732 |      * @expose
 733 |      */
 734 |     LongPrototype.greaterThan = function greaterThan(other) {
 735 |         return this.comp(/* validates */ other) > 0;
 736 |     };
 737 | 
 738 |     /**
 739 |      * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
 740 |      * @function
 741 |      * @param {!Long|number|string} other Other value
 742 |      * @returns {boolean}
 743 |      * @expose
 744 |      */
 745 |     LongPrototype.gt = LongPrototype.greaterThan;
 746 | 
 747 |     /**
 748 |      * Tests if this Long's value is greater than or equal the specified's.
 749 |      * @param {!Long|number|string} other Other value
 750 |      * @returns {boolean}
 751 |      * @expose
 752 |      */
 753 |     LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
 754 |         return this.comp(/* validates */ other) >= 0;
 755 |     };
 756 | 
 757 |     /**
 758 |      * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
 759 |      * @function
 760 |      * @param {!Long|number|string} other Other value
 761 |      * @returns {boolean}
 762 |      * @expose
 763 |      */
 764 |     LongPrototype.gte = LongPrototype.greaterThanOrEqual;
 765 | 
 766 |     /**
 767 |      * Compares this Long's value with the specified's.
 768 |      * @param {!Long|number|string} other Other value
 769 |      * @returns {number} 0 if they are the same, 1 if the this is greater and -1
 770 |      *  if the given one is greater
 771 |      * @expose
 772 |      */
 773 |     LongPrototype.compare = function compare(other) {
 774 |         if (!isLong(other))
 775 |             other = fromValue(other);
 776 |         if (this.eq(other))
 777 |             return 0;
 778 |         var thisNeg = this.isNegative(),
 779 |             otherNeg = other.isNegative();
 780 |         if (thisNeg && !otherNeg)
 781 |             return -1;
 782 |         if (!thisNeg && otherNeg)
 783 |             return 1;
 784 |         // At this point the sign bits are the same
 785 |         if (!this.unsigned)
 786 |             return this.sub(other).isNegative() ? -1 : 1;
 787 |         // Both are positive if at least one is unsigned
 788 |         return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
 789 |     };
 790 | 
 791 |     /**
 792 |      * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
 793 |      * @function
 794 |      * @param {!Long|number|string} other Other value
 795 |      * @returns {number} 0 if they are the same, 1 if the this is greater and -1
 796 |      *  if the given one is greater
 797 |      * @expose
 798 |      */
 799 |     LongPrototype.comp = LongPrototype.compare;
 800 | 
 801 |     /**
 802 |      * Negates this Long's value.
 803 |      * @returns {!Long} Negated Long
 804 |      * @expose
 805 |      */
 806 |     LongPrototype.negate = function negate() {
 807 |         if (!this.unsigned && this.eq(MIN_VALUE))
 808 |             return MIN_VALUE;
 809 |         return this.not().add(ONE);
 810 |     };
 811 | 
 812 |     /**
 813 |      * Negates this Long's value. This is an alias of {@link Long#negate}.
 814 |      * @function
 815 |      * @returns {!Long} Negated Long
 816 |      * @expose
 817 |      */
 818 |     LongPrototype.neg = LongPrototype.negate;
 819 | 
 820 |     /**
 821 |      * Returns the sum of this and the specified Long.
 822 |      * @param {!Long|number|string} addend Addend
 823 |      * @returns {!Long} Sum
 824 |      * @expose
 825 |      */
 826 |     LongPrototype.add = function add(addend) {
 827 |         if (!isLong(addend))
 828 |             addend = fromValue(addend);
 829 | 
 830 |         // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
 831 | 
 832 |         var a48 = this.high >>> 16;
 833 |         var a32 = this.high & 0xFFFF;
 834 |         var a16 = this.low >>> 16;
 835 |         var a00 = this.low & 0xFFFF;
 836 | 
 837 |         var b48 = addend.high >>> 16;
 838 |         var b32 = addend.high & 0xFFFF;
 839 |         var b16 = addend.low >>> 16;
 840 |         var b00 = addend.low & 0xFFFF;
 841 | 
 842 |         var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
 843 |         c00 += a00 + b00;
 844 |         c16 += c00 >>> 16;
 845 |         c00 &= 0xFFFF;
 846 |         c16 += a16 + b16;
 847 |         c32 += c16 >>> 16;
 848 |         c16 &= 0xFFFF;
 849 |         c32 += a32 + b32;
 850 |         c48 += c32 >>> 16;
 851 |         c32 &= 0xFFFF;
 852 |         c48 += a48 + b48;
 853 |         c48 &= 0xFFFF;
 854 |         return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
 855 |     };
 856 | 
 857 |     /**
 858 |      * Returns the difference of this and the specified Long.
 859 |      * @param {!Long|number|string} subtrahend Subtrahend
 860 |      * @returns {!Long} Difference
 861 |      * @expose
 862 |      */
 863 |     LongPrototype.subtract = function subtract(subtrahend) {
 864 |         if (!isLong(subtrahend))
 865 |             subtrahend = fromValue(subtrahend);
 866 |         return this.add(subtrahend.neg());
 867 |     };
 868 | 
 869 |     /**
 870 |      * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
 871 |      * @function
 872 |      * @param {!Long|number|string} subtrahend Subtrahend
 873 |      * @returns {!Long} Difference
 874 |      * @expose
 875 |      */
 876 |     LongPrototype.sub = LongPrototype.subtract;
 877 | 
 878 |     /**
 879 |      * Returns the product of this and the specified Long.
 880 |      * @param {!Long|number|string} multiplier Multiplier
 881 |      * @returns {!Long} Product
 882 |      * @expose
 883 |      */
 884 |     LongPrototype.multiply = function multiply(multiplier) {
 885 |         if (this.isZero())
 886 |             return ZERO;
 887 |         if (!isLong(multiplier))
 888 |             multiplier = fromValue(multiplier);
 889 |         if (multiplier.isZero())
 890 |             return ZERO;
 891 |         if (this.eq(MIN_VALUE))
 892 |             return multiplier.isOdd() ? MIN_VALUE : ZERO;
 893 |         if (multiplier.eq(MIN_VALUE))
 894 |             return this.isOdd() ? MIN_VALUE : ZERO;
 895 | 
 896 |         if (this.isNegative()) {
 897 |             if (multiplier.isNegative())
 898 |                 return this.neg().mul(multiplier.neg());
 899 |             else
 900 |                 return this.neg().mul(multiplier).neg();
 901 |         } else if (multiplier.isNegative())
 902 |             return this.mul(multiplier.neg()).neg();
 903 | 
 904 |         // If both longs are small, use float multiplication
 905 |         if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
 906 |             return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
 907 | 
 908 |         // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
 909 |         // We can skip products that would overflow.
 910 | 
 911 |         var a48 = this.high >>> 16;
 912 |         var a32 = this.high & 0xFFFF;
 913 |         var a16 = this.low >>> 16;
 914 |         var a00 = this.low & 0xFFFF;
 915 | 
 916 |         var b48 = multiplier.high >>> 16;
 917 |         var b32 = multiplier.high & 0xFFFF;
 918 |         var b16 = multiplier.low >>> 16;
 919 |         var b00 = multiplier.low & 0xFFFF;
 920 | 
 921 |         var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
 922 |         c00 += a00 * b00;
 923 |         c16 += c00 >>> 16;
 924 |         c00 &= 0xFFFF;
 925 |         c16 += a16 * b00;
 926 |         c32 += c16 >>> 16;
 927 |         c16 &= 0xFFFF;
 928 |         c16 += a00 * b16;
 929 |         c32 += c16 >>> 16;
 930 |         c16 &= 0xFFFF;
 931 |         c32 += a32 * b00;
 932 |         c48 += c32 >>> 16;
 933 |         c32 &= 0xFFFF;
 934 |         c32 += a16 * b16;
 935 |         c48 += c32 >>> 16;
 936 |         c32 &= 0xFFFF;
 937 |         c32 += a00 * b32;
 938 |         c48 += c32 >>> 16;
 939 |         c32 &= 0xFFFF;
 940 |         c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
 941 |         c48 &= 0xFFFF;
 942 |         return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
 943 |     };
 944 | 
 945 |     /**
 946 |      * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
 947 |      * @function
 948 |      * @param {!Long|number|string} multiplier Multiplier
 949 |      * @returns {!Long} Product
 950 |      * @expose
 951 |      */
 952 |     LongPrototype.mul = LongPrototype.multiply;
 953 | 
 954 |     /**
 955 |      * Returns this Long divided by the specified. The result is signed if this Long is signed or
 956 |      *  unsigned if this Long is unsigned.
 957 |      * @param {!Long|number|string} divisor Divisor
 958 |      * @returns {!Long} Quotient
 959 |      * @expose
 960 |      */
 961 |     LongPrototype.divide = function divide(divisor) {
 962 |         if (!isLong(divisor))
 963 |             divisor = fromValue(divisor);
 964 |         if (divisor.isZero())
 965 |             throw Error('division by zero');
 966 |         if (this.isZero())
 967 |             return this.unsigned ? UZERO : ZERO;
 968 |         var approx, rem, res;
 969 |         if (!this.unsigned) {
 970 |             // This section is only relevant for signed longs and is derived from the
 971 |             // closure library as a whole.
 972 |             if (this.eq(MIN_VALUE)) {
 973 |                 if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
 974 |                     return MIN_VALUE;  // recall that -MIN_VALUE == MIN_VALUE
 975 |                 else if (divisor.eq(MIN_VALUE))
 976 |                     return ONE;
 977 |                 else {
 978 |                     // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
 979 |                     var halfThis = this.shr(1);
 980 |                     approx = halfThis.div(divisor).shl(1);
 981 |                     if (approx.eq(ZERO)) {
 982 |                         return divisor.isNegative() ? ONE : NEG_ONE;
 983 |                     } else {
 984 |                         rem = this.sub(divisor.mul(approx));
 985 |                         res = approx.add(rem.div(divisor));
 986 |                         return res;
 987 |                     }
 988 |                 }
 989 |             } else if (divisor.eq(MIN_VALUE))
 990 |                 return this.unsigned ? UZERO : ZERO;
 991 |             if (this.isNegative()) {
 992 |                 if (divisor.isNegative())
 993 |                     return this.neg().div(divisor.neg());
 994 |                 return this.neg().div(divisor).neg();
 995 |             } else if (divisor.isNegative())
 996 |                 return this.div(divisor.neg()).neg();
 997 |             res = ZERO;
 998 |         } else {
 999 |             // The algorithm below has not been made for unsigned longs. It's therefore
1000 |             // required to take special care of the MSB prior to running it.
1001 |             if (!divisor.unsigned)
1002 |                 divisor = divisor.toUnsigned();
1003 |             if (divisor.gt(this))
1004 |                 return UZERO;
1005 |             if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
1006 |                 return UONE;
1007 |             res = UZERO;
1008 |         }
1009 | 
1010 |         // Repeat the following until the remainder is less than other:  find a
1011 |         // floating-point that approximates remainder / other *from below*, add this
1012 |         // into the result, and subtract it from the remainder.  It is critical that
1013 |         // the approximate value is less than or equal to the real value so that the
1014 |         // remainder never becomes negative.
1015 |         rem = this;
1016 |         while (rem.gte(divisor)) {
1017 |             // Approximate the result of division. This may be a little greater or
1018 |             // smaller than the actual value.
1019 |             approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
1020 | 
1021 |             // We will tweak the approximate result by changing it in the 48-th digit or
1022 |             // the smallest non-fractional digit, whichever is larger.
1023 |             var log2 = Math.ceil(Math.log(approx) / Math.LN2),
1024 |                 delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
1025 | 
1026 |             // Decrease the approximation until it is smaller than the remainder.  Note
1027 |             // that if it is too large, the product overflows and is negative.
1028 |                 approxRes = fromNumber(approx),
1029 |                 approxRem = approxRes.mul(divisor);
1030 |             while (approxRem.isNegative() || approxRem.gt(rem)) {
1031 |                 approx -= delta;
1032 |                 approxRes = fromNumber(approx, this.unsigned);
1033 |                 approxRem = approxRes.mul(divisor);
1034 |             }
1035 | 
1036 |             // We know the answer can't be zero... and actually, zero would cause
1037 |             // infinite recursion since we would make no progress.
1038 |             if (approxRes.isZero())
1039 |                 approxRes = ONE;
1040 | 
1041 |             res = res.add(approxRes);
1042 |             rem = rem.sub(approxRem);
1043 |         }
1044 |         return res;
1045 |     };
1046 | 
1047 |     /**
1048 |      * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
1049 |      * @function
1050 |      * @param {!Long|number|string} divisor Divisor
1051 |      * @returns {!Long} Quotient
1052 |      * @expose
1053 |      */
1054 |     LongPrototype.div = LongPrototype.divide;
1055 | 
1056 |     /**
1057 |      * Returns this Long modulo the specified.
1058 |      * @param {!Long|number|string} divisor Divisor
1059 |      * @returns {!Long} Remainder
1060 |      * @expose
1061 |      */
1062 |     LongPrototype.modulo = function modulo(divisor) {
1063 |         if (!isLong(divisor))
1064 |             divisor = fromValue(divisor);
1065 |         return this.sub(this.div(divisor).mul(divisor));
1066 |     };
1067 | 
1068 |     /**
1069 |      * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
1070 |      * @function
1071 |      * @param {!Long|number|string} divisor Divisor
1072 |      * @returns {!Long} Remainder
1073 |      * @expose
1074 |      */
1075 |     LongPrototype.mod = LongPrototype.modulo;
1076 | 
1077 |     /**
1078 |      * Returns the bitwise NOT of this Long.
1079 |      * @returns {!Long}
1080 |      * @expose
1081 |      */
1082 |     LongPrototype.not = function not() {
1083 |         return fromBits(~this.low, ~this.high, this.unsigned);
1084 |     };
1085 | 
1086 |     /**
1087 |      * Returns the bitwise AND of this Long and the specified.
1088 |      * @param {!Long|number|string} other Other Long
1089 |      * @returns {!Long}
1090 |      * @expose
1091 |      */
1092 |     LongPrototype.and = function and(other) {
1093 |         if (!isLong(other))
1094 |             other = fromValue(other);
1095 |         return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
1096 |     };
1097 | 
1098 |     /**
1099 |      * Returns the bitwise OR of this Long and the specified.
1100 |      * @param {!Long|number|string} other Other Long
1101 |      * @returns {!Long}
1102 |      * @expose
1103 |      */
1104 |     LongPrototype.or = function or(other) {
1105 |         if (!isLong(other))
1106 |             other = fromValue(other);
1107 |         return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
1108 |     };
1109 | 
1110 |     /**
1111 |      * Returns the bitwise XOR of this Long and the given one.
1112 |      * @param {!Long|number|string} other Other Long
1113 |      * @returns {!Long}
1114 |      * @expose
1115 |      */
1116 |     LongPrototype.xor = function xor(other) {
1117 |         if (!isLong(other))
1118 |             other = fromValue(other);
1119 |         return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
1120 |     };
1121 | 
1122 |     /**
1123 |      * Returns this Long with bits shifted to the left by the given amount.
1124 |      * @param {number|!Long} numBits Number of bits
1125 |      * @returns {!Long} Shifted Long
1126 |      * @expose
1127 |      */
1128 |     LongPrototype.shiftLeft = function shiftLeft(numBits) {
1129 |         if (isLong(numBits))
1130 |             numBits = numBits.toInt();
1131 |         if ((numBits &= 63) === 0)
1132 |             return this;
1133 |         else if (numBits < 32)
1134 |             return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
1135 |         else
1136 |             return fromBits(0, this.low << (numBits - 32), this.unsigned);
1137 |     };
1138 | 
1139 |     /**
1140 |      * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
1141 |      * @function
1142 |      * @param {number|!Long} numBits Number of bits
1143 |      * @returns {!Long} Shifted Long
1144 |      * @expose
1145 |      */
1146 |     LongPrototype.shl = LongPrototype.shiftLeft;
1147 | 
1148 |     /**
1149 |      * Returns this Long with bits arithmetically shifted to the right by the given amount.
1150 |      * @param {number|!Long} numBits Number of bits
1151 |      * @returns {!Long} Shifted Long
1152 |      * @expose
1153 |      */
1154 |     LongPrototype.shiftRight = function shiftRight(numBits) {
1155 |         if (isLong(numBits))
1156 |             numBits = numBits.toInt();
1157 |         if ((numBits &= 63) === 0)
1158 |             return this;
1159 |         else if (numBits < 32)
1160 |             return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
1161 |         else
1162 |             return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
1163 |     };
1164 | 
1165 |     /**
1166 |      * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
1167 |      * @function
1168 |      * @param {number|!Long} numBits Number of bits
1169 |      * @returns {!Long} Shifted Long
1170 |      * @expose
1171 |      */
1172 |     LongPrototype.shr = LongPrototype.shiftRight;
1173 | 
1174 |     /**
1175 |      * Returns this Long with bits logically shifted to the right by the given amount.
1176 |      * @param {number|!Long} numBits Number of bits
1177 |      * @returns {!Long} Shifted Long
1178 |      * @expose
1179 |      */
1180 |     LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
1181 |         if (isLong(numBits))
1182 |             numBits = numBits.toInt();
1183 |         numBits &= 63;
1184 |         if (numBits === 0)
1185 |             return this;
1186 |         else {
1187 |             var high = this.high;
1188 |             if (numBits < 32) {
1189 |                 var low = this.low;
1190 |                 return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
1191 |             } else if (numBits === 32)
1192 |                 return fromBits(high, 0, this.unsigned);
1193 |             else
1194 |                 return fromBits(high >>> (numBits - 32), 0, this.unsigned);
1195 |         }
1196 |     };
1197 | 
1198 |     /**
1199 |      * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
1200 |      * @function
1201 |      * @param {number|!Long} numBits Number of bits
1202 |      * @returns {!Long} Shifted Long
1203 |      * @expose
1204 |      */
1205 |     LongPrototype.shru = LongPrototype.shiftRightUnsigned;
1206 | 
1207 |     /**
1208 |      * Converts this Long to signed.
1209 |      * @returns {!Long} Signed long
1210 |      * @expose
1211 |      */
1212 |     LongPrototype.toSigned = function toSigned() {
1213 |         if (!this.unsigned)
1214 |             return this;
1215 |         return fromBits(this.low, this.high, false);
1216 |     };
1217 | 
1218 |     /**
1219 |      * Converts this Long to unsigned.
1220 |      * @returns {!Long} Unsigned long
1221 |      * @expose
1222 |      */
1223 |     LongPrototype.toUnsigned = function toUnsigned() {
1224 |         if (this.unsigned)
1225 |             return this;
1226 |         return fromBits(this.low, this.high, true);
1227 |     };
1228 | 
1229 |     return Long;
1230 | });
1231 | 


--------------------------------------------------------------------------------
/public/message.proto:
--------------------------------------------------------------------------------
1 | message Message {
2 |     required string text = 1;
3 |     required string lang = 2;
4 | }


--------------------------------------------------------------------------------