mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 22:22:34 +03:00
140 lines
3.4 KiB
TypeScript
140 lines
3.4 KiB
TypeScript
// Loaded from https://deno.land/std@0.80.0/encoding/_yaml/type/binary.ts
|
|
|
|
|
|
// Ported from js-yaml v3.13.1:
|
|
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
|
|
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
|
import { Type } from "../type.ts";
|
|
import type { Any } from "../utils.ts";
|
|
|
|
// [ 64, 65, 66 ] -> [ padding, CR, LF ]
|
|
const BASE64_MAP =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
|
|
|
|
function resolveYamlBinary(data: Any): boolean {
|
|
if (data === null) return false;
|
|
|
|
let code: number;
|
|
let bitlen = 0;
|
|
const max = data.length;
|
|
const map = BASE64_MAP;
|
|
|
|
// Convert one by one.
|
|
for (let idx = 0; idx < max; idx++) {
|
|
code = map.indexOf(data.charAt(idx));
|
|
|
|
// Skip CR/LF
|
|
if (code > 64) continue;
|
|
|
|
// Fail on illegal characters
|
|
if (code < 0) return false;
|
|
|
|
bitlen += 6;
|
|
}
|
|
|
|
// If there are any bits left, source was corrupted
|
|
return bitlen % 8 === 0;
|
|
}
|
|
|
|
function constructYamlBinary(data: string): Deno.Buffer {
|
|
// remove CR/LF & padding to simplify scan
|
|
const input = data.replace(/[\r\n=]/g, "");
|
|
const max = input.length;
|
|
const map = BASE64_MAP;
|
|
|
|
// Collect by 6*4 bits (3 bytes)
|
|
|
|
const result = [];
|
|
let bits = 0;
|
|
for (let idx = 0; idx < max; idx++) {
|
|
if (idx % 4 === 0 && idx) {
|
|
result.push((bits >> 16) & 0xff);
|
|
result.push((bits >> 8) & 0xff);
|
|
result.push(bits & 0xff);
|
|
}
|
|
|
|
bits = (bits << 6) | map.indexOf(input.charAt(idx));
|
|
}
|
|
|
|
// Dump tail
|
|
|
|
const tailbits = (max % 4) * 6;
|
|
|
|
if (tailbits === 0) {
|
|
result.push((bits >> 16) & 0xff);
|
|
result.push((bits >> 8) & 0xff);
|
|
result.push(bits & 0xff);
|
|
} else if (tailbits === 18) {
|
|
result.push((bits >> 10) & 0xff);
|
|
result.push((bits >> 2) & 0xff);
|
|
} else if (tailbits === 12) {
|
|
result.push((bits >> 4) & 0xff);
|
|
}
|
|
|
|
return new Deno.Buffer(new Uint8Array(result));
|
|
}
|
|
|
|
function representYamlBinary(object: Uint8Array): string {
|
|
const max = object.length;
|
|
const map = BASE64_MAP;
|
|
|
|
// Convert every three bytes to 4 ASCII characters.
|
|
|
|
let result = "";
|
|
let bits = 0;
|
|
for (let idx = 0; idx < max; idx++) {
|
|
if (idx % 3 === 0 && idx) {
|
|
result += map[(bits >> 18) & 0x3f];
|
|
result += map[(bits >> 12) & 0x3f];
|
|
result += map[(bits >> 6) & 0x3f];
|
|
result += map[bits & 0x3f];
|
|
}
|
|
|
|
bits = (bits << 8) + object[idx];
|
|
}
|
|
|
|
// Dump tail
|
|
|
|
const tail = max % 3;
|
|
|
|
if (tail === 0) {
|
|
result += map[(bits >> 18) & 0x3f];
|
|
result += map[(bits >> 12) & 0x3f];
|
|
result += map[(bits >> 6) & 0x3f];
|
|
result += map[bits & 0x3f];
|
|
} else if (tail === 2) {
|
|
result += map[(bits >> 10) & 0x3f];
|
|
result += map[(bits >> 4) & 0x3f];
|
|
result += map[(bits << 2) & 0x3f];
|
|
result += map[64];
|
|
} else if (tail === 1) {
|
|
result += map[(bits >> 2) & 0x3f];
|
|
result += map[(bits << 4) & 0x3f];
|
|
result += map[64];
|
|
result += map[64];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function isBinary(obj: Any): obj is Deno.Buffer {
|
|
const buf = new Deno.Buffer();
|
|
try {
|
|
if (0 > buf.readFromSync(obj as Deno.Buffer)) return true;
|
|
return false;
|
|
} catch {
|
|
return false;
|
|
} finally {
|
|
buf.reset();
|
|
}
|
|
}
|
|
|
|
export const binary = new Type("tag:yaml.org,2002:binary", {
|
|
construct: constructYamlBinary,
|
|
kind: "scalar",
|
|
predicate: isBinary,
|
|
represent: representYamlBinary,
|
|
resolve: resolveYamlBinary,
|
|
});
|