This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.9 KiB
109 lines
3.9 KiB
'use strict'; |
|
|
|
/** |
|
* Implementation of atob() according to the HTML spec, except that instead of |
|
* throwing INVALID_CHARACTER_ERR we return null. |
|
*/ |
|
function atob(input) { |
|
// WebIDL requires DOMStrings to just be converted using ECMAScript |
|
// ToString, which in our case amounts to calling String(). |
|
input = String(input); |
|
// "Remove all space characters from input." |
|
input = input.replace(/[ \t\n\f\r]/g, ''); |
|
// "If the length of input divides by 4 leaving no remainder, then: if |
|
// input ends with one or two U+003D EQUALS SIGN (=) characters, remove |
|
// them from input." |
|
if (input.length % 4 == 0 && /==?$/.test(input)) { |
|
input = input.replace(/==?$/, ''); |
|
} |
|
// "If the length of input divides by 4 leaving a remainder of 1, throw an |
|
// INVALID_CHARACTER_ERR exception and abort these steps." |
|
// |
|
// "If input contains a character that is not in the following list of |
|
// characters and character ranges, throw an INVALID_CHARACTER_ERR |
|
// exception and abort these steps: |
|
// |
|
// U+002B PLUS SIGN (+) |
|
// U+002F SOLIDUS (/) |
|
// U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9) |
|
// U+0041 LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z |
|
// U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z" |
|
if (input.length % 4 == 1 || !/^[+/0-9A-Za-z]*$/.test(input)) { |
|
return null; |
|
} |
|
// "Let output be a string, initially empty." |
|
var output = ''; |
|
// "Let buffer be a buffer that can have bits appended to it, initially |
|
// empty." |
|
// |
|
// We append bits via left-shift and or. accumulatedBits is used to track |
|
// when we've gotten to 24 bits. |
|
var buffer = 0; |
|
var accumulatedBits = 0; |
|
// "While position does not point past the end of input, run these |
|
// substeps:" |
|
for (var i = 0; i < input.length; i++) { |
|
// "Find the character pointed to by position in the first column of |
|
// the following table. Let n be the number given in the second cell of |
|
// the same row." |
|
// |
|
// "Append to buffer the six bits corresponding to number, most |
|
// significant bit first." |
|
// |
|
// atobLookup() implements the table from the spec. |
|
buffer <<= 6; |
|
buffer |= atobLookup(input[i]); |
|
// "If buffer has accumulated 24 bits, interpret them as three 8-bit |
|
// big-endian numbers. Append the three characters with code points |
|
// equal to those numbers to output, in the same order, and then empty |
|
// buffer." |
|
accumulatedBits += 6; |
|
if (accumulatedBits == 24) { |
|
output += String.fromCharCode((buffer & 0xff0000) >> 16); |
|
output += String.fromCharCode((buffer & 0xff00) >> 8); |
|
output += String.fromCharCode(buffer & 0xff); |
|
buffer = accumulatedBits = 0; |
|
} |
|
// "Advance position by one character." |
|
} |
|
// "If buffer is not empty, it contains either 12 or 18 bits. If it |
|
// contains 12 bits, discard the last four and interpret the remaining |
|
// eight as an 8-bit big-endian number. If it contains 18 bits, discard the |
|
// last two and interpret the remaining 16 as two 8-bit big-endian numbers. |
|
// Append the one or two characters with code points equal to those one or |
|
// two numbers to output, in the same order." |
|
if (accumulatedBits == 12) { |
|
buffer >>= 4; |
|
output += String.fromCharCode(buffer); |
|
} else if (accumulatedBits == 18) { |
|
buffer >>= 2; |
|
output += String.fromCharCode((buffer & 0xff00) >> 8); |
|
output += String.fromCharCode(buffer & 0xff); |
|
} |
|
// "Return output." |
|
return output; |
|
} |
|
/** |
|
* A lookup table for atob(), which converts an ASCII character to the |
|
* corresponding six-bit number. |
|
*/ |
|
function atobLookup(chr) { |
|
if (/[A-Z]/.test(chr)) { |
|
return chr.charCodeAt(0) - 'A'.charCodeAt(0); |
|
} |
|
if (/[a-z]/.test(chr)) { |
|
return chr.charCodeAt(0) - 'a'.charCodeAt(0) + 26; |
|
} |
|
if (/[0-9]/.test(chr)) { |
|
return chr.charCodeAt(0) - '0'.charCodeAt(0) + 52; |
|
} |
|
if (chr == '+') { |
|
return 62; |
|
} |
|
if (chr == '/') { |
|
return 63; |
|
} |
|
// Throw exception; should not be hit in tests |
|
} |
|
|
|
module.exports = atob;
|
|
|