0) {
- if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
- while(i >= 0) {
- if(p < k) {
- d = (this[i]&((1<>(p+=this.DB-k);
- }
- else {
- d = (this[i]>>(p-=k))&km;
- if(p <= 0) { p += this.DB; --i; }
- }
- if(d > 0) m = true;
- if(m) r += int2char(d);
- }
- }
- return m?r:"0";
- }
-
- // (public) -this
- function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
-
- // (public) |this|
- function bnAbs() { return (this.s<0)?this.negate():this; }
-
- // (public) return + if this > a, - if this < a, 0 if equal
- function bnCompareTo(a) {
- var r = this.s-a.s;
- if(r != 0) return r;
- var i = this.t;
- r = i-a.t;
- if(r != 0) return (this.s<0)?-r:r;
- while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
- return 0;
- }
-
- // returns bit length of the integer x
- function nbits(x) {
- var r = 1, t;
- if((t=x>>>16) != 0) { x = t; r += 16; }
- if((t=x>>8) != 0) { x = t; r += 8; }
- if((t=x>>4) != 0) { x = t; r += 4; }
- if((t=x>>2) != 0) { x = t; r += 2; }
- if((t=x>>1) != 0) { x = t; r += 1; }
- return r;
- }
-
- // (public) return the number of bits in "this"
- function bnBitLength() {
- if(this.t <= 0) return 0;
- return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
- }
-
- // (protected) r = this << n*DB
- function bnpDLShiftTo(n,r) {
- var i;
- for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
- for(i = n-1; i >= 0; --i) r[i] = 0;
- r.t = this.t+n;
- r.s = this.s;
- }
-
- // (protected) r = this >> n*DB
- function bnpDRShiftTo(n,r) {
- for(var i = n; i < this.t; ++i) r[i-n] = this[i];
- r.t = Math.max(this.t-n,0);
- r.s = this.s;
- }
-
- // (protected) r = this << n
- function bnpLShiftTo(n,r) {
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1<= 0; --i) {
- r[i+ds+1] = (this[i]>>cbs)|c;
- c = (this[i]&bm)<= 0; --i) r[i] = 0;
- r[ds] = c;
- r.t = this.t+ds+1;
- r.s = this.s;
- r.clamp();
- }
-
- // (protected) r = this >> n
- function bnpRShiftTo(n,r) {
- r.s = this.s;
- var ds = Math.floor(n/this.DB);
- if(ds >= this.t) { r.t = 0; return; }
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1<>bs;
- for(var i = ds+1; i < this.t; ++i) {
- r[i-ds-1] |= (this[i]&bm)<>bs;
- }
- if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB;
- }
- if(a.t < this.t) {
- c -= a.s;
- while(i < this.t) {
- c += this[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c += this.s;
- }
- else {
- c += this.s;
- while(i < a.t) {
- c -= a[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c -= a.s;
- }
- r.s = (c<0)?-1:0;
- if(c < -1) r[i++] = this.DV+c;
- else if(c > 0) r[i++] = c;
- r.t = i;
- r.clamp();
- }
-
- // (protected) r = this * a, r != this,a (HAC 14.12)
- // "this" should be the larger one if appropriate.
- function bnpMultiplyTo(a,r) {
- var x = this.abs(), y = a.abs();
- var i = x.t;
- r.t = i+y.t;
- while(--i >= 0) r[i] = 0;
- for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
- r.s = 0;
- r.clamp();
- if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
- }
-
- // (protected) r = this^2, r != this (HAC 14.16)
- function bnpSquareTo(r) {
- var x = this.abs();
- var i = r.t = 2*x.t;
- while(--i >= 0) r[i] = 0;
- for(i = 0; i < x.t-1; ++i) {
- var c = x.am(i,x[i],r,2*i,0,1);
- if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
- r[i+x.t] -= x.DV;
- r[i+x.t+1] = 1;
- }
- }
- if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
- r.s = 0;
- r.clamp();
- }
-
- // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
- // r != q, this != m. q or r may be null.
- function bnpDivRemTo(m,q,r) {
- var pm = m.abs();
- if(pm.t <= 0) return;
- var pt = this.abs();
- if(pt.t < pm.t) {
- if(q != null) q.fromInt(0);
- if(r != null) this.copyTo(r);
- return;
- }
- if(r == null) r = nbi();
- var y = nbi(), ts = this.s, ms = m.s;
- var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
- if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
- else { pm.copyTo(y); pt.copyTo(r); }
- var ys = y.t;
- var y0 = y[ys-1];
- if(y0 == 0) return;
- var yt = y0*(1<1)?y[ys-2]>>this.F2:0);
- var d1 = this.FV/yt, d2 = (1<= 0) {
- r[r.t++] = 1;
- r.subTo(t,r);
- }
- BigInteger.ONE.dlShiftTo(ys,t);
- t.subTo(y,y); // "negative" y so we can replace sub with am later
- while(y.t < ys) y[y.t++] = 0;
- while(--j >= 0) {
- // Estimate quotient digit
- var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
- if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
- y.dlShiftTo(j,t);
- r.subTo(t,r);
- while(r[i] < --qd) r.subTo(t,r);
- }
- }
- if(q != null) {
- r.drShiftTo(ys,q);
- if(ts != ms) BigInteger.ZERO.subTo(q,q);
- }
- r.t = ys;
- r.clamp();
- if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
- if(ts < 0) BigInteger.ZERO.subTo(r,r);
- }
-
- // (public) this mod a
- function bnMod(a) {
- var r = nbi();
- this.abs().divRemTo(a,null,r);
- if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
- return r;
- }
-
- // Modular reduction using "classic" algorithm
- function Classic(m) { this.m = m; }
- function cConvert(x) {
- if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
- else return x;
- }
- function cRevert(x) { return x; }
- function cReduce(x) { x.divRemTo(this.m,null,x); }
- function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
- function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
- Classic.prototype.convert = cConvert;
- Classic.prototype.revert = cRevert;
- Classic.prototype.reduce = cReduce;
- Classic.prototype.mulTo = cMulTo;
- Classic.prototype.sqrTo = cSqrTo;
-
- // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
- // justification:
- // xy == 1 (mod m)
- // xy = 1+km
- // xy(2-xy) = (1+km)(1-km)
- // x[y(2-xy)] = 1-k^2m^2
- // x[y(2-xy)] == 1 (mod m^2)
- // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
- // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
- // JS multiply "overflows" differently from C/C++, so care is needed here.
- function bnpInvDigit() {
- if(this.t < 1) return 0;
- var x = this[0];
- if((x&1) == 0) return 0;
- var y = x&3; // y == 1/x mod 2^2
- y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
- y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
- y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
- // last step - calculate inverse mod DV directly;
- // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
- y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
- // we really want the negative inverse, and -DV < y < DV
- return (y>0)?this.DV-y:-y;
- }
-
- // Montgomery reduction
- function Montgomery(m) {
- this.m = m;
- this.mp = m.invDigit();
- this.mpl = this.mp&0x7fff;
- this.mph = this.mp>>15;
- this.um = (1<<(m.DB-15))-1;
- this.mt2 = 2*m.t;
- }
-
- // xR mod m
- function montConvert(x) {
- var r = nbi();
- x.abs().dlShiftTo(this.m.t,r);
- r.divRemTo(this.m,null,r);
- if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
- return r;
- }
-
- // x/R mod m
- function montRevert(x) {
- var r = nbi();
- x.copyTo(r);
- this.reduce(r);
- return r;
- }
-
- // x = x/R mod m (HAC 14.32)
- function montReduce(x) {
- while(x.t <= this.mt2) // pad x so am has enough room later
- x[x.t++] = 0;
- for(var i = 0; i < this.m.t; ++i) {
- // faster way of calculating u0 = x[i]*mp mod DV
- var j = x[i]&0x7fff;
- var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
- // use am to combine the multiply-shift-add into one call
- j = i+this.m.t;
- x[j] += this.m.am(0,u0,x,i,0,this.m.t);
- // propagate carry
- while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
- }
- x.clamp();
- x.drShiftTo(this.m.t,x);
- if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
- }
-
- // r = "x^2/R mod m"; x != r
- function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
- // r = "xy/R mod m"; x,y != r
- function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
- Montgomery.prototype.convert = montConvert;
- Montgomery.prototype.revert = montRevert;
- Montgomery.prototype.reduce = montReduce;
- Montgomery.prototype.mulTo = montMulTo;
- Montgomery.prototype.sqrTo = montSqrTo;
-
- // (protected) true iff this is even
- function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
-
- // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
- function bnpExp(e,z) {
- if(e > 0xffffffff || e < 1) return BigInteger.ONE;
- var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
- g.copyTo(r);
- while(--i >= 0) {
- z.sqrTo(r,r2);
- if((e&(1< 0) z.mulTo(r2,g,r);
- else { var t = r; r = r2; r2 = t; }
- }
- return z.revert(r);
- }
-
- // (public) this^e % m, 0 <= e < 2^32
- function bnModPowInt(e,m) {
- var z;
- if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
- return this.exp(e,z);
- }
-
- // protected
- BigInteger.prototype.copyTo = bnpCopyTo;
- BigInteger.prototype.fromInt = bnpFromInt;
- BigInteger.prototype.fromString = bnpFromString;
- BigInteger.prototype.clamp = bnpClamp;
- BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
- BigInteger.prototype.drShiftTo = bnpDRShiftTo;
- BigInteger.prototype.lShiftTo = bnpLShiftTo;
- BigInteger.prototype.rShiftTo = bnpRShiftTo;
- BigInteger.prototype.subTo = bnpSubTo;
- BigInteger.prototype.multiplyTo = bnpMultiplyTo;
- BigInteger.prototype.squareTo = bnpSquareTo;
- BigInteger.prototype.divRemTo = bnpDivRemTo;
- BigInteger.prototype.invDigit = bnpInvDigit;
- BigInteger.prototype.isEven = bnpIsEven;
- BigInteger.prototype.exp = bnpExp;
-
- // public
- BigInteger.prototype.toString = bnToString;
- BigInteger.prototype.negate = bnNegate;
- BigInteger.prototype.abs = bnAbs;
- BigInteger.prototype.compareTo = bnCompareTo;
- BigInteger.prototype.bitLength = bnBitLength;
- BigInteger.prototype.mod = bnMod;
- BigInteger.prototype.modPowInt = bnModPowInt;
-
- // "constants"
- BigInteger.ZERO = nbv(0);
- BigInteger.ONE = nbv(1);
-
- // jsbn2 stuff
-
- // (protected) convert from radix string
- function bnpFromRadix(s,b) {
- this.fromInt(0);
- if(b == null) b = 10;
- var cs = this.chunkSize(b);
- var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
- for(var i = 0; i < s.length; ++i) {
- var x = intAt(s,i);
- if(x < 0) {
- if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
- continue;
- }
- w = b*w+x;
- if(++j >= cs) {
- this.dMultiply(d);
- this.dAddOffset(w,0);
- j = 0;
- w = 0;
- }
- }
- if(j > 0) {
- this.dMultiply(Math.pow(b,j));
- this.dAddOffset(w,0);
- }
- if(mi) BigInteger.ZERO.subTo(this,this);
- }
-
- // (protected) return x s.t. r^x < DV
- function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
-
- // (public) 0 if this == 0, 1 if this > 0
- function bnSigNum() {
- if(this.s < 0) return -1;
- else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
- else return 1;
- }
-
- // (protected) this *= n, this >= 0, 1 < n < DV
- function bnpDMultiply(n) {
- this[this.t] = this.am(0,n-1,this,0,0,this.t);
- ++this.t;
- this.clamp();
- }
-
- // (protected) this += n << w words, this >= 0
- function bnpDAddOffset(n,w) {
- if(n == 0) return;
- while(this.t <= w) this[this.t++] = 0;
- this[w] += n;
- while(this[w] >= this.DV) {
- this[w] -= this.DV;
- if(++w >= this.t) this[this.t++] = 0;
- ++this[w];
- }
- }
-
- // (protected) convert to radix string
- function bnpToRadix(b) {
- if(b == null) b = 10;
- if(this.signum() == 0 || b < 2 || b > 36) return "0";
- var cs = this.chunkSize(b);
- var a = Math.pow(b,cs);
- var d = nbv(a), y = nbi(), z = nbi(), r = "";
- this.divRemTo(d,y,z);
- while(y.signum() > 0) {
- r = (a+z.intValue()).toString(b).substr(1) + r;
- y.divRemTo(d,y,z);
- }
- return z.intValue().toString(b) + r;
- }
-
- // (public) return value as integer
- function bnIntValue() {
- if(this.s < 0) {
- if(this.t == 1) return this[0]-this.DV;
- else if(this.t == 0) return -1;
- }
- else if(this.t == 1) return this[0];
- else if(this.t == 0) return 0;
- // assumes 16 < DB < 32
- return ((this[1]&((1<<(32-this.DB))-1))<>= this.DB;
- }
- if(a.t < this.t) {
- c += a.s;
- while(i < this.t) {
- c += this[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c += this.s;
- }
- else {
- c += this.s;
- while(i < a.t) {
- c += a[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c += a.s;
- }
- r.s = (c<0)?-1:0;
- if(c > 0) r[i++] = c;
- else if(c < -1) r[i++] = this.DV+c;
- r.t = i;
- r.clamp();
- }
-
- BigInteger.prototype.fromRadix = bnpFromRadix;
- BigInteger.prototype.chunkSize = bnpChunkSize;
- BigInteger.prototype.signum = bnSigNum;
- BigInteger.prototype.dMultiply = bnpDMultiply;
- BigInteger.prototype.dAddOffset = bnpDAddOffset;
- BigInteger.prototype.toRadix = bnpToRadix;
- BigInteger.prototype.intValue = bnIntValue;
- BigInteger.prototype.addTo = bnpAddTo;
-
- //======= end jsbn =======
-
- // Emscripten wrapper
- var Wrapper = {
- abs: function(l, h) {
- var x = new goog.math.Long(l, h);
- var ret;
- if (x.isNegative()) {
- ret = x.negate();
- } else {
- ret = x;
- }
- HEAP32[tempDoublePtr>>2] = ret.low_;
- HEAP32[tempDoublePtr+4>>2] = ret.high_;
- },
- ensureTemps: function() {
- if (Wrapper.ensuredTemps) return;
- Wrapper.ensuredTemps = true;
- Wrapper.two32 = new BigInteger();
- Wrapper.two32.fromString('4294967296', 10);
- Wrapper.two64 = new BigInteger();
- Wrapper.two64.fromString('18446744073709551616', 10);
- Wrapper.temp1 = new BigInteger();
- Wrapper.temp2 = new BigInteger();
- },
- lh2bignum: function(l, h) {
- var a = new BigInteger();
- a.fromString(h.toString(), 10);
- var b = new BigInteger();
- a.multiplyTo(Wrapper.two32, b);
- var c = new BigInteger();
- c.fromString(l.toString(), 10);
- var d = new BigInteger();
- c.addTo(b, d);
- return d;
- },
- stringify: function(l, h, unsigned) {
- var ret = new goog.math.Long(l, h).toString();
- if (unsigned && ret[0] == '-') {
- // unsign slowly using jsbn bignums
- Wrapper.ensureTemps();
- var bignum = new BigInteger();
- bignum.fromString(ret, 10);
- ret = new BigInteger();
- Wrapper.two64.addTo(bignum, ret);
- ret = ret.toString(10);
- }
- return ret;
- },
- fromString: function(str, base, min, max, unsigned) {
- Wrapper.ensureTemps();
- var bignum = new BigInteger();
- bignum.fromString(str, base);
- var bigmin = new BigInteger();
- bigmin.fromString(min, 10);
- var bigmax = new BigInteger();
- bigmax.fromString(max, 10);
- if (unsigned && bignum.compareTo(BigInteger.ZERO) < 0) {
- var temp = new BigInteger();
- bignum.addTo(Wrapper.two64, temp);
- bignum = temp;
- }
- var error = false;
- if (bignum.compareTo(bigmin) < 0) {
- bignum = bigmin;
- error = true;
- } else if (bignum.compareTo(bigmax) > 0) {
- bignum = bigmax;
- error = true;
- }
- var ret = goog.math.Long.fromString(bignum.toString()); // min-max checks should have clamped this to a range goog.math.Long can handle well
- HEAP32[tempDoublePtr>>2] = ret.low_;
- HEAP32[tempDoublePtr+4>>2] = ret.high_;
- if (error) throw 'range error';
- }
- };
- return Wrapper;
-})();
-
-//======= end closure i64 code =======
-
-
-
-// === Auto-generated postamble setup entry stuff ===
-
-if (memoryInitializer) {
- if (typeof Module['locateFile'] === 'function') {
- memoryInitializer = Module['locateFile'](memoryInitializer);
- } else if (Module['memoryInitializerPrefixURL']) {
- memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer;
- }
- if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
- var data = Module['readBinary'](memoryInitializer);
- HEAPU8.set(data, STATIC_BASE);
- } else {
- addRunDependency('memory initializer');
- Browser.asyncLoad(memoryInitializer, function(data) {
- HEAPU8.set(data, STATIC_BASE);
- removeRunDependency('memory initializer');
- }, function(data) {
- throw 'could not load memory initializer ' + memoryInitializer;
- });
- }
-}
-
-function ExitStatus(status) {
- this.name = "ExitStatus";
- this.message = "Program terminated with exit(" + status + ")";
- this.status = status;
-};
-ExitStatus.prototype = new Error();
-ExitStatus.prototype.constructor = ExitStatus;
-
-var initialStackTop;
-var preloadStartTime = null;
-var calledMain = false;
-
-dependenciesFulfilled = function runCaller() {
- // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
- if (!Module['calledRun'] && shouldRunNow) run();
- if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
-}
-
-Module['callMain'] = Module.callMain = function callMain(args) {
- assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
- assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
-
- args = args || [];
-
- ensureInitRuntime();
-
- var argc = args.length+1;
- function pad() {
- for (var i = 0; i < 4-1; i++) {
- argv.push(0);
- }
- }
- var argv = [allocate(intArrayFromString(Module['thisProgram']), 'i8', ALLOC_NORMAL) ];
- pad();
- for (var i = 0; i < argc-1; i = i + 1) {
- argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
- pad();
- }
- argv.push(0);
- argv = allocate(argv, 'i32', ALLOC_NORMAL);
-
- initialStackTop = STACKTOP;
-
- try {
-
- var ret = Module['_main'](argc, argv, 0);
-
-
- // if we're not running an evented main loop, it's time to exit
- exit(ret);
- }
- catch(e) {
- if (e instanceof ExitStatus) {
- // exit() throws this once it's done to make sure execution
- // has been stopped completely
- return;
- } else if (e == 'SimulateInfiniteLoop') {
- // running an evented main loop, don't immediately exit
- Module['noExitRuntime'] = true;
- return;
- } else {
- if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
- throw e;
- }
- } finally {
- calledMain = true;
- }
-}
-
-
-
-
-function run(args) {
- args = args || Module['arguments'];
-
- if (preloadStartTime === null) preloadStartTime = Date.now();
-
- if (runDependencies > 0) {
- return;
- }
-
- preRun();
-
- if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
- if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
-
- function doRun() {
- if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
- Module['calledRun'] = true;
-
- if (ABORT) return;
-
- ensureInitRuntime();
-
- preMain();
-
- if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
- Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
- }
-
- if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
-
- if (Module['_main'] && shouldRunNow) Module['callMain'](args);
-
- postRun();
- }
-
- if (Module['setStatus']) {
- Module['setStatus']('Running...');
- setTimeout(function() {
- setTimeout(function() {
- Module['setStatus']('');
- }, 1);
- doRun();
- }, 1);
- } else {
- doRun();
- }
-}
-Module['run'] = Module.run = run;
-
-function exit(status) {
- if (Module['noExitRuntime']) {
- return;
- }
-
- ABORT = true;
- EXITSTATUS = status;
- STACKTOP = initialStackTop;
-
- // exit the runtime
- exitRuntime();
-
- if (ENVIRONMENT_IS_NODE) {
- // Work around a node.js bug where stdout buffer is not flushed at process exit:
- // Instead of process.exit() directly, wait for stdout flush event.
- // See https://github.com/joyent/node/issues/1669 and https://github.com/kripken/emscripten/issues/2582
- // Workaround is based on https://github.com/RReverser/acorn/commit/50ab143cecc9ed71a2d66f78b4aec3bb2e9844f6
- process['stdout']['once']('drain', function () {
- process['exit'](status);
- });
- console.log(' '); // Make sure to print something to force the drain event to occur, in case the stdout buffer was empty.
- // Work around another node bug where sometimes 'drain' is never fired - make another effort
- // to emit the exit status, after a significant delay (if node hasn't fired drain by then, give up)
- setTimeout(function() {
- process['exit'](status);
- }, 500);
- } else
- if (ENVIRONMENT_IS_SHELL && typeof quit === 'function') {
- quit(status);
- }
- // if we reach here, we must throw an exception to halt the current execution
- throw new ExitStatus(status);
-}
-Module['exit'] = Module.exit = exit;
-
-function abort(text) {
- if (text) {
- Module.print(text);
- Module.printErr(text);
- }
-
- ABORT = true;
- EXITSTATUS = 1;
-
- var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
-
- throw 'abort() at ' + stackTrace() + extra;
-}
-Module['abort'] = Module.abort = abort;
-
-// {{PRE_RUN_ADDITIONS}}
-
-if (Module['preInit']) {
- if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
- while (Module['preInit'].length > 0) {
- Module['preInit'].pop()();
- }
-}
-
-// shouldRunNow refers to calling main(), not run().
-var shouldRunNow = true;
-if (Module['noInitialRun']) {
- shouldRunNow = false;
-}
-
-
-run();
-
-// {{POST_RUN_ADDITIONS}}
-
-
-
-
-
-
-// {{MODULE_ADDITIONS}}
-
-
-
-
-/* vim: ts=4:sw=4:expandtab
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-var axolotlInternal = axolotlInternal || {};
-
-axolotlInternal.curve25519 = function() {
- 'use strict';
-
- // Insert some bytes into the emscripten memory and return a pointer
- function _allocate(bytes) {
- var address = Module._malloc(bytes.length);
- Module.HEAPU8.set(bytes, address);
-
- return address;
- }
-
- function _readBytes(address, length, array) {
- array.set(Module.HEAPU8.subarray(address, address + length));
- }
-
- var basepoint = new Uint8Array(32);
- basepoint[0] = 9;
-
- return {
- keyPair: function(privKey) {
- return new Promise(function(resolve) {
- var priv = new Uint8Array(privKey);
- priv[0] &= 248;
- priv[31] &= 127;
- priv[31] |= 64
-
- // Where to store the result
- var publicKey_ptr = Module._malloc(32);
-
- // Get a pointer to the private key
- var privateKey_ptr = _allocate(priv);
-
- // The basepoint for generating public keys
- var basepoint_ptr = _allocate(basepoint);
-
- // The return value is just 0, the operation is done in place
- var err = Module._curve25519_donna(publicKey_ptr,
- privateKey_ptr,
- basepoint_ptr);
-
- var res = new Uint8Array(32);
- _readBytes(publicKey_ptr, 32, res);
-
- Module._free(publicKey_ptr);
- Module._free(privateKey_ptr);
- Module._free(basepoint_ptr);
-
- resolve({ pubKey: res.buffer, privKey: privKey });
- });
-
- },
- sharedSecret: function(pubKey, privKey) {
- // Where to store the result
- var sharedKey_ptr = Module._malloc(32);
-
- // Get a pointer to our private key
- var privateKey_ptr = _allocate(new Uint8Array(privKey));
-
- // Get a pointer to their public key, the basepoint when you're
- // generating a shared secret
- var basepoint_ptr = _allocate(new Uint8Array(pubKey));
-
- // Return value is 0 here too of course
- var err = Module._curve25519_donna(sharedKey_ptr,
- privateKey_ptr,
- basepoint_ptr);
-
- var res = new Uint8Array(32);
- _readBytes(sharedKey_ptr, 32, res);
-
- Module._free(sharedKey_ptr);
- Module._free(privateKey_ptr);
- Module._free(basepoint_ptr);
-
- return Promise.resolve(res.buffer);
- },
- sign: function(privKey, message) {
- // Where to store the result
- var signature_ptr = Module._malloc(64);
-
- // Get a pointer to our private key
- var privateKey_ptr = _allocate(new Uint8Array(privKey));
-
- // Get a pointer to the message
- var message_ptr = _allocate(new Uint8Array(message));
-
- var err = Module._curve25519_sign(signature_ptr,
- privateKey_ptr,
- message_ptr,
- message.byteLength);
-
- var res = new Uint8Array(64);
- _readBytes(signature_ptr, 64, res);
-
- Module._free(signature_ptr);
- Module._free(privateKey_ptr);
- Module._free(message_ptr);
-
- return Promise.resolve(res.buffer);
- },
- verify: function(pubKey, message, sig) {
- // Get a pointer to their public key
- var publicKey_ptr = _allocate(new Uint8Array(pubKey));
-
- // Get a pointer to the signature
- var signature_ptr = _allocate(new Uint8Array(sig));
-
- // Get a pointer to the message
- var message_ptr = _allocate(new Uint8Array(message));
-
- var res = Module._curve25519_verify(signature_ptr,
- publicKey_ptr,
- message_ptr,
- message.byteLength);
-
- Module._free(publicKey_ptr);
- Module._free(signature_ptr);
- Module._free(message_ptr);
-
- return new Promise(function(resolve, reject) {
- if (res !== 0) {
- reject(new Error("Invalid signature"));
- } else {
- resolve();
- }
- });
- }
- };
-}();
-
-var axolotlInternal = axolotlInternal || {};
-
-// I am the...workee?
-var origCurve25519 = axolotlInternal.curve25519;
-
-axolotlInternal.startWorker = function(url) {
- axolotlInternal.stopWorker(); // there can be only one
- axolotlInternal.curve25519 = new Curve25519Worker(url);
-};
-axolotlInternal.stopWorker = function() {
- if (axolotlInternal.curve25519 instanceof Curve25519Worker) {
- var worker = axolotlInternal.curve25519.worker;
- axolotlInternal.curve25519 = origCurve25519;
- worker.terminate();
- }
-};
-
-function Curve25519Worker(url) {
- this.jobs = {};
- this.jobId = 0;
- this.worker = new Worker(url);
- this.worker.onmessage = function(e) {
- var job = this.jobs[e.data.id];
- if (e.data.error && typeof job.onerror === 'function') {
- job.onerror(new Error(e.data.error));
- } else if (typeof job.onsuccess === 'function') {
- job.onsuccess(e.data.result);
- }
- delete this.jobs[e.data.id];
- }.bind(this);
-}
-
-Curve25519Worker.prototype = {
- constructor: Curve25519Worker,
- postMessage: function(methodName, args, onsuccess, onerror) {
- return new Promise(function(resolve, reject) {
- this.jobs[this.jobId] = { onsuccess: resolve, onerror: reject };
- this.worker.postMessage({ id: this.jobId, methodName: methodName, args: args });
- this.jobId++;
- }.bind(this));
- },
- keyPair: function(privKey) {
- return this.postMessage('keyPair', [privKey]);
- },
- sharedSecret: function(pubKey, privKey) {
- return this.postMessage('sharedSecret', [pubKey, privKey]);
- },
- sign: function(privKey, message) {
- return this.postMessage('sign', [privKey, message]);
- },
- verify: function(pubKey, message, sig) {
- return this.postMessage('verify', [pubKey, message, sig]);
- }
-};
-
-;(function(){
-/**
- * CryptoJS core components.
- */
-var CryptoJS = CryptoJS || (function (Math, undefined) {
- /**
- * CryptoJS namespace.
- */
- var C = {};
-
- /**
- * Library namespace.
- */
- var C_lib = C.lib = {};
-
- /**
- * Base object for prototypal inheritance.
- */
- var Base = C_lib.Base = (function () {
- function F() {}
-
- return {
- /**
- * Creates a new object that inherits from this object.
- *
- * @param {Object} overrides Properties to copy into the new object.
- *
- * @return {Object} The new object.
- *
- * @static
- *
- * @example
- *
- * var MyType = CryptoJS.lib.Base.extend({
- * field: 'value',
- *
- * method: function () {
- * }
- * });
- */
- extend: function (overrides) {
- // Spawn
- F.prototype = this;
- var subtype = new F();
-
- // Augment
- if (overrides) {
- subtype.mixIn(overrides);
- }
-
- // Create default initializer
- if (!subtype.hasOwnProperty('init')) {
- subtype.init = function () {
- subtype.$super.init.apply(this, arguments);
- };
- }
-
- // Initializer's prototype is the subtype object
- subtype.init.prototype = subtype;
-
- // Reference supertype
- subtype.$super = this;
-
- return subtype;
- },
-
- /**
- * Extends this object and runs the init method.
- * Arguments to create() will be passed to init().
- *
- * @return {Object} The new object.
- *
- * @static
- *
- * @example
- *
- * var instance = MyType.create();
- */
- create: function () {
- var instance = this.extend();
- instance.init.apply(instance, arguments);
-
- return instance;
- },
-
- /**
- * Initializes a newly created object.
- * Override this method to add some logic when your objects are created.
- *
- * @example
- *
- * var MyType = CryptoJS.lib.Base.extend({
- * init: function () {
- * // ...
- * }
- * });
- */
- init: function () {
- },
-
- /**
- * Copies properties into this object.
- *
- * @param {Object} properties The properties to mix in.
- *
- * @example
- *
- * MyType.mixIn({
- * field: 'value'
- * });
- */
- mixIn: function (properties) {
- for (var propertyName in properties) {
- if (properties.hasOwnProperty(propertyName)) {
- this[propertyName] = properties[propertyName];
- }
- }
-
- // IE won't copy toString using the loop above
- if (properties.hasOwnProperty('toString')) {
- this.toString = properties.toString;
- }
- },
-
- /**
- * Creates a copy of this object.
- *
- * @return {Object} The clone.
- *
- * @example
- *
- * var clone = instance.clone();
- */
- clone: function () {
- return this.init.prototype.extend(this);
- }
- };
- }());
-
- /**
- * An array of 32-bit words.
- *
- * @property {Array} words The array of 32-bit words.
- * @property {number} sigBytes The number of significant bytes in this word array.
- */
- var WordArray = C_lib.WordArray = Base.extend({
- /**
- * Initializes a newly created word array.
- *
- * @param {Array} words (Optional) An array of 32-bit words.
- * @param {number} sigBytes (Optional) The number of significant bytes in the words.
- *
- * @example
- *
- * var wordArray = CryptoJS.lib.WordArray.create();
- * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
- * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
- */
- init: function (words, sigBytes) {
- words = this.words = words || [];
-
- if (sigBytes != undefined) {
- this.sigBytes = sigBytes;
- } else {
- this.sigBytes = words.length * 4;
- }
- },
-
- /**
- * Converts this word array to a string.
- *
- * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
- *
- * @return {string} The stringified word array.
- *
- * @example
- *
- * var string = wordArray + '';
- * var string = wordArray.toString();
- * var string = wordArray.toString(CryptoJS.enc.Utf8);
- */
- toString: function (encoder) {
- return (encoder || Hex).stringify(this);
- },
-
- /**
- * Concatenates a word array to this word array.
- *
- * @param {WordArray} wordArray The word array to append.
- *
- * @return {WordArray} This word array.
- *
- * @example
- *
- * wordArray1.concat(wordArray2);
- */
- concat: function (wordArray) {
- // Shortcuts
- var thisWords = this.words;
- var thatWords = wordArray.words;
- var thisSigBytes = this.sigBytes;
- var thatSigBytes = wordArray.sigBytes;
-
- // Clamp excess bits
- this.clamp();
-
- // Concat
- if (thisSigBytes % 4) {
- // Copy one byte at a time
- for (var i = 0; i < thatSigBytes; i++) {
- var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
- thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
- }
- } else if (thatWords.length > 0xffff) {
- // Copy one word at a time
- for (var i = 0; i < thatSigBytes; i += 4) {
- thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
- }
- } else {
- // Copy all words at once
- thisWords.push.apply(thisWords, thatWords);
- }
- this.sigBytes += thatSigBytes;
-
- // Chainable
- return this;
- },
-
- /**
- * Removes insignificant bits.
- *
- * @example
- *
- * wordArray.clamp();
- */
- clamp: function () {
- // Shortcuts
- var words = this.words;
- var sigBytes = this.sigBytes;
-
- // Clamp
- words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
- words.length = Math.ceil(sigBytes / 4);
- },
-
- /**
- * Creates a copy of this word array.
- *
- * @return {WordArray} The clone.
- *
- * @example
- *
- * var clone = wordArray.clone();
- */
- clone: function () {
- var clone = Base.clone.call(this);
- clone.words = this.words.slice(0);
-
- return clone;
- },
-
- /**
- * Creates a word array filled with random bytes.
- *
- * @param {number} nBytes The number of random bytes to generate.
- *
- * @return {WordArray} The random word array.
- *
- * @static
- *
- * @example
- *
- * var wordArray = CryptoJS.lib.WordArray.random(16);
- */
- random: function (nBytes) {
- var words = [];
- for (var i = 0; i < nBytes; i += 4) {
- words.push((Math.random() * 0x100000000) | 0);
- }
-
- return new WordArray.init(words, nBytes);
- }
- });
-
- /**
- * Encoder namespace.
- */
- var C_enc = C.enc = {};
-
- /**
- * Hex encoding strategy.
- */
- var Hex = C_enc.Hex = {
- /**
- * Converts a word array to a hex string.
- *
- * @param {WordArray} wordArray The word array.
- *
- * @return {string} The hex string.
- *
- * @static
- *
- * @example
- *
- * var hexString = CryptoJS.enc.Hex.stringify(wordArray);
- */
- stringify: function (wordArray) {
- // Shortcuts
- var words = wordArray.words;
- var sigBytes = wordArray.sigBytes;
-
- // Convert
- var hexChars = [];
- for (var i = 0; i < sigBytes; i++) {
- var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
- hexChars.push((bite >>> 4).toString(16));
- hexChars.push((bite & 0x0f).toString(16));
- }
-
- return hexChars.join('');
- },
-
- /**
- * Converts a hex string to a word array.
- *
- * @param {string} hexStr The hex string.
- *
- * @return {WordArray} The word array.
- *
- * @static
- *
- * @example
- *
- * var wordArray = CryptoJS.enc.Hex.parse(hexString);
- */
- parse: function (hexStr) {
- // Shortcut
- var hexStrLength = hexStr.length;
-
- // Convert
- var words = [];
- for (var i = 0; i < hexStrLength; i += 2) {
- words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
- }
-
- return new WordArray.init(words, hexStrLength / 2);
- }
- };
-
- /**
- * Latin1 encoding strategy.
- */
- var Latin1 = C_enc.Latin1 = {
- /**
- * Converts a word array to a Latin1 string.
- *
- * @param {WordArray} wordArray The word array.
- *
- * @return {string} The Latin1 string.
- *
- * @static
- *
- * @example
- *
- * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
- */
- stringify: function (wordArray) {
- // Shortcuts
- var words = wordArray.words;
- var sigBytes = wordArray.sigBytes;
-
- // Convert
- var latin1Chars = [];
- for (var i = 0; i < sigBytes; i++) {
- var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
- latin1Chars.push(String.fromCharCode(bite));
- }
-
- return latin1Chars.join('');
- },
-
- /**
- * Converts a Latin1 string to a word array.
- *
- * @param {string} latin1Str The Latin1 string.
- *
- * @return {WordArray} The word array.
- *
- * @static
- *
- * @example
- *
- * var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
- */
- parse: function (latin1Str) {
- // Shortcut
- var latin1StrLength = latin1Str.length;
-
- // Convert
- var words = [];
- for (var i = 0; i < latin1StrLength; i++) {
- words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
- }
-
- return new WordArray.init(words, latin1StrLength);
- }
- };
-
- /**
- * UTF-8 encoding strategy.
- */
- var Utf8 = C_enc.Utf8 = {
- /**
- * Converts a word array to a UTF-8 string.
- *
- * @param {WordArray} wordArray The word array.
- *
- * @return {string} The UTF-8 string.
- *
- * @static
- *
- * @example
- *
- * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
- */
- stringify: function (wordArray) {
- try {
- return decodeURIComponent(escape(Latin1.stringify(wordArray)));
- } catch (e) {
- throw new Error('Malformed UTF-8 data');
- }
- },
-
- /**
- * Converts a UTF-8 string to a word array.
- *
- * @param {string} utf8Str The UTF-8 string.
- *
- * @return {WordArray} The word array.
- *
- * @static
- *
- * @example
- *
- * var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
- */
- parse: function (utf8Str) {
- return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
- }
- };
-
- /**
- * Abstract buffered block algorithm template.
- *
- * The property blockSize must be implemented in a concrete subtype.
- *
- * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
- */
- var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
- /**
- * Resets this block algorithm's data buffer to its initial state.
- *
- * @example
- *
- * bufferedBlockAlgorithm.reset();
- */
- reset: function () {
- // Initial values
- this._data = new WordArray.init();
- this._nDataBytes = 0;
- },
-
- /**
- * Adds new data to this block algorithm's buffer.
- *
- * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
- *
- * @example
- *
- * bufferedBlockAlgorithm._append('data');
- * bufferedBlockAlgorithm._append(wordArray);
- */
- _append: function (data) {
- // Convert string to WordArray, else assume WordArray already
- if (typeof data == 'string') {
- data = Utf8.parse(data);
- }
-
- // Append
- this._data.concat(data);
- this._nDataBytes += data.sigBytes;
- },
-
- /**
- * Processes available data blocks.
- *
- * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
- *
- * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
- *
- * @return {WordArray} The processed data.
- *
- * @example
- *
- * var processedData = bufferedBlockAlgorithm._process();
- * var processedData = bufferedBlockAlgorithm._process(!!'flush');
- */
- _process: function (doFlush) {
- // Shortcuts
- var data = this._data;
- var dataWords = data.words;
- var dataSigBytes = data.sigBytes;
- var blockSize = this.blockSize;
- var blockSizeBytes = blockSize * 4;
-
- // Count blocks ready
- var nBlocksReady = dataSigBytes / blockSizeBytes;
- if (doFlush) {
- // Round up to include partial blocks
- nBlocksReady = Math.ceil(nBlocksReady);
- } else {
- // Round down to include only full blocks,
- // less the number of blocks that must remain in the buffer
- nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
- }
-
- // Count words ready
- var nWordsReady = nBlocksReady * blockSize;
-
- // Count bytes ready
- var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
-
- // Process blocks
- if (nWordsReady) {
- for (var offset = 0; offset < nWordsReady; offset += blockSize) {
- // Perform concrete-algorithm logic
- this._doProcessBlock(dataWords, offset);
- }
-
- // Remove processed words
- var processedWords = dataWords.splice(0, nWordsReady);
- data.sigBytes -= nBytesReady;
- }
-
- // Return processed words
- return new WordArray.init(processedWords, nBytesReady);
- },
-
- /**
- * Creates a copy of this object.
- *
- * @return {Object} The clone.
- *
- * @example
- *
- * var clone = bufferedBlockAlgorithm.clone();
- */
- clone: function () {
- var clone = Base.clone.call(this);
- clone._data = this._data.clone();
-
- return clone;
- },
-
- _minBufferSize: 0
- });
-
- /**
- * Abstract hasher template.
- *
- * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
- */
- var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
- /**
- * Configuration options.
- */
- cfg: Base.extend(),
-
- /**
- * Initializes a newly created hasher.
- *
- * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
- *
- * @example
- *
- * var hasher = CryptoJS.algo.SHA256.create();
- */
- init: function (cfg) {
- // Apply config defaults
- this.cfg = this.cfg.extend(cfg);
-
- // Set initial values
- this.reset();
- },
-
- /**
- * Resets this hasher to its initial state.
- *
- * @example
- *
- * hasher.reset();
- */
- reset: function () {
- // Reset data buffer
- BufferedBlockAlgorithm.reset.call(this);
-
- // Perform concrete-hasher logic
- this._doReset();
- },
-
- /**
- * Updates this hasher with a message.
- *
- * @param {WordArray|string} messageUpdate The message to append.
- *
- * @return {Hasher} This hasher.
- *
- * @example
- *
- * hasher.update('message');
- * hasher.update(wordArray);
- */
- update: function (messageUpdate) {
- // Append
- this._append(messageUpdate);
-
- // Update the hash
- this._process();
-
- // Chainable
- return this;
- },
-
- /**
- * Finalizes the hash computation.
- * Note that the finalize operation is effectively a destructive, read-once operation.
- *
- * @param {WordArray|string} messageUpdate (Optional) A final message update.
- *
- * @return {WordArray} The hash.
- *
- * @example
- *
- * var hash = hasher.finalize();
- * var hash = hasher.finalize('message');
- * var hash = hasher.finalize(wordArray);
- */
- finalize: function (messageUpdate) {
- // Final message update
- if (messageUpdate) {
- this._append(messageUpdate);
- }
-
- // Perform concrete-hasher logic
- var hash = this._doFinalize();
-
- return hash;
- },
-
- blockSize: 512/32,
-
- /**
- * Creates a shortcut function to a hasher's object interface.
- *
- * @param {Hasher} hasher The hasher to create a helper for.
- *
- * @return {Function} The shortcut function.
- *
- * @static
- *
- * @example
- *
- * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
- */
- _createHelper: function (hasher) {
- return function (message, cfg) {
- return new hasher.init(cfg).finalize(message);
- };
- },
-
- /**
- * Creates a shortcut function to the HMAC's object interface.
- *
- * @param {Hasher} hasher The hasher to use in this HMAC helper.
- *
- * @return {Function} The shortcut function.
- *
- * @static
- *
- * @example
- *
- * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
- */
- _createHmacHelper: function (hasher) {
- return function (message, key) {
- return new C_algo.HMAC.init(hasher, key).finalize(message);
- };
- }
- });
-
- /**
- * Algorithm namespace.
- */
- var C_algo = C.algo = {};
-
- return C;
-}(Math));
-
-(function (Math) {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var WordArray = C_lib.WordArray;
- var Hasher = C_lib.Hasher;
- var C_algo = C.algo;
-
- // Initialization and round constants tables
- var H = [];
- var K = [];
-
- // Compute constants
- (function () {
- function isPrime(n) {
- var sqrtN = Math.sqrt(n);
- for (var factor = 2; factor <= sqrtN; factor++) {
- if (!(n % factor)) {
- return false;
- }
- }
-
- return true;
- }
-
- function getFractionalBits(n) {
- return ((n - (n | 0)) * 0x100000000) | 0;
- }
-
- var n = 2;
- var nPrime = 0;
- while (nPrime < 64) {
- if (isPrime(n)) {
- if (nPrime < 8) {
- H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
- }
- K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
-
- nPrime++;
- }
-
- n++;
- }
- }());
-
- // Reusable object
- var W = [];
-
- /**
- * SHA-256 hash algorithm.
- */
- var SHA256 = C_algo.SHA256 = Hasher.extend({
- _doReset: function () {
- this._hash = new WordArray.init(H.slice(0));
- },
-
- _doProcessBlock: function (M, offset) {
- // Shortcut
- var H = this._hash.words;
-
- // Working variables
- var a = H[0];
- var b = H[1];
- var c = H[2];
- var d = H[3];
- var e = H[4];
- var f = H[5];
- var g = H[6];
- var h = H[7];
-
- // Computation
- for (var i = 0; i < 64; i++) {
- if (i < 16) {
- W[i] = M[offset + i] | 0;
- } else {
- var gamma0x = W[i - 15];
- var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
- ((gamma0x << 14) | (gamma0x >>> 18)) ^
- (gamma0x >>> 3);
-
- var gamma1x = W[i - 2];
- var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
- ((gamma1x << 13) | (gamma1x >>> 19)) ^
- (gamma1x >>> 10);
-
- W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
- }
-
- var ch = (e & f) ^ (~e & g);
- var maj = (a & b) ^ (a & c) ^ (b & c);
-
- var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
- var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
-
- var t1 = h + sigma1 + ch + K[i] + W[i];
- var t2 = sigma0 + maj;
-
- h = g;
- g = f;
- f = e;
- e = (d + t1) | 0;
- d = c;
- c = b;
- b = a;
- a = (t1 + t2) | 0;
- }
-
- // Intermediate hash value
- H[0] = (H[0] + a) | 0;
- H[1] = (H[1] + b) | 0;
- H[2] = (H[2] + c) | 0;
- H[3] = (H[3] + d) | 0;
- H[4] = (H[4] + e) | 0;
- H[5] = (H[5] + f) | 0;
- H[6] = (H[6] + g) | 0;
- H[7] = (H[7] + h) | 0;
- },
-
- _doFinalize: function () {
- // Shortcuts
- var data = this._data;
- var dataWords = data.words;
-
- var nBitsTotal = this._nDataBytes * 8;
- var nBitsLeft = data.sigBytes * 8;
-
- // Add padding
- dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
- dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
- dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
- data.sigBytes = dataWords.length * 4;
-
- // Hash final blocks
- this._process();
-
- // Return final computed hash
- return this._hash;
- },
-
- clone: function () {
- var clone = Hasher.clone.call(this);
- clone._hash = this._hash.clone();
-
- return clone;
- }
- });
-
- /**
- * Shortcut function to the hasher's object interface.
- *
- * @param {WordArray|string} message The message to hash.
- *
- * @return {WordArray} The hash.
- *
- * @static
- *
- * @example
- *
- * var hash = CryptoJS.SHA256('message');
- * var hash = CryptoJS.SHA256(wordArray);
- */
- C.SHA256 = Hasher._createHelper(SHA256);
-
- /**
- * Shortcut function to the HMAC's object interface.
- *
- * @param {WordArray|string} message The message to hash.
- * @param {WordArray|string} key The secret key.
- *
- * @return {WordArray} The HMAC.
- *
- * @static
- *
- * @example
- *
- * var hmac = CryptoJS.HmacSHA256(message, key);
- */
- C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
-}(Math));
-
-(function () {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var Base = C_lib.Base;
- var C_enc = C.enc;
- var Utf8 = C_enc.Utf8;
- var C_algo = C.algo;
-
- /**
- * HMAC algorithm.
- */
- var HMAC = C_algo.HMAC = Base.extend({
- /**
- * Initializes a newly created HMAC.
- *
- * @param {Hasher} hasher The hash algorithm to use.
- * @param {WordArray|string} key The secret key.
- *
- * @example
- *
- * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
- */
- init: function (hasher, key) {
- // Init hasher
- hasher = this._hasher = new hasher.init();
-
- // Convert string to WordArray, else assume WordArray already
- if (typeof key == 'string') {
- key = Utf8.parse(key);
- }
-
- // Shortcuts
- var hasherBlockSize = hasher.blockSize;
- var hasherBlockSizeBytes = hasherBlockSize * 4;
-
- // Allow arbitrary length keys
- if (key.sigBytes > hasherBlockSizeBytes) {
- key = hasher.finalize(key);
- }
-
- // Clamp excess bits
- key.clamp();
-
- // Clone key for inner and outer pads
- var oKey = this._oKey = key.clone();
- var iKey = this._iKey = key.clone();
-
- // Shortcuts
- var oKeyWords = oKey.words;
- var iKeyWords = iKey.words;
-
- // XOR keys with pad constants
- for (var i = 0; i < hasherBlockSize; i++) {
- oKeyWords[i] ^= 0x5c5c5c5c;
- iKeyWords[i] ^= 0x36363636;
- }
- oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
-
- // Set initial values
- this.reset();
- },
-
- /**
- * Resets this HMAC to its initial state.
- *
- * @example
- *
- * hmacHasher.reset();
- */
- reset: function () {
- // Shortcut
- var hasher = this._hasher;
-
- // Reset
- hasher.reset();
- hasher.update(this._iKey);
- },
-
- /**
- * Updates this HMAC with a message.
- *
- * @param {WordArray|string} messageUpdate The message to append.
- *
- * @return {HMAC} This HMAC instance.
- *
- * @example
- *
- * hmacHasher.update('message');
- * hmacHasher.update(wordArray);
- */
- update: function (messageUpdate) {
- this._hasher.update(messageUpdate);
-
- // Chainable
- return this;
- },
-
- /**
- * Finalizes the HMAC computation.
- * Note that the finalize operation is effectively a destructive, read-once operation.
- *
- * @param {WordArray|string} messageUpdate (Optional) A final message update.
- *
- * @return {WordArray} The HMAC.
- *
- * @example
- *
- * var hmac = hmacHasher.finalize();
- * var hmac = hmacHasher.finalize('message');
- * var hmac = hmacHasher.finalize(wordArray);
- */
- finalize: function (messageUpdate) {
- // Shortcut
- var hasher = this._hasher;
-
- // Compute HMAC
- var innerHash = hasher.finalize(messageUpdate);
- hasher.reset();
- var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
-
- return hmac;
- }
- });
-}());
-
-(function () {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var WordArray = C_lib.WordArray;
- var C_enc = C.enc;
-
- /**
- * Base64 encoding strategy.
- */
- var Base64 = C_enc.Base64 = {
- /**
- * Converts a word array to a Base64 string.
- *
- * @param {WordArray} wordArray The word array.
- *
- * @return {string} The Base64 string.
- *
- * @static
- *
- * @example
- *
- * var base64String = CryptoJS.enc.Base64.stringify(wordArray);
- */
- stringify: function (wordArray) {
- // Shortcuts
- var words = wordArray.words;
- var sigBytes = wordArray.sigBytes;
- var map = this._map;
-
- // Clamp excess bits
- wordArray.clamp();
-
- // Convert
- var base64Chars = [];
- for (var i = 0; i < sigBytes; i += 3) {
- var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
- var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
- var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
-
- var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
-
- for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
- base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
- }
- }
-
- // Add padding
- var paddingChar = map.charAt(64);
- if (paddingChar) {
- while (base64Chars.length % 4) {
- base64Chars.push(paddingChar);
- }
- }
-
- return base64Chars.join('');
- },
-
- /**
- * Converts a Base64 string to a word array.
- *
- * @param {string} base64Str The Base64 string.
- *
- * @return {WordArray} The word array.
- *
- * @static
- *
- * @example
- *
- * var wordArray = CryptoJS.enc.Base64.parse(base64String);
- */
- parse: function (base64Str) {
- // Shortcuts
- var base64StrLength = base64Str.length;
- var map = this._map;
-
- // Ignore padding
- var paddingChar = map.charAt(64);
- if (paddingChar) {
- var paddingIndex = base64Str.indexOf(paddingChar);
- if (paddingIndex != -1) {
- base64StrLength = paddingIndex;
- }
- }
-
- // Convert
- var words = [];
- var nBytes = 0;
- for (var i = 0; i < base64StrLength; i++) {
- if (i % 4) {
- var bits1 = map.indexOf(base64Str.charAt(i - 1)) << ((i % 4) * 2);
- var bits2 = map.indexOf(base64Str.charAt(i)) >>> (6 - (i % 4) * 2);
- words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);
- nBytes++;
- }
- }
-
- return WordArray.create(words, nBytes);
- },
-
- _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
- };
-}());
-
-(function (Math) {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var WordArray = C_lib.WordArray;
- var Hasher = C_lib.Hasher;
- var C_algo = C.algo;
-
- // Constants table
- var T = [];
-
- // Compute constants
- (function () {
- for (var i = 0; i < 64; i++) {
- T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
- }
- }());
-
- /**
- * MD5 hash algorithm.
- */
- var MD5 = C_algo.MD5 = Hasher.extend({
- _doReset: function () {
- this._hash = new WordArray.init([
- 0x67452301, 0xefcdab89,
- 0x98badcfe, 0x10325476
- ]);
- },
-
- _doProcessBlock: function (M, offset) {
- // Swap endian
- for (var i = 0; i < 16; i++) {
- // Shortcuts
- var offset_i = offset + i;
- var M_offset_i = M[offset_i];
-
- M[offset_i] = (
- (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
- (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
- );
- }
-
- // Shortcuts
- var H = this._hash.words;
-
- var M_offset_0 = M[offset + 0];
- var M_offset_1 = M[offset + 1];
- var M_offset_2 = M[offset + 2];
- var M_offset_3 = M[offset + 3];
- var M_offset_4 = M[offset + 4];
- var M_offset_5 = M[offset + 5];
- var M_offset_6 = M[offset + 6];
- var M_offset_7 = M[offset + 7];
- var M_offset_8 = M[offset + 8];
- var M_offset_9 = M[offset + 9];
- var M_offset_10 = M[offset + 10];
- var M_offset_11 = M[offset + 11];
- var M_offset_12 = M[offset + 12];
- var M_offset_13 = M[offset + 13];
- var M_offset_14 = M[offset + 14];
- var M_offset_15 = M[offset + 15];
-
- // Working varialbes
- var a = H[0];
- var b = H[1];
- var c = H[2];
- var d = H[3];
-
- // Computation
- a = FF(a, b, c, d, M_offset_0, 7, T[0]);
- d = FF(d, a, b, c, M_offset_1, 12, T[1]);
- c = FF(c, d, a, b, M_offset_2, 17, T[2]);
- b = FF(b, c, d, a, M_offset_3, 22, T[3]);
- a = FF(a, b, c, d, M_offset_4, 7, T[4]);
- d = FF(d, a, b, c, M_offset_5, 12, T[5]);
- c = FF(c, d, a, b, M_offset_6, 17, T[6]);
- b = FF(b, c, d, a, M_offset_7, 22, T[7]);
- a = FF(a, b, c, d, M_offset_8, 7, T[8]);
- d = FF(d, a, b, c, M_offset_9, 12, T[9]);
- c = FF(c, d, a, b, M_offset_10, 17, T[10]);
- b = FF(b, c, d, a, M_offset_11, 22, T[11]);
- a = FF(a, b, c, d, M_offset_12, 7, T[12]);
- d = FF(d, a, b, c, M_offset_13, 12, T[13]);
- c = FF(c, d, a, b, M_offset_14, 17, T[14]);
- b = FF(b, c, d, a, M_offset_15, 22, T[15]);
-
- a = GG(a, b, c, d, M_offset_1, 5, T[16]);
- d = GG(d, a, b, c, M_offset_6, 9, T[17]);
- c = GG(c, d, a, b, M_offset_11, 14, T[18]);
- b = GG(b, c, d, a, M_offset_0, 20, T[19]);
- a = GG(a, b, c, d, M_offset_5, 5, T[20]);
- d = GG(d, a, b, c, M_offset_10, 9, T[21]);
- c = GG(c, d, a, b, M_offset_15, 14, T[22]);
- b = GG(b, c, d, a, M_offset_4, 20, T[23]);
- a = GG(a, b, c, d, M_offset_9, 5, T[24]);
- d = GG(d, a, b, c, M_offset_14, 9, T[25]);
- c = GG(c, d, a, b, M_offset_3, 14, T[26]);
- b = GG(b, c, d, a, M_offset_8, 20, T[27]);
- a = GG(a, b, c, d, M_offset_13, 5, T[28]);
- d = GG(d, a, b, c, M_offset_2, 9, T[29]);
- c = GG(c, d, a, b, M_offset_7, 14, T[30]);
- b = GG(b, c, d, a, M_offset_12, 20, T[31]);
-
- a = HH(a, b, c, d, M_offset_5, 4, T[32]);
- d = HH(d, a, b, c, M_offset_8, 11, T[33]);
- c = HH(c, d, a, b, M_offset_11, 16, T[34]);
- b = HH(b, c, d, a, M_offset_14, 23, T[35]);
- a = HH(a, b, c, d, M_offset_1, 4, T[36]);
- d = HH(d, a, b, c, M_offset_4, 11, T[37]);
- c = HH(c, d, a, b, M_offset_7, 16, T[38]);
- b = HH(b, c, d, a, M_offset_10, 23, T[39]);
- a = HH(a, b, c, d, M_offset_13, 4, T[40]);
- d = HH(d, a, b, c, M_offset_0, 11, T[41]);
- c = HH(c, d, a, b, M_offset_3, 16, T[42]);
- b = HH(b, c, d, a, M_offset_6, 23, T[43]);
- a = HH(a, b, c, d, M_offset_9, 4, T[44]);
- d = HH(d, a, b, c, M_offset_12, 11, T[45]);
- c = HH(c, d, a, b, M_offset_15, 16, T[46]);
- b = HH(b, c, d, a, M_offset_2, 23, T[47]);
-
- a = II(a, b, c, d, M_offset_0, 6, T[48]);
- d = II(d, a, b, c, M_offset_7, 10, T[49]);
- c = II(c, d, a, b, M_offset_14, 15, T[50]);
- b = II(b, c, d, a, M_offset_5, 21, T[51]);
- a = II(a, b, c, d, M_offset_12, 6, T[52]);
- d = II(d, a, b, c, M_offset_3, 10, T[53]);
- c = II(c, d, a, b, M_offset_10, 15, T[54]);
- b = II(b, c, d, a, M_offset_1, 21, T[55]);
- a = II(a, b, c, d, M_offset_8, 6, T[56]);
- d = II(d, a, b, c, M_offset_15, 10, T[57]);
- c = II(c, d, a, b, M_offset_6, 15, T[58]);
- b = II(b, c, d, a, M_offset_13, 21, T[59]);
- a = II(a, b, c, d, M_offset_4, 6, T[60]);
- d = II(d, a, b, c, M_offset_11, 10, T[61]);
- c = II(c, d, a, b, M_offset_2, 15, T[62]);
- b = II(b, c, d, a, M_offset_9, 21, T[63]);
-
- // Intermediate hash value
- H[0] = (H[0] + a) | 0;
- H[1] = (H[1] + b) | 0;
- H[2] = (H[2] + c) | 0;
- H[3] = (H[3] + d) | 0;
- },
-
- _doFinalize: function () {
- // Shortcuts
- var data = this._data;
- var dataWords = data.words;
-
- var nBitsTotal = this._nDataBytes * 8;
- var nBitsLeft = data.sigBytes * 8;
-
- // Add padding
- dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
-
- var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
- var nBitsTotalL = nBitsTotal;
- dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
- (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
- (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00)
- );
- dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
- (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
- (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00)
- );
-
- data.sigBytes = (dataWords.length + 1) * 4;
-
- // Hash final blocks
- this._process();
-
- // Shortcuts
- var hash = this._hash;
- var H = hash.words;
-
- // Swap endian
- for (var i = 0; i < 4; i++) {
- // Shortcut
- var H_i = H[i];
-
- H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
- (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
- }
-
- // Return final computed hash
- return hash;
- },
-
- clone: function () {
- var clone = Hasher.clone.call(this);
- clone._hash = this._hash.clone();
-
- return clone;
- }
- });
-
- function FF(a, b, c, d, x, s, t) {
- var n = a + ((b & c) | (~b & d)) + x + t;
- return ((n << s) | (n >>> (32 - s))) + b;
- }
-
- function GG(a, b, c, d, x, s, t) {
- var n = a + ((b & d) | (c & ~d)) + x + t;
- return ((n << s) | (n >>> (32 - s))) + b;
- }
-
- function HH(a, b, c, d, x, s, t) {
- var n = a + (b ^ c ^ d) + x + t;
- return ((n << s) | (n >>> (32 - s))) + b;
- }
-
- function II(a, b, c, d, x, s, t) {
- var n = a + (c ^ (b | ~d)) + x + t;
- return ((n << s) | (n >>> (32 - s))) + b;
- }
-
- /**
- * Shortcut function to the hasher's object interface.
- *
- * @param {WordArray|string} message The message to hash.
- *
- * @return {WordArray} The hash.
- *
- * @static
- *
- * @example
- *
- * var hash = CryptoJS.MD5('message');
- * var hash = CryptoJS.MD5(wordArray);
- */
- C.MD5 = Hasher._createHelper(MD5);
-
- /**
- * Shortcut function to the HMAC's object interface.
- *
- * @param {WordArray|string} message The message to hash.
- * @param {WordArray|string} key The secret key.
- *
- * @return {WordArray} The HMAC.
- *
- * @static
- *
- * @example
- *
- * var hmac = CryptoJS.HmacMD5(message, key);
- */
- C.HmacMD5 = Hasher._createHmacHelper(MD5);
-}(Math));
-
-(function () {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var Base = C_lib.Base;
- var WordArray = C_lib.WordArray;
- var C_algo = C.algo;
- var MD5 = C_algo.MD5;
-
- /**
- * This key derivation function is meant to conform with EVP_BytesToKey.
- * www.openssl.org/docs/crypto/EVP_BytesToKey.html
- */
- var EvpKDF = C_algo.EvpKDF = Base.extend({
- /**
- * Configuration options.
- *
- * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
- * @property {Hasher} hasher The hash algorithm to use. Default: MD5
- * @property {number} iterations The number of iterations to perform. Default: 1
- */
- cfg: Base.extend({
- keySize: 128/32,
- hasher: MD5,
- iterations: 1
- }),
-
- /**
- * Initializes a newly created key derivation function.
- *
- * @param {Object} cfg (Optional) The configuration options to use for the derivation.
- *
- * @example
- *
- * var kdf = CryptoJS.algo.EvpKDF.create();
- * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
- * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
- */
- init: function (cfg) {
- this.cfg = this.cfg.extend(cfg);
- },
-
- /**
- * Derives a key from a password.
- *
- * @param {WordArray|string} password The password.
- * @param {WordArray|string} salt A salt.
- *
- * @return {WordArray} The derived key.
- *
- * @example
- *
- * var key = kdf.compute(password, salt);
- */
- compute: function (password, salt) {
- // Shortcut
- var cfg = this.cfg;
-
- // Init hasher
- var hasher = cfg.hasher.create();
-
- // Initial values
- var derivedKey = WordArray.create();
-
- // Shortcuts
- var derivedKeyWords = derivedKey.words;
- var keySize = cfg.keySize;
- var iterations = cfg.iterations;
-
- // Generate key
- while (derivedKeyWords.length < keySize) {
- if (block) {
- hasher.update(block);
- }
- var block = hasher.update(password).finalize(salt);
- hasher.reset();
-
- // Iterations
- for (var i = 1; i < iterations; i++) {
- block = hasher.finalize(block);
- hasher.reset();
- }
-
- derivedKey.concat(block);
- }
- derivedKey.sigBytes = keySize * 4;
-
- return derivedKey;
- }
- });
-
- /**
- * Derives a key from a password.
- *
- * @param {WordArray|string} password The password.
- * @param {WordArray|string} salt A salt.
- * @param {Object} cfg (Optional) The configuration options to use for this computation.
- *
- * @return {WordArray} The derived key.
- *
- * @static
- *
- * @example
- *
- * var key = CryptoJS.EvpKDF(password, salt);
- * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
- * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
- */
- C.EvpKDF = function (password, salt, cfg) {
- return EvpKDF.create(cfg).compute(password, salt);
- };
-}());
-
-/**
- * Cipher core components.
- */
-CryptoJS.lib.Cipher || (function (undefined) {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var Base = C_lib.Base;
- var WordArray = C_lib.WordArray;
- var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
- var C_enc = C.enc;
- var Utf8 = C_enc.Utf8;
- var Base64 = C_enc.Base64;
- var C_algo = C.algo;
- var EvpKDF = C_algo.EvpKDF;
-
- /**
- * Abstract base cipher template.
- *
- * @property {number} keySize This cipher's key size. Default: 4 (128 bits)
- * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
- * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
- * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
- */
- var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
- /**
- * Configuration options.
- *
- * @property {WordArray} iv The IV to use for this operation.
- */
- cfg: Base.extend(),
-
- /**
- * Creates this cipher in encryption mode.
- *
- * @param {WordArray} key The key.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @return {Cipher} A cipher instance.
- *
- * @static
- *
- * @example
- *
- * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
- */
- createEncryptor: function (key, cfg) {
- return this.create(this._ENC_XFORM_MODE, key, cfg);
- },
-
- /**
- * Creates this cipher in decryption mode.
- *
- * @param {WordArray} key The key.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @return {Cipher} A cipher instance.
- *
- * @static
- *
- * @example
- *
- * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
- */
- createDecryptor: function (key, cfg) {
- return this.create(this._DEC_XFORM_MODE, key, cfg);
- },
-
- /**
- * Initializes a newly created cipher.
- *
- * @param {number} xformMode Either the encryption or decryption transormation mode constant.
- * @param {WordArray} key The key.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @example
- *
- * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
- */
- init: function (xformMode, key, cfg) {
- // Apply config defaults
- this.cfg = this.cfg.extend(cfg);
-
- // Store transform mode and key
- this._xformMode = xformMode;
- this._key = key;
-
- // Set initial values
- this.reset();
- },
-
- /**
- * Resets this cipher to its initial state.
- *
- * @example
- *
- * cipher.reset();
- */
- reset: function () {
- // Reset data buffer
- BufferedBlockAlgorithm.reset.call(this);
-
- // Perform concrete-cipher logic
- this._doReset();
- },
-
- /**
- * Adds data to be encrypted or decrypted.
- *
- * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
- *
- * @return {WordArray} The data after processing.
- *
- * @example
- *
- * var encrypted = cipher.process('data');
- * var encrypted = cipher.process(wordArray);
- */
- process: function (dataUpdate) {
- // Append
- this._append(dataUpdate);
-
- // Process available blocks
- return this._process();
- },
-
- /**
- * Finalizes the encryption or decryption process.
- * Note that the finalize operation is effectively a destructive, read-once operation.
- *
- * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
- *
- * @return {WordArray} The data after final processing.
- *
- * @example
- *
- * var encrypted = cipher.finalize();
- * var encrypted = cipher.finalize('data');
- * var encrypted = cipher.finalize(wordArray);
- */
- finalize: function (dataUpdate) {
- // Final data update
- if (dataUpdate) {
- this._append(dataUpdate);
- }
-
- // Perform concrete-cipher logic
- var finalProcessedData = this._doFinalize();
-
- return finalProcessedData;
- },
-
- keySize: 128/32,
-
- ivSize: 128/32,
-
- _ENC_XFORM_MODE: 1,
-
- _DEC_XFORM_MODE: 2,
-
- /**
- * Creates shortcut functions to a cipher's object interface.
- *
- * @param {Cipher} cipher The cipher to create a helper for.
- *
- * @return {Object} An object with encrypt and decrypt shortcut functions.
- *
- * @static
- *
- * @example
- *
- * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
- */
- _createHelper: (function () {
- function selectCipherStrategy(key) {
- if (typeof key == 'string') {
- return PasswordBasedCipher;
- } else {
- return SerializableCipher;
- }
- }
-
- return function (cipher) {
- return {
- encrypt: function (message, key, cfg) {
- return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
- },
-
- decrypt: function (ciphertext, key, cfg) {
- return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
- }
- };
- };
- }())
- });
-
- /**
- * Abstract base stream cipher template.
- *
- * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
- */
- var StreamCipher = C_lib.StreamCipher = Cipher.extend({
- _doFinalize: function () {
- // Process partial blocks
- var finalProcessedBlocks = this._process(!!'flush');
-
- return finalProcessedBlocks;
- },
-
- blockSize: 1
- });
-
- /**
- * Mode namespace.
- */
- var C_mode = C.mode = {};
-
- /**
- * Abstract base block cipher mode template.
- */
- var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
- /**
- * Creates this mode for encryption.
- *
- * @param {Cipher} cipher A block cipher instance.
- * @param {Array} iv The IV words.
- *
- * @static
- *
- * @example
- *
- * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
- */
- createEncryptor: function (cipher, iv) {
- return this.Encryptor.create(cipher, iv);
- },
-
- /**
- * Creates this mode for decryption.
- *
- * @param {Cipher} cipher A block cipher instance.
- * @param {Array} iv The IV words.
- *
- * @static
- *
- * @example
- *
- * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
- */
- createDecryptor: function (cipher, iv) {
- return this.Decryptor.create(cipher, iv);
- },
-
- /**
- * Initializes a newly created mode.
- *
- * @param {Cipher} cipher A block cipher instance.
- * @param {Array} iv The IV words.
- *
- * @example
- *
- * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
- */
- init: function (cipher, iv) {
- this._cipher = cipher;
- this._iv = iv;
- }
- });
-
- /**
- * Cipher Block Chaining mode.
- */
- var CBC = C_mode.CBC = (function () {
- /**
- * Abstract base CBC mode.
- */
- var CBC = BlockCipherMode.extend();
-
- /**
- * CBC encryptor.
- */
- CBC.Encryptor = CBC.extend({
- /**
- * Processes the data block at offset.
- *
- * @param {Array} words The data words to operate on.
- * @param {number} offset The offset where the block starts.
- *
- * @example
- *
- * mode.processBlock(data.words, offset);
- */
- processBlock: function (words, offset) {
- // Shortcuts
- var cipher = this._cipher;
- var blockSize = cipher.blockSize;
-
- // XOR and encrypt
- xorBlock.call(this, words, offset, blockSize);
- cipher.encryptBlock(words, offset);
-
- // Remember this block to use with next block
- this._prevBlock = words.slice(offset, offset + blockSize);
- }
- });
-
- /**
- * CBC decryptor.
- */
- CBC.Decryptor = CBC.extend({
- /**
- * Processes the data block at offset.
- *
- * @param {Array} words The data words to operate on.
- * @param {number} offset The offset where the block starts.
- *
- * @example
- *
- * mode.processBlock(data.words, offset);
- */
- processBlock: function (words, offset) {
- // Shortcuts
- var cipher = this._cipher;
- var blockSize = cipher.blockSize;
-
- // Remember this block to use with next block
- var thisBlock = words.slice(offset, offset + blockSize);
-
- // Decrypt and XOR
- cipher.decryptBlock(words, offset);
- xorBlock.call(this, words, offset, blockSize);
-
- // This block becomes the previous block
- this._prevBlock = thisBlock;
- }
- });
-
- function xorBlock(words, offset, blockSize) {
- // Shortcut
- var iv = this._iv;
-
- // Choose mixing block
- if (iv) {
- var block = iv;
-
- // Remove IV for subsequent blocks
- this._iv = undefined;
- } else {
- var block = this._prevBlock;
- }
-
- // XOR blocks
- for (var i = 0; i < blockSize; i++) {
- words[offset + i] ^= block[i];
- }
- }
-
- return CBC;
- }());
-
- /**
- * Padding namespace.
- */
- var C_pad = C.pad = {};
-
- /**
- * PKCS #5/7 padding strategy.
- */
- var Pkcs7 = C_pad.Pkcs7 = {
- /**
- * Pads data using the algorithm defined in PKCS #5/7.
- *
- * @param {WordArray} data The data to pad.
- * @param {number} blockSize The multiple that the data should be padded to.
- *
- * @static
- *
- * @example
- *
- * CryptoJS.pad.Pkcs7.pad(wordArray, 4);
- */
- pad: function (data, blockSize) {
- // Shortcut
- var blockSizeBytes = blockSize * 4;
-
- // Count padding bytes
- var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
-
- // Create padding word
- var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
-
- // Create padding
- var paddingWords = [];
- for (var i = 0; i < nPaddingBytes; i += 4) {
- paddingWords.push(paddingWord);
- }
- var padding = WordArray.create(paddingWords, nPaddingBytes);
-
- // Add padding
- data.concat(padding);
- },
-
- /**
- * Unpads data that had been padded using the algorithm defined in PKCS #5/7.
- *
- * @param {WordArray} data The data to unpad.
- *
- * @static
- *
- * @example
- *
- * CryptoJS.pad.Pkcs7.unpad(wordArray);
- */
- unpad: function (data) {
- // Get number of padding bytes from last byte
- var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
-
- // Remove padding
- data.sigBytes -= nPaddingBytes;
- }
- };
-
- /**
- * Abstract base block cipher template.
- *
- * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
- */
- var BlockCipher = C_lib.BlockCipher = Cipher.extend({
- /**
- * Configuration options.
- *
- * @property {Mode} mode The block mode to use. Default: CBC
- * @property {Padding} padding The padding strategy to use. Default: Pkcs7
- */
- cfg: Cipher.cfg.extend({
- mode: CBC,
- padding: Pkcs7
- }),
-
- reset: function () {
- // Reset cipher
- Cipher.reset.call(this);
-
- // Shortcuts
- var cfg = this.cfg;
- var iv = cfg.iv;
- var mode = cfg.mode;
-
- // Reset block mode
- if (this._xformMode == this._ENC_XFORM_MODE) {
- var modeCreator = mode.createEncryptor;
- } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
- var modeCreator = mode.createDecryptor;
-
- // Keep at least one block in the buffer for unpadding
- this._minBufferSize = 1;
- }
- this._mode = modeCreator.call(mode, this, iv && iv.words);
- },
-
- _doProcessBlock: function (words, offset) {
- this._mode.processBlock(words, offset);
- },
-
- _doFinalize: function () {
- // Shortcut
- var padding = this.cfg.padding;
-
- // Finalize
- if (this._xformMode == this._ENC_XFORM_MODE) {
- // Pad data
- padding.pad(this._data, this.blockSize);
-
- // Process final blocks
- var finalProcessedBlocks = this._process(!!'flush');
- } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
- // Process final blocks
- var finalProcessedBlocks = this._process(!!'flush');
-
- // Unpad data
- padding.unpad(finalProcessedBlocks);
- }
-
- return finalProcessedBlocks;
- },
-
- blockSize: 128/32
- });
-
- /**
- * A collection of cipher parameters.
- *
- * @property {WordArray} ciphertext The raw ciphertext.
- * @property {WordArray} key The key to this ciphertext.
- * @property {WordArray} iv The IV used in the ciphering operation.
- * @property {WordArray} salt The salt used with a key derivation function.
- * @property {Cipher} algorithm The cipher algorithm.
- * @property {Mode} mode The block mode used in the ciphering operation.
- * @property {Padding} padding The padding scheme used in the ciphering operation.
- * @property {number} blockSize The block size of the cipher.
- * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
- */
- var CipherParams = C_lib.CipherParams = Base.extend({
- /**
- * Initializes a newly created cipher params object.
- *
- * @param {Object} cipherParams An object with any of the possible cipher parameters.
- *
- * @example
- *
- * var cipherParams = CryptoJS.lib.CipherParams.create({
- * ciphertext: ciphertextWordArray,
- * key: keyWordArray,
- * iv: ivWordArray,
- * salt: saltWordArray,
- * algorithm: CryptoJS.algo.AES,
- * mode: CryptoJS.mode.CBC,
- * padding: CryptoJS.pad.PKCS7,
- * blockSize: 4,
- * formatter: CryptoJS.format.OpenSSL
- * });
- */
- init: function (cipherParams) {
- this.mixIn(cipherParams);
- },
-
- /**
- * Converts this cipher params object to a string.
- *
- * @param {Format} formatter (Optional) The formatting strategy to use.
- *
- * @return {string} The stringified cipher params.
- *
- * @throws Error If neither the formatter nor the default formatter is set.
- *
- * @example
- *
- * var string = cipherParams + '';
- * var string = cipherParams.toString();
- * var string = cipherParams.toString(CryptoJS.format.OpenSSL);
- */
- toString: function (formatter) {
- return (formatter || this.formatter).stringify(this);
- }
- });
-
- /**
- * Format namespace.
- */
- var C_format = C.format = {};
-
- /**
- * OpenSSL formatting strategy.
- */
- var OpenSSLFormatter = C_format.OpenSSL = {
- /**
- * Converts a cipher params object to an OpenSSL-compatible string.
- *
- * @param {CipherParams} cipherParams The cipher params object.
- *
- * @return {string} The OpenSSL-compatible string.
- *
- * @static
- *
- * @example
- *
- * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
- */
- stringify: function (cipherParams) {
- // Shortcuts
- var ciphertext = cipherParams.ciphertext;
- var salt = cipherParams.salt;
-
- // Format
- if (salt) {
- var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
- } else {
- var wordArray = ciphertext;
- }
-
- return wordArray.toString(Base64);
- },
-
- /**
- * Converts an OpenSSL-compatible string to a cipher params object.
- *
- * @param {string} openSSLStr The OpenSSL-compatible string.
- *
- * @return {CipherParams} The cipher params object.
- *
- * @static
- *
- * @example
- *
- * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
- */
- parse: function (openSSLStr) {
- // Parse base64
- var ciphertext = Base64.parse(openSSLStr);
-
- // Shortcut
- var ciphertextWords = ciphertext.words;
-
- // Test for salt
- if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
- // Extract salt
- var salt = WordArray.create(ciphertextWords.slice(2, 4));
-
- // Remove salt from ciphertext
- ciphertextWords.splice(0, 4);
- ciphertext.sigBytes -= 16;
- }
-
- return CipherParams.create({ ciphertext: ciphertext, salt: salt });
- }
- };
-
- /**
- * A cipher wrapper that returns ciphertext as a serializable cipher params object.
- */
- var SerializableCipher = C_lib.SerializableCipher = Base.extend({
- /**
- * Configuration options.
- *
- * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
- */
- cfg: Base.extend({
- format: OpenSSLFormatter
- }),
-
- /**
- * Encrypts a message.
- *
- * @param {Cipher} cipher The cipher algorithm to use.
- * @param {WordArray|string} message The message to encrypt.
- * @param {WordArray} key The key.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @return {CipherParams} A cipher params object.
- *
- * @static
- *
- * @example
- *
- * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
- * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
- * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
- */
- encrypt: function (cipher, message, key, cfg) {
- // Apply config defaults
- cfg = this.cfg.extend(cfg);
-
- // Encrypt
- var encryptor = cipher.createEncryptor(key, cfg);
- var ciphertext = encryptor.finalize(message);
-
- // Shortcut
- var cipherCfg = encryptor.cfg;
-
- // Create and return serializable cipher params
- return CipherParams.create({
- ciphertext: ciphertext,
- key: key,
- iv: cipherCfg.iv,
- algorithm: cipher,
- mode: cipherCfg.mode,
- padding: cipherCfg.padding,
- blockSize: cipher.blockSize,
- formatter: cfg.format
- });
- },
-
- /**
- * Decrypts serialized ciphertext.
- *
- * @param {Cipher} cipher The cipher algorithm to use.
- * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
- * @param {WordArray} key The key.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @return {WordArray} The plaintext.
- *
- * @static
- *
- * @example
- *
- * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
- * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
- */
- decrypt: function (cipher, ciphertext, key, cfg) {
- // Apply config defaults
- cfg = this.cfg.extend(cfg);
-
- // Convert string to CipherParams
- ciphertext = this._parse(ciphertext, cfg.format);
-
- // Decrypt
- var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
-
- return plaintext;
- },
-
- /**
- * Converts serialized ciphertext to CipherParams,
- * else assumed CipherParams already and returns ciphertext unchanged.
- *
- * @param {CipherParams|string} ciphertext The ciphertext.
- * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
- *
- * @return {CipherParams} The unserialized ciphertext.
- *
- * @static
- *
- * @example
- *
- * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
- */
- _parse: function (ciphertext, format) {
- if (typeof ciphertext == 'string') {
- return format.parse(ciphertext, this);
- } else {
- return ciphertext;
- }
- }
- });
-
- /**
- * Key derivation function namespace.
- */
- var C_kdf = C.kdf = {};
-
- /**
- * OpenSSL key derivation function.
- */
- var OpenSSLKdf = C_kdf.OpenSSL = {
- /**
- * Derives a key and IV from a password.
- *
- * @param {string} password The password to derive from.
- * @param {number} keySize The size in words of the key to generate.
- * @param {number} ivSize The size in words of the IV to generate.
- * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
- *
- * @return {CipherParams} A cipher params object with the key, IV, and salt.
- *
- * @static
- *
- * @example
- *
- * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
- * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
- */
- execute: function (password, keySize, ivSize, salt) {
- // Generate random salt
- if (!salt) {
- salt = WordArray.random(64/8);
- }
-
- // Derive key and IV
- var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
-
- // Separate key and IV
- var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
- key.sigBytes = keySize * 4;
-
- // Return params
- return CipherParams.create({ key: key, iv: iv, salt: salt });
- }
- };
-
- /**
- * A serializable cipher wrapper that derives the key from a password,
- * and returns ciphertext as a serializable cipher params object.
- */
- var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
- /**
- * Configuration options.
- *
- * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
- */
- cfg: SerializableCipher.cfg.extend({
- kdf: OpenSSLKdf
- }),
-
- /**
- * Encrypts a message using a password.
- *
- * @param {Cipher} cipher The cipher algorithm to use.
- * @param {WordArray|string} message The message to encrypt.
- * @param {string} password The password.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @return {CipherParams} A cipher params object.
- *
- * @static
- *
- * @example
- *
- * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
- * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
- */
- encrypt: function (cipher, message, password, cfg) {
- // Apply config defaults
- cfg = this.cfg.extend(cfg);
-
- // Derive key and other params
- var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
-
- // Add IV to config
- cfg.iv = derivedParams.iv;
-
- // Encrypt
- var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
-
- // Mix in derived params
- ciphertext.mixIn(derivedParams);
-
- return ciphertext;
- },
-
- /**
- * Decrypts serialized ciphertext using a password.
- *
- * @param {Cipher} cipher The cipher algorithm to use.
- * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
- * @param {string} password The password.
- * @param {Object} cfg (Optional) The configuration options to use for this operation.
- *
- * @return {WordArray} The plaintext.
- *
- * @static
- *
- * @example
- *
- * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
- * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
- */
- decrypt: function (cipher, ciphertext, password, cfg) {
- // Apply config defaults
- cfg = this.cfg.extend(cfg);
-
- // Convert string to CipherParams
- ciphertext = this._parse(ciphertext, cfg.format);
-
- // Derive key and other params
- var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
-
- // Add IV to config
- cfg.iv = derivedParams.iv;
-
- // Decrypt
- var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
-
- return plaintext;
- }
- });
-}());
-
-(function () {
- // Shortcuts
- var C = CryptoJS;
- var C_lib = C.lib;
- var BlockCipher = C_lib.BlockCipher;
- var C_algo = C.algo;
-
- // Lookup tables
- var SBOX = [];
- var INV_SBOX = [];
- var SUB_MIX_0 = [];
- var SUB_MIX_1 = [];
- var SUB_MIX_2 = [];
- var SUB_MIX_3 = [];
- var INV_SUB_MIX_0 = [];
- var INV_SUB_MIX_1 = [];
- var INV_SUB_MIX_2 = [];
- var INV_SUB_MIX_3 = [];
-
- // Compute lookup tables
- (function () {
- // Compute double table
- var d = [];
- for (var i = 0; i < 256; i++) {
- if (i < 128) {
- d[i] = i << 1;
- } else {
- d[i] = (i << 1) ^ 0x11b;
- }
- }
-
- // Walk GF(2^8)
- var x = 0;
- var xi = 0;
- for (var i = 0; i < 256; i++) {
- // Compute sbox
- var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
- sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
- SBOX[x] = sx;
- INV_SBOX[sx] = x;
-
- // Compute multiplication
- var x2 = d[x];
- var x4 = d[x2];
- var x8 = d[x4];
-
- // Compute sub bytes, mix columns tables
- var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
- SUB_MIX_0[x] = (t << 24) | (t >>> 8);
- SUB_MIX_1[x] = (t << 16) | (t >>> 16);
- SUB_MIX_2[x] = (t << 8) | (t >>> 24);
- SUB_MIX_3[x] = t;
-
- // Compute inv sub bytes, inv mix columns tables
- var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
- INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
- INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
- INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
- INV_SUB_MIX_3[sx] = t;
-
- // Compute next counter
- if (!x) {
- x = xi = 1;
- } else {
- x = x2 ^ d[d[d[x8 ^ x2]]];
- xi ^= d[d[xi]];
- }
- }
- }());
-
- // Precomputed Rcon lookup
- var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
-
- /**
- * AES block cipher algorithm.
- */
- var AES = C_algo.AES = BlockCipher.extend({
- _doReset: function () {
- // Shortcuts
- var key = this._key;
- var keyWords = key.words;
- var keySize = key.sigBytes / 4;
-
- // Compute number of rounds
- var nRounds = this._nRounds = keySize + 6
-
- // Compute number of key schedule rows
- var ksRows = (nRounds + 1) * 4;
-
- // Compute key schedule
- var keySchedule = this._keySchedule = [];
- for (var ksRow = 0; ksRow < ksRows; ksRow++) {
- if (ksRow < keySize) {
- keySchedule[ksRow] = keyWords[ksRow];
- } else {
- var t = keySchedule[ksRow - 1];
-
- if (!(ksRow % keySize)) {
- // Rot word
- t = (t << 8) | (t >>> 24);
-
- // Sub word
- t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
-
- // Mix Rcon
- t ^= RCON[(ksRow / keySize) | 0] << 24;
- } else if (keySize > 6 && ksRow % keySize == 4) {
- // Sub word
- t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
- }
-
- keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
- }
- }
-
- // Compute inv key schedule
- var invKeySchedule = this._invKeySchedule = [];
- for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
- var ksRow = ksRows - invKsRow;
-
- if (invKsRow % 4) {
- var t = keySchedule[ksRow];
- } else {
- var t = keySchedule[ksRow - 4];
- }
-
- if (invKsRow < 4 || ksRow <= 4) {
- invKeySchedule[invKsRow] = t;
- } else {
- invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
- INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
- }
- }
- },
-
- encryptBlock: function (M, offset) {
- this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
- },
-
- decryptBlock: function (M, offset) {
- // Swap 2nd and 4th rows
- var t = M[offset + 1];
- M[offset + 1] = M[offset + 3];
- M[offset + 3] = t;
-
- this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
-
- // Inv swap 2nd and 4th rows
- var t = M[offset + 1];
- M[offset + 1] = M[offset + 3];
- M[offset + 3] = t;
- },
-
- _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
- // Shortcut
- var nRounds = this._nRounds;
-
- // Get input, add round key
- var s0 = M[offset] ^ keySchedule[0];
- var s1 = M[offset + 1] ^ keySchedule[1];
- var s2 = M[offset + 2] ^ keySchedule[2];
- var s3 = M[offset + 3] ^ keySchedule[3];
-
- // Key schedule row counter
- var ksRow = 4;
-
- // Rounds
- for (var round = 1; round < nRounds; round++) {
- // Shift rows, sub bytes, mix columns, add round key
- var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
- var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
- var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
- var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
-
- // Update state
- s0 = t0;
- s1 = t1;
- s2 = t2;
- s3 = t3;
- }
-
- // Shift rows, sub bytes, add round key
- var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
- var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
- var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
- var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
-
- // Set output
- M[offset] = t0;
- M[offset + 1] = t1;
- M[offset + 2] = t2;
- M[offset + 3] = t3;
- },
-
- keySize: 256/32
- });
-
- /**
- * Shortcut functions to the cipher's object interface.
- *
- * @example
- *
- * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
- * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
- */
- C.AES = BlockCipher._createHelper(AES);
-}());
-
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-;(function() {
- 'use strict';
- // Test for webcrypto support, polyfill if needed.
- if (window.crypto.subtle === undefined || window.crypto.subtle === null) {
- window.crypto.subtle = (function () {
- var StaticArrayBufferProto = new ArrayBuffer().__proto__;
- function assertIsArrayBuffer(thing) {
- if (thing !== Object(thing) || thing.__proto__ != StaticArrayBufferProto)
- throw new Error("Needed a ArrayBuffer");
- }
-
- // Synchronous implementation functions for polyfilling webcrypto
- // All inputs/outputs are arraybuffers!
- function HmacSHA256(key, input) {
- assertIsArrayBuffer(key);
- assertIsArrayBuffer(input);
- return CryptoJS.HmacSHA256(
- CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(input)),
- CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(key))
- );
- };
-
- function encryptAESCBC(plaintext, key, iv) {
- assertIsArrayBuffer(plaintext);
- assertIsArrayBuffer(key);
- assertIsArrayBuffer(iv);
- return CryptoJS.AES.encrypt(
- CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(plaintext)),
- CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(key)),
- { iv: CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(iv)) }
- ).ciphertext;
- };
-
- function decryptAESCBC(ciphertext, key, iv) {
- assertIsArrayBuffer(ciphertext);
- assertIsArrayBuffer(key);
- assertIsArrayBuffer(iv);
- return CryptoJS.AES.decrypt(
- btoa(axolotlInternal.utils.convertToString(ciphertext)),
- CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(key)),
- { iv: CryptoJS.enc.Latin1.parse(axolotlInternal.utils.convertToString(iv)) }
- );
- };
-
- // utility function for connecting front and back ends via promises
- // Takes an implementation function and 0 or more arguments
- function promise(implementation) {
- var args = Array.prototype.slice.call(arguments);
- args.shift();
- return new Promise(function(resolve) {
- var wordArray = implementation.apply(this, args);
- // convert 32bit WordArray to array buffer
- var buffer = new ArrayBuffer(wordArray.sigBytes);
- var view = new DataView(buffer);
- for(var i = 0; i*4 < buffer.byteLength; i++) {
- view.setInt32(i*4, wordArray.words[i]);
- }
- resolve(buffer);
- });
- };
-
- return {
- encrypt: function(algorithm, key, data) {
- if (algorithm.name === "AES-CBC")
- return promise(encryptAESCBC, data, key, algorithm.iv.buffer || algorithm.iv);
- },
-
- decrypt: function(algorithm, key, data) {
- if (algorithm.name === "AES-CBC")
- return promise(decryptAESCBC, data, key, algorithm.iv.buffer || algorithm.iv);
- },
-
- sign: function(algorithm, key, data) {
- if (algorithm.name === "HMAC" && algorithm.hash === "SHA-256")
- return promise(HmacSHA256, key, data);
- },
-
- importKey: function(format, key, algorithm, extractable, usages) {
- return new Promise(function(resolve,reject){ resolve(key); });
- }
- };
- })();
- } // if !window.crypto.subtle
-})();
-
-})();
-/*
- Copyright 2013 Daniel Wirtz
- Copyright 2009 The Closure Library Authors. All Rights Reserved.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS-IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/**
- * @license Long.js (c) 2013 Daniel Wirtz
- * Released under the Apache License, Version 2.0
- * see: https://github.com/dcodeIO/Long.js for details
- */
-(function(global) {
- "use strict";
-
- /**
- * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
- * See the from* functions below for more convenient ways of constructing Longs.
- * @exports Long
- * @class A Long class for representing a 64 bit two's-complement integer value.
- * @param {number} low The low (signed) 32 bits of the long
- * @param {number} high The high (signed) 32 bits of the long
- * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
- * @constructor
- */
- var Long = function(low, high, unsigned) {
-
- /**
- * The low 32 bits as a signed value.
- * @type {number}
- * @expose
- */
- this.low = low|0;
-
- /**
- * The high 32 bits as a signed value.
- * @type {number}
- * @expose
- */
- this.high = high|0;
-
- /**
- * Whether unsigned or not.
- * @type {boolean}
- * @expose
- */
- this.unsigned = !!unsigned;
- };
-
- // The internal representation of a long is the two given signed, 32-bit values.
- // We use 32-bit pieces because these are the size of integers on which
- // Javascript performs bit-operations. For operations like addition and
- // multiplication, we split each number into 16 bit pieces, which can easily be
- // multiplied within Javascript's floating-point representation without overflow
- // or change in sign.
- //
- // In the algorithms below, we frequently reduce the negative case to the
- // positive case by negating the input(s) and then post-processing the result.
- // Note that we must ALWAYS check specially whether those values are MIN_VALUE
- // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
- // a positive number, it overflows back into a negative). Not handling this
- // case would often result in infinite recursion.
- //
- // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
- // methods on which they depend.
-
- /**
- * Tests if the specified object is a Long.
- * @param {*} obj Object
- * @returns {boolean}
- * @expose
- */
- Long.isLong = function(obj) {
- return (obj && obj instanceof Long) === true;
- };
-
- /**
- * A cache of the Long representations of small integer values.
- * @type {!Object}
- * @inner
- */
- var INT_CACHE = {};
-
- /**
- * A cache of the Long representations of small unsigned integer values.
- * @type {!Object}
- * @inner
- */
- var UINT_CACHE = {};
-
- /**
- * Returns a Long representing the given 32 bit integer value.
- * @param {number} value The 32 bit integer in question
- * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
- * @returns {!Long} The corresponding Long value
- * @expose
- */
- Long.fromInt = function(value, unsigned) {
- var obj, cachedObj;
- if (!unsigned) {
- value = value | 0;
- if (-128 <= value && value < 128) {
- cachedObj = INT_CACHE[value];
- if (cachedObj)
- return cachedObj;
- }
- obj = new Long(value, value < 0 ? -1 : 0, false);
- if (-128 <= value && value < 128)
- INT_CACHE[value] = obj;
- return obj;
- } else {
- value = value >>> 0;
- if (0 <= value && value < 256) {
- cachedObj = UINT_CACHE[value];
- if (cachedObj)
- return cachedObj;
- }
- obj = new Long(value, (value | 0) < 0 ? -1 : 0, true);
- if (0 <= value && value < 256)
- UINT_CACHE[value] = obj;
- return obj;
- }
- };
-
- /**
- * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
- * @param {number} value The number in question
- * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
- * @returns {!Long} The corresponding Long value
- * @expose
- */
- Long.fromNumber = function(value, unsigned) {
- unsigned = !!unsigned;
- if (isNaN(value) || !isFinite(value))
- return Long.ZERO;
- if (!unsigned && value <= -TWO_PWR_63_DBL)
- return Long.MIN_VALUE;
- if (!unsigned && value + 1 >= TWO_PWR_63_DBL)
- return Long.MAX_VALUE;
- if (unsigned && value >= TWO_PWR_64_DBL)
- return Long.MAX_UNSIGNED_VALUE;
- if (value < 0)
- return Long.fromNumber(-value, unsigned).negate();
- return new Long((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
- };
-
- /**
- * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
- * assumed to use 32 bits.
- * @param {number} lowBits The low 32 bits
- * @param {number} highBits The high 32 bits
- * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
- * @returns {!Long} The corresponding Long value
- * @expose
- */
- Long.fromBits = function(lowBits, highBits, unsigned) {
- return new Long(lowBits, highBits, unsigned);
- };
-
- /**
- * Returns a Long representation of the given string, written using the specified radix.
- * @param {string} str The textual representation of the Long
- * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
- * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
- * @returns {!Long} The corresponding Long value
- * @expose
- */
- Long.fromString = function(str, unsigned, radix) {
- if (str.length === 0)
- throw Error('number format error: empty string');
- if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
- return Long.ZERO;
- if (typeof unsigned === 'number') // For goog.math.long compatibility
- radix = unsigned,
- unsigned = false;
- radix = radix || 10;
- if (radix < 2 || 36 < radix)
- throw Error('radix out of range: ' + radix);
-
- var p;
- if ((p = str.indexOf('-')) > 0)
- throw Error('number format error: interior "-" character: ' + str);
- else if (p === 0)
- return Long.fromString(str.substring(1), unsigned, radix).negate();
-
- // Do several (8) digits each time through the loop, so as to
- // minimize the calls to the very expensive emulated div.
- var radixToPower = Long.fromNumber(Math.pow(radix, 8));
-
- var result = Long.ZERO;
- for (var i = 0; i < str.length; i += 8) {
- var size = Math.min(8, str.length - i);
- var value = parseInt(str.substring(i, i + size), radix);
- if (size < 8) {
- var power = Long.fromNumber(Math.pow(radix, size));
- result = result.multiply(power).add(Long.fromNumber(value));
- } else {
- result = result.multiply(radixToPower);
- result = result.add(Long.fromNumber(value));
- }
- }
- result.unsigned = unsigned;
- return result;
- };
-
- /**
- * Converts the specified value to a Long.
- * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
- * @returns {!Long}
- * @expose
- */
- Long.fromValue = function(val) {
- if (typeof val === 'number')
- return Long.fromNumber(val);
- if (typeof val === 'string')
- return Long.fromString(val);
- if (Long.isLong(val))
- return val;
- // Throws for not an object (undefined, null):
- return new Long(val.low, val.high, val.unsigned);
- };
-
- // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
- // no runtime penalty for these.
-
- /**
- * @type {number}
- * @const
- * @inner
- */
- var TWO_PWR_16_DBL = 1 << 16;
-
- /**
- * @type {number}
- * @const
- * @inner
- */
- var TWO_PWR_24_DBL = 1 << 24;
-
- /**
- * @type {number}
- * @const
- * @inner
- */
- var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
-
- /**
- * @type {number}
- * @const
- * @inner
- */
- var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
-
- /**
- * @type {number}
- * @const
- * @inner
- */
- var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
-
- /**
- * @type {!Long}
- * @const
- * @inner
- */
- var TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL);
-
- /**
- * Signed zero.
- * @type {!Long}
- * @expose
- */
- Long.ZERO = Long.fromInt(0);
-
- /**
- * Unsigned zero.
- * @type {!Long}
- * @expose
- */
- Long.UZERO = Long.fromInt(0, true);
-
- /**
- * Signed one.
- * @type {!Long}
- * @expose
- */
- Long.ONE = Long.fromInt(1);
-
- /**
- * Unsigned one.
- * @type {!Long}
- * @expose
- */
- Long.UONE = Long.fromInt(1, true);
-
- /**
- * Signed negative one.
- * @type {!Long}
- * @expose
- */
- Long.NEG_ONE = Long.fromInt(-1);
-
- /**
- * Maximum signed value.
- * @type {!Long}
- * @expose
- */
- Long.MAX_VALUE = Long.fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
-
- /**
- * Maximum unsigned value.
- * @type {!Long}
- * @expose
- */
- Long.MAX_UNSIGNED_VALUE = Long.fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
-
- /**
- * Minimum signed value.
- * @type {!Long}
- * @expose
- */
- Long.MIN_VALUE = Long.fromBits(0, 0x80000000|0, false);
-
- /**
- * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
- * @returns {number}
- * @expose
- */
- Long.prototype.toInt = function() {
- return this.unsigned ? this.low >>> 0 : this.low;
- };
-
- /**
- * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
- * @returns {number}
- * @expose
- */
- Long.prototype.toNumber = function() {
- if (this.unsigned) {
- return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
- }
- return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
- };
-
- /**
- * Converts the Long to a string written in the specified radix.
- * @param {number=} radix Radix (2-36), defaults to 10
- * @returns {string}
- * @override
- * @throws {RangeError} If `radix` is out of range
- * @expose
- */
- Long.prototype.toString = function(radix) {
- radix = radix || 10;
- if (radix < 2 || 36 < radix)
- throw RangeError('radix out of range: ' + radix);
- if (this.isZero())
- return '0';
- var rem;
- if (this.isNegative()) { // Unsigned Longs are never negative
- if (this.equals(Long.MIN_VALUE)) {
- // We need to change the Long value before it can be negated, so we remove
- // the bottom-most digit in this base and then recurse to do the rest.
- var radixLong = Long.fromNumber(radix);
- var div = this.div(radixLong);
- rem = div.multiply(radixLong).subtract(this);
- return div.toString(radix) + rem.toInt().toString(radix);
- } else
- return '-' + this.negate().toString(radix);
- }
-
- // Do several (6) digits each time through the loop, so as to
- // minimize the calls to the very expensive emulated div.
- var radixToPower = Long.fromNumber(Math.pow(radix, 6), this.unsigned);
- rem = this;
- var result = '';
- while (true) {
- var remDiv = rem.div(radixToPower),
- intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0,
- digits = intval.toString(radix);
- rem = remDiv;
- if (rem.isZero())
- return digits + result;
- else {
- while (digits.length < 6)
- digits = '0' + digits;
- result = '' + digits + result;
- }
- }
- };
-
- /**
- * Gets the high 32 bits as a signed integer.
- * @returns {number} Signed high bits
- * @expose
- */
- Long.prototype.getHighBits = function() {
- return this.high;
- };
-
- /**
- * Gets the high 32 bits as an unsigned integer.
- * @returns {number} Unsigned high bits
- * @expose
- */
- Long.prototype.getHighBitsUnsigned = function() {
- return this.high >>> 0;
- };
-
- /**
- * Gets the low 32 bits as a signed integer.
- * @returns {number} Signed low bits
- * @expose
- */
- Long.prototype.getLowBits = function() {
- return this.low;
- };
-
- /**
- * Gets the low 32 bits as an unsigned integer.
- * @returns {number} Unsigned low bits
- * @expose
- */
- Long.prototype.getLowBitsUnsigned = function() {
- return this.low >>> 0;
- };
-
- /**
- * Gets the number of bits needed to represent the absolute value of this Long.
- * @returns {number}
- * @expose
- */
- Long.prototype.getNumBitsAbs = function() {
- if (this.isNegative()) // Unsigned Longs are never negative
- return this.equals(Long.MIN_VALUE) ? 64 : this.negate().getNumBitsAbs();
- var val = this.high != 0 ? this.high : this.low;
- for (var bit = 31; bit > 0; bit--)
- if ((val & (1 << bit)) != 0)
- break;
- return this.high != 0 ? bit + 33 : bit + 1;
- };
-
- /**
- * Tests if this Long's value equals zero.
- * @returns {boolean}
- * @expose
- */
- Long.prototype.isZero = function() {
- return this.high === 0 && this.low === 0;
- };
-
- /**
- * Tests if this Long's value is negative.
- * @returns {boolean}
- * @expose
- */
- Long.prototype.isNegative = function() {
- return !this.unsigned && this.high < 0;
- };
-
- /**
- * Tests if this Long's value is positive.
- * @returns {boolean}
- * @expose
- */
- Long.prototype.isPositive = function() {
- return this.unsigned || this.high >= 0;
- };
-
- /**
- * Tests if this Long's value is odd.
- * @returns {boolean}
- * @expose
- */
- Long.prototype.isOdd = function() {
- return (this.low & 1) === 1;
- };
-
- /**
- * Tests if this Long's value is even.
- * @returns {boolean}
- * @expose
- */
- Long.prototype.isEven = function() {
- return (this.low & 1) === 0;
- };
-
- /**
- * Tests if this Long's value equals the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- * @expose
- */
- Long.prototype.equals = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
- return false;
- return this.high === other.high && this.low === other.low;
- };
-
- /**
- * Tests if this Long's value differs from the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- * @expose
- */
- Long.prototype.notEquals = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return !this.equals(other);
- };
-
- /**
- * Tests if this Long's value is less than the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- * @expose
- */
- Long.prototype.lessThan = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return this.compare(other) < 0;
- };
-
- /**
- * Tests if this Long's value is less than or equal the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- * @expose
- */
- Long.prototype.lessThanOrEqual = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return this.compare(other) <= 0;
- };
-
- /**
- * Tests if this Long's value is greater than the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- * @expose
- */
- Long.prototype.greaterThan = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return this.compare(other) > 0;
- };
-
- /**
- * Tests if this Long's value is greater than or equal the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- * @expose
- */
- Long.prototype.greaterThanOrEqual = function(other) {
- return this.compare(other) >= 0;
- };
-
- /**
- * Compares this Long's value with the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {number} 0 if they are the same, 1 if the this is greater and -1
- * if the given one is greater
- * @expose
- */
- Long.prototype.compare = function(other) {
- if (this.equals(other))
- return 0;
- var thisNeg = this.isNegative(),
- otherNeg = other.isNegative();
- if (thisNeg && !otherNeg)
- return -1;
- if (!thisNeg && otherNeg)
- return 1;
- // At this point the sign bits are the same
- if (!this.unsigned)
- return this.subtract(other).isNegative() ? -1 : 1;
- // Both are positive if at least one is unsigned
- return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
- };
-
- /**
- * Negates this Long's value.
- * @returns {!Long} Negated Long
- * @expose
- */
- Long.prototype.negate = function() {
- if (!this.unsigned && this.equals(Long.MIN_VALUE))
- return Long.MIN_VALUE;
- return this.not().add(Long.ONE);
- };
-
- /**
- * Returns the sum of this and the specified Long.
- * @param {!Long|number|string} addend Addend
- * @returns {!Long} Sum
- * @expose
- */
- Long.prototype.add = function(addend) {
- if (!Long.isLong(addend))
- addend = Long.fromValue(addend);
-
- // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
-
- var a48 = this.high >>> 16;
- var a32 = this.high & 0xFFFF;
- var a16 = this.low >>> 16;
- var a00 = this.low & 0xFFFF;
-
- var b48 = addend.high >>> 16;
- var b32 = addend.high & 0xFFFF;
- var b16 = addend.low >>> 16;
- var b00 = addend.low & 0xFFFF;
-
- var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
- c00 += a00 + b00;
- c16 += c00 >>> 16;
- c00 &= 0xFFFF;
- c16 += a16 + b16;
- c32 += c16 >>> 16;
- c16 &= 0xFFFF;
- c32 += a32 + b32;
- c48 += c32 >>> 16;
- c32 &= 0xFFFF;
- c48 += a48 + b48;
- c48 &= 0xFFFF;
- return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
- };
-
- /**
- * Returns the difference of this and the specified Long.
- * @param {!Long|number|string} subtrahend Subtrahend
- * @returns {!Long} Difference
- * @expose
- */
- Long.prototype.subtract = function(subtrahend) {
- if (!Long.isLong(subtrahend))
- subtrahend = Long.fromValue(subtrahend);
- return this.add(subtrahend.negate());
- };
-
- /**
- * Returns the product of this and the specified Long.
- * @param {!Long|number|string} multiplier Multiplier
- * @returns {!Long} Product
- * @expose
- */
- Long.prototype.multiply = function(multiplier) {
- if (this.isZero())
- return Long.ZERO;
- if (!Long.isLong(multiplier))
- multiplier = Long.fromValue(multiplier);
- if (multiplier.isZero())
- return Long.ZERO;
- if (this.equals(Long.MIN_VALUE))
- return multiplier.isOdd() ? Long.MIN_VALUE : Long.ZERO;
- if (multiplier.equals(Long.MIN_VALUE))
- return this.isOdd() ? Long.MIN_VALUE : Long.ZERO;
-
- if (this.isNegative()) {
- if (multiplier.isNegative())
- return this.negate().multiply(multiplier.negate());
- else
- return this.negate().multiply(multiplier).negate();
- } else if (multiplier.isNegative())
- return this.multiply(multiplier.negate()).negate();
-
- // If both longs are small, use float multiplication
- if (this.lessThan(TWO_PWR_24) && multiplier.lessThan(TWO_PWR_24))
- return Long.fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
-
- // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
- // We can skip products that would overflow.
-
- var a48 = this.high >>> 16;
- var a32 = this.high & 0xFFFF;
- var a16 = this.low >>> 16;
- var a00 = this.low & 0xFFFF;
-
- var b48 = multiplier.high >>> 16;
- var b32 = multiplier.high & 0xFFFF;
- var b16 = multiplier.low >>> 16;
- var b00 = multiplier.low & 0xFFFF;
-
- var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
- c00 += a00 * b00;
- c16 += c00 >>> 16;
- c00 &= 0xFFFF;
- c16 += a16 * b00;
- c32 += c16 >>> 16;
- c16 &= 0xFFFF;
- c16 += a00 * b16;
- c32 += c16 >>> 16;
- c16 &= 0xFFFF;
- c32 += a32 * b00;
- c48 += c32 >>> 16;
- c32 &= 0xFFFF;
- c32 += a16 * b16;
- c48 += c32 >>> 16;
- c32 &= 0xFFFF;
- c32 += a00 * b32;
- c48 += c32 >>> 16;
- c32 &= 0xFFFF;
- c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
- c48 &= 0xFFFF;
- return Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
- };
-
- /**
- * Returns this Long divided by the specified.
- * @param {!Long|number|string} divisor Divisor
- * @returns {!Long} Quotient
- * @expose
- */
- Long.prototype.div = function(divisor) {
- if (!Long.isLong(divisor))
- divisor = Long.fromValue(divisor);
- if (divisor.isZero())
- throw(new Error('division by zero'));
- if (this.isZero())
- return this.unsigned ? Long.UZERO : Long.ZERO;
- var approx, rem, res;
- if (this.equals(Long.MIN_VALUE)) {
- if (divisor.equals(Long.ONE) || divisor.equals(Long.NEG_ONE))
- return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
- else if (divisor.equals(Long.MIN_VALUE))
- return Long.ONE;
- else {
- // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
- var halfThis = this.shiftRight(1);
- approx = halfThis.div(divisor).shiftLeft(1);
- if (approx.equals(Long.ZERO)) {
- return divisor.isNegative() ? Long.ONE : Long.NEG_ONE;
- } else {
- rem = this.subtract(divisor.multiply(approx));
- res = approx.add(rem.div(divisor));
- return res;
- }
- }
- } else if (divisor.equals(Long.MIN_VALUE))
- return this.unsigned ? Long.UZERO : Long.ZERO;
- if (this.isNegative()) {
- if (divisor.isNegative())
- return this.negate().div(divisor.negate());
- return this.negate().div(divisor).negate();
- } else if (divisor.isNegative())
- return this.div(divisor.negate()).negate();
-
- // Repeat the following until the remainder is less than other: find a
- // floating-point that approximates remainder / other *from below*, add this
- // into the result, and subtract it from the remainder. It is critical that
- // the approximate value is less than or equal to the real value so that the
- // remainder never becomes negative.
- res = Long.ZERO;
- rem = this;
- while (rem.greaterThanOrEqual(divisor)) {
- // Approximate the result of division. This may be a little greater or
- // smaller than the actual value.
- approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
-
- // We will tweak the approximate result by changing it in the 48-th digit or
- // the smallest non-fractional digit, whichever is larger.
- var log2 = Math.ceil(Math.log(approx) / Math.LN2),
- delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48),
-
- // Decrease the approximation until it is smaller than the remainder. Note
- // that if it is too large, the product overflows and is negative.
- approxRes = Long.fromNumber(approx),
- approxRem = approxRes.multiply(divisor);
- while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
- approx -= delta;
- approxRes = Long.fromNumber(approx, this.unsigned);
- approxRem = approxRes.multiply(divisor);
- }
-
- // We know the answer can't be zero... and actually, zero would cause
- // infinite recursion since we would make no progress.
- if (approxRes.isZero())
- approxRes = Long.ONE;
-
- res = res.add(approxRes);
- rem = rem.subtract(approxRem);
- }
- return res;
- };
-
- /**
- * Returns this Long modulo the specified.
- * @param {!Long|number|string} divisor Divisor
- * @returns {!Long} Remainder
- * @expose
- */
- Long.prototype.modulo = function(divisor) {
- if (!Long.isLong(divisor))
- divisor = Long.fromValue(divisor);
- return this.subtract(this.div(divisor).multiply(divisor));
- };
-
- /**
- * Returns the bitwise NOT of this Long.
- * @returns {!Long}
- * @expose
- */
- Long.prototype.not = function() {
- return Long.fromBits(~this.low, ~this.high, this.unsigned);
- };
-
- /**
- * Returns the bitwise AND of this Long and the specified.
- * @param {!Long|number|string} other Other Long
- * @returns {!Long}
- * @expose
- */
- Long.prototype.and = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return Long.fromBits(this.low & other.low, this.high & other.high, this.unsigned);
- };
-
- /**
- * Returns the bitwise OR of this Long and the specified.
- * @param {!Long|number|string} other Other Long
- * @returns {!Long}
- * @expose
- */
- Long.prototype.or = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return Long.fromBits(this.low | other.low, this.high | other.high, this.unsigned);
- };
-
- /**
- * Returns the bitwise XOR of this Long and the given one.
- * @param {!Long|number|string} other Other Long
- * @returns {!Long}
- * @expose
- */
- Long.prototype.xor = function(other) {
- if (!Long.isLong(other))
- other = Long.fromValue(other);
- return Long.fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
- };
-
- /**
- * Returns this Long with bits shifted to the left by the given amount.
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- * @expose
- */
- Long.prototype.shiftLeft = function(numBits) {
- if (Long.isLong(numBits))
- numBits = numBits.toInt();
- if ((numBits &= 63) === 0)
- return this;
- else if (numBits < 32)
- return Long.fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
- else
- return Long.fromBits(0, this.low << (numBits - 32), this.unsigned);
- };
-
- /**
- * Returns this Long with bits arithmetically shifted to the right by the given amount.
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- * @expose
- */
- Long.prototype.shiftRight = function(numBits) {
- if (Long.isLong(numBits))
- numBits = numBits.toInt();
- if ((numBits &= 63) === 0)
- return this;
- else if (numBits < 32)
- return Long.fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
- else
- return Long.fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
- };
-
- /**
- * Returns this Long with bits logically shifted to the right by the given amount.
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- * @expose
- */
- Long.prototype.shiftRightUnsigned = function(numBits) {
- if (Long.isLong(numBits))
- numBits = numBits.toInt();
- numBits &= 63;
- if (numBits === 0)
- return this;
- else {
- var high = this.high;
- if (numBits < 32) {
- var low = this.low;
- return Long.fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
- } else if (numBits === 32)
- return Long.fromBits(high, 0, this.unsigned);
- else
- return Long.fromBits(high >>> (numBits - 32), 0, this.unsigned);
- }
- };
-
- /**
- * Converts this Long to signed.
- * @returns {!Long} Signed long
- * @expose
- */
- Long.prototype.toSigned = function() {
- if (!this.unsigned)
- return this;
- return new Long(this.low, this.high, false);
- };
-
- /**
- * Converts this Long to unsigned.
- * @returns {!Long} Unsigned long
- * @expose
- */
- Long.prototype.toUnsigned = function() {
- if (this.unsigned)
- return this;
- return new Long(this.low, this.high, true);
- };
-
- /* CommonJS */ if (typeof require === 'function' && typeof module === 'object' && module && typeof exports === 'object' && exports)
- module["exports"] = Long;
- /* AMD */ else if (typeof define === 'function' && define["amd"])
- define(function() { return Long; });
- /* Global */ else
- (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = Long;
-
-})(this);
-
-/*
- Copyright 2013-2014 Daniel Wirtz
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/**
- * @license ByteBuffer.js (c) 2013-2014 Daniel Wirtz
- * This version of ByteBuffer.js uses an ArrayBuffer (AB) as its backing buffer and is compatible with modern browsers.
- * Released under the Apache License, Version 2.0
- * see: https://github.com/dcodeIO/ByteBuffer.js for details
- */ //
-(function(global) {
- "use strict";
-
- /**
- * @param {function(new: Long, number, number, boolean=)=} Long
- * @returns {function(new: ByteBuffer, number=, boolean=, boolean=)}}
- * @inner
- */
- function loadByteBuffer(Long) {
-
- /**
- * Constructs a new ByteBuffer.
- * @class The swiss army knife for binary data in JavaScript.
- * @exports ByteBuffer
- * @constructor
- * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @expose
- */
- var ByteBuffer = function(capacity, littleEndian, noAssert) {
- if (typeof capacity === 'undefined') capacity = ByteBuffer.DEFAULT_CAPACITY;
- if (typeof littleEndian === 'undefined') littleEndian = ByteBuffer.DEFAULT_ENDIAN;
- if (typeof noAssert === 'undefined') noAssert = ByteBuffer.DEFAULT_NOASSERT;
- if (!noAssert) {
- capacity = capacity | 0;
- if (capacity < 0)
- throw RangeError("Illegal capacity");
- littleEndian = !!littleEndian;
- noAssert = !!noAssert;
- }
-
- /**
- * Backing buffer.
- * @type {!ArrayBuffer}
- * @expose
- */
- this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
-
- /**
- * Data view to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
- * @type {?DataView}
- * @expose
- */
- this.view = capacity === 0 ? null : new DataView(this.buffer);
-
- /**
- * Absolute read/write offset.
- * @type {number}
- * @expose
- * @see ByteBuffer#flip
- * @see ByteBuffer#clear
- */
- this.offset = 0;
-
- /**
- * Marked offset.
- * @type {number}
- * @expose
- * @see ByteBuffer#mark
- * @see ByteBuffer#reset
- */
- this.markedOffset = -1;
-
- /**
- * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
- * @type {number}
- * @expose
- * @see ByteBuffer#flip
- * @see ByteBuffer#clear
- */
- this.limit = capacity;
-
- /**
- * Whether to use little endian byte order, defaults to `false` for big endian.
- * @type {boolean}
- * @expose
- */
- this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : false;
-
- /**
- * Whether to skip assertions of offsets and values, defaults to `false`.
- * @type {boolean}
- * @expose
- */
- this.noAssert = !!noAssert;
- };
-
- /**
- * ByteBuffer version.
- * @type {string}
- * @const
- * @expose
- */
- ByteBuffer.VERSION = "3.5.4";
-
- /**
- * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
- * @type {boolean}
- * @const
- * @expose
- */
- ByteBuffer.LITTLE_ENDIAN = true;
-
- /**
- * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
- * @type {boolean}
- * @const
- * @expose
- */
- ByteBuffer.BIG_ENDIAN = false;
-
- /**
- * Default initial capacity of `16`.
- * @type {number}
- * @expose
- */
- ByteBuffer.DEFAULT_CAPACITY = 16;
-
- /**
- * Default endianess of `false` for big endian.
- * @type {boolean}
- * @expose
- */
- ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
-
- /**
- * Default no assertions flag of `false`.
- * @type {boolean}
- * @expose
- */
- ByteBuffer.DEFAULT_NOASSERT = false;
-
- /**
- * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
- * and int64 support is not available.
- * @type {?Long}
- * @const
- * @see https://github.com/dcodeIO/Long.js
- * @expose
- */
- ByteBuffer.Long = Long || null;
-
- /**
- * @alias ByteBuffer.prototype
- * @inner
- */
- var ByteBufferPrototype = ByteBuffer.prototype;
-
- // helpers
-
- /**
- * @type {!ArrayBuffer}
- * @inner
- */
- var EMPTY_BUFFER = new ArrayBuffer(0);
-
- /**
- * String.fromCharCode reference for compile-time renaming.
- * @type {function(...number):string}
- * @inner
- */
- var stringFromCharCode = String.fromCharCode;
-
- /**
- * Creates a source function for a string.
- * @param {string} s String to read from
- * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
- * no more characters left.
- * @throws {TypeError} If the argument is invalid
- * @inner
- */
- function stringSource(s) {
- var i=0; return function() {
- return i < s.length ? s.charCodeAt(i++) : null;
- };
- }
-
- /**
- * Creates a destination function for a string.
- * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
- * Returns the final string when called without arguments.
- * @inner
- */
- function stringDestination() {
- var cs = [], ps = []; return function() {
- if (arguments.length === 0)
- return ps.join('')+stringFromCharCode.apply(String, cs);
- if (cs.length + arguments.length > 1024)
- ps.push(stringFromCharCode.apply(String, cs)),
- cs.length = 0;
- Array.prototype.push.apply(cs, arguments);
- };
- }
-
- /**
- * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
- * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer}
- * @expose
- */
- ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
- return new ByteBuffer(capacity, littleEndian, noAssert);
- };
-
- /**
- * Concatenates multiple ByteBuffers into one.
- * @param {!Array.} buffers Buffers to concatenate
- * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
- * defaults to "utf8")
- * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
- * to {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} Concatenated ByteBuffer
- * @expose
- */
- ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
- if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
- noAssert = littleEndian;
- littleEndian = encoding;
- encoding = undefined;
- }
- var capacity = 0;
- for (var i=0, k=buffers.length, length; i 0) capacity += length;
- }
- if (capacity === 0)
- return new ByteBuffer(0, littleEndian, noAssert);
- var bb = new ByteBuffer(capacity, littleEndian, noAssert),
- bi;
- var view = new Uint8Array(bb.buffer);
- i=0; while (i} buffer Anything that can be wrapped
- * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
- * "utf8")
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
- * @expose
- */
- ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
- if (typeof encoding !== 'string') {
- noAssert = littleEndian;
- littleEndian = encoding;
- encoding = undefined;
- }
- if (typeof buffer === 'string') {
- if (typeof encoding === 'undefined')
- encoding = "utf8";
- switch (encoding) {
- case "base64":
- return ByteBuffer.fromBase64(buffer, littleEndian);
- case "hex":
- return ByteBuffer.fromHex(buffer, littleEndian);
- case "binary":
- return ByteBuffer.fromBinary(buffer, littleEndian);
- case "utf8":
- return ByteBuffer.fromUTF8(buffer, littleEndian);
- case "debug":
- return ByteBuffer.fromDebug(buffer, littleEndian);
- default:
- throw Error("Unsupported encoding: "+encoding);
- }
- }
- if (buffer === null || typeof buffer !== 'object')
- throw TypeError("Illegal buffer");
- var bb;
- if (ByteBuffer.isByteBuffer(buffer)) {
- bb = ByteBufferPrototype.clone.call(buffer);
- bb.markedOffset = -1;
- return bb;
- }
- if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
- bb = new ByteBuffer(0, littleEndian, noAssert);
- if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
- bb.buffer = buffer.buffer;
- bb.offset = buffer.byteOffset;
- bb.limit = buffer.byteOffset + buffer.length;
- bb.view = buffer.length > 0 ? new DataView(buffer.buffer) : null;
- }
- } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
- bb = new ByteBuffer(0, littleEndian, noAssert);
- if (buffer.byteLength > 0) {
- bb.buffer = buffer;
- bb.offset = 0;
- bb.limit = buffer.byteLength;
- bb.view = buffer.byteLength > 0 ? new DataView(buffer) : null;
- }
- } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
- bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
- bb.limit = buffer.length;
- for (i=0; i>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 1;
- var capacity0 = this.buffer.byteLength;
- if (offset > capacity0)
- this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
- offset -= 1;
- this.view.setInt8(offset, value);
- if (relative) this.offset += 1;
- return this;
- };
-
- /**
- * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
- * @function
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
-
- /**
- * Reads an 8bit signed integer.
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
- * @returns {number} Value read
- * @expose
- */
- ByteBufferPrototype.readInt8 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 1 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getInt8(offset);
- if (relative) this.offset += 1;
- return value;
- };
-
- /**
- * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
- * @function
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
- * @returns {number} Value read
- * @expose
- */
- ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
-
- /**
- * Writes an 8bit unsigned integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeUint8 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value >>>= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 1;
- var capacity1 = this.buffer.byteLength;
- if (offset > capacity1)
- this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
- offset -= 1;
- this.view.setUint8(offset, value);
- if (relative) this.offset += 1;
- return this;
- };
-
- /**
- * Reads an 8bit unsigned integer.
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
- * @returns {number} Value read
- * @expose
- */
- ByteBufferPrototype.readUint8 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 1 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getUint8(offset);
- if (relative) this.offset += 1;
- return value;
- };
-
- // types/ints/int16
-
- /**
- * Writes a 16bit signed integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
- * @throws {TypeError} If `offset` or `value` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @expose
- */
- ByteBufferPrototype.writeInt16 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value |= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 2;
- var capacity2 = this.buffer.byteLength;
- if (offset > capacity2)
- this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
- offset -= 2;
- this.view.setInt16(offset, value, this.littleEndian);
- if (relative) this.offset += 2;
- return this;
- };
-
- /**
- * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
- * @function
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
- * @throws {TypeError} If `offset` or `value` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @expose
- */
- ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
-
- /**
- * Reads a 16bit signed integer.
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
- * @returns {number} Value read
- * @throws {TypeError} If `offset` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @expose
- */
- ByteBufferPrototype.readInt16 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 2 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getInt16(offset, this.littleEndian);
- if (relative) this.offset += 2;
- return value;
- };
-
- /**
- * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
- * @function
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
- * @returns {number} Value read
- * @throws {TypeError} If `offset` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @expose
- */
- ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
-
- /**
- * Writes a 16bit unsigned integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
- * @throws {TypeError} If `offset` or `value` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @expose
- */
- ByteBufferPrototype.writeUint16 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value >>>= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 2;
- var capacity3 = this.buffer.byteLength;
- if (offset > capacity3)
- this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
- offset -= 2;
- this.view.setUint16(offset, value, this.littleEndian);
- if (relative) this.offset += 2;
- return this;
- };
-
- /**
- * Reads a 16bit unsigned integer.
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
- * @returns {number} Value read
- * @throws {TypeError} If `offset` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @expose
- */
- ByteBufferPrototype.readUint16 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 2 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getUint16(offset, this.littleEndian);
- if (relative) this.offset += 2;
- return value;
- };
-
- // types/ints/int32
-
- /**
- * Writes a 32bit signed integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @expose
- */
- ByteBufferPrototype.writeInt32 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value |= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 4;
- var capacity4 = this.buffer.byteLength;
- if (offset > capacity4)
- this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
- offset -= 4;
- this.view.setInt32(offset, value, this.littleEndian);
- if (relative) this.offset += 4;
- return this;
- };
-
- /**
- * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @expose
- */
- ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
-
- /**
- * Reads a 32bit signed integer.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {number} Value read
- * @expose
- */
- ByteBufferPrototype.readInt32 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 4 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getInt32(offset, this.littleEndian);
- if (relative) this.offset += 4;
- return value;
- };
-
- /**
- * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
- * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {number} Value read
- * @expose
- */
- ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
-
- /**
- * Writes a 32bit unsigned integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @expose
- */
- ByteBufferPrototype.writeUint32 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value >>>= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 4;
- var capacity5 = this.buffer.byteLength;
- if (offset > capacity5)
- this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
- offset -= 4;
- this.view.setUint32(offset, value, this.littleEndian);
- if (relative) this.offset += 4;
- return this;
- };
-
- /**
- * Reads a 32bit unsigned integer.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {number} Value read
- * @expose
- */
- ByteBufferPrototype.readUint32 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 4 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getUint32(offset, this.littleEndian);
- if (relative) this.offset += 4;
- return value;
- };
-
- // types/ints/int64
-
- if (Long) {
-
- /**
- * Writes a 64bit signed integer.
- * @param {number|!Long} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeInt64 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value === 'number')
- value = Long.fromNumber(value);
- else if (!(value && value instanceof Long))
- throw TypeError("Illegal value: "+value+" (not an integer or Long)");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- if (typeof value === 'number')
- value = Long.fromNumber(value);
- offset += 8;
- var capacity6 = this.buffer.byteLength;
- if (offset > capacity6)
- this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
- offset -= 8;
- if (this.littleEndian) {
- this.view.setInt32(offset , value.low , true);
- this.view.setInt32(offset+4, value.high, true);
- } else {
- this.view.setInt32(offset , value.high, false);
- this.view.setInt32(offset+4, value.low , false);
- }
- if (relative) this.offset += 8;
- return this;
- };
-
- /**
- * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
- * @param {number|!Long} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
-
- /**
- * Reads a 64bit signed integer.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!Long}
- * @expose
- */
- ByteBufferPrototype.readInt64 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 8 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
- }
- var value = this.littleEndian
- ? new Long(this.view.getInt32(offset , true ), this.view.getInt32(offset+4, true ), false)
- : new Long(this.view.getInt32(offset+4, false), this.view.getInt32(offset , false), false);
- if (relative) this.offset += 8;
- return value;
- };
-
- /**
- * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!Long}
- * @expose
- */
- ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
-
- /**
- * Writes a 64bit unsigned integer.
- * @param {number|!Long} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeUint64 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value === 'number')
- value = Long.fromNumber(value);
- else if (!(value && value instanceof Long))
- throw TypeError("Illegal value: "+value+" (not an integer or Long)");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- if (typeof value === 'number')
- value = Long.fromNumber(value);
- offset += 8;
- var capacity7 = this.buffer.byteLength;
- if (offset > capacity7)
- this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
- offset -= 8;
- if (this.littleEndian) {
- this.view.setInt32(offset , value.low , true);
- this.view.setInt32(offset+4, value.high, true);
- } else {
- this.view.setInt32(offset , value.high, false);
- this.view.setInt32(offset+4, value.low , false);
- }
- if (relative) this.offset += 8;
- return this;
- };
-
- /**
- * Reads a 64bit unsigned integer.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!Long}
- * @expose
- */
- ByteBufferPrototype.readUint64 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 8 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
- }
- var value = this.littleEndian
- ? new Long(this.view.getInt32(offset , true ), this.view.getInt32(offset+4, true ), true)
- : new Long(this.view.getInt32(offset+4, false), this.view.getInt32(offset , false), true);
- if (relative) this.offset += 8;
- return value;
- };
-
- } // Long
-
-
- // types/floats/float32
-
- /**
- * Writes a 32bit float.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeFloat32 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number')
- throw TypeError("Illegal value: "+value+" (not a number)");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 4;
- var capacity8 = this.buffer.byteLength;
- if (offset > capacity8)
- this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
- offset -= 4;
- this.view.setFloat32(offset, value, this.littleEndian);
- if (relative) this.offset += 4;
- return this;
- };
-
- /**
- * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
- * @function
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
-
- /**
- * Reads a 32bit float.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {number}
- * @expose
- */
- ByteBufferPrototype.readFloat32 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 4 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getFloat32(offset, this.littleEndian);
- if (relative) this.offset += 4;
- return value;
- };
-
- /**
- * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
- * @function
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
- * @returns {number}
- * @expose
- */
- ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
-
- // types/floats/float64
-
- /**
- * Writes a 64bit float.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeFloat64 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number')
- throw TypeError("Illegal value: "+value+" (not a number)");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- offset += 8;
- var capacity9 = this.buffer.byteLength;
- if (offset > capacity9)
- this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
- offset -= 8;
- this.view.setFloat64(offset, value, this.littleEndian);
- if (relative) this.offset += 8;
- return this;
- };
-
- /**
- * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
- * @function
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
-
- /**
- * Reads a 64bit float.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {number}
- * @expose
- */
- ByteBufferPrototype.readFloat64 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 8 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
- }
- var value = this.view.getFloat64(offset, this.littleEndian);
- if (relative) this.offset += 8;
- return value;
- };
-
- /**
- * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
- * @function
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
- * @returns {number}
- * @expose
- */
- ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
-
-
- // types/varints/varint32
-
- /**
- * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
- * @type {number}
- * @const
- * @expose
- */
- ByteBuffer.MAX_VARINT32_BYTES = 5;
-
- /**
- * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
- * @param {number} value Value to encode
- * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
- * @expose
- */
- ByteBuffer.calculateVarint32 = function(value) {
- // ref: src/google/protobuf/io/coded_stream.cc
- value = value >>> 0;
- if (value < 1 << 7 ) return 1;
- else if (value < 1 << 14) return 2;
- else if (value < 1 << 21) return 3;
- else if (value < 1 << 28) return 4;
- else return 5;
- };
-
- /**
- * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
- * @param {number} n Signed 32bit integer
- * @returns {number} Unsigned zigzag encoded 32bit integer
- * @expose
- */
- ByteBuffer.zigZagEncode32 = function(n) {
- return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
- };
-
- /**
- * Decodes a zigzag encoded signed 32bit integer.
- * @param {number} n Unsigned zigzag encoded 32bit integer
- * @returns {number} Signed 32bit integer
- * @expose
- */
- ByteBuffer.zigZagDecode32 = function(n) {
- return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
- };
-
- /**
- * Writes a 32bit base 128 variable-length integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
- * @expose
- */
- ByteBufferPrototype.writeVarint32 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value |= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- var size = ByteBuffer.calculateVarint32(value),
- b;
- offset += size;
- var capacity10 = this.buffer.byteLength;
- if (offset > capacity10)
- this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
- offset -= size;
- // ref: http://code.google.com/searchframe#WTeibokF6gE/trunk/src/google/protobuf/io/coded_stream.cc
- this.view.setUint8(offset, b = value | 0x80);
- value >>>= 0;
- if (value >= 1 << 7) {
- b = (value >> 7) | 0x80;
- this.view.setUint8(offset+1, b);
- if (value >= 1 << 14) {
- b = (value >> 14) | 0x80;
- this.view.setUint8(offset+2, b);
- if (value >= 1 << 21) {
- b = (value >> 21) | 0x80;
- this.view.setUint8(offset+3, b);
- if (value >= 1 << 28) {
- this.view.setUint8(offset+4, (value >> 28) & 0x0F);
- size = 5;
- } else {
- this.view.setUint8(offset+3, b & 0x7F);
- size = 4;
- }
- } else {
- this.view.setUint8(offset+2, b & 0x7F);
- size = 3;
- }
- } else {
- this.view.setUint8(offset+1, b & 0x7F);
- size = 2;
- }
- } else {
- this.view.setUint8(offset, b & 0x7F);
- size = 1;
- }
- if (relative) {
- this.offset += size;
- return this;
- }
- return size;
- };
-
- /**
- * Writes a zig-zag encoded 32bit base 128 variable-length integer.
- * @param {number} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
- * @expose
- */
- ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
- return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
- };
-
- /**
- * Reads a 32bit base 128 variable-length integer.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
- * and the actual number of bytes read.
- * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
- * to fully decode the varint.
- * @expose
- */
- ByteBufferPrototype.readVarint32 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 1 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
- }
- // ref: src/google/protobuf/io/coded_stream.cc
- var size = 0,
- value = 0 >>> 0,
- temp,
- ioffset;
- do {
- ioffset = offset+size;
- if (!this.noAssert && ioffset > this.limit) {
- var err = Error("Truncated");
- err['truncated'] = true;
- throw err;
- }
- temp = this.view.getUint8(ioffset);
- if (size < 5)
- value |= ((temp&0x7F)<<(7*size)) >>> 0;
- ++size;
- } while ((temp & 0x80) === 0x80);
- value = value | 0; // Make sure to discard the higher order bits
- if (relative) {
- this.offset += size;
- return value;
- }
- return {
- "value": value,
- "length": size
- };
- };
-
- /**
- * Reads a zig-zag encoded 32bit base 128 variable-length integer.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
- * and the actual number of bytes read.
- * @throws {Error} If it's not a valid varint
- * @expose
- */
- ByteBufferPrototype.readVarint32ZigZag = function(offset) {
- var val = this.readVarint32(offset);
- if (typeof val === 'object')
- val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
- else
- val = ByteBuffer.zigZagDecode32(val);
- return val;
- };
-
- // types/varints/varint64
-
- if (Long) {
-
- /**
- * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
- * @type {number}
- * @const
- * @expose
- */
- ByteBuffer.MAX_VARINT64_BYTES = 10;
-
- /**
- * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
- * @param {number|!Long} value Value to encode
- * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
- * @expose
- */
- ByteBuffer.calculateVarint64 = function(value) {
- if (typeof value === 'number')
- value = Long.fromNumber(value);
- // ref: src/google/protobuf/io/coded_stream.cc
- var part0 = value.toInt() >>> 0,
- part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
- part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
- if (part2 == 0) {
- if (part1 == 0) {
- if (part0 < 1 << 14)
- return part0 < 1 << 7 ? 1 : 2;
- else
- return part0 < 1 << 21 ? 3 : 4;
- } else {
- if (part1 < 1 << 14)
- return part1 < 1 << 7 ? 5 : 6;
- else
- return part1 < 1 << 21 ? 7 : 8;
- }
- } else
- return part2 < 1 << 7 ? 9 : 10;
- };
-
- /**
- * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
- * @param {number|!Long} value Signed long
- * @returns {!Long} Unsigned zigzag encoded long
- * @expose
- */
- ByteBuffer.zigZagEncode64 = function(value) {
- if (typeof value === 'number')
- value = Long.fromNumber(value, false);
- else if (value.unsigned !== false) value = value.toSigned();
- // ref: src/google/protobuf/wire_format_lite.h
- return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
- };
-
- /**
- * Decodes a zigzag encoded signed 64bit integer.
- * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
- * @returns {!Long} Signed long
- * @expose
- */
- ByteBuffer.zigZagDecode64 = function(value) {
- if (typeof value === 'number')
- value = Long.fromNumber(value, false);
- else if (value.unsigned !== false) value = value.toSigned();
- // ref: src/google/protobuf/wire_format_lite.h
- return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
- };
-
- /**
- * Writes a 64bit base 128 variable-length integer.
- * @param {number|Long} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
- * @expose
- */
- ByteBufferPrototype.writeVarint64 = function(value, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof value === 'number')
- value = Long.fromNumber(value);
- else if (!(value && value instanceof Long))
- throw TypeError("Illegal value: "+value+" (not an integer or Long)");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- if (typeof value === 'number')
- value = Long.fromNumber(value, false);
- else if (value.unsigned !== false) value = value.toSigned();
- var size = ByteBuffer.calculateVarint64(value),
- part0 = value.toInt() >>> 0,
- part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
- part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
- offset += size;
- var capacity11 = this.buffer.byteLength;
- if (offset > capacity11)
- this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
- offset -= size;
- switch (size) {
- case 10: this.view.setUint8(offset+9, (part2 >>> 7) & 0x01);
- case 9 : this.view.setUint8(offset+8, size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F);
- case 8 : this.view.setUint8(offset+7, size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F);
- case 7 : this.view.setUint8(offset+6, size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F);
- case 6 : this.view.setUint8(offset+5, size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F);
- case 5 : this.view.setUint8(offset+4, size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F);
- case 4 : this.view.setUint8(offset+3, size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F);
- case 3 : this.view.setUint8(offset+2, size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F);
- case 2 : this.view.setUint8(offset+1, size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F);
- case 1 : this.view.setUint8(offset , size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F);
- }
- if (relative) {
- this.offset += size;
- return this;
- } else {
- return size;
- }
- };
-
- /**
- * Writes a zig-zag encoded 64bit base 128 variable-length integer.
- * @param {number|Long} value Value to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
- * @expose
- */
- ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
- return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
- };
-
- /**
- * Reads a 64bit base 128 variable-length integer. Requires Long.js.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
- * the actual number of bytes read.
- * @throws {Error} If it's not a valid varint
- * @expose
- */
- ByteBufferPrototype.readVarint64 = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 1 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
- }
- // ref: src/google/protobuf/io/coded_stream.cc
- var start = offset,
- part0 = 0,
- part1 = 0,
- part2 = 0,
- b = 0;
- b = this.view.getUint8(offset++); part0 = (b & 0x7F) ; if (b & 0x80) {
- b = this.view.getUint8(offset++); part0 |= (b & 0x7F) << 7; if (b & 0x80) {
- b = this.view.getUint8(offset++); part0 |= (b & 0x7F) << 14; if (b & 0x80) {
- b = this.view.getUint8(offset++); part0 |= (b & 0x7F) << 21; if (b & 0x80) {
- b = this.view.getUint8(offset++); part1 = (b & 0x7F) ; if (b & 0x80) {
- b = this.view.getUint8(offset++); part1 |= (b & 0x7F) << 7; if (b & 0x80) {
- b = this.view.getUint8(offset++); part1 |= (b & 0x7F) << 14; if (b & 0x80) {
- b = this.view.getUint8(offset++); part1 |= (b & 0x7F) << 21; if (b & 0x80) {
- b = this.view.getUint8(offset++); part2 = (b & 0x7F) ; if (b & 0x80) {
- b = this.view.getUint8(offset++); part2 |= (b & 0x7F) << 7; if (b & 0x80) {
- throw Error("Buffer overrun"); }}}}}}}}}}
- var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
- if (relative) {
- this.offset = offset;
- return value;
- } else {
- return {
- 'value': value,
- 'length': offset-start
- };
- }
- };
-
- /**
- * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
- * the actual number of bytes read.
- * @throws {Error} If it's not a valid varint
- * @expose
- */
- ByteBufferPrototype.readVarint64ZigZag = function(offset) {
- var val = this.readVarint64(offset);
- if (val && val['value'] instanceof Long)
- val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
- else
- val = ByteBuffer.zigZagDecode64(val);
- return val;
- };
-
- } // Long
-
-
- // types/strings/cstring
-
- /**
- * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
- * characters itself.
- * @param {string} str String to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * contained in `str` + 1 if omitted.
- * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
- * @expose
- */
- ByteBufferPrototype.writeCString = function(str, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- var i,
- k = str.length;
- if (!this.noAssert) {
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- for (i=0; i>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- var start = offset;
- // UTF8 strings do not contain zero bytes in between except for the zero character, so:
- k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
- offset += k+1;
- var capacity12 = this.buffer.byteLength;
- if (offset > capacity12)
- this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
- offset -= k+1;
- utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
- this.view.setUint8(offset++, b);
- }.bind(this));
- this.view.setUint8(offset++, 0);
- if (relative) {
- this.offset = offset - start;
- return this;
- }
- return k;
- };
-
- /**
- * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
- * itself.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
- * read and the actual number of bytes read.
- * @expose
- */
- ByteBufferPrototype.readCString = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 1 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
- }
- var start = offset,
- temp;
- // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
- var sd, b = -1;
- utfx.decodeUTF8toUTF16(function() {
- if (b === 0) return null;
- if (offset >= this.limit)
- throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
- return (b = this.view.getUint8(offset++)) === 0 ? null : b;
- }.bind(this), sd = stringDestination(), true);
- if (relative) {
- this.offset = offset;
- return sd();
- } else {
- return {
- "string": sd(),
- "length": offset - start
- };
- }
- };
-
- // types/strings/istring
-
- /**
- * Writes a length as uint32 prefixed UTF8 encoded string.
- * @param {string} str String to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
- * @expose
- * @see ByteBuffer#writeVarint32
- */
- ByteBufferPrototype.writeIString = function(str, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- var start = offset,
- k;
- k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
- offset += 4+k;
- var capacity13 = this.buffer.byteLength;
- if (offset > capacity13)
- this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
- offset -= 4+k;
- this.view.setUint32(offset, k, this.littleEndian);
- offset += 4;
- utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
- this.view.setUint8(offset++, b);
- }.bind(this));
- if (offset !== start + 4 + k)
- throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
- if (relative) {
- this.offset = offset;
- return this;
- }
- return offset - start;
- };
-
- /**
- * Reads a length as uint32 prefixed UTF8 encoded string.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
- * read and the actual number of bytes read.
- * @expose
- * @see ByteBuffer#readVarint32
- */
- ByteBufferPrototype.readIString = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 4 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
- }
- var temp = 0,
- start = offset,
- str;
- temp = this.view.getUint32(offset, this.littleEndian);
- offset += 4;
- var k = offset + temp,
- sd;
- utfx.decodeUTF8toUTF16(function() {
- return offset < k ? this.view.getUint8(offset++) : null;
- }.bind(this), sd = stringDestination(), this.noAssert);
- str = sd();
- if (relative) {
- this.offset = offset;
- return str;
- } else {
- return {
- 'string': str,
- 'length': offset - start
- };
- }
- };
-
- // types/strings/utf8string
-
- /**
- * Metrics representing number of UTF8 characters. Evaluates to `c`.
- * @type {string}
- * @const
- * @expose
- */
- ByteBuffer.METRICS_CHARS = 'c';
-
- /**
- * Metrics representing number of bytes. Evaluates to `b`.
- * @type {string}
- * @const
- * @expose
- */
- ByteBuffer.METRICS_BYTES = 'b';
-
- /**
- * Writes an UTF8 encoded string.
- * @param {string} str String to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
- * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
- * @expose
- */
- ByteBufferPrototype.writeUTF8String = function(str, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- var k;
- var start = offset;
- k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
- offset += k;
- var capacity14 = this.buffer.byteLength;
- if (offset > capacity14)
- this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
- offset -= k;
- utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
- this.view.setUint8(offset++, b);
- }.bind(this));
- if (relative) {
- this.offset = offset;
- return this;
- }
- return offset - start;
- };
-
- /**
- * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
- * @function
- * @param {string} str String to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
- * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
- * @expose
- */
- ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
-
- /**
- * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
- * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
- * @function
- * @param {string} str String to calculate
- * @returns {number} Number of UTF8 characters
- * @expose
- */
- ByteBuffer.calculateUTF8Chars = function(str) {
- return utfx.calculateUTF16asUTF8(stringSource(str))[0];
- };
-
- /**
- * Calculates the number of UTF8 bytes of a string.
- * @function
- * @param {string} str String to calculate
- * @returns {number} Number of UTF8 bytes
- * @expose
- */
- ByteBuffer.calculateUTF8Bytes = function(str) {
- return utfx.calculateUTF16asUTF8(stringSource(str))[1];
- };
-
- /**
- * Reads an UTF8 encoded string.
- * @param {number} length Number of characters or bytes to read.
- * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
- * {@link ByteBuffer.METRICS_CHARS}.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
- * read and the actual number of bytes read.
- * @expose
- */
- ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
- if (typeof metrics === 'number') {
- offset = metrics;
- metrics = undefined;
- }
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
- if (!this.noAssert) {
- if (typeof length !== 'number' || length % 1 !== 0)
- throw TypeError("Illegal length: "+length+" (not an integer)");
- length |= 0;
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- var i = 0,
- start = offset,
- sd;
- if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
- sd = stringDestination();
- utfx.decodeUTF8(function() {
- return i < length && offset < this.limit ? this.view.getUint8(offset++) : null;
- }.bind(this), function(cp) {
- ++i; utfx.UTF8toUTF16(cp, sd);
- }.bind(this));
- if (i !== length)
- throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
- if (relative) {
- this.offset = offset;
- return sd();
- } else {
- return {
- "string": sd(),
- "length": offset - start
- };
- }
- } else if (metrics === ByteBuffer.METRICS_BYTES) {
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + length > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
- }
- var k = offset + length;
- utfx.decodeUTF8toUTF16(function() {
- return offset < k ? this.view.getUint8(offset++) : null;
- }.bind(this), sd = stringDestination(), this.noAssert);
- if (offset !== k)
- throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
- if (relative) {
- this.offset = offset;
- return sd();
- } else {
- return {
- 'string': sd(),
- 'length': offset - start
- };
- }
- } else
- throw TypeError("Unsupported metrics: "+metrics);
- };
-
- /**
- * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
- * @function
- * @param {number} length Number of characters or bytes to read
- * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
- * {@link ByteBuffer.METRICS_CHARS}.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
- * read and the actual number of bytes read.
- * @expose
- */
- ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
-
- // types/strings/vstring
-
- /**
- * Writes a length as varint32 prefixed UTF8 encoded string.
- * @param {string} str String to write
- * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted.
- * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
- * @expose
- * @see ByteBuffer#writeVarint32
- */
- ByteBufferPrototype.writeVString = function(str, offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- var start = offset,
- k, l;
- k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
- l = ByteBuffer.calculateVarint32(k);
- offset += l+k;
- var capacity15 = this.buffer.byteLength;
- if (offset > capacity15)
- this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
- offset -= l+k;
- offset += this.writeVarint32(k, offset);
- utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
- this.view.setUint8(offset++, b);
- }.bind(this));
- if (offset !== start+k+l)
- throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
- if (relative) {
- this.offset = offset;
- return this;
- }
- return offset - start;
- };
-
- /**
- * Reads a length as varint32 prefixed UTF8 encoded string.
- * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
- * read and the actual number of bytes read.
- * @expose
- * @see ByteBuffer#readVarint32
- */
- ByteBufferPrototype.readVString = function(offset) {
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 1 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
- }
- var temp = this.readVarint32(offset),
- start = offset,
- str;
- offset += temp['length'];
- temp = temp['value'];
- var k = offset + temp,
- sd = stringDestination();
- utfx.decodeUTF8toUTF16(function() {
- return offset < k ? this.view.getUint8(offset++) : null;
- }.bind(this), sd, this.noAssert);
- str = sd();
- if (relative) {
- this.offset = offset;
- return str;
- } else {
- return {
- 'string': str,
- 'length': offset - start
- };
- }
- };
-
-
- /**
- * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
- * data's length.
- * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
- * will be modified according to the performed read operation.
- * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
- * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
- * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
- */
- ByteBufferPrototype.append = function(source, encoding, offset) {
- if (typeof encoding === 'number' || typeof encoding !== 'string') {
- offset = encoding;
- encoding = undefined;
- }
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- if (!(source instanceof ByteBuffer))
- source = ByteBuffer.wrap(source, encoding);
- var length = source.limit - source.offset;
- if (length <= 0) return this; // Nothing to append
- offset += length;
- var capacity16 = this.buffer.byteLength;
- if (offset > capacity16)
- this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
- offset -= length;
- new Uint8Array(this.buffer, offset).set(new Uint8Array(source.buffer).subarray(source.offset, source.limit));
- source.offset += length;
- if (relative) this.offset += length;
- return this;
- };
-
- /**
- * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents behind the specified
- * offset up to the length of this ByteBuffer's data.
- * @param {!ByteBuffer} target Target ByteBuffer
- * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * read if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- * @see ByteBuffer#append
- */
- ByteBufferPrototype.appendTo = function(target, offset) {
- target.append(this, offset);
- return this;
- };
-
- /**
- * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
- * disable them if your code already makes sure that everything is valid.
- * @param {boolean} assert `true` to enable assertions, otherwise `false`
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.assert = function(assert) {
- this.noAssert = !assert;
- return this;
- };
-
- /**
- * Gets the capacity of this ByteBuffer's backing buffer.
- * @returns {number} Capacity of the backing buffer
- * @expose
- */
- ByteBufferPrototype.capacity = function() {
- return this.buffer.byteLength;
- };
-
- /**
- * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
- * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.clear = function() {
- this.offset = 0;
- this.limit = this.buffer.byteLength;
- this.markedOffset = -1;
- return this;
- };
-
- /**
- * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
- * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
- * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
- * @returns {!ByteBuffer} Cloned instance
- * @expose
- */
- ByteBufferPrototype.clone = function(copy) {
- var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
- if (copy) {
- var buffer = new ArrayBuffer(this.buffer.byteLength);
- new Uint8Array(buffer).set(this.buffer);
- bb.buffer = buffer;
- bb.view = new DataView(buffer);
- } else {
- bb.buffer = this.buffer;
- bb.view = this.view;
- }
- bb.offset = this.offset;
- bb.markedOffset = this.markedOffset;
- bb.limit = this.limit;
- return bb;
- };
-
- /**
- * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
- * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
- * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
- * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
- * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.compact = function(begin, end) {
- if (typeof begin === 'undefined') begin = this.offset;
- if (typeof end === 'undefined') end = this.limit;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- if (begin === 0 && end === this.buffer.byteLength)
- return this; // Already compacted
- var len = end - begin;
- if (len === 0) {
- this.buffer = EMPTY_BUFFER;
- this.view = null;
- if (this.markedOffset >= 0) this.markedOffset -= begin;
- this.offset = 0;
- this.limit = 0;
- return this;
- }
- var buffer = new ArrayBuffer(len);
- new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(begin, end));
- this.buffer = buffer;
- this.view = new DataView(buffer);
- if (this.markedOffset >= 0) this.markedOffset -= begin;
- this.offset = 0;
- this.limit = len;
- return this;
- };
-
- /**
- * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
- * {@link ByteBuffer#limit}.
- * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
- * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
- * @returns {!ByteBuffer} Copy
- * @expose
- */
- ByteBufferPrototype.copy = function(begin, end) {
- if (typeof begin === 'undefined') begin = this.offset;
- if (typeof end === 'undefined') end = this.limit;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- if (begin === end)
- return new ByteBuffer(0, this.littleEndian, this.noAssert);
- var capacity = end - begin,
- bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
- bb.offset = 0;
- bb.limit = capacity;
- if (bb.markedOffset >= 0) bb.markedOffset -= begin;
- this.copyTo(bb, 0, begin, end);
- return bb;
- };
-
- /**
- * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
- * {@link ByteBuffer#limit}.
- * @param {!ByteBuffer} target Target ByteBuffer
- * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
- * by the number of bytes copied if omitted.
- * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
- * number of bytes copied if omitted.
- * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
- var relative,
- targetRelative;
- if (!this.noAssert) {
- if (!ByteBuffer.isByteBuffer(target))
- throw TypeError("Illegal target: Not a ByteBuffer");
- }
- targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
- sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
- sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
-
- if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
- throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
- if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
- throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
-
- var len = sourceLimit - sourceOffset;
- if (len === 0)
- return target; // Nothing to copy
-
- target.ensureCapacity(targetOffset + len);
-
- new Uint8Array(target.buffer).set(new Uint8Array(this.buffer).subarray(sourceOffset, sourceLimit), targetOffset);
-
- if (relative) this.offset += len;
- if (targetRelative) target.offset += len;
-
- return this;
- };
-
- /**
- * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
- * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
- * the required capacity will be used instead.
- * @param {number} capacity Required capacity
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.ensureCapacity = function(capacity) {
- var current = this.buffer.byteLength;
- if (current < capacity)
- return this.resize((current *= 2) > capacity ? current : capacity);
- return this;
- };
-
- /**
- * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
- * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
- * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
- * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
- * written if omitted. defaults to {@link ByteBuffer#offset}.
- * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
- * @returns {!ByteBuffer} this
- * @expose
- * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
- */
- ByteBufferPrototype.fill = function(value, begin, end) {
- var relative = typeof begin === 'undefined';
- if (relative) begin = this.offset;
- if (typeof value === 'string' && value.length > 0)
- value = value.charCodeAt(0);
- if (typeof begin === 'undefined') begin = this.offset;
- if (typeof end === 'undefined') end = this.limit;
- if (!this.noAssert) {
- if (typeof value !== 'number' || value % 1 !== 0)
- throw TypeError("Illegal value: "+value+" (not an integer)");
- value |= 0;
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- if (begin >= end)
- return this; // Nothing to fill
- while (begin < end) this.view.setUint8(begin++, value);
- if (relative) this.offset = begin;
- return this;
- };
-
- /**
- * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
- * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.flip = function() {
- this.limit = this.offset;
- this.offset = 0;
- return this;
- };
- /**
- * Marks an offset on this ByteBuffer to be used later.
- * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
- * @returns {!ByteBuffer} this
- * @throws {TypeError} If `offset` is not a valid number
- * @throws {RangeError} If `offset` is out of bounds
- * @see ByteBuffer#reset
- * @expose
- */
- ByteBufferPrototype.mark = function(offset) {
- offset = typeof offset === 'undefined' ? this.offset : offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- this.markedOffset = offset;
- return this;
- };
- /**
- * Sets the byte order.
- * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.order = function(littleEndian) {
- if (!this.noAssert) {
- if (typeof littleEndian !== 'boolean')
- throw TypeError("Illegal littleEndian: Not a boolean");
- }
- this.littleEndian = !!littleEndian;
- return this;
- };
-
- /**
- * Switches (to) little endian byte order.
- * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.LE = function(littleEndian) {
- this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
- return this;
- };
-
- /**
- * Switches (to) big endian byte order.
- * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.BE = function(bigEndian) {
- this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
- return this;
- };
- /**
- * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
- * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
- * will be resized and its contents moved accordingly.
- * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
- * modified according to the performed read operation.
- * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
- * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
- * prepended if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
- * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
- */
- ByteBufferPrototype.prepend = function(source, encoding, offset) {
- if (typeof encoding === 'number' || typeof encoding !== 'string') {
- offset = encoding;
- encoding = undefined;
- }
- var relative = typeof offset === 'undefined';
- if (relative) offset = this.offset;
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: "+offset+" (not an integer)");
- offset >>>= 0;
- if (offset < 0 || offset + 0 > this.buffer.byteLength)
- throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
- }
- if (!(source instanceof ByteBuffer))
- source = ByteBuffer.wrap(source, encoding);
- var len = source.limit - source.offset;
- if (len <= 0) return this; // Nothing to prepend
- var diff = len - offset;
- var arrayView;
- if (diff > 0) { // Not enough space before offset, so resize + move
- var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
- arrayView = new Uint8Array(buffer);
- arrayView.set(new Uint8Array(this.buffer).subarray(offset, this.buffer.byteLength), len);
- this.buffer = buffer;
- this.view = new DataView(buffer);
- this.offset += diff;
- if (this.markedOffset >= 0) this.markedOffset += diff;
- this.limit += diff;
- offset += diff;
- } else {
- arrayView = new Uint8Array(this.buffer);
- }
- arrayView.set(new Uint8Array(source.buffer).subarray(source.offset, source.limit), offset - len);
- source.offset = source.limit;
- if (relative)
- this.offset -= len;
- return this;
- };
-
- /**
- * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
- * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
- * will be resized and its contents moved accordingly.
- * @param {!ByteBuffer} target Target ByteBuffer
- * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
- * prepended if omitted.
- * @returns {!ByteBuffer} this
- * @expose
- * @see ByteBuffer#prepend
- */
- ByteBufferPrototype.prependTo = function(target, offset) {
- target.prepend(this, offset);
- return this;
- };
- /**
- * Prints debug information about this ByteBuffer's contents.
- * @param {function(string)=} out Output function to call, defaults to console.log
- * @expose
- */
- ByteBufferPrototype.printDebug = function(out) {
- if (typeof out !== 'function') out = console.log.bind(console);
- out(
- this.toString()+"\n"+
- "-------------------------------------------------------------------\n"+
- this.toDebug(/* columns */ true)
- );
- };
-
- /**
- * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
- * {@link ByteBuffer#limit}, so this returns `limit - offset`.
- * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
- * @expose
- */
- ByteBufferPrototype.remaining = function() {
- return this.limit - this.offset;
- };
- /**
- * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
- * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
- * marked, sets `offset = 0`.
- * @returns {!ByteBuffer} this
- * @see ByteBuffer#mark
- * @expose
- */
- ByteBufferPrototype.reset = function() {
- if (this.markedOffset >= 0) {
- this.offset = this.markedOffset;
- this.markedOffset = -1;
- } else {
- this.offset = 0;
- }
- return this;
- };
- /**
- * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
- * large or larger.
- * @param {number} capacity Capacity required
- * @returns {!ByteBuffer} this
- * @throws {TypeError} If `capacity` is not a number
- * @throws {RangeError} If `capacity < 0`
- * @expose
- */
- ByteBufferPrototype.resize = function(capacity) {
- if (!this.noAssert) {
- if (typeof capacity !== 'number' || capacity % 1 !== 0)
- throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
- capacity |= 0;
- if (capacity < 0)
- throw RangeError("Illegal capacity: 0 <= "+capacity);
- }
- if (this.buffer.byteLength < capacity) {
- var buffer = new ArrayBuffer(capacity);
- new Uint8Array(buffer).set(new Uint8Array(this.buffer));
- this.buffer = buffer;
- this.view = new DataView(buffer);
- }
- return this;
- };
- /**
- * Reverses this ByteBuffer's contents.
- * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
- * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.reverse = function(begin, end) {
- if (typeof begin === 'undefined') begin = this.offset;
- if (typeof end === 'undefined') end = this.limit;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- if (begin === end)
- return this; // Nothing to reverse
- Array.prototype.reverse.call(new Uint8Array(this.buffer).subarray(begin, end));
- this.view = new DataView(this.buffer); // FIXME: Why exactly is this necessary?
- return this;
- };
- /**
- * Skips the next `length` bytes. This will just advance
- * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
- * @returns {!ByteBuffer} this
- * @expose
- */
- ByteBufferPrototype.skip = function(length) {
- if (!this.noAssert) {
- if (typeof length !== 'number' || length % 1 !== 0)
- throw TypeError("Illegal length: "+length+" (not an integer)");
- length |= 0;
- }
- var offset = this.offset + length;
- if (!this.noAssert) {
- if (offset < 0 || offset > this.buffer.byteLength)
- throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
- }
- this.offset = offset;
- return this;
- };
-
- /**
- * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
- * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
- * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
- * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
- * @expose
- */
- ByteBufferPrototype.slice = function(begin, end) {
- if (typeof begin === 'undefined') begin = this.offset;
- if (typeof end === 'undefined') end = this.limit;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- var bb = this.clone();
- bb.offset = begin;
- bb.limit = end;
- return bb;
- };
- /**
- * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
- * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will transparently {@link ByteBuffer#flip} this
- * ByteBuffer if `offset > limit` but the actual offsets remain untouched.
- * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
- * possible. Defaults to `false`
- * @returns {!ArrayBuffer} Contents as an ArrayBuffer
- * @expose
- */
- ByteBufferPrototype.toBuffer = function(forceCopy) {
- var offset = this.offset,
- limit = this.limit;
- if (offset > limit) {
- var t = offset;
- offset = limit;
- limit = t;
- }
- if (!this.noAssert) {
- if (typeof offset !== 'number' || offset % 1 !== 0)
- throw TypeError("Illegal offset: Not an integer");
- offset >>>= 0;
- if (typeof limit !== 'number' || limit % 1 !== 0)
- throw TypeError("Illegal limit: Not an integer");
- limit >>>= 0;
- if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
- }
- // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
- // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
- if (!forceCopy && offset === 0 && limit === this.buffer.byteLength) {
- return this.buffer;
- }
- if (offset === limit) {
- return EMPTY_BUFFER;
- }
- var buffer = new ArrayBuffer(limit - offset);
- new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
- return buffer;
- };
-
- /**
- * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
- * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will transparently {@link ByteBuffer#flip} this
- * ByteBuffer if `offset > limit` but the actual offsets remain untouched. This is an alias of
- * {@link ByteBuffer#toBuffer}.
- * @function
- * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
- * Defaults to `false`
- * @returns {!ArrayBuffer} Contents as an ArrayBuffer
- * @expose
- */
- ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
-
-
- /**
- * Converts the ByteBuffer's contents to a string.
- * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
- * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
- * highlighted offsets.
- * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
- * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
- * @returns {string} String representation
- * @throws {Error} If `encoding` is invalid
- * @expose
- */
- ByteBufferPrototype.toString = function(encoding, begin, end) {
- if (typeof encoding === 'undefined')
- return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
- if (typeof encoding === 'number')
- encoding = "utf8",
- begin = encoding,
- end = begin;
- switch (encoding) {
- case "utf8":
- return this.toUTF8(begin, end);
- case "base64":
- return this.toBase64(begin, end);
- case "hex":
- return this.toHex(begin, end);
- case "binary":
- return this.toBinary(begin, end);
- case "debug":
- return this.toDebug();
- case "columns":
- return this.toColumns();
- default:
- throw Error("Unsupported encoding: "+encoding);
- }
- };
-
- // lxiv-embeddable
-
- /**
- * lxiv-embeddable (c) 2014 Daniel Wirtz
- * Released under the Apache License, Version 2.0
- * see: https://github.com/dcodeIO/lxiv for details
- */
- var lxiv = function() {
- "use strict";
-
- /**
- * lxiv namespace.
- * @type {!Object.}
- * @exports lxiv
- */
- var lxiv = {};
-
- /**
- * Character codes for output.
- * @type {!Array.}
- * @inner
- */
- var aout = [
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
- 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
- 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
- ];
-
- /**
- * Character codes for input.
- * @type {!Array.}
- * @inner
- */
- var ain = [];
- for (var i=0, k=aout.length; i>2)&0x3f]);
- t = (b&0x3)<<4;
- if ((b = src()) !== null) {
- t |= (b>>4)&0xf;
- dst(aout[(t|((b>>4)&0xf))&0x3f]);
- t = (b&0xf)<<2;
- if ((b = src()) !== null)
- dst(aout[(t|((b>>6)&0x3))&0x3f]),
- dst(aout[b&0x3f]);
- else
- dst(aout[t&0x3f]),
- dst(61);
- } else
- dst(aout[t&0x3f]),
- dst(61),
- dst(61);
- }
- };
-
- /**
- * Decodes base64 char codes to bytes.
- * @param {!function():number|null} src Characters source as a function returning the next char code respectively
- * `null` if there are no more characters left.
- * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
- * @throws {Error} If a character code is invalid
- */
- lxiv.decode = function(src, dst) {
- var c, t1, t2;
- function fail(c) {
- throw Error("Illegal character code: "+c);
- }
- while ((c = src()) !== null) {
- t1 = ain[c];
- if (typeof t1 === 'undefined') fail(c);
- if ((c = src()) !== null) {
- t2 = ain[c];
- if (typeof t2 === 'undefined') fail(c);
- dst((t1<<2)>>>0|(t2&0x30)>>4);
- if ((c = src()) !== null) {
- t1 = ain[c];
- if (typeof t1 === 'undefined')
- if (c === 61) break; else fail(c);
- dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
- if ((c = src()) !== null) {
- t2 = ain[c];
- if (typeof t2 === 'undefined')
- if (c === 61) break; else fail(c);
- dst(((t1&0x3)<<6)>>>0|t2);
- }
- }
- }
- }
- };
-
- /**
- * Tests if a string is valid base64.
- * @param {string} str String to test
- * @returns {boolean} `true` if valid, otherwise `false`
- */
- lxiv.test = function(str) {
- return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
- };
-
- return lxiv;
- }();
-
- // encodings/base64
-
- /**
- * Encodes this ByteBuffer's contents to a base64 encoded string.
- * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
- * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
- * @returns {string} Base64 encoded string
- * @expose
- */
- ByteBufferPrototype.toBase64 = function(begin, end) {
- if (typeof begin === 'undefined')
- begin = this.offset;
- if (typeof end === 'undefined')
- end = this.limit;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- var sd; lxiv.encode(function() {
- return begin < end ? this.view.getUint8(begin++) : null;
- }.bind(this), sd = stringDestination());
- return sd();
- };
-
- /**
- * Decodes a base64 encoded string to a ByteBuffer.
- * @param {string} str String to decode
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} ByteBuffer
- * @expose
- */
- ByteBuffer.fromBase64 = function(str, littleEndian, noAssert) {
- if (!noAssert) {
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- if (str.length % 4 !== 0)
- throw TypeError("Illegal str: Length not a multiple of 4");
- }
- var bb = new ByteBuffer(str.length/4*3, littleEndian, noAssert),
- i = 0;
- lxiv.decode(stringSource(str), function(b) {
- bb.view.setUint8(i++, b);
- });
- bb.limit = i;
- return bb;
- };
-
- /**
- * Encodes a binary string to base64 like `window.btoa` does.
- * @param {string} str Binary string
- * @returns {string} Base64 encoded string
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
- * @expose
- */
- ByteBuffer.btoa = function(str) {
- return ByteBuffer.fromBinary(str).toBase64();
- };
-
- /**
- * Decodes a base64 encoded string to binary like `window.atob` does.
- * @param {string} b64 Base64 encoded string
- * @returns {string} Binary string
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
- * @expose
- */
- ByteBuffer.atob = function(b64) {
- return ByteBuffer.fromBase64(b64).toBinary();
- };
-
- // encodings/binary
-
- /**
- * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
- * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
- * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
- * @returns {string} Binary encoded string
- * @throws {RangeError} If `offset > limit`
- * @expose
- */
- ByteBufferPrototype.toBinary = function(begin, end) {
- begin = typeof begin === 'undefined' ? this.offset : begin;
- end = typeof end === 'undefined' ? this.limit : end;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- if (begin === end)
- return "";
- var cc = [], pt = [];
- while (begin < end) {
- cc.push(this.view.getUint8(begin++));
- if (cc.length >= 1024)
- pt.push(String.fromCharCode.apply(String, cc)),
- cc = [];
- }
- return pt.join('') + String.fromCharCode.apply(String, cc);
- };
-
- /**
- * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
- * @param {string} str String to decode
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} ByteBuffer
- * @expose
- */
- ByteBuffer.fromBinary = function(str, littleEndian, noAssert) {
- if (!noAssert) {
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- }
- var i = 0, k = str.length, charCode,
- bb = new ByteBuffer(k, littleEndian, noAssert);
- while (i 255)
- throw RangeError("Illegal charCode at "+i+": 0 <= "+charCode+" <= 255");
- bb.view.setUint8(i++, charCode);
- }
- bb.limit = k;
- return bb;
- };
-
- // encodings/debug
-
- /**
- * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
- * * `<` : offset,
- * * `'` : markedOffset,
- * * `>` : limit,
- * * `|` : offset and limit,
- * * `[` : offset and markedOffset,
- * * `]` : markedOffset and limit,
- * * `!` : offset, markedOffset and limit
- * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
- * @returns {string|!Array.} Debug string or array of lines if `asArray = true`
- * @expose
- * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
- * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
- * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
- * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
- */
- ByteBufferPrototype.toDebug = function(columns) {
- var i = -1,
- k = this.buffer.byteLength,
- b,
- hex = "",
- asc = "",
- out = "";
- while (i 32 && b < 127 ? String.fromCharCode(b) : '.';
- }
- }
- ++i;
- if (columns) {
- if (i > 0 && i % 16 === 0 && i !== k) {
- while (hex.length < 3*16+3) hex += " ";
- out += hex+asc+"\n";
- hex = asc = "";
- }
- }
- if (i === this.offset && i === this.limit)
- hex += i === this.markedOffset ? "!" : "|";
- else if (i === this.offset)
- hex += i === this.markedOffset ? "[" : "<";
- else if (i === this.limit)
- hex += i === this.markedOffset ? "]" : ">";
- else
- hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
- }
- if (columns && hex !== " ") {
- while (hex.length < 3*16+3) hex += " ";
- out += hex+asc+"\n";
- }
- return columns ? out : hex;
- };
-
- /**
- * Decodes a hex encoded string with marked offsets to a ByteBuffer.
- * @param {string} str Debug string to decode (not be generated with `columns = true`)
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} ByteBuffer
- * @expose
- * @see ByteBuffer#toDebug
- */
- ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
- var k = str.length,
- bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
- var i = 0, j = 0, ch, b,
- rs = false, // Require symbol next
- ho = false, hm = false, hl = false, // Already has offset, markedOffset, limit?
- fail = false;
- while (i':
- if (!noAssert) {
- if (hl) {
- fail = true; break;
- }
- hl = true;
- }
- bb.limit = j;
- rs = false;
- break;
- case "'":
- if (!noAssert) {
- if (hm) {
- fail = true; break;
- }
- hm = true;
- }
- bb.markedOffset = j;
- rs = false;
- break;
- case ' ':
- rs = false;
- break;
- default:
- if (!noAssert) {
- if (rs) {
- fail = true; break;
- }
- }
- b = parseInt(ch+str.charAt(i++), 16);
- if (!noAssert) {
- if (isNaN(b) || b < 0 || b > 255)
- throw TypeError("Illegal str: Not a debug encoded string");
- }
- bb.view.setUint8(j++, b);
- rs = true;
- }
- if (fail)
- throw TypeError("Illegal str: Invalid symbol at "+i);
- }
- if (!noAssert) {
- if (!ho || !hl)
- throw TypeError("Illegal str: Missing offset or limit");
- if (j>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- var out = new Array(end - begin),
- b;
- while (begin < end) {
- b = this.view.getUint8(begin++);
- if (b < 0x10)
- out.push("0", b.toString(16));
- else out.push(b.toString(16));
- }
- return out.join('');
- };
-
- /**
- * Decodes a hex encoded string to a ByteBuffer.
- * @param {string} str String to decode
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} ByteBuffer
- * @expose
- */
- ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
- if (!noAssert) {
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- if (str.length % 2 !== 0)
- throw TypeError("Illegal str: Length not a multiple of 2");
- }
- var k = str.length,
- bb = new ByteBuffer((k / 2) | 0, littleEndian),
- b;
- for (var i=0, j=0; i 255)
- throw TypeError("Illegal str: Contains non-hex characters");
- bb.view.setUint8(j++, b);
- }
- bb.limit = j;
- return bb;
- };
-
- // utfx-embeddable
-
- /**
- * utfx-embeddable (c) 2014 Daniel Wirtz
- * Released under the Apache License, Version 2.0
- * see: https://github.com/dcodeIO/utfx for details
- */
- var utfx = function() {
- "use strict";
-
- /**
- * utfx namespace.
- * @inner
- * @type {!Object.}
- */
- var utfx = {};
-
- /**
- * Maximum valid code point.
- * @type {number}
- * @const
- */
- utfx.MAX_CODEPOINT = 0x10FFFF;
-
- /**
- * Encodes UTF8 code points to UTF8 bytes.
- * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
- * respectively `null` if there are no more code points left or a single numeric code point.
- * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
- */
- utfx.encodeUTF8 = function(src, dst) {
- var cp = null;
- if (typeof src === 'number')
- cp = src,
- src = function() { return null; };
- while (cp !== null || (cp = src()) !== null) {
- if (cp < 0x80)
- dst(cp&0x7F);
- else if (cp < 0x800)
- dst(((cp>>6)&0x1F)|0xC0),
- dst((cp&0x3F)|0x80);
- else if (cp < 0x10000)
- dst(((cp>>12)&0x0F)|0xE0),
- dst(((cp>>6)&0x3F)|0x80),
- dst((cp&0x3F)|0x80);
- else
- dst(((cp>>18)&0x07)|0xF0),
- dst(((cp>>12)&0x3F)|0x80),
- dst(((cp>>6)&0x3F)|0x80),
- dst((cp&0x3F)|0x80);
- cp = null;
- }
- };
-
- /**
- * Decodes UTF8 bytes to UTF8 code points.
- * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
- * are no more bytes left.
- * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
- * @throws {RangeError} If a starting byte is invalid in UTF8
- * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
- * remaining bytes.
- */
- utfx.decodeUTF8 = function(src, dst) {
- var a, b, c, d, fail = function(b) {
- b = b.slice(0, b.indexOf(null));
- var err = Error(b.toString());
- err.name = "TruncatedError";
- err['bytes'] = b;
- throw err;
- };
- while ((a = src()) !== null) {
- if ((a&0x80) === 0)
- dst(a);
- else if ((a&0xE0) === 0xC0)
- ((b = src()) === null) && fail([a, b]),
- dst(((a&0x1F)<<6) | (b&0x3F));
- else if ((a&0xF0) === 0xE0)
- ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
- dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
- else if ((a&0xF8) === 0xF0)
- ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
- dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
- else throw RangeError("Illegal starting byte: "+a);
- }
- };
-
- /**
- * Converts UTF16 characters to UTF8 code points.
- * @param {!function():number|null} src Characters source as a function returning the next char code respectively
- * `null` if there are no more characters left.
- * @param {!function(number)} dst Code points destination as a function successively called with each converted code
- * point.
- */
- utfx.UTF16toUTF8 = function(src, dst) {
- var c1, c2 = null;
- while (true) {
- if ((c1 = c2 !== null ? c2 : src()) === null)
- break;
- if (c1 >= 0xD800 && c1 <= 0xDFFF) {
- if ((c2 = src()) !== null) {
- if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
- dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
- c2 = null; continue;
- }
- }
- }
- dst(c1);
- }
- if (c2 !== null) dst(c2);
- };
-
- /**
- * Converts UTF8 code points to UTF16 characters.
- * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
- * respectively `null` if there are no more code points left or a single numeric code point.
- * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
- * @throws {RangeError} If a code point is out of range
- */
- utfx.UTF8toUTF16 = function(src, dst) {
- var cp = null;
- if (typeof src === 'number')
- cp = src, src = function() { return null; };
- while (cp !== null || (cp = src()) !== null) {
- if (cp <= 0xFFFF)
- dst(cp);
- else
- cp -= 0x10000,
- dst((cp>>10)+0xD800),
- dst((cp%0x400)+0xDC00);
- cp = null;
- }
- };
-
- /**
- * Converts and encodes UTF16 characters to UTF8 bytes.
- * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
- * if there are no more characters left.
- * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
- */
- utfx.encodeUTF16toUTF8 = function(src, dst) {
- utfx.UTF16toUTF8(src, function(cp) {
- utfx.encodeUTF8(cp, dst);
- });
- };
-
- /**
- * Decodes and converts UTF8 bytes to UTF16 characters.
- * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
- * are no more bytes left.
- * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
- * @throws {RangeError} If a starting byte is invalid in UTF8
- * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
- */
- utfx.decodeUTF8toUTF16 = function(src, dst) {
- utfx.decodeUTF8(src, function(cp) {
- utfx.UTF8toUTF16(cp, dst);
- });
- };
-
- /**
- * Calculates the byte length of an UTF8 code point.
- * @param {number} cp UTF8 code point
- * @returns {number} Byte length
- */
- utfx.calculateCodePoint = function(cp) {
- return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
- };
-
- /**
- * Calculates the number of UTF8 bytes required to store UTF8 code points.
- * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
- * `null` if there are no more code points left.
- * @returns {number} The number of UTF8 bytes required
- */
- utfx.calculateUTF8 = function(src) {
- var cp, l=0;
- while ((cp = src()) !== null)
- l += utfx.calculateCodePoint(cp);
- return l;
- };
-
- /**
- * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
- * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
- * `null` if there are no more characters left.
- * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
- */
- utfx.calculateUTF16asUTF8 = function(src) {
- var n=0, l=0;
- utfx.UTF16toUTF8(src, function(cp) {
- ++n; l += utfx.calculateCodePoint(cp);
- });
- return [n,l];
- };
-
- return utfx;
- }();
-
- // encodings/utf8
-
- /**
- * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
- * string.
- * @returns {string} Hex encoded string
- * @throws {RangeError} If `offset > limit`
- * @expose
- */
- ByteBufferPrototype.toUTF8 = function(begin, end) {
- if (typeof begin === 'undefined') begin = this.offset;
- if (typeof end === 'undefined') end = this.limit;
- if (!this.noAssert) {
- if (typeof begin !== 'number' || begin % 1 !== 0)
- throw TypeError("Illegal begin: Not an integer");
- begin >>>= 0;
- if (typeof end !== 'number' || end % 1 !== 0)
- throw TypeError("Illegal end: Not an integer");
- end >>>= 0;
- if (begin < 0 || begin > end || end > this.buffer.byteLength)
- throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
- }
- var sd; try {
- utfx.decodeUTF8toUTF16(function() {
- return begin < end ? this.view.getUint8(begin++) : null;
- }.bind(this), sd = stringDestination());
- } catch (e) {
- if (begin !== end)
- throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
- }
- return sd();
- };
-
- /**
- * Decodes an UTF8 encoded string to a ByteBuffer.
- * @param {string} str String to decode
- * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
- * {@link ByteBuffer.DEFAULT_ENDIAN}.
- * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
- * {@link ByteBuffer.DEFAULT_NOASSERT}.
- * @returns {!ByteBuffer} ByteBuffer
- * @expose
- */
- ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
- if (!noAssert)
- if (typeof str !== 'string')
- throw TypeError("Illegal str: Not a string");
- var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
- i = 0;
- utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
- bb.view.setUint8(i++, b);
- });
- bb.limit = i;
- return bb;
- };
-
-
- return ByteBuffer;
- }
-
- /* CommonJS */ if (typeof require === 'function' && typeof module === 'object' && module && typeof exports === 'object' && exports)
- module['exports'] = (function() {
- var Long; try { Long = require("long"); } catch (e) {}
- return loadByteBuffer(Long);
- })();
- /* AMD */ else if (typeof define === 'function' && define["amd"])
- define("ByteBuffer", ["Long"], function(Long) { return loadByteBuffer(Long); });
- /* Global */ else
- (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = loadByteBuffer(global["dcodeIO"]["Long"]);
-
-})(this);
-
-/*
- Copyright 2013 Daniel Wirtz
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/**
- * @license ProtoBuf.js (c) 2013 Daniel Wirtz
- * Released under the Apache License, Version 2.0
- * see: https://github.com/dcodeIO/ProtoBuf.js for details
- */
-(function(global) {
- "use strict";
-
- function init(ByteBuffer) {
-
- /**
- * The ProtoBuf namespace.
- * @exports ProtoBuf
- * @namespace
- * @expose
- */
- var ProtoBuf = {};
-
- /**
- * ProtoBuf.js version.
- * @type {string}
- * @const
- * @expose
- */
- ProtoBuf.VERSION = "3.8.0";
-
- /**
- * Wire types.
- * @type {Object.}
- * @const
- * @expose
- */
- ProtoBuf.WIRE_TYPES = {};
-
- /**
- * Varint wire type.
- * @type {number}
- * @expose
- */
- ProtoBuf.WIRE_TYPES.VARINT = 0;
-
- /**
- * Fixed 64 bits wire type.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.WIRE_TYPES.BITS64 = 1;
-
- /**
- * Length delimited wire type.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.WIRE_TYPES.LDELIM = 2;
-
- /**
- * Start group wire type.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.WIRE_TYPES.STARTGROUP = 3;
-
- /**
- * End group wire type.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.WIRE_TYPES.ENDGROUP = 4;
-
- /**
- * Fixed 32 bits wire type.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.WIRE_TYPES.BITS32 = 5;
-
- /**
- * Packable wire types.
- * @type {!Array.}
- * @const
- * @expose
- */
- ProtoBuf.PACKABLE_WIRE_TYPES = [
- ProtoBuf.WIRE_TYPES.VARINT,
- ProtoBuf.WIRE_TYPES.BITS64,
- ProtoBuf.WIRE_TYPES.BITS32
- ];
-
- /**
- * Types.
- * @dict
- * @type {Object.}
- * @const
- * @expose
- */
- ProtoBuf.TYPES = {
- // According to the protobuf spec.
- "int32": {
- name: "int32",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "uint32": {
- name: "uint32",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "sint32": {
- name: "sint32",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "int64": {
- name: "int64",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "uint64": {
- name: "uint64",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "sint64": {
- name: "sint64",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "bool": {
- name: "bool",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "double": {
- name: "double",
- wireType: ProtoBuf.WIRE_TYPES.BITS64
- },
- "string": {
- name: "string",
- wireType: ProtoBuf.WIRE_TYPES.LDELIM
- },
- "bytes": {
- name: "bytes",
- wireType: ProtoBuf.WIRE_TYPES.LDELIM
- },
- "fixed32": {
- name: "fixed32",
- wireType: ProtoBuf.WIRE_TYPES.BITS32
- },
- "sfixed32": {
- name: "sfixed32",
- wireType: ProtoBuf.WIRE_TYPES.BITS32
- },
- "fixed64": {
- name: "fixed64",
- wireType: ProtoBuf.WIRE_TYPES.BITS64
- },
- "sfixed64": {
- name: "sfixed64",
- wireType: ProtoBuf.WIRE_TYPES.BITS64
- },
- "float": {
- name: "float",
- wireType: ProtoBuf.WIRE_TYPES.BITS32
- },
- "enum": {
- name: "enum",
- wireType: ProtoBuf.WIRE_TYPES.VARINT
- },
- "message": {
- name: "message",
- wireType: ProtoBuf.WIRE_TYPES.LDELIM
- },
- "group": {
- name: "group",
- wireType: ProtoBuf.WIRE_TYPES.STARTGROUP
- }
- };
-
- /**
- * Minimum field id.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.ID_MIN = 1;
-
- /**
- * Maximum field id.
- * @type {number}
- * @const
- * @expose
- */
- ProtoBuf.ID_MAX = 0x1FFFFFFF;
-
- /**
- * @type {!function(new: ByteBuffer, ...[*])}
- * @expose
- */
- ProtoBuf.ByteBuffer = ByteBuffer;
-
- /**
- * @type {?function(new: Long, ...[*])}
- * @expose
- */
- ProtoBuf.Long = ByteBuffer.Long || null;
-
- /**
- * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.
- * Must be set prior to parsing.
- * @type {boolean}
- * @expose
- */
- ProtoBuf.convertFieldsToCamelCase = false;
-
- /**
- * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by
- * setting this to `false` prior to building messages.
- * @type {boolean}
- * @expose
- */
- ProtoBuf.populateAccessors = true;
-
- /**
- * @alias ProtoBuf.Util
- * @expose
- */
- ProtoBuf.Util = (function() {
- "use strict";
-
- // Object.create polyfill
- // ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
- if (!Object.create)
- /** @expose */
- Object.create = function (o) {
- if (arguments.length > 1)
- throw Error('Object.create polyfill only accepts the first parameter.');
- function F() {}
- F.prototype = o;
- return new F();
- };
-
- /**
- * ProtoBuf utilities.
- * @exports ProtoBuf.Util
- * @namespace
- */
- var Util = {};
-
- /**
- * Flag if running in node (fs is available) or not.
- * @type {boolean}
- * @const
- * @expose
- */
- Util.IS_NODE = false;
- try {
- // There is no reliable way to detect node.js as an environment, so our
- // best bet is to feature-detect what we actually need.
- Util.IS_NODE =
- typeof require === 'function' &&
- typeof require("fs").readFileSync === 'function' &&
- typeof require("path").resolve === 'function';
- } catch (e) {}
-
- /**
- * Constructs a XMLHttpRequest object.
- * @return {XMLHttpRequest}
- * @throws {Error} If XMLHttpRequest is not supported
- * @expose
- */
- Util.XHR = function() {
- // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
- var XMLHttpFactories = [
- function () {return new XMLHttpRequest()},
- function () {return new ActiveXObject("Msxml2.XMLHTTP")},
- function () {return new ActiveXObject("Msxml3.XMLHTTP")},
- function () {return new ActiveXObject("Microsoft.XMLHTTP")}
- ];
- /** @type {?XMLHttpRequest} */
- var xhr = null;
- for (var i=0;i}
- * @expose
- */
- ProtoBuf.Lang = {
- OPEN: "{",
- CLOSE: "}",
- OPTOPEN: "[",
- OPTCLOSE: "]",
- OPTEND: ",",
- EQUAL: "=",
- END: ";",
- STRINGOPEN: '"',
- STRINGCLOSE: '"',
- STRINGOPEN_SQ: "'",
- STRINGCLOSE_SQ: "'",
- COPTOPEN: '(',
- COPTCLOSE: ')',
- DELIM: /[\s\{\}=;\[\],'"\(\)]/g,
- // KEYWORD: /^(?:package|option|import|message|enum|extend|service|syntax|extensions|group)$/,
- RULE: /^(?:required|optional|repeated)$/,
- TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,
- NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,
- TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,
- TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)+$/,
- FQTYPEREF: /^(?:\.[a-zA-Z][a-zA-Z_0-9]*)+$/,
- NUMBER: /^-?(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+|([0-9]*\.[0-9]+([Ee][+-]?[0-9]+)?))$/,
- NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,
- NUMBER_HEX: /^0x[0-9a-fA-F]+$/,
- NUMBER_OCT: /^0[0-7]+$/,
- NUMBER_FLT: /^[0-9]*\.[0-9]+([Ee][+-]?[0-9]+)?$/,
- ID: /^(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
- NEGID: /^\-?(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
- WHITESPACE: /\s/,
- STRING: /['"]([^'"\\]*(\\.[^"\\]*)*)['"]/g,
- BOOL: /^(?:true|false)$/i
- };
-
- /**
- * @alias ProtoBuf.DotProto
- * @expose
- */
- ProtoBuf.DotProto = (function(ProtoBuf, Lang) {
- "use strict";
-
- /**
- * Utilities to parse .proto files.
- * @exports ProtoBuf.DotProto
- * @namespace
- */
- var DotProto = {};
-
- /**
- * Constructs a new Tokenizer.
- * @exports ProtoBuf.DotProto.Tokenizer
- * @class prototype tokenizer
- * @param {string} proto Proto to tokenize
- * @constructor
- */
- var Tokenizer = function(proto) {
-
- /**
- * Source to parse.
- * @type {string}
- * @expose
- */
- this.source = ""+proto; // In case it's a buffer
-
- /**
- * Current index.
- * @type {number}
- * @expose
- */
- this.index = 0;
-
- /**
- * Current line.
- * @type {number}
- * @expose
- */
- this.line = 1;
-
- /**
- * Stacked values.
- * @type {Array}
- * @expose
- */
- this.stack = [];
-
- /**
- * Whether currently reading a string or not.
- * @type {boolean}
- * @expose
- */
- this.readingString = false;
-
- /**
- * Whatever character ends the string. Either a single or double quote character.
- * @type {string}
- * @expose
- */
- this.stringEndsWith = Lang.STRINGCLOSE;
- };
-
- /**
- * @alias ProtoBuf.DotProto.Tokenizer.prototype
- * @inner
- */
- var TokenizerPrototype = Tokenizer.prototype;
-
- /**
- * Reads a string beginning at the current index.
- * @return {string} The string
- * @throws {Error} If it's not a valid string
- * @private
- */
- TokenizerPrototype._readString = function() {
- Lang.STRING.lastIndex = this.index-1; // Include the open quote
- var match;
- if ((match = Lang.STRING.exec(this.source)) !== null) {
- var s = match[1];
- this.index = Lang.STRING.lastIndex;
- this.stack.push(this.stringEndsWith);
- return s;
- }
- throw Error("Unterminated string at line "+this.line+", index "+this.index);
- };
-
- /**
- * Gets the next token and advances by one.
- * @return {?string} Token or `null` on EOF
- * @throws {Error} If it's not a valid proto file
- * @expose
- */
- TokenizerPrototype.next = function() {
- if (this.stack.length > 0)
- return this.stack.shift();
- if (this.index >= this.source.length)
- return null; // No more tokens
- if (this.readingString) {
- this.readingString = false;
- return this._readString();
- }
- var repeat, last;
- do {
- repeat = false;
- // Strip white spaces
- while (Lang.WHITESPACE.test(last = this.source.charAt(this.index))) {
- this.index++;
- if (last === "\n")
- this.line++;
- if (this.index === this.source.length)
- return null;
- }
- // Strip comments
- if (this.source.charAt(this.index) === '/') {
- if (this.source.charAt(++this.index) === '/') { // Single line
- while (this.source.charAt(this.index) !== "\n") {
- this.index++;
- if (this.index == this.source.length)
- return null;
- }
- this.index++;
- this.line++;
- repeat = true;
- } else if (this.source.charAt(this.index) === '*') { /* Block */
- last = '';
- while (last+(last=this.source.charAt(this.index)) !== '*/') {
- this.index++;
- if (last === "\n")
- this.line++;
- if (this.index === this.source.length)
- return null;
- }
- this.index++;
- repeat = true;
- } else
- throw Error("Unterminated comment at line "+this.line+": /"+this.source.charAt(this.index));
- }
- } while (repeat);
- if (this.index === this.source.length) return null;
-
- // Read the next token
- var end = this.index;
- Lang.DELIM.lastIndex = 0;
- var delim = Lang.DELIM.test(this.source.charAt(end));
- if (!delim) {
- ++end;
- while(end < this.source.length && !Lang.DELIM.test(this.source.charAt(end)))
- end++;
- } else
- ++end;
- var token = this.source.substring(this.index, this.index = end);
- if (token === Lang.STRINGOPEN)
- this.readingString = true,
- this.stringEndsWith = Lang.STRINGCLOSE;
- else if (token === Lang.STRINGOPEN_SQ)
- this.readingString = true,
- this.stringEndsWith = Lang.STRINGCLOSE_SQ;
- return token;
- };
-
- /**
- * Peeks for the next token.
- * @return {?string} Token or `null` on EOF
- * @throws {Error} If it's not a valid proto file
- * @expose
- */
- TokenizerPrototype.peek = function() {
- if (this.stack.length === 0) {
- var token = this.next();
- if (token === null)
- return null;
- this.stack.push(token);
- }
- return this.stack[0];
- };
-
- /**
- * Returns a string representation of this object.
- * @return {string} String representation as of "Tokenizer(index/length)"
- * @expose
- */
- TokenizerPrototype.toString = function() {
- return "Tokenizer("+this.index+"/"+this.source.length+" at line "+this.line+")";
- };
-
- /**
- * @alias ProtoBuf.DotProto.Tokenizer
- * @expose
- */
- DotProto.Tokenizer = Tokenizer;
-
- /**
- * Constructs a new Parser.
- * @exports ProtoBuf.DotProto.Parser
- * @class prototype parser
- * @param {string} proto Protocol source
- * @constructor
- */
- var Parser = function(proto) {
-
- /**
- * Tokenizer.
- * @type {ProtoBuf.DotProto.Tokenizer}
- * @expose
- */
- this.tn = new Tokenizer(proto);
- };
-
- /**
- * @alias ProtoBuf.DotProto.Parser.prototype
- * @inner
- */
- var ParserPrototype = Parser.prototype;
-
- /**
- * Runs the parser.
- * @return {{package: string|null, messages: Array.