121 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
						|
	Author Tobias Koppers @sokra
 | 
						|
*/
 | 
						|
 | 
						|
"use strict";
 | 
						|
 | 
						|
const ALPHABET =
 | 
						|
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
						|
 | 
						|
const CONTINUATION_BIT = 0x20;
 | 
						|
const END_SEGMENT_BIT = 0x40;
 | 
						|
const NEXT_LINE = END_SEGMENT_BIT | 0x01;
 | 
						|
const INVALID = END_SEGMENT_BIT | 0x02;
 | 
						|
const DATA_MASK = 0x1f;
 | 
						|
 | 
						|
const ccToValue = new Uint8Array("z".charCodeAt(0) + 1);
 | 
						|
 | 
						|
ccToValue.fill(INVALID);
 | 
						|
 | 
						|
for (let i = 0; i < ALPHABET.length; i++) {
 | 
						|
	ccToValue[ALPHABET.charCodeAt(i)] = i;
 | 
						|
}
 | 
						|
 | 
						|
ccToValue[",".charCodeAt(0)] = END_SEGMENT_BIT;
 | 
						|
ccToValue[";".charCodeAt(0)] = NEXT_LINE;
 | 
						|
 | 
						|
const ccMax = ccToValue.length - 1;
 | 
						|
 | 
						|
/** @typedef {(generatedLine: number, generatedColumn: number, sourceIndex: number, originalLine: number, originalColumn: number, nameIndex: number) => void} OnMapping */
 | 
						|
 | 
						|
/**
 | 
						|
 * @param {string} mappings the mappings string
 | 
						|
 * @param {OnMapping} onMapping called for each mapping
 | 
						|
 * @returns {void}
 | 
						|
 */
 | 
						|
const readMappings = (mappings, onMapping) => {
 | 
						|
	// generatedColumn, [sourceIndex, originalLine, orignalColumn, [nameIndex]]
 | 
						|
	const currentData = new Uint32Array([0, 0, 1, 0, 0]);
 | 
						|
	let currentDataPos = 0;
 | 
						|
	// currentValue will include a sign bit at bit 0
 | 
						|
	let currentValue = 0;
 | 
						|
	let currentValuePos = 0;
 | 
						|
	let generatedLine = 1;
 | 
						|
	let generatedColumn = -1;
 | 
						|
	for (let i = 0; i < mappings.length; i++) {
 | 
						|
		const cc = mappings.charCodeAt(i);
 | 
						|
		if (cc > ccMax) continue;
 | 
						|
		const value = ccToValue[cc];
 | 
						|
		if ((value & END_SEGMENT_BIT) !== 0) {
 | 
						|
			// End current segment
 | 
						|
			if (currentData[0] > generatedColumn) {
 | 
						|
				if (currentDataPos === 1) {
 | 
						|
					onMapping(generatedLine, currentData[0], -1, -1, -1, -1);
 | 
						|
				} else if (currentDataPos === 4) {
 | 
						|
					onMapping(
 | 
						|
						generatedLine,
 | 
						|
						currentData[0],
 | 
						|
						currentData[1],
 | 
						|
						currentData[2],
 | 
						|
						currentData[3],
 | 
						|
						-1,
 | 
						|
					);
 | 
						|
				} else if (currentDataPos === 5) {
 | 
						|
					onMapping(
 | 
						|
						generatedLine,
 | 
						|
						currentData[0],
 | 
						|
						currentData[1],
 | 
						|
						currentData[2],
 | 
						|
						currentData[3],
 | 
						|
						currentData[4],
 | 
						|
					);
 | 
						|
				}
 | 
						|
				[generatedColumn] = currentData;
 | 
						|
			}
 | 
						|
			currentDataPos = 0;
 | 
						|
			if (value === NEXT_LINE) {
 | 
						|
				// Start new line
 | 
						|
				generatedLine++;
 | 
						|
				currentData[0] = 0;
 | 
						|
				generatedColumn = -1;
 | 
						|
			}
 | 
						|
		} else if ((value & CONTINUATION_BIT) === 0) {
 | 
						|
			// last sextet
 | 
						|
			currentValue |= value << currentValuePos;
 | 
						|
			const finalValue =
 | 
						|
				currentValue & 1 ? -(currentValue >> 1) : currentValue >> 1;
 | 
						|
			currentData[currentDataPos++] += finalValue;
 | 
						|
			currentValuePos = 0;
 | 
						|
			currentValue = 0;
 | 
						|
		} else {
 | 
						|
			currentValue |= (value & DATA_MASK) << currentValuePos;
 | 
						|
			currentValuePos += 5;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	// End current segment
 | 
						|
	if (currentDataPos === 1) {
 | 
						|
		onMapping(generatedLine, currentData[0], -1, -1, -1, -1);
 | 
						|
	} else if (currentDataPos === 4) {
 | 
						|
		onMapping(
 | 
						|
			generatedLine,
 | 
						|
			currentData[0],
 | 
						|
			currentData[1],
 | 
						|
			currentData[2],
 | 
						|
			currentData[3],
 | 
						|
			-1,
 | 
						|
		);
 | 
						|
	} else if (currentDataPos === 5) {
 | 
						|
		onMapping(
 | 
						|
			generatedLine,
 | 
						|
			currentData[0],
 | 
						|
			currentData[1],
 | 
						|
			currentData[2],
 | 
						|
			currentData[3],
 | 
						|
			currentData[4],
 | 
						|
		);
 | 
						|
	}
 | 
						|
};
 | 
						|
 | 
						|
module.exports = readMappings;
 |