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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 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 91 92 93 94
|
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
module TypeScript {
class Base64Format {
static encodedValues = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
static encode(inValue: number) {
if (inValue < 64) {
return Base64Format.encodedValues.charAt(inValue);
}
throw TypeError(inValue + ": not a 64 based value");
}
static decodeChar(inChar: string) {
if (inChar.length === 1) {
return Base64Format.encodedValues.indexOf(inChar);
} else {
throw TypeError('"' + inChar + '" must have length 1');
}
}
}
export class Base64VLQFormat {
static encode(inValue: number) {
// Add a new least significant bit that has the sign of the value.
// if negative number the least significant bit that gets added to the number has value 1
// else least significant bit value that gets added is 0
// eg. -1 changes to binary : 01 [1] => 3
// +1 changes to binary : 01 [0] => 2
if (inValue < 0) {
inValue = ((-inValue) << 1) + 1;
}
else {
inValue = inValue << 1;
}
// Encode 5 bits at a time starting from least significant bits
var encodedStr = "";
do {
var currentDigit = inValue & 31; // 11111
inValue = inValue >> 5;
if (inValue > 0) {
// There are still more digits to decode, set the msb (6th bit)
currentDigit = currentDigit | 32;
}
encodedStr = encodedStr + Base64Format.encode(currentDigit);
} while (inValue > 0);
return encodedStr;
}
static decode(inString: string) {
var result = 0;
var negative = false;
var shift = 0;
for (var i = 0; i < inString.length; i++) {
var byte = Base64Format.decodeChar(inString[i]);
if (i === 0) {
// Sign bit appears in the LSBit of the first value
if ((byte & 1) === 1) {
negative = true;
}
result = (byte >> 1) & 15; // 1111x
} else {
result = result | ((byte & 31) << shift); // 11111
}
shift += (i === 0) ? 4 : 5;
if ((byte & 32) === 32) {
// Continue
} else {
return { value: negative ? -(result) : result, rest: inString.substr(i + 1) };
}
}
throw new Error(getDiagnosticMessage(DiagnosticCode.Base64_value_0_finished_with_a_continuation_bit, [inString]));
}
}
}
|