l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

binary.js (3274B)


      1 'use strict';
      2 
      3 /*eslint-disable no-bitwise*/
      4 
      5 var NodeBuffer;
      6 
      7 try {
      8   // A trick for browserified version, to not include `Buffer` shim
      9   var _require = require;
     10   NodeBuffer = _require('buffer').Buffer;
     11 } catch (__) {}
     12 
     13 var Type       = require('../type');
     14 
     15 
     16 // [ 64, 65, 66 ] -> [ padding, CR, LF ]
     17 var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
     18 
     19 
     20 function resolveYamlBinary(data) {
     21   if (data === null) return false;
     22 
     23   var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
     24 
     25   // Convert one by one.
     26   for (idx = 0; idx < max; idx++) {
     27     code = map.indexOf(data.charAt(idx));
     28 
     29     // Skip CR/LF
     30     if (code > 64) continue;
     31 
     32     // Fail on illegal characters
     33     if (code < 0) return false;
     34 
     35     bitlen += 6;
     36   }
     37 
     38   // If there are any bits left, source was corrupted
     39   return (bitlen % 8) === 0;
     40 }
     41 
     42 function constructYamlBinary(data) {
     43   var idx, tailbits,
     44       input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
     45       max = input.length,
     46       map = BASE64_MAP,
     47       bits = 0,
     48       result = [];
     49 
     50   // Collect by 6*4 bits (3 bytes)
     51 
     52   for (idx = 0; idx < max; idx++) {
     53     if ((idx % 4 === 0) && idx) {
     54       result.push((bits >> 16) & 0xFF);
     55       result.push((bits >> 8) & 0xFF);
     56       result.push(bits & 0xFF);
     57     }
     58 
     59     bits = (bits << 6) | map.indexOf(input.charAt(idx));
     60   }
     61 
     62   // Dump tail
     63 
     64   tailbits = (max % 4) * 6;
     65 
     66   if (tailbits === 0) {
     67     result.push((bits >> 16) & 0xFF);
     68     result.push((bits >> 8) & 0xFF);
     69     result.push(bits & 0xFF);
     70   } else if (tailbits === 18) {
     71     result.push((bits >> 10) & 0xFF);
     72     result.push((bits >> 2) & 0xFF);
     73   } else if (tailbits === 12) {
     74     result.push((bits >> 4) & 0xFF);
     75   }
     76 
     77   // Wrap into Buffer for NodeJS and leave Array for browser
     78   if (NodeBuffer) {
     79     // Support node 6.+ Buffer API when available
     80     return NodeBuffer.from ? NodeBuffer.from(result) : new NodeBuffer(result);
     81   }
     82 
     83   return result;
     84 }
     85 
     86 function representYamlBinary(object /*, style*/) {
     87   var result = '', bits = 0, idx, tail,
     88       max = object.length,
     89       map = BASE64_MAP;
     90 
     91   // Convert every three bytes to 4 ASCII characters.
     92 
     93   for (idx = 0; idx < max; idx++) {
     94     if ((idx % 3 === 0) && idx) {
     95       result += map[(bits >> 18) & 0x3F];
     96       result += map[(bits >> 12) & 0x3F];
     97       result += map[(bits >> 6) & 0x3F];
     98       result += map[bits & 0x3F];
     99     }
    100 
    101     bits = (bits << 8) + object[idx];
    102   }
    103 
    104   // Dump tail
    105 
    106   tail = max % 3;
    107 
    108   if (tail === 0) {
    109     result += map[(bits >> 18) & 0x3F];
    110     result += map[(bits >> 12) & 0x3F];
    111     result += map[(bits >> 6) & 0x3F];
    112     result += map[bits & 0x3F];
    113   } else if (tail === 2) {
    114     result += map[(bits >> 10) & 0x3F];
    115     result += map[(bits >> 4) & 0x3F];
    116     result += map[(bits << 2) & 0x3F];
    117     result += map[64];
    118   } else if (tail === 1) {
    119     result += map[(bits >> 2) & 0x3F];
    120     result += map[(bits << 4) & 0x3F];
    121     result += map[64];
    122     result += map[64];
    123   }
    124 
    125   return result;
    126 }
    127 
    128 function isBinary(object) {
    129   return NodeBuffer && NodeBuffer.isBuffer(object);
    130 }
    131 
    132 module.exports = new Type('tag:yaml.org,2002:binary', {
    133   kind: 'scalar',
    134   resolve: resolveYamlBinary,
    135   construct: constructYamlBinary,
    136   predicate: isBinary,
    137   represent: representYamlBinary
    138 });