f77fbc08fa988910f73df86d67023fe8a1c6ffb059644c4853f4b5cb082d13abc56df156be00255075c85ed00c9c5769c6b60dc9b6b683980f0194e84d9f74 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. 'use strict';
  2. var common = require('../common');
  3. var Type = require('../type');
  4. function isHexCode(c) {
  5. return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
  6. ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
  7. ((0x61/* a */ <= c) && (c <= 0x66/* f */));
  8. }
  9. function isOctCode(c) {
  10. return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
  11. }
  12. function isDecCode(c) {
  13. return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
  14. }
  15. function resolveYamlInteger(data) {
  16. if (data === null) return false;
  17. var max = data.length,
  18. index = 0,
  19. hasDigits = false,
  20. ch;
  21. if (!max) return false;
  22. ch = data[index];
  23. // sign
  24. if (ch === '-' || ch === '+') {
  25. ch = data[++index];
  26. }
  27. if (ch === '0') {
  28. // 0
  29. if (index + 1 === max) return true;
  30. ch = data[++index];
  31. // base 2, base 8, base 16
  32. if (ch === 'b') {
  33. // base 2
  34. index++;
  35. for (; index < max; index++) {
  36. ch = data[index];
  37. if (ch === '_') continue;
  38. if (ch !== '0' && ch !== '1') return false;
  39. hasDigits = true;
  40. }
  41. return hasDigits;
  42. }
  43. if (ch === 'x') {
  44. // base 16
  45. index++;
  46. for (; index < max; index++) {
  47. ch = data[index];
  48. if (ch === '_') continue;
  49. if (!isHexCode(data.charCodeAt(index))) return false;
  50. hasDigits = true;
  51. }
  52. return hasDigits;
  53. }
  54. // base 8
  55. for (; index < max; index++) {
  56. ch = data[index];
  57. if (ch === '_') continue;
  58. if (!isOctCode(data.charCodeAt(index))) return false;
  59. hasDigits = true;
  60. }
  61. return hasDigits;
  62. }
  63. // base 10 (except 0) or base 60
  64. for (; index < max; index++) {
  65. ch = data[index];
  66. if (ch === '_') continue;
  67. if (ch === ':') break;
  68. if (!isDecCode(data.charCodeAt(index))) {
  69. return false;
  70. }
  71. hasDigits = true;
  72. }
  73. if (!hasDigits) return false;
  74. // if !base60 - done;
  75. if (ch !== ':') return true;
  76. // base60 almost not used, no needs to optimize
  77. return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
  78. }
  79. function constructYamlInteger(data) {
  80. var value = data, sign = 1, ch, base, digits = [];
  81. if (value.indexOf('_') !== -1) {
  82. value = value.replace(/_/g, '');
  83. }
  84. ch = value[0];
  85. if (ch === '-' || ch === '+') {
  86. if (ch === '-') sign = -1;
  87. value = value.slice(1);
  88. ch = value[0];
  89. }
  90. if (value === '0') return 0;
  91. if (ch === '0') {
  92. if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
  93. if (value[1] === 'x') return sign * parseInt(value, 16);
  94. return sign * parseInt(value, 8);
  95. }
  96. if (value.indexOf(':') !== -1) {
  97. value.split(':').forEach(function (v) {
  98. digits.unshift(parseInt(v, 10));
  99. });
  100. value = 0;
  101. base = 1;
  102. digits.forEach(function (d) {
  103. value += (d * base);
  104. base *= 60;
  105. });
  106. return sign * value;
  107. }
  108. return sign * parseInt(value, 10);
  109. }
  110. function isInteger(object) {
  111. return (Object.prototype.toString.call(object)) === '[object Number]' &&
  112. (object % 1 === 0 && !common.isNegativeZero(object));
  113. }
  114. module.exports = new Type('tag:yaml.org,2002:int', {
  115. kind: 'scalar',
  116. resolve: resolveYamlInteger,
  117. construct: constructYamlInteger,
  118. predicate: isInteger,
  119. represent: {
  120. binary: function (object) { return '0b' + object.toString(2); },
  121. octal: function (object) { return '0' + object.toString(8); },
  122. decimal: function (object) { return object.toString(10); },
  123. hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }
  124. },
  125. defaultStyle: 'decimal',
  126. styleAliases: {
  127. binary: [ 2, 'bin' ],
  128. octal: [ 8, 'oct' ],
  129. decimal: [ 10, 'dec' ],
  130. hexadecimal: [ 16, 'hex' ]
  131. }
  132. });