فهرست منبع

Cleanup and Test: base64.js

This is the first commit in a series of commits
which improve the readability of some of the code
and add tests.

File: base64.js
Tests Added: True
Changes:
- Improved indentation
- Fixed JSHint errors
- Moved loop variables to be declared in the loop for better readability
  (N.B. Javascript does not have block scoping, so the variables are
  still technically available outside the loop -- it just makes the code
  clearer to place them inside the loop, since they are only used there)
Solly Ross 11 سال پیش
والد
کامیت
f8e9b9f1bf
2فایلهای تغییر یافته به همراه129 افزوده شده و 98 حذف شده
  1. 96 98
      include/base64.js
  2. 33 0
      tests/test.base64.js

+ 96 - 98
include/base64.js

@@ -4,112 +4,110 @@
 
 // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js
 
-/*jslint white: false, bitwise: false, plusplus: false */
+/*jslint white: false */
 /*global console */
 
 var Base64 = {
+    /* Convert data (an array of integers) to a Base64 string. */
+    toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
+    base64Pad     : '=',
+
+    encode: function (data) {
+        "use strict";
+        var result = '';
+        var toBase64Table = Base64.toBase64Table;
+        var length = data.length;
+        var lengthpad = (length % 3);
+        // Convert every three bytes to 4 ascii characters.
+
+        for (var i = 0; i < (length - 2); i += 3) {
+            result += toBase64Table[data[i] >> 2];
+            result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
+            result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
+            result += toBase64Table[data[i + 2] & 0x3f];
+        }
 
-/* Convert data (an array of integers) to a Base64 string. */
-toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
-base64Pad     : '=',
-
-encode: function (data) {
-    "use strict";
-    var result = '';
-    var toBase64Table = Base64.toBase64Table;
-    var length = data.length
-    var lengthpad = (length%3);
-    var i = 0, j = 0;
-    // Convert every three bytes to 4 ascii characters.
-  /* BEGIN LOOP */
-    for (i = 0; i < (length - 2); i += 3) {
-        result += toBase64Table[data[i] >> 2];
-        result += toBase64Table[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
-        result += toBase64Table[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
-        result += toBase64Table[data[i+2] & 0x3f];
-    }
-  /* END LOOP */
-
-    // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
-    if (lengthpad === 2) {
-        j = length - lengthpad;
-        result += toBase64Table[data[j] >> 2];
-        result += toBase64Table[((data[j] & 0x03) << 4) + (data[j+1] >> 4)];
-        result += toBase64Table[(data[j+1] & 0x0f) << 2];
-        result += toBase64Table[64];
-    } else if (lengthpad === 1) {
-        j = length - lengthpad;
-        result += toBase64Table[data[j] >> 2];
-        result += toBase64Table[(data[j] & 0x03) << 4];
-        result += toBase64Table[64];
-        result += toBase64Table[64];
-    }
-
-    return result;
-},
-
-/* Convert Base64 data to a string */
-toBinaryTable : [
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
-    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
-    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
-    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
-    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
-],
-
-decode: function (data, offset) {
-    "use strict";
-    offset = typeof(offset) !== 'undefined' ? offset : 0;
-    var toBinaryTable = Base64.toBinaryTable;
-    var base64Pad = Base64.base64Pad;
-    var result, result_length, idx, i, c, padding;
-    var leftbits = 0; // number of bits decoded, but yet to be appended
-    var leftdata = 0; // bits decoded, but yet to be appended
-    var data_length = data.indexOf('=') - offset;
-
-    if (data_length < 0) { data_length = data.length - offset; }
-
-    /* Every four characters is 3 resulting numbers */
-    result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5);
-    result = new Array(result_length);
-
-    // Convert one by one.
-  /* BEGIN LOOP */
-    for (idx = 0, i = offset; i < data.length; i++) {
-        c = toBinaryTable[data.charCodeAt(i) & 0x7f];
-        padding = (data.charAt(i) === base64Pad);
-        // Skip illegal characters and whitespace
-        if (c === -1) {
-            console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
-            continue;
+        // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
+        var j = 0;
+        if (lengthpad === 2) {
+            j = length - lengthpad;
+            result += toBase64Table[data[j] >> 2];
+            result += toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
+            result += toBase64Table[(data[j + 1] & 0x0f) << 2];
+            result += toBase64Table[64];
+        } else if (lengthpad === 1) {
+            j = length - lengthpad;
+            result += toBase64Table[data[j] >> 2];
+            result += toBase64Table[(data[j] & 0x03) << 4];
+            result += toBase64Table[64];
+            result += toBase64Table[64];
         }
-        
-        // Collect data into leftdata, update bitcount
-        leftdata = (leftdata << 6) | c;
-        leftbits += 6;
 
-        // If we have 8 or more bits, append 8 bits to the result
-        if (leftbits >= 8) {
-            leftbits -= 8;
-            // Append if not padding.
-            if (!padding) {
-                result[idx++] = (leftdata >> leftbits) & 0xff;
+        return result;
+    },
+
+    /* Convert Base64 data to a string */
+    /* jshint -W013 */
+    toBinaryTable : [
+        -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+        -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+        -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+        52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
+        -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+        15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+        -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+        41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+    ],
+    /* jshint +W013 */
+
+    decode: function (data, offset) {
+        "use strict";
+        offset = typeof(offset) !== 'undefined' ? offset : 0;
+        var toBinaryTable = Base64.toBinaryTable;
+        var base64Pad = Base64.base64Pad;
+        var result, result_length;
+        var leftbits = 0; // number of bits decoded, but yet to be appended
+        var leftdata = 0; // bits decoded, but yet to be appended
+        var data_length = data.indexOf('=') - offset;
+
+        if (data_length < 0) { data_length = data.length - offset; }
+
+        /* Every four characters is 3 resulting numbers */
+        result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5);
+        result = new Array(result_length);
+
+        // Convert one by one.
+        for (var idx = 0, i = offset; i < data.length; i++) {
+            var c = toBinaryTable[data.charCodeAt(i) & 0x7f];
+            var padding = (data.charAt(i) === base64Pad);
+            // Skip illegal characters and whitespace
+            if (c === -1) {
+                console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
+                continue;
+            }
+          
+            // Collect data into leftdata, update bitcount
+            leftdata = (leftdata << 6) | c;
+            leftbits += 6;
+
+            // If we have 8 or more bits, append 8 bits to the result
+            if (leftbits >= 8) {
+                leftbits -= 8;
+                // Append if not padding.
+                if (!padding) {
+                    result[idx++] = (leftdata >> leftbits) & 0xff;
+                }
+                leftdata &= (1 << leftbits) - 1;
             }
-            leftdata &= (1 << leftbits) - 1;
         }
-    }
-  /* END LOOP */
 
-    // If there are any bits left, the base64 string was corrupted
-    if (leftbits) {
-        throw {name: 'Base64-Error', 
-               message: 'Corrupted base64 string'};
-    }
-
-    return result;
-}
+        // If there are any bits left, the base64 string was corrupted
+        if (leftbits) {
+            err = new Error('Corrupted base64 string');
+            err.name = 'Base64-Error';
+            throw err;
+        }
 
+        return result;
+    }
 }; /* End of Base64 namespace */

+ 33 - 0
tests/test.base64.js

@@ -0,0 +1,33 @@
+// requires local modules: base64
+var assert = chai.assert;
+var expect = chai.expect;
+
+describe('Base64 Tools', function() {
+    "use strict";
+
+    var BIN_ARR = new Array(256);
+    for (var i = 0; i < 256; i++) {
+        BIN_ARR[i] = i;
+    }
+    
+    var B64_STR = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==";
+
+
+    describe('encode', function() {
+        it('should encode a binary string into Base64', function() {
+            var encoded = Base64.encode(BIN_ARR);
+            expect(encoded).to.equal(B64_STR);
+        });
+    });
+
+    describe('decode', function() {
+        it('should decode a Base64 string into a normal string', function() {
+            var decoded = Base64.decode(B64_STR);
+            expect(decoded).to.deep.equal(BIN_ARR);
+        });
+
+        it('should throw an error if we have extra characters at the end of the string', function() {
+            expect(function () { Base64.decode(B64_STR+'abcdef'); }).to.throw(Error);
+        });
+    });
+});