comparison base64.js @ 35:3faa4e3eedac

Fix object structure for process input in perf test
author Chris Cannam
date Mon, 26 Sep 2016 16:18:44 +0100
parents
children
comparison
equal deleted inserted replaced
34:0eafc96a039c 35:3faa4e3eedac
1 'use strict'
2
3 if (typeof document === "undefined") {
4 exports.byteLength = byteLength
5 exports.toByteArray = toByteArray
6 exports.fromByteArray = fromByteArray
7 }
8
9 var lookup = []
10 var revLookup = []
11 var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
12
13 var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
14 for (var i = 0, len = code.length; i < len; ++i) {
15 lookup[i] = code[i]
16 revLookup[code.charCodeAt(i)] = i
17 }
18
19 revLookup['-'.charCodeAt(0)] = 62
20 revLookup['_'.charCodeAt(0)] = 63
21
22 function placeHoldersCount (b64) {
23 var len = b64.length
24 if (len % 4 > 0) {
25 throw new Error('Invalid string. Length must be a multiple of 4')
26 }
27
28 // the number of equal signs (place holders)
29 // if there are two placeholders, than the two characters before it
30 // represent one byte
31 // if there is only one, then the three characters before it represent 2 bytes
32 // this is just a cheap hack to not do indexOf twice
33 return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
34 }
35
36 function byteLength (b64) {
37 // base64 is 4/3 + up to two characters of the original data
38 return b64.length * 3 / 4 - placeHoldersCount(b64)
39 }
40
41 function toByteArray (b64) {
42 var i, j, l, tmp, placeHolders, arr
43 var len = b64.length
44 placeHolders = placeHoldersCount(b64)
45
46 arr = new Arr(len * 3 / 4 - placeHolders)
47
48 // if there are placeholders, only get up to the last complete 4 chars
49 l = placeHolders > 0 ? len - 4 : len
50
51 var L = 0
52
53 for (i = 0, j = 0; i < l; i += 4, j += 3) {
54 tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
55 arr[L++] = (tmp >> 16) & 0xFF
56 arr[L++] = (tmp >> 8) & 0xFF
57 arr[L++] = tmp & 0xFF
58 }
59
60 if (placeHolders === 2) {
61 tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
62 arr[L++] = tmp & 0xFF
63 } else if (placeHolders === 1) {
64 tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
65 arr[L++] = (tmp >> 8) & 0xFF
66 arr[L++] = tmp & 0xFF
67 }
68
69 return arr
70 }
71
72 function tripletToBase64 (num) {
73 return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
74 }
75
76 function encodeChunk (uint8, start, end) {
77 var tmp
78 var output = []
79 for (var i = start; i < end; i += 3) {
80 tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
81 output.push(tripletToBase64(tmp))
82 }
83 return output.join('')
84 }
85
86 function fromByteArray (uint8) {
87 var tmp
88 var len = uint8.length
89 var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
90 var output = ''
91 var parts = []
92 var maxChunkLength = 16383 // must be multiple of 3
93
94 // go through the array every three bytes, we'll deal with trailing stuff later
95 for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
96 parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
97 }
98
99 // pad the end with zeros, but make sure to not forget the extra bytes
100 if (extraBytes === 1) {
101 tmp = uint8[len - 1]
102 output += lookup[tmp >> 2]
103 output += lookup[(tmp << 4) & 0x3F]
104 output += '=='
105 } else if (extraBytes === 2) {
106 tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
107 output += lookup[tmp >> 10]
108 output += lookup[(tmp >> 4) & 0x3F]
109 output += lookup[(tmp << 2) & 0x3F]
110 output += '='
111 }
112
113 parts.push(output)
114
115 return parts.join('')
116 }