forked from SuperMap/iClient-JavaScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJSON.js
More file actions
309 lines (282 loc) · 11.9 KB
/
JSON.js
File metadata and controls
309 lines (282 loc) · 11.9 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/* Copyright© 2000 - 2021 SuperMap Software Co.Ltd. All rights reserved.
* This program are made available under the terms of the Apache License, Version 2.0
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
import {
SuperMap
} from '../SuperMap';
import {
Format
} from './Format';
/**
* @class SuperMap.Format.JSON
* @classdesc 安全的读写 JSON 的解析类。使用 {@link SuperMap.Format.JSON} 构造函数创建新实例。
* @category BaseTypes Format
* @param {Object} [options] - 参数。
* @param {string} [options.indent=" "] - 用于格式化输出,indent 字符串会在每次缩进的时候使用一次。
* @param {string} [options.space=" "] - 用于格式化输出,space 字符串会在名值对的 ":" 后边添加。
* @param {string} [options.newline="\n"] - 用于格式化输出, newline 字符串会用在每一个名值对或数组项末尾。
* @param {number} [options.level=0] - 用于格式化输出, 表示的是缩进级别。
* @param {boolean} [options.pretty=false] - 是否在序列化的时候使用额外的空格控制结构。在 write 方法中使用。
* @param {boolean} [options.nativeJSON] - 需要被注册的监听器对象。
* @extends {SuperMap.Format}
*/
export class JSONFormat extends Format {
constructor(options) {
super(options);
/**
* @member {string} [SuperMap.Format.JSON.prototype.indent=" "]
* @description 用于格式化输出,indent 字符串会在每次缩进的时候使用一次。
*/
this.indent = " ";
/**
* @member {string} [SuperMap.Format.JSON.prototype.space=" "]
* @description 用于格式化输出,space 字符串会在名值对的 ":" 后边添加。
*/
this.space = " ";
/**
* @member {string} [SuperMap.Format.JSON.prototype.newline="\n"]
* @description 用于格式化输出, newline 字符串会用在每一个名值对或数组项末尾。
*/
this.newline = "\n";
/**
* @member {integer} [SuperMap.Format.JSON.prototype.level=0]
* @description 用于格式化输出, 表示的是缩进级别。
*/
this.level = 0;
/**
* @member {boolean} [SuperMap.Format.JSON.prototype.pretty=false]
* @description 是否在序列化的时候使用额外的空格控制结构。在 write 方法中使用。
*/
this.pretty = false;
/**
* @member {boolean} SuperMap.Format.JSON.prototype.nativeJSON
* @description 判断浏览器是否原生支持 JSON 格式数据。
*/
this.nativeJSON = (function () {
return !!(window.JSON && typeof JSON.parse === "function" && typeof JSON.stringify === "function");
})();
this.CLASS_NAME = "SuperMap.Format.JSON";
/**
* @member SuperMap.Format.JSON.prototype.serialize
* @description 提供一些类型对象转 JSON 字符串的方法。
*/
this.serialize = {
/**
* @function SuperMap.Format.JSON.serialize.object
* @description 把对象转换为 JSON 字符串。
* @param {Object} object - 可序列化的对象。
* @returns {string} JSON 字符串。
*/
'object': function (object) {
// three special objects that we want to treat differently
if (object == null) {
return "null";
}
if (object.constructor === Date) {
return this.serialize.date.apply(this, [object]);
}
if (object.constructor === Array) {
return this.serialize.array.apply(this, [object]);
}
var pieces = ['{'];
this.level += 1;
var key, keyJSON, valueJSON;
var addComma = false;
for (key in object) {
if (object.hasOwnProperty(key)) {
// recursive calls need to allow for sub-classing
keyJSON = this.write.apply(this,
[key, this.pretty]);
valueJSON = this.write.apply(this,
[object[key], this.pretty]);
if (keyJSON != null && valueJSON != null) {
if (addComma) {
pieces.push(',');
}
pieces.push(this.writeNewline(), this.writeIndent(),
keyJSON, ':', this.writeSpace(), valueJSON);
addComma = true;
}
}
}
this.level -= 1;
pieces.push(this.writeNewline(), this.writeIndent(), '}');
return pieces.join('');
},
/**
* @function SuperMap.Format.JSON.serialize.array
* @description 把数组转换成 JSON 字符串。
* @param {Array} array - 可序列化的数组。
* @returns {string} JSON 字符串。
*/
'array': function (array) {
var json;
var pieces = ['['];
this.level += 1;
for (var i = 0, len = array.length; i < len; ++i) {
// recursive calls need to allow for sub-classing
json = this.write.apply(this,
[array[i], this.pretty]);
if (json != null) {
if (i > 0) {
pieces.push(',');
}
pieces.push(this.writeNewline(), this.writeIndent(), json);
}
}
this.level -= 1;
pieces.push(this.writeNewline(), this.writeIndent(), ']');
return pieces.join('');
},
/**
* @function SuperMap.Format.JSON.serialize.string
* @description 把字符串转换成 JSON 字符串。
* @param {string} string - 可序列化的字符串。
* @returns {string} JSON 字符串。
*/
'string': function (string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can simply slap some quotes around it.
// Otherwise we must also replace the offending characters with safe
// sequences.
var m = {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"': '\\"',
'\\': '\\\\'
};
/*eslint-disable no-control-regex*/
if (/["\\\x00-\x1f]/.test(string)) {
return '"' + string.replace(/([\x00-\x1f\\"])/g, function (a, b) {
var c = m[b];
if (c) {
return c;
}
c = b.charCodeAt();
return '\\u00' +
Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}) + '"';
}
return '"' + string + '"';
},
/**
* @function SuperMap.Format.JSON.serialize.number
* @description 把数字转换成 JSON 字符串。
* @param {number} number - 可序列化的数字。
* @returns {string} JSON 字符串。
*/
'number': function (number) {
return isFinite(number) ? String(number) : "null";
},
/**
* @function SuperMap.Format.JSON.serialize.boolean
* @description Transform a boolean into a JSON string.
* @param {boolean} bool - The boolean to be serialized.
* @returns {string} A JSON string representing the boolean.
*/
'boolean': function (bool) {
return String(bool);
},
/**
* @function SuperMap.Format.JSON.serialize.object
* @description 将日期对象转换成 JSON 字符串。
* @param {Date} date - 可序列化的日期对象。
* @returns {string} JSON 字符串。
*/
'date': function (date) {
function format(number) {
// Format integers to have at least two digits.
return (number < 10) ? '0' + number : number;
}
return '"' + date.getFullYear() + '-' +
format(date.getMonth() + 1) + '-' +
format(date.getDate()) + 'T' +
format(date.getHours()) + ':' +
format(date.getMinutes()) + ':' +
format(date.getSeconds()) + '"';
}
};
}
/**
* @function SuperMap.Format.JSON.prototype.read
* @description 将一个符合 JSON 结构的字符串进行解析。
* @param {string} json - 符合 JSON 结构的字符串。
* @param {function} filter - 过滤方法,最终结果的每一个键值对都会调用该过滤方法,并在对应的值的位置替换成该方法返回的值。
* @returns {Object} 对象,数组,字符串或数字。
*/
read(json, filter) {
var object;
if (this.nativeJSON) {
try {
object = JSON.parse(json, filter);
} catch (e) {
// Fall through if the regexp test fails.
}
}
if (this.keepData) {
this.data = object;
}
return object;
}
/**
* @function SuperMap.Format.JSON.prototype.write
* @description 序列化一个对象到一个符合 JSON 格式的字符串。
* @param {(object|string|Array|number|boolean)} value - 需要被序列化的对象,数组,字符串,数字,布尔值。
* @param {boolean} [pretty=false] - 是否在序列化的时候使用额外的空格控制结构。在 write 方法中使用。
* @returns {string} 符合 JSON 格式的字符串。
*
*/
write(value, pretty) {
this.pretty = !!pretty;
var json = null;
var type = typeof value;
if (this.serialize[type]) {
try {
json = (!this.pretty && this.nativeJSON) ?
JSON.stringify(value) :
this.serialize[type].apply(this, [value]);
} catch (err) {
//SuperMap.Console.error("Trouble serializing: " + err);
}
}
return json;
}
/**
* @function SuperMap.Format.JSON.prototype.writeIndent
* @description 根据缩进级别输出一个缩进字符串。
* @private
* @returns {string} 一个适当的缩进字符串。
*/
writeIndent() {
var pieces = [];
if (this.pretty) {
for (var i = 0; i < this.level; ++i) {
pieces.push(this.indent);
}
}
return pieces.join('');
}
/**
* @function SuperMap.Format.JSON.prototype.writeNewline
* @description 在格式化输出模式情况下输出代表新一行的字符串。
* @private
* @returns {string} 代表新的一行的字符串。
*/
writeNewline() {
return (this.pretty) ? this.newline : '';
}
/**
* @function SuperMap.Format.JSON.prototype.writeSpace
* @private
* @description 在格式化输出模式情况下输出一个代表空格的字符串。
* @returns {string} 一个空格。
*/
writeSpace() {
return (this.pretty) ? this.space : '';
}
}
SuperMap.Format.JSON = JSONFormat;