diff --git a/index.html.erb b/index.html.erb index d52729b65..5df81a55c 100644 --- a/index.html.erb +++ b/index.html.erb @@ -20,8 +20,7 @@ - - + @@ -63,7 +62,7 @@ } catch (e) { return; } - var msg = msgpack.pack(obj); + var msg = MessagePack.encode(obj); var hex = jQuery.map(msg, function(e,i) { return ("0" + e.toString(16)).slice(-2); }).join(" "); @@ -80,7 +79,7 @@ msgbytes.push(parseInt(hex.substr(i, 2), 16)); } var msg = String.fromCharCode.apply(String, msgbytes); - var obj=msgpack.unpack(msg); + var obj=MessagePack.decode(msg); var text=JSON.stringify(obj); $("#json-text").text(text); var textLength = encodeURIComponent(text).replace(/%../g,"%").length; diff --git a/js/msgpack.js b/js/msgpack.js deleted file mode 100644 index 08f5de6bf..000000000 --- a/js/msgpack.js +++ /dev/null @@ -1,698 +0,0 @@ -/*!{id:msgpack.js,ver:1.05,license:"MIT",author:"uupaa.js@gmail.com"}*/ - -// === msgpack === -// MessagePack -> http://msgpack.sourceforge.net/ - -this.msgpack || (function(globalScope) { - -globalScope.msgpack = { - pack: msgpackpack, // msgpack.pack(data:Mix, - // toString:Boolean = false):ByteArray/ByteString/false - // [1][mix to String] msgpack.pack({}, true) -> "..." - // [2][mix to ByteArray] msgpack.pack({}) -> [...] - unpack: msgpackunpack, // msgpack.unpack(data:BinaryString/ByteArray):Mix - // [1][String to mix] msgpack.unpack("...") -> {} - // [2][ByteArray to mix] msgpack.unpack([...]) -> {} - worker: "msgpack.js", // msgpack.worker - WebWorkers script filename - upload: msgpackupload, // msgpack.upload(url:String, option:Hash, callback:Function) - download: msgpackdownload // msgpack.download(url:String, option:Hash, callback:Function) -}; - -var _ie = /MSIE/.test(navigator.userAgent), - _bin2num = {}, // BinaryStringToNumber { "\00": 0, ... "\ff": 255 } - _num2bin = {}, // NumberToBinaryString { 0: "\00", ... 255: "\ff" } - _num2b64 = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + - "abcdefghijklmnopqrstuvwxyz0123456789+/").split(""), - _buf = [], // decode buffer - _idx = 0, // decode buffer[index] - _error = 0, // msgpack.pack() error code. 1 = CYCLIC_REFERENCE_ERROR - _isArray = Array.isArray || (function(mix) { - return Object.prototype.toString.call(mix) === "[object Array]"; - }), - _isUint8Array = function(mix) { - return Object.prototype.toString.call(mix) === "[object Uint8Array]"; - }, - _toString = String.fromCharCode, // CharCode/ByteArray to String - _MAX_DEPTH = 512; - -// for WebWorkers Code Block -self.importScripts && (onmessage = function(event) { - if (event.data.method === "pack") { - postMessage(base64encode(msgpackpack(event.data.data))); - } else { - postMessage(msgpackunpack(event.data.data)); - } -}); - -// msgpack.pack -function msgpackpack(data, // @param Mix: - toString) { // @param Boolean(= false): - // @return ByteArray/BinaryString/false: - // false is error return - // [1][mix to String] msgpack.pack({}, true) -> "..." - // [2][mix to ByteArray] msgpack.pack({}) -> [...] - - _error = 0; - - var byteArray = encode([], data, 0); - - return _error ? false - : toString ? byteArrayToByteString(byteArray) - : byteArray; -} - -// msgpack.unpack -function msgpackunpack(data) { // @param BinaryString/ByteArray: - // @return Mix/undefined: - // undefined is error return - // [1][String to mix] msgpack.unpack("...") -> {} - // [2][ByteArray to mix] msgpack.unpack([...]) -> {} - - _buf = typeof data === "string" ? toByteArray(data) : data; - _idx = -1; - return decode(); // mix or undefined -} - -// inner - encoder -function encode(rv, // @param ByteArray: result - mix, // @param Mix: source data - depth) { // @param Number: depth - var size, i, iz, c, pos, // for UTF8.encode, Array.encode, Hash.encode - high, low, sign, exp, frac; // for IEEE754 - - if (mix == null) { // null or undefined -> 0xc0 ( null ) - rv.push(0xc0); - } else if (mix === false) { // false -> 0xc2 ( false ) - rv.push(0xc2); - } else if (mix === true) { // true -> 0xc3 ( true ) - rv.push(0xc3); - } else { - switch (typeof mix) { - case "number": - if (mix !== mix) { // isNaN - rv.push(0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff); // quiet NaN - } else if (mix === Infinity) { - rv.push(0xcb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); // positive infinity - } else if (Math.floor(mix) === mix) { // int or uint - if (mix < 0) { - // int - if (mix >= -32) { // negative fixnum - rv.push(0xe0 + mix + 32); - } else if (mix > -0x80) { - rv.push(0xd0, mix + 0x100); - } else if (mix > -0x8000) { - mix += 0x10000; - rv.push(0xd1, mix >> 8, mix & 0xff); - } else if (mix > -0x80000000) { - mix += 0x100000000; - rv.push(0xd2, mix >>> 24, (mix >> 16) & 0xff, - (mix >> 8) & 0xff, mix & 0xff); - } else { - high = Math.floor(mix / 0x100000000); - low = mix & 0xffffffff; - rv.push(0xd3, (high >> 24) & 0xff, (high >> 16) & 0xff, - (high >> 8) & 0xff, high & 0xff, - (low >> 24) & 0xff, (low >> 16) & 0xff, - (low >> 8) & 0xff, low & 0xff); - } - } else { - // uint - if (mix < 0x80) { - rv.push(mix); // positive fixnum - } else if (mix < 0x100) { // uint 8 - rv.push(0xcc, mix); - } else if (mix < 0x10000) { // uint 16 - rv.push(0xcd, mix >> 8, mix & 0xff); - } else if (mix < 0x100000000) { // uint 32 - rv.push(0xce, mix >>> 24, (mix >> 16) & 0xff, - (mix >> 8) & 0xff, mix & 0xff); - } else { - high = Math.floor(mix / 0x100000000); - low = mix & 0xffffffff; - rv.push(0xcf, (high >> 24) & 0xff, (high >> 16) & 0xff, - (high >> 8) & 0xff, high & 0xff, - (low >> 24) & 0xff, (low >> 16) & 0xff, - (low >> 8) & 0xff, low & 0xff); - } - } - } else { // double - // THX!! @edvakf - // http://javascript.g.hatena.ne.jp/edvakf/20101128/1291000731 - sign = mix < 0; - sign && (mix *= -1); - - // add offset 1023 to ensure positive - // 0.6931471805599453 = Math.LN2; - exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0; - - // shift 52 - (exp - 1023) bits to make integer part exactly 53 bits, - // then throw away trash less than decimal point - frac = mix * Math.pow(2, 52 + 1023 - exp); - - // S+-Exp(11)--++-----------------Fraction(52bits)-----------------------+ - // || || | - // v+----------++--------------------------------------------------------+ - // 00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000 - // 6 5 55 4 4 3 2 1 8 0 - // 3 6 21 8 0 2 4 6 - // - // +----------high(32bits)-----------+ +----------low(32bits)------------+ - // | | | | - // +---------------------------------+ +---------------------------------+ - // 3 2 21 1 8 0 - // 1 4 09 6 - low = frac & 0xffffffff; - sign && (exp |= 0x800); - high = ((frac / 0x100000000) & 0xfffff) | (exp << 20); - - rv.push(0xcb, (high >> 24) & 0xff, (high >> 16) & 0xff, - (high >> 8) & 0xff, high & 0xff, - (low >> 24) & 0xff, (low >> 16) & 0xff, - (low >> 8) & 0xff, low & 0xff); - } - break; - case "string": - // http://d.hatena.ne.jp/uupaa/20101128 - iz = mix.length; - pos = rv.length; // keep rewrite position - - rv.push(0); // placeholder - - // utf8.encode - for (i = 0; i < iz; ++i) { - c = mix.charCodeAt(i); - if (c < 0x80) { // ASCII(0x00 ~ 0x7f) - rv.push(c & 0x7f); - } else if (c < 0x0800) { - rv.push(((c >>> 6) & 0x1f) | 0xc0, (c & 0x3f) | 0x80); - } else if (c < 0x10000) { - rv.push(((c >>> 12) & 0x0f) | 0xe0, - ((c >>> 6) & 0x3f) | 0x80, (c & 0x3f) | 0x80); - } - } - size = rv.length - pos - 1; - - if (size < 32) { - rv[pos] = 0xa0 + size; // rewrite - } else if (size < 0x100) { // 8 - rv.splice(pos, 1, 0xd9, size); - } else if (size < 0x10000) { // 16 - rv.splice(pos, 1, 0xda, size >> 8, size & 0xff); - } else if (size < 0x100000000) { // 32 - rv.splice(pos, 1, 0xdb, - size >>> 24, (size >> 16) & 0xff, - (size >> 8) & 0xff, size & 0xff); - } - break; - default: // array, hash, or Uint8Array - if (_isUint8Array(mix)) { - size = mix.length; - - if (size < 0x100) { // 8 - rv.push(0xc4, size); - } else if (size < 0x10000) { // 16 - rv.push(0xc5, size >> 8, size & 0xff); - } else if (size < 0x100000000) { // 32 - rv.push(0xc6, size >>> 24, (size >> 16) & 0xff, - (size >> 8) & 0xff, size & 0xff); - } - Array.prototype.push.apply(rv, mix); - break; - } - if (++depth >= _MAX_DEPTH) { - _error = 1; // CYCLIC_REFERENCE_ERROR - return rv = []; // clear - } - if (_isArray(mix)) { - size = mix.length; - if (size < 16) { - rv.push(0x90 + size); - } else if (size < 0x10000) { // 16 - rv.push(0xdc, size >> 8, size & 0xff); - } else if (size < 0x100000000) { // 32 - rv.push(0xdd, size >>> 24, (size >> 16) & 0xff, - (size >> 8) & 0xff, size & 0xff); - } - for (i = 0; i < size; ++i) { - encode(rv, mix[i], depth); - } - } else { // hash - // http://d.hatena.ne.jp/uupaa/20101129 - pos = rv.length; // keep rewrite position - rv.push(0); // placeholder - size = 0; - for (i in mix) { - ++size; - encode(rv, i, depth); - encode(rv, mix[i], depth); - } - if (size < 16) { - rv[pos] = 0x80 + size; // rewrite - } else if (size < 0x10000) { // 16 - rv.splice(pos, 1, 0xde, size >> 8, size & 0xff); - } else if (size < 0x100000000) { // 32 - rv.splice(pos, 1, 0xdf, - size >>> 24, (size >> 16) & 0xff, - (size >> 8) & 0xff, size & 0xff); - } - } - } - } - return rv; -} - -// inner - decoder -function decode() { // @return Mix: - var size, i, iz, c, num = 0, - sign, exp, frac, ary, hash, - buf = _buf, type = buf[++_idx]; - - if (type >= 0xe0) { // Negative FixNum (111x xxxx) (-32 ~ -1) - return type - 0x100; - } - if (type < 0xc0) { - if (type < 0x80) { // Positive FixNum (0xxx xxxx) (0 ~ 127) - return type; - } - if (type < 0x90) { // FixMap (1000 xxxx) - num = type - 0x80; - type = 0x80; - } else if (type < 0xa0) { // FixArray (1001 xxxx) - num = type - 0x90; - type = 0x90; - } else { // if (type < 0xc0) { // FixRaw (101x xxxx) - num = type - 0xa0; - type = 0xa0; - } - } - switch (type) { - case 0xc0: return null; - case 0xc2: return false; - case 0xc3: return true; - case 0xca: // float - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + - (buf[++_idx] << 8) + buf[++_idx]; - sign = num & 0x80000000; // 1bit - exp = (num >> 23) & 0xff; // 8bits - frac = num & 0x7fffff; // 23bits - if (!num || num === 0x80000000) { // 0.0 or -0.0 - return 0; - } - if (exp === 0xff) { // NaN or Infinity - return frac ? NaN : Infinity; - } - return (sign ? -1 : 1) * - (frac | 0x800000) * Math.pow(2, exp - 127 - 23); // 127: bias - case 0xcb: // double - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + - (buf[++_idx] << 8) + buf[++_idx]; - sign = num & 0x80000000; // 1bit - exp = (num >> 20) & 0x7ff; // 11bits - frac = num & 0xfffff; // 52bits - 32bits (high word) - if (!num || num === 0x80000000) { // 0.0 or -0.0 - _idx += 4; - return 0; - } - if (exp === 0x7ff) { // NaN or Infinity - _idx += 4; - return frac ? NaN : Infinity; - } - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + - (buf[++_idx] << 8) + buf[++_idx]; - return (sign ? -1 : 1) * - ((frac | 0x100000) * Math.pow(2, exp - 1023 - 20) // 1023: bias - + num * Math.pow(2, exp - 1023 - 52)); - // 0xcf: uint64, 0xce: uint32, 0xcd: uint16 - case 0xcf: num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + - (buf[++_idx] << 8) + buf[++_idx]; - return num * 0x100000000 + - buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + - (buf[++_idx] << 8) + buf[++_idx]; - case 0xce: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xcd: num += buf[++_idx] << 8; - case 0xcc: return num + buf[++_idx]; - // 0xd3: int64, 0xd2: int32, 0xd1: int16, 0xd0: int8 - case 0xd3: num = buf[++_idx]; - if (num & 0x80) { // sign -> avoid overflow - return ((num ^ 0xff) * 0x100000000000000 + - (buf[++_idx] ^ 0xff) * 0x1000000000000 + - (buf[++_idx] ^ 0xff) * 0x10000000000 + - (buf[++_idx] ^ 0xff) * 0x100000000 + - (buf[++_idx] ^ 0xff) * 0x1000000 + - (buf[++_idx] ^ 0xff) * 0x10000 + - (buf[++_idx] ^ 0xff) * 0x100 + - (buf[++_idx] ^ 0xff) + 1) * -1; - } - return num * 0x100000000000000 + - buf[++_idx] * 0x1000000000000 + - buf[++_idx] * 0x10000000000 + - buf[++_idx] * 0x100000000 + - buf[++_idx] * 0x1000000 + - buf[++_idx] * 0x10000 + - buf[++_idx] * 0x100 + - buf[++_idx]; - case 0xd2: num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + - (buf[++_idx] << 8) + buf[++_idx]; - return num < 0x80000000 ? num : num - 0x100000000; // 0x80000000 * 2 - case 0xd1: num = (buf[++_idx] << 8) + buf[++_idx]; - return num < 0x8000 ? num : num - 0x10000; // 0x8000 * 2 - case 0xd0: num = buf[++_idx]; - return num < 0x80 ? num : num - 0x100; // 0x80 * 2 - // 0xdb: str32, 0xda: str16, 0xd9: str8, 0xa0: fixstr - case 0xdb: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xda: num += buf[++_idx] << 8; - case 0xd9: num += buf[++_idx]; - case 0xa0: // utf8.decode - for (ary = [], i = _idx, iz = i + num; i < iz; ) { - c = buf[++i]; // lead byte - ary.push(c < 0x80 ? c : // ASCII(0x00 ~ 0x7f) - c < 0xe0 ? ((c & 0x1f) << 6 | (buf[++i] & 0x3f)) : - ((c & 0x0f) << 12 | (buf[++i] & 0x3f) << 6 - | (buf[++i] & 0x3f))); - } - _idx = i; - return ary.length < 10240 ? _toString.apply(null, ary) - : byteArrayToByteString(ary); - // 0xc6: bin32, 0xc5: bin16, 0xc4: bin8 - case 0xc6: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xc5: num += buf[++_idx] << 8; - case 0xc4: num += buf[++_idx]; - var end = ++_idx + num - var ret = buf.slice(_idx, end); - _idx += num; - return ret; - // 0xdf: map32, 0xde: map16, 0x80: map - case 0xdf: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xde: num += (buf[++_idx] << 8) + buf[++_idx]; - case 0x80: hash = {}; - while (num--) { - // make key/value pair - size = buf[++_idx] - 0xa0; - - for (ary = [], i = _idx, iz = i + size; i < iz; ) { - c = buf[++i]; // lead byte - ary.push(c < 0x80 ? c : // ASCII(0x00 ~ 0x7f) - c < 0xe0 ? ((c & 0x1f) << 6 | (buf[++i] & 0x3f)) : - ((c & 0x0f) << 12 | (buf[++i] & 0x3f) << 6 - | (buf[++i] & 0x3f))); - } - _idx = i; - hash[_toString.apply(null, ary)] = decode(); - } - return hash; - // 0xdd: array32, 0xdc: array16, 0x90: array - case 0xdd: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xdc: num += (buf[++_idx] << 8) + buf[++_idx]; - case 0x90: ary = []; - while (num--) { - ary.push(decode()); - } - return ary; - } - return; -} - -// inner - byteArray To ByteString -function byteArrayToByteString(byteArray) { // @param ByteArray - // @return String - // http://d.hatena.ne.jp/uupaa/20101128 - try { - return _toString.apply(this, byteArray); // toString - } catch(err) { - ; // avoid "Maximum call stack size exceeded" - } - var rv = [], i = 0, iz = byteArray.length, num2bin = _num2bin; - - for (; i < iz; ++i) { - rv[i] = num2bin[byteArray[i]]; - } - return rv.join(""); -} - -// msgpack.download - load from server -function msgpackdownload(url, // @param String: - option, // @param Hash: { worker, timeout, before, after } - // option.worker - Boolean(= false): true is use WebWorkers - // option.timeout - Number(= 10): timeout sec - // option.before - Function: before(xhr, option) - // option.after - Function: after(xhr, option, { status, ok }) - callback) { // @param Function: callback(data, option, { status, ok }) - // data - Mix/null: - // option - Hash: - // status - Number: HTTP status code - // ok - Boolean: - option.method = "GET"; - option.binary = true; - ajax(url, option, callback); -} - -// msgpack.upload - save to server -function msgpackupload(url, // @param String: - option, // @param Hash: { data, worker, timeout, before, after } - // option.data - Mix: - // option.worker - Boolean(= false): true is use WebWorkers - // option.timeout - Number(= 10): timeout sec - // option.before - Function: before(xhr, option) - // option.after - Function: after(xhr, option, { status, ok }) - callback) { // @param Function: callback(data, option, { status, ok }) - // data - String: responseText - // option - Hash: - // status - Number: HTTP status code - // ok - Boolean: - option.method = "PUT"; - option.binary = true; - - if (option.worker && globalScope.Worker) { - var worker = new Worker(msgpack.worker); - - worker.onmessage = function(event) { - option.data = event.data; - ajax(url, option, callback); - }; - worker.postMessage({ method: "pack", data: option.data }); - } else { - // pack and base64 encode - option.data = base64encode(msgpackpack(option.data)); - ajax(url, option, callback); - } -} - -// inner - -function ajax(url, // @param String: - option, // @param Hash: { data, ifmod, method, timeout, - // header, binary, before, after, worker } - // option.data - Mix: upload data - // option.ifmod - Boolean: true is "If-Modified-Since" header - // option.method - String: "GET", "POST", "PUT" - // option.timeout - Number(= 10): timeout sec - // option.header - Hash(= {}): { key: "value", ... } - // option.binary - Boolean(= false): true is binary data - // option.before - Function: before(xhr, option) - // option.after - Function: after(xhr, option, { status, ok }) - // option.worker - Boolean(= false): true is use WebWorkers - callback) { // @param Function: callback(data, option, { status, ok }) - // data - String/Mix/null: - // option - Hash: - // status - Number: HTTP status code - // ok - Boolean: - function readyStateChange() { - if (xhr.readyState === 4) { - var data, status = xhr.status, worker, byteArray, - rv = { status: status, ok: status >= 200 && status < 300 }; - - if (!run++) { - if (method === "PUT") { - data = rv.ok ? xhr.responseText : ""; - } else { - if (rv.ok) { - if (option.worker && globalScope.Worker) { - worker = new Worker(msgpack.worker); - worker.onmessage = function(event) { - callback(event.data, option, rv); - }; - worker.postMessage({ method: "unpack", - data: xhr.responseText }); - gc(); - return; - } else { - byteArray = _ie ? toByteArrayIE(xhr) - : toByteArray(xhr.responseText); - data = msgpackunpack(byteArray); - } - } - } - after && after(xhr, option, rv); - callback(data, option, rv); - gc(); - } - } - } - - function ng(abort, status) { - if (!run++) { - var rv = { status: status || 400, ok: false }; - - after && after(xhr, option, rv); - callback(null, option, rv); - gc(abort); - } - } - - function gc(abort) { - abort && xhr && xhr.abort && xhr.abort(); - watchdog && (clearTimeout(watchdog), watchdog = 0); - xhr = null; - globalScope.addEventListener && - globalScope.removeEventListener("beforeunload", ng, false); - } - - var watchdog = 0, - method = option.method || "GET", - header = option.header || {}, - before = option.before, - after = option.after, - data = option.data || null, - xhr = globalScope.XMLHttpRequest ? new XMLHttpRequest() : - globalScope.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : - null, - run = 0, i, - overrideMimeType = "overrideMimeType", - setRequestHeader = "setRequestHeader", - getbinary = method === "GET" && option.binary; - - try { - xhr.onreadystatechange = readyStateChange; - xhr.open(method, url, true); // ASync - - before && before(xhr, option); - - getbinary && xhr[overrideMimeType] && - xhr[overrideMimeType]("text/plain; charset=x-user-defined"); - data && - xhr[setRequestHeader]("Content-Type", - "application/x-www-form-urlencoded"); - - for (i in header) { - xhr[setRequestHeader](i, header[i]); - } - - globalScope.addEventListener && - globalScope.addEventListener("beforeunload", ng, false); // 400: Bad Request - - xhr.send(data); - watchdog = setTimeout(function() { - ng(1, 408); // 408: Request Time-out - }, (option.timeout || 10) * 1000); - } catch (err) { - ng(0, 400); // 400: Bad Request - } -} - -// inner - BinaryString To ByteArray -function toByteArray(data) { // @param BinaryString: "\00\01" - // @return ByteArray: [0x00, 0x01] - var rv = [], bin2num = _bin2num, remain, - ary = data.split(""), - i = -1, iz; - - iz = ary.length; - remain = iz % 8; - - while (remain--) { - ++i; - rv[i] = bin2num[ary[i]]; - } - remain = iz >> 3; - while (remain--) { - rv.push(bin2num[ary[++i]], bin2num[ary[++i]], - bin2num[ary[++i]], bin2num[ary[++i]], - bin2num[ary[++i]], bin2num[ary[++i]], - bin2num[ary[++i]], bin2num[ary[++i]]); - } - return rv; -} - -// inner - BinaryString to ByteArray -function toByteArrayIE(xhr) { - var rv = [], data, remain, - charCodeAt = "charCodeAt", - loop, v0, v1, v2, v3, v4, v5, v6, v7, - i = -1, iz; - - iz = vblen(xhr); - data = vbstr(xhr); - loop = Math.ceil(iz / 2); - remain = loop % 8; - - while (remain--) { - v0 = data[charCodeAt](++i); // 0x00,0x01 -> 0x0100 - rv.push(v0 & 0xff, v0 >> 8); - } - remain = loop >> 3; - while (remain--) { - v0 = data[charCodeAt](++i); - v1 = data[charCodeAt](++i); - v2 = data[charCodeAt](++i); - v3 = data[charCodeAt](++i); - v4 = data[charCodeAt](++i); - v5 = data[charCodeAt](++i); - v6 = data[charCodeAt](++i); - v7 = data[charCodeAt](++i); - rv.push(v0 & 0xff, v0 >> 8, v1 & 0xff, v1 >> 8, - v2 & 0xff, v2 >> 8, v3 & 0xff, v3 >> 8, - v4 & 0xff, v4 >> 8, v5 & 0xff, v5 >> 8, - v6 & 0xff, v6 >> 8, v7 & 0xff, v7 >> 8); - } - iz % 2 && rv.pop(); - - return rv; -} - -// inner - base64.encode -function base64encode(data) { // @param ByteArray: - // @return Base64String: - var rv = [], - c = 0, i = -1, iz = data.length, - pad = [0, 2, 1][data.length % 3], - num2bin = _num2bin, - num2b64 = _num2b64; - - if (globalScope.btoa) { - while (i < iz) { - rv.push(num2bin[data[++i]]); - } - return btoa(rv.join("")); - } - --iz; - while (i < iz) { - c = (data[++i] << 16) | (data[++i] << 8) | (data[++i]); // 24bit - rv.push(num2b64[(c >> 18) & 0x3f], - num2b64[(c >> 12) & 0x3f], - num2b64[(c >> 6) & 0x3f], - num2b64[ c & 0x3f]); - } - pad > 1 && (rv[rv.length - 2] = "="); - pad > 0 && (rv[rv.length - 1] = "="); - return rv.join(""); -} - -// --- init --- -(function() { - var i = 0, v; - - for (; i < 0x100; ++i) { - v = _toString(i); - _bin2num[v] = i; // "\00" -> 0x00 - _num2bin[i] = v; // 0 -> "\00" - } - // http://twitter.com/edvakf/statuses/15576483807 - for (i = 0x80; i < 0x100; ++i) { // [Webkit][Gecko] - _bin2num[_toString(0xf700 + i)] = i; // "\f780" -> 0x80 - } -})(); - -_ie && document.write('