node-opcua-factory 2.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/dist/constructor_type.d.ts +15 -0
- package/dist/constructor_type.js +3 -0
- package/dist/constructor_type.js.map +1 -0
- package/dist/datatype_factory.d.ts +40 -0
- package/dist/datatype_factory.js +330 -0
- package/dist/datatype_factory.js.map +1 -0
- package/dist/factories_baseobject.d.ts +56 -0
- package/dist/factories_baseobject.js +498 -0
- package/dist/factories_baseobject.js.map +1 -0
- package/dist/factories_basic_type.d.ts +40 -0
- package/dist/factories_basic_type.js +136 -0
- package/dist/factories_basic_type.js.map +1 -0
- package/dist/factories_builtin_types.d.ts +32 -0
- package/dist/factories_builtin_types.js +262 -0
- package/dist/factories_builtin_types.js.map +1 -0
- package/dist/factories_builtin_types_special.d.ts +5 -0
- package/dist/factories_builtin_types_special.js +46 -0
- package/dist/factories_builtin_types_special.js.map +1 -0
- package/dist/factories_enumerations.d.ts +31 -0
- package/dist/factories_enumerations.js +77 -0
- package/dist/factories_enumerations.js.map +1 -0
- package/dist/factories_factories.d.ts +17 -0
- package/dist/factories_factories.js +54 -0
- package/dist/factories_factories.js.map +1 -0
- package/dist/factories_id_generator.d.ts +3 -0
- package/dist/factories_id_generator.js +22 -0
- package/dist/factories_id_generator.js.map +1 -0
- package/dist/factories_schema_helpers.d.ts +26 -0
- package/dist/factories_schema_helpers.js +121 -0
- package/dist/factories_schema_helpers.js.map +1 -0
- package/dist/factories_structuredTypeSchema.d.ts +46 -0
- package/dist/factories_structuredTypeSchema.js +269 -0
- package/dist/factories_structuredTypeSchema.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +111 -0
- package/dist/types.js +56 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
- package/source/constructor_type.ts +18 -0
- package/source/datatype_factory.ts +368 -0
- package/source/factories_baseobject.ts +567 -0
- package/source/factories_basic_type.ts +168 -0
- package/source/factories_builtin_types.ts +381 -0
- package/source/factories_builtin_types_special.ts +55 -0
- package/source/factories_enumerations.ts +97 -0
- package/source/factories_factories.ts +58 -0
- package/source/factories_id_generator.ts +18 -0
- package/source/factories_schema_helpers.ts +125 -0
- package/source/factories_structuredTypeSchema.ts +330 -0
- package/source/index.ts +15 -0
- package/source/types.ts +180 -0
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-factory
|
|
3
|
+
*/
|
|
4
|
+
// tslint:disable:no-shadowed-variable
|
|
5
|
+
import * as chalk from "chalk";
|
|
6
|
+
import { assert } from "node-opcua-assert";
|
|
7
|
+
import { BinaryStream, BinaryStreamSizeCalculator, OutputBinaryStream } from "node-opcua-binary-stream";
|
|
8
|
+
import { hexDump } from "node-opcua-debug";
|
|
9
|
+
import { NodeId } from "node-opcua-nodeid";
|
|
10
|
+
import * as utils from "node-opcua-utils";
|
|
11
|
+
|
|
12
|
+
import { getBuildInType } from "./factories_builtin_types";
|
|
13
|
+
import { getEnumeration, hasEnumeration } from "./factories_enumerations";
|
|
14
|
+
import { callConstructor, DataTypeFactory } from "./datatype_factory";
|
|
15
|
+
import { getStructureTypeConstructor } from "./factories_factories";
|
|
16
|
+
import { get_base_schema, StructuredTypeSchema } from "./factories_structuredTypeSchema";
|
|
17
|
+
import { EnumerationDefinition, FieldCategory, StructuredTypeField, BuiltInTypeDefinition, FieldType } from "./types";
|
|
18
|
+
import { AttributeIds } from "node-opcua-basic-types";
|
|
19
|
+
|
|
20
|
+
function r(str: string, length = 30) {
|
|
21
|
+
return (str + " ").substr(0, length);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function _decode_member_(value: any, field: StructuredTypeField, stream: BinaryStream, options: any) {
|
|
25
|
+
const tracer = options.tracer;
|
|
26
|
+
const cursorBefore = stream.length;
|
|
27
|
+
const fieldType = field.fieldType;
|
|
28
|
+
|
|
29
|
+
switch (field.category) {
|
|
30
|
+
case FieldCategory.basic:
|
|
31
|
+
if (field.schema.decode) {
|
|
32
|
+
value = field.schema.decode(stream);
|
|
33
|
+
}
|
|
34
|
+
tracer.trace("member", options.name, value, cursorBefore, stream.length, fieldType);
|
|
35
|
+
break;
|
|
36
|
+
case FieldCategory.enumeration:
|
|
37
|
+
if (field.schema.decode) {
|
|
38
|
+
value = field.schema.decode(stream);
|
|
39
|
+
}
|
|
40
|
+
tracer.trace("member", options.name, value, cursorBefore, stream.length, fieldType);
|
|
41
|
+
break;
|
|
42
|
+
case FieldCategory.complex: {
|
|
43
|
+
assert(field.category === FieldCategory.complex);
|
|
44
|
+
|
|
45
|
+
if (!field.fieldTypeConstructor) {
|
|
46
|
+
field.fieldTypeConstructor = getStructureTypeConstructor(field.fieldType);
|
|
47
|
+
}
|
|
48
|
+
if (typeof field.fieldTypeConstructor !== "function") {
|
|
49
|
+
throw new Error("Cannot find constructor for " + field.name + "of type " + field.fieldType);
|
|
50
|
+
}
|
|
51
|
+
// assert(typeof field.fieldTypeConstructor === "function");
|
|
52
|
+
const constructor = field.fieldTypeConstructor;
|
|
53
|
+
value = callConstructor(constructor);
|
|
54
|
+
value.decodeDebug(stream, options);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type Func1 = (a: any, field: StructuredTypeField, data: ExploreParams, args: any) => void;
|
|
62
|
+
|
|
63
|
+
function applyOnAllSchemaFields(self: BaseUAObject, schema: StructuredTypeSchema, data: ExploreParams, functor: Func1, args: any) {
|
|
64
|
+
const baseSchema = get_base_schema(schema);
|
|
65
|
+
if (baseSchema) {
|
|
66
|
+
applyOnAllSchemaFields(self, baseSchema, data, functor, args);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const field of schema.fields) {
|
|
70
|
+
functor(self, field, data, args);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const _nbElements = process.env.ARRAYLENGTH ? parseInt(process.env.ARRAYLENGTH, 10) : 10;
|
|
75
|
+
|
|
76
|
+
function _arrayEllipsis(value: any[] | null, data: ExploreParams): string {
|
|
77
|
+
if (!value) {
|
|
78
|
+
return "null []";
|
|
79
|
+
} else {
|
|
80
|
+
if (value.length === 0) {
|
|
81
|
+
return "[ /* empty*/ ]";
|
|
82
|
+
}
|
|
83
|
+
assert(Array.isArray(value));
|
|
84
|
+
|
|
85
|
+
const v = [];
|
|
86
|
+
|
|
87
|
+
const m = Math.min(_nbElements, value.length);
|
|
88
|
+
const ellipsis = value.length > _nbElements ? " ... " : "";
|
|
89
|
+
|
|
90
|
+
const pad = data.padding + " ";
|
|
91
|
+
let isMultiLine = true;
|
|
92
|
+
for (let i = 0; i < m; i++) {
|
|
93
|
+
let element = value[i];
|
|
94
|
+
if (element instanceof Buffer) {
|
|
95
|
+
element = hexDump(element, 32, 16);
|
|
96
|
+
} else if (utils.isNullOrUndefined(element)) {
|
|
97
|
+
element = "null";
|
|
98
|
+
} else {
|
|
99
|
+
element = element.toString();
|
|
100
|
+
const s = element.split("\n");
|
|
101
|
+
if (s.length > 1) {
|
|
102
|
+
element = "\n" + pad + s.join("\n" + pad);
|
|
103
|
+
isMultiLine = true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (element.length > 80) {
|
|
107
|
+
isMultiLine = true;
|
|
108
|
+
}
|
|
109
|
+
v.push(element);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const length = "/* length =" + value.length + "*/";
|
|
113
|
+
if (isMultiLine) {
|
|
114
|
+
return "[ " + length + "\n" + pad + v.join(",\n" + pad + " ") + ellipsis + "\n" + data.padding + "]";
|
|
115
|
+
} else {
|
|
116
|
+
return "[ " + length + v.join(",") + ellipsis + "]";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface ExploreParams {
|
|
122
|
+
padding: string;
|
|
123
|
+
lines: string[];
|
|
124
|
+
}
|
|
125
|
+
function _exploreObject(self: BaseUAObject, field: StructuredTypeField, data: ExploreParams, args: any) {
|
|
126
|
+
if (!self) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
assert(self);
|
|
130
|
+
|
|
131
|
+
const fieldType = field.fieldType;
|
|
132
|
+
|
|
133
|
+
const fieldName = field.name;
|
|
134
|
+
const category = field.category;
|
|
135
|
+
|
|
136
|
+
const padding = data.padding;
|
|
137
|
+
|
|
138
|
+
let value = (self as any)[fieldName];
|
|
139
|
+
|
|
140
|
+
let str;
|
|
141
|
+
|
|
142
|
+
// decorate the field name with ?# if the field is optional
|
|
143
|
+
let opt = " ";
|
|
144
|
+
if (field.switchBit !== undefined) {
|
|
145
|
+
opt = " ?" + field.switchBit + " ";
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (field.switchValue !== undefined) {
|
|
149
|
+
opt = " !" + field.switchValue + " ";
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const fieldNameF = chalk.yellow(r(padding + fieldName, 30));
|
|
153
|
+
const fieldTypeF = chalk.cyan("/* " + r(fieldType + opt, 17) + (field.isArray ? "[]" : " ") + " */");
|
|
154
|
+
|
|
155
|
+
// detected when optional field is not specified in value
|
|
156
|
+
if (field.switchBit !== undefined && value === undefined) {
|
|
157
|
+
str = fieldNameF + " " + fieldTypeF + ": " + chalk.italic.grey("undefined") + " /* optional field not specified */";
|
|
158
|
+
data.lines.push(str);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// detected when union field is not specified in value
|
|
162
|
+
if (field.switchValue !== undefined && value === undefined) {
|
|
163
|
+
str = fieldNameF + " " + fieldTypeF + ": " + chalk.italic.grey("undefined") + " /* union field not specified */";
|
|
164
|
+
data.lines.push(str);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// compact version of very usual objects
|
|
169
|
+
if (fieldType === "QualifiedName" && !field.isArray && value) {
|
|
170
|
+
value = value.toString() || "<null>";
|
|
171
|
+
str = fieldNameF + " " + fieldTypeF + ": " + chalk.green(value.toString());
|
|
172
|
+
data.lines.push(str);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (fieldType === "LocalizedText" && !field.isArray && value) {
|
|
176
|
+
value = value.toString() || "<null>";
|
|
177
|
+
str = fieldNameF + " " + fieldTypeF + ": " + chalk.green(value.toString());
|
|
178
|
+
data.lines.push(str);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (fieldType === "DataValue" && !field.isArray && value) {
|
|
182
|
+
value = value.toString(data);
|
|
183
|
+
str = fieldNameF + " " + fieldTypeF + ": " + chalk.green(value.toString(data));
|
|
184
|
+
data.lines.push(str);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function _dump_simple_value(
|
|
189
|
+
self: BaseUAObject,
|
|
190
|
+
field: StructuredTypeField,
|
|
191
|
+
data: ExploreParams,
|
|
192
|
+
value: any,
|
|
193
|
+
fieldType: string
|
|
194
|
+
) {
|
|
195
|
+
let str = "";
|
|
196
|
+
if (value instanceof Buffer) {
|
|
197
|
+
data.lines.push(fieldNameF + " " + fieldTypeF);
|
|
198
|
+
if (process.env?.FULLBUFFER) {
|
|
199
|
+
const _hexDump = hexDump(value);
|
|
200
|
+
data.lines.push("BUFFER{" + _hexDump + "}");
|
|
201
|
+
} else {
|
|
202
|
+
data.lines.push("BUFFER");
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
if (field.isArray) {
|
|
206
|
+
str = fieldNameF + " " + fieldTypeF + ": " + _arrayEllipsis(value, data);
|
|
207
|
+
} else {
|
|
208
|
+
if (field.fieldType === "NodeId" && value instanceof NodeId) {
|
|
209
|
+
value = value.displayText();
|
|
210
|
+
} else if (fieldType === "IntegerId" || fieldType === "UInt32") {
|
|
211
|
+
if (field.name === "attributeId") {
|
|
212
|
+
value = "AttributeIds." + AttributeIds[value] + "/* " + value + " */";
|
|
213
|
+
} else {
|
|
214
|
+
const extra = value !== undefined ? "0x" + value.toString(16) : "undefined";
|
|
215
|
+
value = "" + value + " " + extra;
|
|
216
|
+
}
|
|
217
|
+
} else if (fieldType === "DateTime" || fieldType === "UtcTime") {
|
|
218
|
+
value = value && value.toISOString ? value.toISOString() : value;
|
|
219
|
+
} else if (typeof value === "object" && value !== null && value !== undefined) {
|
|
220
|
+
value = value.toString.apply(value, args);
|
|
221
|
+
}
|
|
222
|
+
str =
|
|
223
|
+
fieldNameF +
|
|
224
|
+
" " +
|
|
225
|
+
fieldTypeF +
|
|
226
|
+
": " +
|
|
227
|
+
(value === null || value === undefined ? chalk.blue("null") : value.toString());
|
|
228
|
+
}
|
|
229
|
+
data.lines.push(str);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function _dump_complex_value(
|
|
234
|
+
self: BaseUAObject,
|
|
235
|
+
field: StructuredTypeField,
|
|
236
|
+
data: ExploreParams,
|
|
237
|
+
value: any,
|
|
238
|
+
fieldType: string
|
|
239
|
+
) {
|
|
240
|
+
if (field.subType) {
|
|
241
|
+
// this is a synonymous
|
|
242
|
+
fieldType = field.subType;
|
|
243
|
+
_dump_simple_value(self, field, data, value, fieldType);
|
|
244
|
+
} else {
|
|
245
|
+
const typeDictionary = (self.schema as any).$$factory as DataTypeFactory;
|
|
246
|
+
// istanbul ignore next
|
|
247
|
+
if (!typeDictionary) {
|
|
248
|
+
// tslint:disable-next-line: no-console
|
|
249
|
+
console.log(" No typeDictionary for ", self.schema);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
field.fieldTypeConstructor = field.fieldTypeConstructor || typeDictionary.getStructureTypeConstructor(fieldType);
|
|
253
|
+
const fieldTypeConstructor = field.fieldTypeConstructor;
|
|
254
|
+
|
|
255
|
+
const _newFieldSchema =
|
|
256
|
+
(field.schema as StructuredTypeSchema) ||
|
|
257
|
+
fieldTypeConstructor.prototype.schema ||
|
|
258
|
+
(fieldTypeConstructor as any).schema;
|
|
259
|
+
|
|
260
|
+
if (field.isArray) {
|
|
261
|
+
if (value === null) {
|
|
262
|
+
data.lines.push(fieldNameF + " " + fieldTypeF + ": null []");
|
|
263
|
+
} else if (value.length === 0) {
|
|
264
|
+
data.lines.push(fieldNameF + " " + fieldTypeF + ": [ /* empty */ ]");
|
|
265
|
+
} else {
|
|
266
|
+
data.lines.push(fieldNameF + " " + fieldTypeF + ": [");
|
|
267
|
+
const m = Math.min(_nbElements, value.length);
|
|
268
|
+
|
|
269
|
+
for (let i = 0; i < m; i++) {
|
|
270
|
+
const element = value[i];
|
|
271
|
+
data.lines.push(padding + chalk.cyan(" { " + ("/*" + i + "*/")));
|
|
272
|
+
|
|
273
|
+
const data1 = {
|
|
274
|
+
lines: [] as string[],
|
|
275
|
+
padding: padding + " "
|
|
276
|
+
};
|
|
277
|
+
applyOnAllSchemaFields(element, _newFieldSchema, data1, _exploreObject, args);
|
|
278
|
+
|
|
279
|
+
data.lines = data.lines.concat(data1.lines);
|
|
280
|
+
|
|
281
|
+
data.lines.push(padding + " }" + (i === value.length - 1 ? "" : ","));
|
|
282
|
+
}
|
|
283
|
+
if (m < value.length) {
|
|
284
|
+
data.lines.push(padding + " ..... ( " + value.length + " elements )");
|
|
285
|
+
}
|
|
286
|
+
data.lines.push(padding + "]");
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
data.lines.push(fieldNameF + " " + fieldTypeF + ": {");
|
|
290
|
+
const data1 = { padding: padding + " ", lines: [] as string[] };
|
|
291
|
+
applyOnAllSchemaFields(value, _newFieldSchema, data1, _exploreObject, args);
|
|
292
|
+
data.lines = data.lines.concat(data1.lines);
|
|
293
|
+
|
|
294
|
+
data.lines.push(padding + "}");
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
switch (category) {
|
|
300
|
+
case FieldCategory.enumeration:
|
|
301
|
+
const s = field.schema as EnumerationDefinition;
|
|
302
|
+
|
|
303
|
+
// istanbul ignore next
|
|
304
|
+
if (!s.typedEnum) {
|
|
305
|
+
// tslint:disable:no-console
|
|
306
|
+
console.log("xxxx cannot find typeEnum", s);
|
|
307
|
+
}
|
|
308
|
+
// istanbul ignore next
|
|
309
|
+
if (!s.typedEnum.get(value)) {
|
|
310
|
+
// tslint:disable:no-console
|
|
311
|
+
(s.typedEnum as any)._isFlaggable = true;
|
|
312
|
+
console.log("xxxx cannot find typeEnum value ", value);
|
|
313
|
+
str = fieldNameF + " " + fieldTypeF + ": " + s.name + "." + s.typedEnum.get(value) + " ( " + value + ")";
|
|
314
|
+
data.lines.push(str);
|
|
315
|
+
} else {
|
|
316
|
+
str = fieldNameF + " " + fieldTypeF + ": " + s.name + "." + s.typedEnum.get(value)!.key + " ( " + value + ")";
|
|
317
|
+
data.lines.push(str);
|
|
318
|
+
}
|
|
319
|
+
break;
|
|
320
|
+
case FieldCategory.basic:
|
|
321
|
+
_dump_simple_value(self, field, data, value, fieldType);
|
|
322
|
+
break;
|
|
323
|
+
case FieldCategory.complex:
|
|
324
|
+
_dump_complex_value(self, field, data, value, fieldType);
|
|
325
|
+
break;
|
|
326
|
+
default:
|
|
327
|
+
throw new Error("internal error: unknown kind_of_field " + category);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function json_ify(t: BuiltInTypeDefinition, value: any, fieldType: FieldType) {
|
|
332
|
+
if (value instanceof Array) {
|
|
333
|
+
return value.map((e) => (e && e.toJSON ? e.toJSON() : e));
|
|
334
|
+
}
|
|
335
|
+
/*
|
|
336
|
+
if (typeof fieldType.toJSON === "function") {
|
|
337
|
+
return fieldType.toJSON(value);
|
|
338
|
+
} else
|
|
339
|
+
*/
|
|
340
|
+
if (t && t.toJSON) {
|
|
341
|
+
return t.toJSON(value);
|
|
342
|
+
} else if (value.toJSON) {
|
|
343
|
+
return value.toJSON();
|
|
344
|
+
} else {
|
|
345
|
+
return value;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function _JSONify(self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) {
|
|
350
|
+
/* jshint validthis: true */
|
|
351
|
+
for (const field of schema.fields) {
|
|
352
|
+
const fieldValue = (self as any)[field.name];
|
|
353
|
+
if (fieldValue === null || fieldValue === undefined) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (hasEnumeration(field.fieldType)) {
|
|
358
|
+
const enumeration = getEnumeration(field.fieldType);
|
|
359
|
+
assert(enumeration !== null);
|
|
360
|
+
if (field.isArray) {
|
|
361
|
+
pojo[field.name] = fieldValue.map((value: any) => enumeration.enumValues[value.toString()]);
|
|
362
|
+
} else {
|
|
363
|
+
pojo[field.name] = enumeration.enumValues[fieldValue.toString()];
|
|
364
|
+
}
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
const t = getBuildInType(field.fieldType);
|
|
368
|
+
|
|
369
|
+
if (field.isArray) {
|
|
370
|
+
pojo[field.name] = fieldValue.map((value: any) => json_ify(t, value, field));
|
|
371
|
+
} else {
|
|
372
|
+
pojo[field.name] = json_ify(t, fieldValue, field);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export interface DecodeDebugOptions {
|
|
378
|
+
tracer: any;
|
|
379
|
+
name: string;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/* tslint:disable:no-empty*/
|
|
383
|
+
|
|
384
|
+
export interface BaseUAObject {
|
|
385
|
+
schema: StructuredTypeSchema;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* @class BaseUAObject
|
|
390
|
+
* @constructor
|
|
391
|
+
*/
|
|
392
|
+
export class BaseUAObject {
|
|
393
|
+
constructor() {}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Encode the object to the binary stream.
|
|
397
|
+
* @class BaseUAObject
|
|
398
|
+
* @method encode
|
|
399
|
+
* @param stream {BinaryStream}
|
|
400
|
+
*/
|
|
401
|
+
public encode(stream: OutputBinaryStream): void {}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Decode the object from the binary stream.
|
|
405
|
+
* @class BaseUAObject
|
|
406
|
+
* @method decode
|
|
407
|
+
* @param stream {BinaryStream}
|
|
408
|
+
*/
|
|
409
|
+
public decode(stream: BinaryStream): void {}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Calculate the required size to store this object in a binary stream.
|
|
413
|
+
* @method binaryStoreSize
|
|
414
|
+
* @return number
|
|
415
|
+
*/
|
|
416
|
+
public binaryStoreSize(): number {
|
|
417
|
+
const stream = new BinaryStreamSizeCalculator();
|
|
418
|
+
this.encode(stream as OutputBinaryStream);
|
|
419
|
+
return stream.length;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* @method toString
|
|
424
|
+
* @return {String}
|
|
425
|
+
*/
|
|
426
|
+
public toString(...args: any[]): string {
|
|
427
|
+
if (this.schema && this.schema.hasOwnProperty("toString")) {
|
|
428
|
+
return this.schema.toString.apply(this, arguments as any);
|
|
429
|
+
} else {
|
|
430
|
+
if (!this.explore) {
|
|
431
|
+
// xx console.log(util.inspect(this));
|
|
432
|
+
return Object.prototype.toString.apply(this, arguments as any);
|
|
433
|
+
}
|
|
434
|
+
return this.explore.apply(this, arguments as any);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
*
|
|
440
|
+
* verify that all object attributes values are valid according to schema
|
|
441
|
+
* @method isValid
|
|
442
|
+
* @return boolean
|
|
443
|
+
*/
|
|
444
|
+
public isValid(): boolean {
|
|
445
|
+
assert(this.schema);
|
|
446
|
+
if (this.schema.isValid) {
|
|
447
|
+
return this.schema.isValid(this);
|
|
448
|
+
} else {
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* @method decodeDebug
|
|
455
|
+
*
|
|
456
|
+
*/
|
|
457
|
+
public decodeDebug(stream: BinaryStream, options: DecodeDebugOptions): void {
|
|
458
|
+
const tracer = options.tracer;
|
|
459
|
+
const schema = this.schema;
|
|
460
|
+
|
|
461
|
+
tracer.trace("start", options.name + "(" + schema.name + ")", stream.length, stream.length);
|
|
462
|
+
const self: any = this as any;
|
|
463
|
+
|
|
464
|
+
for (const field of schema.fields) {
|
|
465
|
+
const value = self[field.name];
|
|
466
|
+
|
|
467
|
+
if (typeof field.switchValue === "number" ) {
|
|
468
|
+
// skip
|
|
469
|
+
if (self["switchField"] !== field.switchValue) {
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (field.isArray) {
|
|
474
|
+
const cursorBefore = stream.length;
|
|
475
|
+
let nb = stream.readUInt32();
|
|
476
|
+
if (nb === 0xffffffff) {
|
|
477
|
+
nb = 0;
|
|
478
|
+
}
|
|
479
|
+
options.name = field.name + [];
|
|
480
|
+
|
|
481
|
+
tracer.trace("start_array", field.name, nb, cursorBefore, stream.length);
|
|
482
|
+
for (let i = 0; i < nb; i++) {
|
|
483
|
+
tracer.trace("start_element", field.name, i);
|
|
484
|
+
options.name = "element #" + i;
|
|
485
|
+
|
|
486
|
+
_decode_member_(value, field, stream, options);
|
|
487
|
+
|
|
488
|
+
tracer.trace("end_element", field.name, i);
|
|
489
|
+
}
|
|
490
|
+
tracer.trace("end_array", field.name, stream.length - 4);
|
|
491
|
+
} else {
|
|
492
|
+
options.name = field.name;
|
|
493
|
+
_decode_member_(value, field, stream, options);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
tracer.trace("end", schema.name, stream.length, stream.length);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
public explore(): string {
|
|
501
|
+
const data: { padding: string; lines: string[] } = {
|
|
502
|
+
lines: [],
|
|
503
|
+
padding: " "
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
data.lines.push("{" + chalk.cyan(" /*" + (this.schema ? this.schema.name : "") + "*/"));
|
|
507
|
+
if (this.schema) {
|
|
508
|
+
applyOnAllSchemaFields(this, this.schema, data, _exploreObject, arguments);
|
|
509
|
+
}
|
|
510
|
+
data.lines.push("};");
|
|
511
|
+
return data.lines.join("\n");
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
public toJSON(): any {
|
|
515
|
+
assert(this.schema);
|
|
516
|
+
if (this.schema.toJSON) {
|
|
517
|
+
return this.schema.toJSON.apply(this, arguments as any);
|
|
518
|
+
} else {
|
|
519
|
+
assert(this.schema);
|
|
520
|
+
const schema = this.schema;
|
|
521
|
+
const pojo = {};
|
|
522
|
+
_visitSchemaChain(this, schema, pojo, _JSONify, null);
|
|
523
|
+
return pojo;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
public clone(/*options,optionalFilter,extraInfo*/): any {
|
|
528
|
+
const self: any = this as any;
|
|
529
|
+
|
|
530
|
+
const params = {};
|
|
531
|
+
|
|
532
|
+
function construct_param(schema: any, options: any) {
|
|
533
|
+
for (const field of schema.fields) {
|
|
534
|
+
const f = self[field.name];
|
|
535
|
+
if (f === null || f === undefined) {
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (field.isArray) {
|
|
539
|
+
options[field.name] = self[field.name];
|
|
540
|
+
} else {
|
|
541
|
+
options[field.name] = self[field.name];
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
construct_param.call(this, self.schema, params);
|
|
547
|
+
|
|
548
|
+
return new self.constructor(params);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function _visitSchemaChain(
|
|
553
|
+
self: BaseUAObject,
|
|
554
|
+
schema: StructuredTypeSchema,
|
|
555
|
+
pojo: any,
|
|
556
|
+
func: (self: BaseUAObject, schema: StructuredTypeSchema, pojo: any) => void,
|
|
557
|
+
extraData: any
|
|
558
|
+
) {
|
|
559
|
+
assert(typeof func === "function");
|
|
560
|
+
|
|
561
|
+
// apply also construct to baseType schema first
|
|
562
|
+
const baseSchema = get_base_schema(schema);
|
|
563
|
+
if (baseSchema) {
|
|
564
|
+
_visitSchemaChain(self, baseSchema, pojo, func, extraData);
|
|
565
|
+
}
|
|
566
|
+
func.call(null, self, schema, pojo);
|
|
567
|
+
}
|