0f44575dd9173c5f2e21cb905a7ee836f1a6f07a6e31a301acc9d8e0120b814f1ea57b027c86fd0b9e38bd3eebd74a3bcde4df3ec26e4325f0e4a0ad9f3edc 3.2 KB

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