├── public
├── message.proto
├── index.html
├── axios.min.js
├── long.js
└── bytebuffer.js
├── package.json
└── index.js
/public/message.proto:
--------------------------------------------------------------------------------
1 | message Message {
2 | required string text = 1;
3 | required string lang = 2;
4 | }
--------------------------------------------------------------------------------
/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/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
45 |
46 |
--------------------------------------------------------------------------------
/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)
--------------------------------------------------------------------------------
/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 | 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/bytebuffer.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2013-2014 Daniel Wirtz
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 |
--------------------------------------------------------------------------------