Skip to main content
Module

std/encoding/_yaml/type/binary.ts

Deno standard library
Go to Latest
File
// 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-2022 the Deno authors. All rights reserved. MIT license.import { Type } from "../type.ts";import type { Any } from "../utils.ts";import { Buffer } from "../../../io/buffer.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): 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 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 Buffer { const buf = new Buffer(); try { if (0 > buf.readFromSync(obj as 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,});