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.
		
		
		
		
		
			
		
			
				
					141 lines
				
				4.6 KiB
			
		
		
			
		
	
	
					141 lines
				
				4.6 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								/* -*- Mode: js; js-indent-level: 2; -*- */
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright 2011 Mozilla Foundation and contributors
							 | 
						||
| 
								 | 
							
								 * Licensed under the New BSD license. See LICENSE or:
							 | 
						||
| 
								 | 
							
								 * http://opensource.org/licenses/BSD-3-Clause
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Based on the Base 64 VLQ implementation in Closure Compiler:
							 | 
						||
| 
								 | 
							
								 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
							 | 
						||
| 
								 | 
							
								 * Redistribution and use in source and binary forms, with or without
							 | 
						||
| 
								 | 
							
								 * modification, are permitted provided that the following conditions are
							 | 
						||
| 
								 | 
							
								 * met:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *  * Redistributions of source code must retain the above copyright
							 | 
						||
| 
								 | 
							
								 *    notice, this list of conditions and the following disclaimer.
							 | 
						||
| 
								 | 
							
								 *  * Redistributions in binary form must reproduce the above
							 | 
						||
| 
								 | 
							
								 *    copyright notice, this list of conditions and the following
							 | 
						||
| 
								 | 
							
								 *    disclaimer in the documentation and/or other materials provided
							 | 
						||
| 
								 | 
							
								 *    with the distribution.
							 | 
						||
| 
								 | 
							
								 *  * Neither the name of Google Inc. nor the names of its
							 | 
						||
| 
								 | 
							
								 *    contributors may be used to endorse or promote products derived
							 | 
						||
| 
								 | 
							
								 *    from this software without specific prior written permission.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
							 | 
						||
| 
								 | 
							
								 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
							 | 
						||
| 
								 | 
							
								 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
							 | 
						||
| 
								 | 
							
								 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
							 | 
						||
| 
								 | 
							
								 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
							 | 
						||
| 
								 | 
							
								 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
							 | 
						||
| 
								 | 
							
								 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
							 | 
						||
| 
								 | 
							
								 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
							 | 
						||
| 
								 | 
							
								 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
							 | 
						||
| 
								 | 
							
								 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
							 | 
						||
| 
								 | 
							
								 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var base64 = require('./base64');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// A single base 64 digit can contain 6 bits of data. For the base 64 variable
							 | 
						||
| 
								 | 
							
								// length quantities we use in the source map spec, the first bit is the sign,
							 | 
						||
| 
								 | 
							
								// the next four bits are the actual value, and the 6th bit is the
							 | 
						||
| 
								 | 
							
								// continuation bit. The continuation bit tells us whether there are more
							 | 
						||
| 
								 | 
							
								// digits in this value following this digit.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//   Continuation
							 | 
						||
| 
								 | 
							
								//   |    Sign
							 | 
						||
| 
								 | 
							
								//   |    |
							 | 
						||
| 
								 | 
							
								//   V    V
							 | 
						||
| 
								 | 
							
								//   101011
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var VLQ_BASE_SHIFT = 5;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// binary: 100000
							 | 
						||
| 
								 | 
							
								var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// binary: 011111
							 | 
						||
| 
								 | 
							
								var VLQ_BASE_MASK = VLQ_BASE - 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// binary: 100000
							 | 
						||
| 
								 | 
							
								var VLQ_CONTINUATION_BIT = VLQ_BASE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Converts from a two-complement value to a value where the sign bit is
							 | 
						||
| 
								 | 
							
								 * placed in the least significant bit.  For example, as decimals:
							 | 
						||
| 
								 | 
							
								 *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
							 | 
						||
| 
								 | 
							
								 *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function toVLQSigned(aValue) {
							 | 
						||
| 
								 | 
							
								  return aValue < 0
							 | 
						||
| 
								 | 
							
								    ? ((-aValue) << 1) + 1
							 | 
						||
| 
								 | 
							
								    : (aValue << 1) + 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Converts to a two-complement value from a value where the sign bit is
							 | 
						||
| 
								 | 
							
								 * placed in the least significant bit.  For example, as decimals:
							 | 
						||
| 
								 | 
							
								 *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
							 | 
						||
| 
								 | 
							
								 *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function fromVLQSigned(aValue) {
							 | 
						||
| 
								 | 
							
								  var isNegative = (aValue & 1) === 1;
							 | 
						||
| 
								 | 
							
								  var shifted = aValue >> 1;
							 | 
						||
| 
								 | 
							
								  return isNegative
							 | 
						||
| 
								 | 
							
								    ? -shifted
							 | 
						||
| 
								 | 
							
								    : shifted;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Returns the base 64 VLQ encoded value.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								exports.encode = function base64VLQ_encode(aValue) {
							 | 
						||
| 
								 | 
							
								  var encoded = "";
							 | 
						||
| 
								 | 
							
								  var digit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var vlq = toVLQSigned(aValue);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  do {
							 | 
						||
| 
								 | 
							
								    digit = vlq & VLQ_BASE_MASK;
							 | 
						||
| 
								 | 
							
								    vlq >>>= VLQ_BASE_SHIFT;
							 | 
						||
| 
								 | 
							
								    if (vlq > 0) {
							 | 
						||
| 
								 | 
							
								      // There are still more digits in this value, so we must make sure the
							 | 
						||
| 
								 | 
							
								      // continuation bit is marked.
							 | 
						||
| 
								 | 
							
								      digit |= VLQ_CONTINUATION_BIT;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    encoded += base64.encode(digit);
							 | 
						||
| 
								 | 
							
								  } while (vlq > 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return encoded;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Decodes the next base 64 VLQ value from the given string and returns the
							 | 
						||
| 
								 | 
							
								 * value and the rest of the string via the out parameter.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
							 | 
						||
| 
								 | 
							
								  var strLen = aStr.length;
							 | 
						||
| 
								 | 
							
								  var result = 0;
							 | 
						||
| 
								 | 
							
								  var shift = 0;
							 | 
						||
| 
								 | 
							
								  var continuation, digit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  do {
							 | 
						||
| 
								 | 
							
								    if (aIndex >= strLen) {
							 | 
						||
| 
								 | 
							
								      throw new Error("Expected more digits in base 64 VLQ value.");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    digit = base64.decode(aStr.charCodeAt(aIndex++));
							 | 
						||
| 
								 | 
							
								    if (digit === -1) {
							 | 
						||
| 
								 | 
							
								      throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    continuation = !!(digit & VLQ_CONTINUATION_BIT);
							 | 
						||
| 
								 | 
							
								    digit &= VLQ_BASE_MASK;
							 | 
						||
| 
								 | 
							
								    result = result + (digit << shift);
							 | 
						||
| 
								 | 
							
								    shift += VLQ_BASE_SHIFT;
							 | 
						||
| 
								 | 
							
								  } while (continuation);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  aOutParam.value = fromVLQSigned(result);
							 | 
						||
| 
								 | 
							
								  aOutParam.rest = aIndex;
							 | 
						||
| 
								 | 
							
								};
							 |