3d6b02362c350e386eda27f55f74cbfc76c807ed8c7fbc96c393494aa78094c3c73b8ea5e99822256ea44e6cd677bd8da1e9a4ef64a95901dee2addf5425d8 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 && ch !== '_';
  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 && ch !== '_';
  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 && ch !== '_';
  62. }
  63. // base 10 (except 0) or base 60
  64. // value should not start with `_`;
  65. if (ch === '_') return false;
  66. for (; index < max; index++) {
  67. ch = data[index];
  68. if (ch === '_') continue;
  69. if (ch === ':') break;
  70. if (!isDecCode(data.charCodeAt(index))) {
  71. return false;
  72. }
  73. hasDigits = true;
  74. }
  75. // Should have digits and should not end with `_`
  76. if (!hasDigits || ch === '_') return false;
  77. // if !base60 - done;
  78. if (ch !== ':') return true;
  79. // base60 almost not used, no needs to optimize
  80. return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
  81. }
  82. function constructYamlInteger(data) {
  83. var value = data, sign = 1, ch, base, digits = [];
  84. if (value.indexOf('_') !== -1) {
  85. value = value.replace(/_/g, '');
  86. }
  87. ch = value[0];
  88. if (ch === '-' || ch === '+') {
  89. if (ch === '-') sign = -1;
  90. value = value.slice(1);
  91. ch = value[0];
  92. }
  93. if (value === '0') return 0;
  94. if (ch === '0') {
  95. if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
  96. if (value[1] === 'x') return sign * parseInt(value, 16);
  97. return sign * parseInt(value, 8);
  98. }
  99. if (value.indexOf(':') !== -1) {
  100. value.split(':').forEach(function (v) {
  101. digits.unshift(parseInt(v, 10));
  102. });
  103. value = 0;
  104. base = 1;
  105. digits.forEach(function (d) {
  106. value += (d * base);
  107. base *= 60;
  108. });
  109. return sign * value;
  110. }
  111. return sign * parseInt(value, 10);
  112. }
  113. function isInteger(object) {
  114. return (Object.prototype.toString.call(object)) === '[object Number]' &&
  115. (object % 1 === 0 && !common.isNegativeZero(object));
  116. }
  117. module.exports = new Type('tag:yaml.org,2002:int', {
  118. kind: 'scalar',
  119. resolve: resolveYamlInteger,
  120. construct: constructYamlInteger,
  121. predicate: isInteger,
  122. represent: {
  123. binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },
  124. octal: function (obj) { return obj >= 0 ? '0' + obj.toString(8) : '-0' + obj.toString(8).slice(1); },
  125. decimal: function (obj) { return obj.toString(10); },
  126. /* eslint-disable max-len */
  127. hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }
  128. },
  129. defaultStyle: 'decimal',
  130. styleAliases: {
  131. binary: [ 2, 'bin' ],
  132. octal: [ 8, 'oct' ],
  133. decimal: [ 10, 'dec' ],
  134. hexadecimal: [ 16, 'hex' ]
  135. }
  136. });