Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added Base64 global functions and helper class

  • Loading branch information...
commit 824b5fa6750502e41eb6eb0b852d8a8dbcb8ca15 1 parent b6102fa
@skyboy authored
View
222 skyboy/serialization/Base64Helper.as
@@ -0,0 +1,222 @@
+package skyboy.serialization {
+ /**
+ * Base64Helper by skyboy. June 29th 2011.
+ * Visit http://github.com/skyboy for documentation, updates
+ * and more free code.
+ *
+ *
+ * Copyright (c) 2010, skyboy
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software with
+ * restriction, with limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions and limitations:
+ *
+ * ^ Attribution will be given to:
+ * skyboy, http://www.kongregate.com/accounts/skyboy;
+ * http://github.com/skyboy; http://skybov.deviantart.com
+ *
+ * ^ Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer in all copies or
+ * substantial portions of the Software.
+ *
+ * ^ Redistributions of modified source code must be marked as such, with
+ * the modifications marked and ducumented and the modifer's name clearly
+ * listed as having modified the source code.
+ *
+ * ^ Redistributions of source code may not add to, subtract from, or in
+ * any other way modify the above copyright notice, this list of conditions,
+ * or the following disclaimer for any reason.
+ *
+ * ^ Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ * OR COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * OR OTHER LIABILITY,(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER AN ACTION OF IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING FROM, OUT OF, IN CONNECTION OR
+ * IN ANY OTHER WAY OUT OF THE USE OF OR OTHER DEALINGS WITH THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ import flash.utils.ByteArray;
+ /**
+ * ...
+ * @author skyboy
+ */
+ public class Base64Helper {
+ static internal const Base64Std:Vector.<uint> = new <uint>[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,61];
+ static internal const Base64FileName:Vector.<uint> = new <uint>[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,45,61];
+ static internal const Base64URL:Vector.<uint> = new <uint>[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,45,95,61];
+ static internal const Base64XMLTok:Vector.<uint> = new <uint>[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,46,45,61];
+ static internal const Base64XMLIdn:Vector.<uint> = new <uint>[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,95,58,61];
+ static internal const Base64ProgID1:Vector.<uint> = new <uint>[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,95,45,61];
+ static internal const Base64ProgID2:Vector.<uint> = new <uint>[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,46,95,61];
+ static internal const Base64RegExp:Vector.<uint> = new <uint>[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,33,45,61];
+ //static internal const Base64Std:Vector.<uint> = new <uint>[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,61];
+
+ static internal const Base64Stdr:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64FileNamer:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64URLr:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64XMLTokr:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64XMLIdnr:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64ProgID1r:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64ProgID2r:Vector.<uint> = new Vector.<uint>(256, true);
+ static internal const Base64RegExpr:Vector.<uint> = new Vector.<uint>(256, true);
+
+ private static function init():void {
+ var i:uint = 256, c:uint = uint(-1);
+ while (i--) {
+ Base64Stdr[i] = c;
+ Base64FileNamer[i] = c;
+ Base64URLr[i] = c;
+ Base64XMLTokr[i] = c;
+ Base64XMLIdnr[i] = c;
+ Base64ProgID1r[i] = c;
+ Base64ProgID2r[i] = c;
+ Base64RegExpr[i] = c;
+ }
+ c = 128;
+ i = 0x09;
+ Base64Stdr[i] = c;
+ Base64FileNamer[i] = c;
+ Base64URLr[i] = c;
+ Base64XMLTokr[i] = c;
+ Base64XMLIdnr[i] = c;
+ Base64ProgID1r[i] = c;
+ Base64ProgID2r[i] = c;
+ Base64RegExpr[i] = c;
+ i = 0x0A;
+ Base64Stdr[i] = c;
+ Base64FileNamer[i] = c;
+ Base64URLr[i] = c;
+ Base64XMLTokr[i] = c;
+ Base64XMLIdnr[i] = c;
+ Base64ProgID1r[i] = c;
+ Base64ProgID2r[i] = c;
+ Base64RegExpr[i] = c;
+ i = 0x0D;
+ Base64Stdr[i] = c;
+ Base64FileNamer[i] = c;
+ Base64URLr[i] = c;
+ Base64XMLTokr[i] = c;
+ Base64XMLIdnr[i] = c;
+ Base64ProgID1r[i] = c;
+ Base64ProgID2r[i] = c;
+ Base64RegExpr[i] = c;
+ i = 0x20;
+ Base64Stdr[i] = c;
+ Base64FileNamer[i] = c;
+ Base64URLr[i] = c;
+ Base64XMLTokr[i] = c;
+ Base64XMLIdnr[i] = c;
+ Base64ProgID1r[i] = c;
+ Base64ProgID2r[i] = c;
+ Base64RegExpr[i] = c;
+ for (i = 65; i--; ) {
+ Base64Stdr[Base64Std[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64FileNamer[Base64FileName[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64URLr[Base64URL[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64XMLTokr[Base64XMLTok[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64XMLIdnr[Base64XMLIdn[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64ProgID1r[Base64ProgID1[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64ProgID2r[Base64ProgID2[i]] = i;
+ }
+ for (i = 65; i--; ) {
+ Base64RegExpr[Base64RegExp[i]] = i;
+ }
+ Base64Std.fixed = true;
+ Base64FileName.fixed = true;
+ Base64URL.fixed = true;
+ Base64XMLTok.fixed = true;
+ Base64XMLIdn.fixed = true;
+ Base64ProgID1.fixed = true;
+ Base64ProgID2.fixed = true;
+ Base64RegExp.fixed = true;
+ }
+ init();
+
+ private static const string:Function = {}.toString;
+ static internal function PString(obj:*):String {
+ return (obj == null ? (obj === undefined ? "[object void]" : "[object Null]") : string.call(obj));
+ }
+
+ public static function encode(input:*, options:uint = 0, breakAt:uint = 64):* {
+ return encodeBase64(input, options, breakAt);
+ }
+ public function decode(input:*, options:uint = 0):* {
+ return decodeBase64(input, options);
+ }
+
+ /**
+ * Return types
+ */
+ public static const RETURN_STRING:uint = 0;
+ public static const RETURN_BYTEARRAY:uint = 1;
+ public static const RETURN_INTVECTOR:uint = 2;
+ public static const RETURN_ARRAY:uint = 3; // two bits (2)
+
+ /**
+ * Padding
+ */
+ public static const PAD:uint = 0 << 2;
+ public static const NO_PAD:uint = 1 << 2; // 1 bit (3)
+
+ /**
+ * Encoding types
+ */
+ public static const STANDARD:uint = 0 << 3;
+ public static const FILE_NAME:uint = 1 << 3;
+ public static const URL:uint = 2 << 3;
+ public static const XML_TOKEN:uint = 3 << 3;
+ public static const XML_IDENTIFIER:uint = 4 << 3;
+ public static const PROGRAM_IDENTIFIER_1:uint = 5 << 3;
+ public static const PROGRAM_IDENTIFIER_2:uint = 6 << 3;
+ public static const REGULAR_EXPRESSION:uint = 7 << 3;
+ //public static const name:uint = val;
+ //public static const CUSTOM_ENCODING:uint = 15 << 3; // 4 bits (7)
+
+ /**
+ * New line options
+ */
+ public static const BREAK_AT_64:uint = 0 << 7;
+ public static const BREAK_AT_VAL:uint = 1 << 7;
+ public static const NO_BREAK:uint = 2 << 7;
+ public static const BREAK_AT_76:uint = 3 << 7; // two bits (9)
+
+ /**
+ * Validation options
+ */
+ public static const ERROR_ON_UNKNOWN:uint = 0 << 9;
+ public static const IGNORE_UNKNOWN:uint = 1 << 9; // 1 bit (10)
+
+ public static const IGNORE_WHITESPACE:uint = 0 << 10;
+ public static const ERROR_ON_WHITESPACE:uint = 1 << 10; // 1 bit (11)
+
+ public static const NO_CHECKSUM:uint = 0 << 11;
+ public static const CRC18_CHECKSUM:uint = 1 << 11; // 1 bit so far.
+ }
+}
View
294 skyboy/serialization/decodeBase64.as
@@ -0,0 +1,294 @@
+package skyboy.serialization {
+ /**
+ * decodeBase64 by skyboy. June 29th 2011.
+ * Visit http://github.com/skyboy for documentation, updates
+ * and more free code.
+ *
+ *
+ * Copyright (c) 2010, skyboy
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software with
+ * restriction, with limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions and limitations:
+ *
+ * ^ Attribution will be given to:
+ * skyboy, http://www.kongregate.com/accounts/skyboy;
+ * http://github.com/skyboy; http://skybov.deviantart.com
+ *
+ * ^ Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer in all copies or
+ * substantial portions of the Software.
+ *
+ * ^ Redistributions of modified source code must be marked as such, with
+ * the modifications marked and ducumented and the modifer's name clearly
+ * listed as having modified the source code.
+ *
+ * ^ Redistributions of source code may not add to, subtract from, or in
+ * any other way modify the above copyright notice, this list of conditions,
+ * or the following disclaimer for any reason.
+ *
+ * ^ Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ * OR COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * OR OTHER LIABILITY,(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER AN ACTION OF IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING FROM, OUT OF, IN CONNECTION OR
+ * IN ANY OTHER WAY OUT OF THE USE OF OR OTHER DEALINGS WITH THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ import flash.utils.ByteArray;
+
+ public function decodeBase64(input:*, options:uint = 0):* {
+ var decode:ByteArray, out:ByteArray = median;
+ var ops:uint = options >> 3 & 15;
+ const invalid:uint = uint(-1), pad:uint = 64, space:uint = 128;
+ var temp:Vector.<uint>;
+ if (!ops || (ops > 7)) {
+ EncMed = Base64Helper.Base64Stdr;
+ temp = Base64Helper.Base64Std;
+ } else if (ops == 1) {
+ EncMed = Base64Helper.Base64FileNamer;
+ temp = Base64Helper.Base64FileName;
+ } else if (ops == 2) {
+ EncMed = Base64Helper.Base64URLr;
+ temp = Base64Helper.Base64URL;
+ } else if (ops == 3) {
+ EncMed = Base64Helper.Base64XMLTokr;
+ temp = Base64Helper.Base64XMLTok;
+ } else if (ops == 4) {
+ EncMed = Base64Helper.Base64XMLIdnr;
+ temp = Base64Helper.Base64XMLIdn;
+ } else if (ops == 5) {
+ EncMed = Base64Helper.Base64ProgID1r;
+ temp = Base64Helper.Base64ProgID1;
+ } else if (ops == 6) {
+ EncMed = Base64Helper.Base64ProgID2r;
+ temp = Base64Helper.Base64ProgID2;
+ } else if (ops == 7) {
+ EncMed = Base64Helper.Base64RegExpr;
+ temp = Base64Helper.Base64RegExp;
+ }
+ if (input is ByteArray) {
+ decode = new ByteArray();
+ decode.writeBytes(input, 0, input.length);
+ } else if (input is String) {
+ decode = new ByteArray();
+ decode.writeUTFBytes(input);
+ } else if (input is Number) {
+ decode = new ByteArray();
+ decode.writeDouble(input);
+ } else if (input is Vector.<uint> || input is Vector.<int>) {
+ decode = new ByteArray();
+ var i:int = input.length, b:int, d:int = i * 4;
+ decode.length = d;
+ while (i % 4) decode[--d] = input[--i];
+ while (i) {
+ decode[--d] = input[--i];
+ decode[--d] = input[--i];
+ decode[--d] = input[--i];
+ decode[--d] = input[--i];
+ }
+ } else if (input is Array) {
+ decode = new ByteArray();
+ i = input.length, d = i * 4;
+ decode.length = d;
+ while (i % 4) decode[--d] = uint(input[--i]);
+ while (i) {
+ decode[--d] = uint(input[--i]);
+ decode[--d] = uint(input[--i]);
+ decode[--d] = uint(input[--i]);
+ decode[--d] = uint(input[--i]);
+ }
+ } else throw new Error("Unexpected " + Base64Helper.PString(input) + ".");
+ var c:int;
+ i = decode.length;
+ d = -1;
+ b = 0;
+ if (!((options >>> 10) & 1)) {
+ if ((options >>> 9) & 1) {
+ while (i--) {
+ if (EncMed[decode[++d]] <= 64) {
+ decode[b++] = decode[d];
+ }
+ }
+ } else {
+ while (i--) {
+ c = EncMed[decode[++d]];
+ if (c <= 64) {
+ decode[b++] = decode[d];
+ } else if (c == invalid) throw new Error("Unexpected character " + decode[d] + " @" + d);
+ }
+ }
+ decode.length = b;
+ } else {
+ while (i--) {
+ if (EncMed[decode[++d]] > 64) {
+ throw new Error("Unexpected character " + decode[d] + " @" + d);
+ }
+ }
+ }
+ if (options >> 11 & 1) {
+ i = decode.length;
+ while (EncMed[decode[--i]] == 64) void;
+ decode.length = ++i;
+ i = 0;
+ const SUMI:uint = 0xB704CE;
+ const SUMP:uint = 0x1864CFB;
+ const SUMA:uint = 0x1000000;
+ const AN:uint = 63;
+ var end:uint = decode.length - (decode.length % 75);
+ var i2:int = 0;
+ var i3:int = 0;
+ var tempBA:ByteArray = new ByteArray();
+ tempBA.length = decode.length;
+ while (i2 != end) {
+ tempBA.writeBytes(decode, i2, 72);
+ for (var sum:uint = SUMI, len:int = 36; len--; ) {
+ sum ^= decode[i2++] << 16;
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum ^= decode[i2++] << 16;
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ }
+ var tempi:int = int(decode[i2] == temp[sum >>> 12 & AN]);
+ tempi += int(decode[++i2] == temp[sum >>> 6 & AN]) + int(decode[++i2] == temp[sum & AN]);
+ if (tempi != 3) throw new Error("(CRC) Invalid Base64 data.");
+ i += 72;
+ ++i2;
+ }
+ len = (decode.length % 75) - 3;
+ if (len > 0) {
+ tempBA.writeBytes(decode, i2, len);
+ i += len - int(((len - 2) % 4) == 0); // an artifact of encoding means every 3 digits will jump in length by 1 more than normally expected
+ // ((len - 2) % 4) == 0 checks for this jump, and then corrects it by subtracting 1. the new jump ((len - 2) % 4) == 1 is handled without error
+ sum = SUMI;
+ while (len--) {
+ sum ^= decode[i2++] << 16;
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ sum <<= 1; sum ^= SUMP * int((sum & SUMA) != 0);
+ }
+ tempi = int(decode[i2] == temp[sum >>> 12 & AN]);
+ tempi += int(decode[++i2] == temp[sum >>> 6 & AN]) + int(decode[++i2] == temp[sum & AN]);
+ if (tempi != 3) throw new Error("(CRC) Invalid Base64 data.");
+ } else if (len + 3) throw new Error("(CRC) Invalid Base64 data.");
+ decode.clear();
+ decode.writeBytes(tempBA, 0, ++i);
+ }
+ i = decode.length
+ c = i % 4;
+ i >>>= 2;
+ var o:int = -1;
+ d = -1;
+ while (i--) {
+ b = EncMed[decode[++d]];
+ out[++o] = b << 2;
+ b = EncMed[decode[++d]];
+ out[o] |= b >> 4;
+ out[++o] = b << 4;
+ b = EncMed[decode[++d]];
+ out[o] |= b >> 2;
+ out[++o] = b << 6;
+ b = EncMed[decode[++d]];
+ out[o] |= b;
+ }
+ switch (c) {
+ case 1:
+ b = EncMed[decode[++d]];
+ out[++o] = b << 2;
+ break;
+ case 2:
+ b = EncMed[decode[++d]];
+ out[++o] = b << 2;
+ b = EncMed[decode[++d]];
+ out[o] |= b >> 4;
+ out[++o] = b << 4;
+ break;
+ case 3:
+ b = EncMed[decode[++d]];
+ out[++o] = b << 2;
+ b = EncMed[decode[++d]];
+ out[o] |= b >> 4;
+ out[++o] = b << 4;
+ b = EncMed[decode[++d]];
+ out[o] |= b >> 2;
+ out[++o] = b << 6;
+ break;
+ case 0:
+ default:
+ break;
+ }
+ ops = options & 3;
+ if (!ops) {
+ var rtnStr:String = out.readUTFBytes(o);
+ out.length = 0;
+ return rtnStr;
+ } else if (ops == 1) {
+ tempBA = new ByteArray();
+ tempBA.writeBytes(out, 0, o);
+ out.length = 0;
+ return tempBA;
+ } else if (ops == 2) {
+ var tempVec:Vector.<int> = new Vector.<int>(o);
+ decode = out;
+ i = o;
+ while (i % 4) { tempVec[--i] = decode[i]; }
+ while (i) {
+ tempVec[--i] = decode[i];
+ tempVec[--i] = decode[i];
+ tempVec[--i] = decode[i];
+ tempVec[--i] = decode[i];
+ }
+ decode.length = 0;
+ return tempVec;
+ } else {
+ var tempA:Array = new Array(o);
+ decode = out;
+ i = o;
+ while (i % 4) { tempA[--i] = decode[i]; }
+ while (i) {
+ tempA[--i] = decode[i];
+ tempA[--i] = decode[i];
+ tempA[--i] = decode[i];
+ tempA[--i] = decode[i];
+ }
+ tempBA.length = 0;
+ return tempA;
+ }
+ }
+}
+import flash.utils.ByteArray;
+internal const median:ByteArray = new ByteArray();
+internal var EncMed:Vector.<uint>;
View
381 skyboy/serialization/encodeBase64.as
@@ -0,0 +1,381 @@
+package skyboy.serialization {
+ /**
+ * encodeBase64 by skyboy. June 29th 2011.
+ * Visit http://github.com/skyboy for documentation, updates
+ * and more free code.
+ *
+ *
+ * Copyright (c) 2010, skyboy
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software with
+ * restriction, with limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions and limitations:
+ *
+ * ^ Attribution will be given to:
+ * skyboy, http://www.kongregate.com/accounts/skyboy;
+ * http://github.com/skyboy; http://skybov.deviantart.com
+ *
+ * ^ Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer in all copies or
+ * substantial portions of the Software.
+ *
+ * ^ Redistributions of modified source code must be marked as such, with
+ * the modifications marked and ducumented and the modifer's name clearly
+ * listed as having modified the source code.
+ *
+ * ^ Redistributions of source code may not add to, subtract from, or in
+ * any other way modify the above copyright notice, this list of conditions,
+ * or the following disclaimer for any reason.
+ *
+ * ^ Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ * OR COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * OR OTHER LIABILITY,(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER AN ACTION OF IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING FROM, OUT OF, IN CONNECTION OR
+ * IN ANY OTHER WAY OUT OF THE USE OF OR OTHER DEALINGS WITH THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ import flash.display.Bitmap;
+ import flash.display.BitmapData;
+ import flash.utils.ByteArray;
+ import skyboy.serialization.Base64Helper;
+ /**
+ * ...
+ * @author skyboy
+ */
+ public function encodeBase64(input:*, options:uint = 0, breakAt:uint = 64):* {
+ var ops:uint = options >> 3 & 15;
+ if (!ops || (ops > 7)) {
+ EncMed = Base64Helper.Base64Std;
+ } else if (ops == 1) {
+ EncMed = Base64Helper.Base64FileName;
+ } else if (ops == 2) {
+ EncMed = Base64Helper.Base64URL;
+ } else if (ops == 3) {
+ EncMed = Base64Helper.Base64XMLTok;
+ } else if (ops == 4) {
+ EncMed = Base64Helper.Base64XMLIdn;
+ } else if (ops == 5) {
+ EncMed = Base64Helper.Base64ProgID1;
+ } else if (ops == 6) {
+ EncMed = Base64Helper.Base64ProgID2;
+ } else if (ops == 7) {
+ EncMed = Base64Helper.Base64RegExp;
+ }
+ var pad:uint = EncMed[64];
+ if (input is ByteArray) encodeByteArray(input);
+ else if (input is String) {
+ tempBA = new ByteArray();
+ tempBA.writeUTFBytes(input);
+ encodeByteArray(tempBA);
+ } else if (input is Number) {
+ tempBA = new ByteArray();
+ tempBA.writeDouble(input);
+ encodeByteArray(tempBA);
+ } else if (input is Vector.<uint>) {
+ encodeUVector(input);
+ } else if (input is Vector.<int>) {
+ encodeIVector(input);
+ } else if (input is Bitmap) {
+ tempBD = input.bitmapData;
+ tempBA = tempBD.getPixels(input.rect);
+ encodeByteArray(tempBA);
+ } else if (input is BitmapData) {
+ tempBA = input.getPixels(input.rect);
+ encodeByteArray(tempBA);
+ } else throw new Error("Unexpected " + Base64Helper.PString(input) + ".");
+ if ((options >> 11) & 1) {
+ tempBA = median;
+ i = tempBA.length;
+ if (tempBA[--i] == pad) --tempBA.length;
+ if (tempBA[--i] == pad) --tempBA.length;
+ i = 0;
+ const SUMI:uint = 0xB704CE;
+ const SUMP:uint = 0x1864CFB;
+ const SUMA:uint = 0x1000000;
+ const AN:uint = 63;
+ var i2:int = 0;
+ tempBA = new ByteArray();
+ end = median.length;
+ tempBA.length = end + (end / 18 | 0);
+ end -= end % 72;
+ while (i != end) {
+ tempBA.writeBytes(median, i, 72);
+ for (var sum:uint = SUMI, len:int = 72, c:int = 8; len--; c = 8) {
+ sum ^= tempBA[i2++] << 16;
+ while (c--) {
+ sum <<= 1;
+ if (sum & SUMA) sum ^= SUMP;
+ }
+ }
+ //tempBA[i2] = EncMed[int(Math.random() * 64)];
+ tempBA[i2] = EncMed[sum >>> 12 & AN];
+ tempBA[++i2] = EncMed[sum >>> 6 & AN];
+ tempBA[++i2] = EncMed[sum & AN];
+ tempBA.position = ++i2;
+ i += 72;
+ }
+ len = median.length - end;
+ if (len) {
+ tempBA.writeBytes(median, end, len);
+ sum = SUMI;
+ for (c = 8; len--; c = 8) {
+ sum ^= tempBA[i2++] << 16;
+ while (c--) {
+ sum <<= 1;
+ if (sum & SUMA) sum ^= SUMP;
+ }
+ }
+ //tempBA[i2] = EncMed[int(Math.random() * 64)];
+ tempBA[i2] = EncMed[sum >>> 12 & AN];
+ tempBA[++i2] = EncMed[sum >>> 6 & AN];
+ tempBA[++i2] = EncMed[sum & AN];
+ }
+ if (!((options >> 2) & 1)) if (i2 % 3) {
+ tempBA[++i2] = pad;
+ if (i2 % 3) tempBA[++i2] = pad;
+ }
+ median.writeBytes(tempBA, 0, i2 + 1);
+ median.position = 0;
+ } else if ((options >> 2) & 1) {
+ tempBA = median;
+ i = tempBA.length;
+ if (tempBA[--i] == pad) --tempBA.length;
+ if (tempBA[--i] == pad) --tempBA.length;
+ }
+ ops = options >> 7 & 3;
+ if (ops != 2) {
+ if (ops == 0 || !breakAt) {
+ breakAt = 64;
+ } else if (ops == 3) {
+ breakAt = 76;
+ }
+ i = 0;
+ len = median.length % breakAt;
+ var end:uint = median.length - len;
+ tempBA = new ByteArray();
+ while (i != end) {
+ tempBA.writeBytes(median, i, breakAt);
+ tempBA.writeByte(10);
+ i += breakAt;
+ }
+ if (len) tempBA.writeBytes(median, end, len);
+ median.writeBytes(tempBA, 0, tempBA.length);
+ median.position = 0;
+ //options = options >>> 2 << 2;
+ }
+ ops = options & 3;
+ if (!ops) {
+ var rtnStr:String = median.readUTFBytes(median.length);
+ median.length = 0;
+ return rtnStr;
+ } else if (ops == 1) {
+ var tempBA:ByteArray = new ByteArray();
+ tempBA.writeBytes(median, 0, median.length);
+ median.length = 0;
+ return tempBA;
+ } else if (ops == 2) {
+ var tempVec:Vector.<int> = new Vector.<int>(median.length);
+ tempBA = median;
+ var i:uint = tempBA.length;
+ while (i % 4) { tempVec[--i] = tempBA[i]; }
+ while (i) {
+ tempVec[--i] = tempBA[i];
+ tempVec[--i] = tempBA[i];
+ tempVec[--i] = tempBA[i];
+ tempVec[--i] = tempBA[i];
+ }
+ tempBA.length = 0;
+ return tempVec;
+ } else {
+ var temp:Array = new Array(median.length);
+ tempBA = median;
+ i = tempBA.length;
+ while (i % 4) { temp[--i] = tempBA[i]; }
+ while (i) {
+ temp[--i] = tempBA[i];
+ temp[--i] = tempBA[i];
+ temp[--i] = tempBA[i];
+ temp[--i] = tempBA[i];
+ }
+ tempBA.length = 0;
+ return temp;
+ }
+ var tempBD:BitmapData; // at the bottom to ensure last varaible after compiling
+ }
+}
+import flash.utils.ByteArray;
+internal const median:ByteArray = new ByteArray();
+internal var EncMed:Vector.<uint>;
+internal function encodeByteArray(a:ByteArray):void {
+ var o:ByteArray = median;
+ o.position = 0;
+ if (!a.length) {
+ throw new Error("Empty data.");
+ return;
+ }
+ var i:int = -1, j:int = i, e:int = a.length, b:int = e % 3;
+ var enc:Vector.<uint> = EncMed;
+ var pad:uint = enc[64];
+ o.length = (e + 2 - ((e + 2) % 3)) / 3 << 2;
+ if (b) {
+ if (b - 1) { // 2
+ b = o.length;
+ o[--b] = pad;
+ o[--b] = enc[(a[--e] & 15) << 2];
+ o[--b] = enc[(a[e] >> 4) | ((a[--e] & 3) << 4)];
+ o[--b] = enc[a[e] >> 2];
+ } else { // 1
+ b = o.length;
+ o[--b] = pad;
+ o[--b] = pad;
+ o[--b] = enc[(a[--e] & 3) << 4];
+ o[--b] = enc[a[e] >> 2];
+ }
+ if (!e) return;
+ }
+ while (e) {
+ o[++j] = enc[a[++i] >> 2];
+ o[++j] = enc[((a[i] & 3) << 4) | (a[++i] >> 4)];
+ o[++j] = enc[((a[i] & 15) << 2) | (a[++i] >> 6)];
+ o[++j] = enc[a[i] & 63];
+ e -= 3;
+ }
+}
+internal function encodeUVector(a:Vector.<uint>):void {
+ var o:ByteArray = median;
+ o.position = 0;
+ if (!a.length) {
+ throw new Error("Empty Vector<uint>.");
+ return;
+ }
+ var i:int = -1, j:int = i, e:int = a.length, b:int = e % 3;
+ var enc:Vector.<uint> = EncMed;
+ var pad:uint = enc[64];
+ e <<= 2;
+ o.length = (e + 2 - ((e + 2) % 3)) / 3 << 2;
+ e >>>= 2;
+ if (b) {
+ if (b - 1) { // 2
+ b = o.length;
+ o[--b] = pad;
+ o[--b] = pad;
+ o[--b] = enc[(a[--e] << 2) & 63];
+ o[--b] = enc[(a[e] >> 4) & 63];
+ o[--b] = enc[(a[e] >> 10) & 63];
+ o[--b] = enc[(a[e] >> 16) & 63];
+ o[--b] = enc[(a[e] >> 22) & 63];
+ o[--b] = enc[((a[e] << 4) | (a[--e] >>> 28)) & 63];
+ o[--b] = enc[(a[e] >> 2) & 63];
+ o[--b] = enc[(a[e] >> 8) & 63];
+ o[--b] = enc[(a[e] >> 14) & 63];
+ o[--b] = enc[(a[e] >> 20) & 63];
+ o[--b] = enc[a[e] >>> 26];
+ } else { // 1
+ b = o.length;
+ o[--b] = pad;
+ o[--b] = enc[(a[--e] << 4) & 63];
+ o[--b] = enc[(a[e] >> 2) & 63];
+ o[--b] = enc[(a[e] >> 8) & 63];
+ o[--b] = enc[(a[e] >> 14) & 63];
+ o[--b] = enc[(a[e] >> 20) & 63];
+ o[--b] = enc[a[e] >>> 26];
+ }
+ if (!e) return;
+ }
+ while (e) {
+ o[++j] = enc[(a[++i] >>> 26) & 63];
+ o[++j] = enc[(a[i] >> 20) & 63];
+ o[++j] = enc[(a[i] >> 14) & 63];
+ o[++j] = enc[(a[i] >> 8) & 63];
+ o[++j] = enc[(a[i] >> 2) & 63];
+ o[++j] = enc[((a[i] << 4) | (a[++i] >>> 28)) & 63];
+ o[++j] = enc[(a[i] >> 22) & 63];
+ o[++j] = enc[(a[i] >> 16) & 63];
+ o[++j] = enc[(a[i] >> 10) & 63];
+ o[++j] = enc[(a[i] >> 4) & 63];
+ o[++j] = enc[((a[i] << 2) | (a[++i] >>> 30)) & 63];
+ o[++j] = enc[(a[i] >> 24) & 63];
+ o[++j] = enc[(a[i] >> 18) & 63];
+ o[++j] = enc[(a[i] >> 12) & 63];
+ o[++j] = enc[(a[i] >> 6) & 63];
+ o[++j] = enc[a[i] & 63];
+ e -= 3;
+ }
+}
+internal function encodeIVector(a:Vector.<int>):void {
+ var o:ByteArray = median;
+ o.position = 0;
+ if (!a.length) {
+ throw new Error("Empty Vector<int>.");
+ return;
+ }
+ var i:int = -1, j:int = i, e:int = a.length, b:int = e % 3;
+ var enc:Vector.<uint> = EncMed;
+ var pad:uint = enc[64];
+ e <<= 2;
+ o.length = (e + 2 - ((e + 2) % 3)) / 3 << 2;
+ e >>>= 2;
+ if (b) {
+ if (b - 1) { // 2
+ b = o.length;
+ o[--b] = pad;
+ o[--b] = pad;
+ o[--b] = enc[(a[--e] << 2) & 63];
+ o[--b] = enc[(a[e] >> 4) & 63];
+ o[--b] = enc[(a[e] >> 10) & 63];
+ o[--b] = enc[(a[e] >> 16) & 63];
+ o[--b] = enc[(a[e] >> 22) & 63];
+ o[--b] = enc[((a[e] << 4) | (a[--e] >>> 28)) & 63];
+ o[--b] = enc[(a[e] >> 2) & 63];
+ o[--b] = enc[(a[e] >> 8) & 63];
+ o[--b] = enc[(a[e] >> 14) & 63];
+ o[--b] = enc[(a[e] >> 20) & 63];
+ o[--b] = enc[a[e] >>> 26];
+ } else { // 1
+ b = o.length;
+ o[--b] = pad;
+ o[--b] = enc[(a[--e] << 4) & 63];
+ o[--b] = enc[(a[e] >> 2) & 63];
+ o[--b] = enc[(a[e] >> 8) & 63];
+ o[--b] = enc[(a[e] >> 14) & 63];
+ o[--b] = enc[(a[e] >> 20) & 63];
+ o[--b] = enc[a[e] >>> 26];
+ }
+ if (!e) return;
+ }
+ while (e) {
+ o[++j] = enc[(a[++i] >>> 26) & 63];
+ o[++j] = enc[(a[i] >> 20) & 63];
+ o[++j] = enc[(a[i] >> 14) & 63];
+ o[++j] = enc[(a[i] >> 8) & 63];
+ o[++j] = enc[(a[i] >> 2) & 63];
+ o[++j] = enc[((a[i] << 4) | (a[++i] >>> 28)) & 63];
+ o[++j] = enc[(a[i] >> 22) & 63];
+ o[++j] = enc[(a[i] >> 16) & 63];
+ o[++j] = enc[(a[i] >> 10) & 63];
+ o[++j] = enc[(a[i] >> 4) & 63];
+ o[++j] = enc[((a[i] << 2) | (a[++i] >>> 30)) & 63];
+ o[++j] = enc[(a[i] >> 24) & 63];
+ o[++j] = enc[(a[i] >> 18) & 63];
+ o[++j] = enc[(a[i] >> 12) & 63];
+ o[++j] = enc[(a[i] >> 6) & 63];
+ o[++j] = enc[a[i] & 63];
+ e -= 3;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.