JavaScript 版的 TOML Encoder


原本是用在 Node.js 上的.但其實也可以用在 Client Side 裡.

測試一下代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script language="javascript" src="toml_encoder.js">
<script language="javascript">
var testData = {
'a': 1,
'b': [1, 2, 3],
'c': {
'a': 'apple',
'b': [4, 5, 6],
'c': "C\\Windows\\etc\\host",

'd': "\0",
'e': "\t",
'f': "\n",
'g': "\r",
'h': "'",
'i': "\\",
},
'd': true
};

var toml = new TOMLEncoder(),
data = toml.encode(testData);

console.log(data);
</script>

Encoder 的代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
function TOMLEncoder() {
}

TOMLEncoder.prototype.encode = function(toml) {
if (this.isObject(toml) === false) {
throw new Error("Encode data must JSON object");
}

var temp = [];
for(var key in toml) {
temp.push(this.process(key, toml[key]));
}

return temp.join('');
}

TOMLEncoder.prototype.process = function(key, value, parentKey) {
var temp = [];

if (this.isObject(value) === true) {
if (this.isAssoc(value) === true) {
temp.push(key + " = [" + this.implodeArray(",", value) + "] \n");
}else{
if (parentKey) {
key = parentKey + "." + key;
}
temp.push("[" + key + "] \n");
for(var k in value) {
temp.push(this.process(k, value[k], key));
}
}
}else{
var value = this.processValue(value);

temp.push(key + " = " + value + " \n");
}

return temp.join('');
}

TOMLEncoder.prototype.implodeArray = function(spliter, array) {
var i = 0, temp = [];

while(i < array.length) {
var value = array[i];

if (this.isObject(value) === true) {
temp.push("[" + this.implodeArray(",", value) + "]");
}else{
value = this.processValue(value);
temp.push(value);
}

if (i != array.length - 1) {
temp.push(",");
}

i++;
}

return temp.join('');
}

TOMLEncoder.prototype.processValue = function(value) {
if (this.isISODate(value) === true) {

}else if (this.isString(value) === true) {
value = this.processString(value);
}else if (this.isBoolean(value)) {
if (value)
value = "true";
else
value = "false"
}

return value;
}

TOMLEncoder.prototype.processString = function(value) {
var searchPattern = ["\0", "\t", "\n", "\r", '"', "\\\\"],
replacePattern = ['\\0', '\\t', '\\n', '\\r', '\"', '\\'];

for(var i=0; i<searchPattern.length; i++) {
value = value.replace(new RegExp(searchPattern[i], "gi"), replacePattern[i]);
}

value = '"' + value + '"';

return value;
}

TOMLEncoder.prototype.isObject = function(object) {
return (typeof object === "object")
}

TOMLEncoder.prototype.isAssoc = function(array) {
var self = this;

return (this.objectKeys(array).filter(function(value) {
return (self.isString(value) === true && isNaN(value) === true);
}).length === 0);
}

TOMLEncoder.prototype.isString = function(value) {
return (typeof value == "string");
}

TOMLEncoder.prototype.isISODate = function(value) {
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/.test(value);
}

TOMLEncoder.prototype.isBoolean = function(value) {
return (typeof value == "boolean");
}

TOMLEncoder.prototype.objectKeys = function(object) {
var keys = [];
for(var i in object) {
if (object.hasOwnProperty(i) === true) {
keys.push(i);
}
}
return keys;
}