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.
69 lines
1.8 KiB
69 lines
1.8 KiB
var toArr = require('./toArr'); |
|
|
|
exports = { |
|
encode: function(arr) { |
|
arr = toArr(arr); |
|
var ret = ''; |
|
for (var i = 0, len = arr.length; i < len; i++) { |
|
ret += encode(arr[i]); |
|
} |
|
return ret; |
|
}, |
|
decode: function(str) { |
|
var ret = []; |
|
var i = 0; |
|
var len = str.length; |
|
while (i < len) { |
|
var value = 0; |
|
var continuation = false; |
|
var shift = 0; |
|
do { |
|
var digit = charToInt[str[i++]]; |
|
continuation = (digit & VLQ_CONTINUATION_BIT) !== 0; |
|
digit &= VLQ_BASE_MASK; |
|
value = value + (digit << shift); |
|
shift = shift + VLQ_BASE_SHIFT; |
|
} while (continuation); |
|
ret.push(fromVLQSigned(value)); |
|
} |
|
return ret; |
|
} |
|
}; |
|
var charToInt = {}; |
|
var intToChar = {}; |
|
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; |
|
for (var i = 0, len = chars.length; i < len; i++) { |
|
charToInt[chars[i]] = i; |
|
intToChar[i] = chars[i]; |
|
} |
|
var VLQ_BASE_SHIFT = 5; |
|
var VLQ_BASE = 1 << VLQ_BASE_SHIFT; |
|
var VLQ_BASE_MASK = VLQ_BASE - 1; |
|
var VLQ_CONTINUATION_BIT = VLQ_BASE; |
|
function encode(value) { |
|
var ret = ''; |
|
value = toVLQSigned(value); |
|
do { |
|
var digit = value & VLQ_BASE_MASK; |
|
value >>>= VLQ_BASE_SHIFT; |
|
if (value > 0) { |
|
digit |= VLQ_CONTINUATION_BIT; |
|
} |
|
ret += intToChar[digit]; |
|
} while (value > 0); |
|
return ret; |
|
} |
|
function toVLQSigned(value) { |
|
if (value < 0) { |
|
return (-value << 1) + 1; |
|
} else { |
|
return (value << 1) + 0; |
|
} |
|
} |
|
function fromVLQSigned(value) { |
|
var negate = (value & 1) === 1; |
|
value = value >> 1; |
|
return negate ? -value : value; |
|
} |
|
|
|
module.exports = exports;
|
|
|