9e3eff4decfd939d862794b5050bea83481795c9
[platform/framework/web/crosswalk-tizen.git] /
1 'use strict';
2
3 var common = require('../common');
4 var Type   = require('../type');
5
6 var YAML_FLOAT_PATTERN = new RegExp(
7   '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' +
8   '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' +
9   '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
10   '|[-+]?\\.(?:inf|Inf|INF)' +
11   '|\\.(?:nan|NaN|NAN))$');
12
13 function resolveYamlFloat(data) {
14   if (null === data) {
15     return false;
16   }
17
18   var value, sign, base, digits;
19
20   if (!YAML_FLOAT_PATTERN.test(data)) {
21     return false;
22   }
23   return true;
24 }
25
26 function constructYamlFloat(data) {
27   var value, sign, base, digits;
28
29   value  = data.replace(/_/g, '').toLowerCase();
30   sign   = '-' === value[0] ? -1 : 1;
31   digits = [];
32
33   if (0 <= '+-'.indexOf(value[0])) {
34     value = value.slice(1);
35   }
36
37   if ('.inf' === value) {
38     return (1 === sign) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
39
40   } else if ('.nan' === value) {
41     return NaN;
42
43   } else if (0 <= value.indexOf(':')) {
44     value.split(':').forEach(function (v) {
45       digits.unshift(parseFloat(v, 10));
46     });
47
48     value = 0.0;
49     base = 1;
50
51     digits.forEach(function (d) {
52       value += d * base;
53       base *= 60;
54     });
55
56     return sign * value;
57
58   } else {
59     return sign * parseFloat(value, 10);
60   }
61 }
62
63 function representYamlFloat(object, style) {
64   if (isNaN(object)) {
65     switch (style) {
66     case 'lowercase':
67       return '.nan';
68     case 'uppercase':
69       return '.NAN';
70     case 'camelcase':
71       return '.NaN';
72     }
73   } else if (Number.POSITIVE_INFINITY === object) {
74     switch (style) {
75     case 'lowercase':
76       return '.inf';
77     case 'uppercase':
78       return '.INF';
79     case 'camelcase':
80       return '.Inf';
81     }
82   } else if (Number.NEGATIVE_INFINITY === object) {
83     switch (style) {
84     case 'lowercase':
85       return '-.inf';
86     case 'uppercase':
87       return '-.INF';
88     case 'camelcase':
89       return '-.Inf';
90     }
91   } else if (common.isNegativeZero(object)) {
92     return '-0.0';
93   } else {
94     return object.toString(10);
95   }
96 }
97
98 function isFloat(object) {
99   return ('[object Number]' === Object.prototype.toString.call(object)) &&
100          (0 !== object % 1 || common.isNegativeZero(object));
101 }
102
103 module.exports = new Type('tag:yaml.org,2002:float', {
104   kind: 'scalar',
105   resolve: resolveYamlFloat,
106   construct: constructYamlFloat,
107   predicate: isFloat,
108   represent: representYamlFloat,
109   defaultStyle: 'lowercase'
110 });