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