/
extra_data_type_manager.ts
128 lines (109 loc) · 4.71 KB
/
extra_data_type_manager.ts
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
/**
* @module node-opcua-client-dynamic-extension-object
*/
import assert from "node-opcua-assert";
import {
StructuredTypeSchema ,
getStandartDataTypeFactory,
DataTypeFactory
} from "node-opcua-factory";
import { NodeId } from "node-opcua-nodeid";
import {
AnyConstructorFunc,
createDynamicObjectConstructor,
TypeDictionary
} from "node-opcua-schemas";
export class ExtraDataTypeManager {
public namespaceArray: string[] = [];
private readonly typeDictionaries: { [key: string]: TypeDictionary } = {};
private readonly typeDictionariesByNamespace: { [key: number]: TypeDictionary } = {};
constructor() {
/* */
}
public setNamespaceArray(namespaceArray: string[]) {
this.namespaceArray = namespaceArray;
}
public hasDataTypeDictionary(nodeId: NodeId): boolean {
return !!this.typeDictionaries.hasOwnProperty(this.makeKey(nodeId));
}
public registerTypeDictionary(nodeId: NodeId, typeDictionary: TypeDictionary) {
/* istanbul ignore next */
if (this.hasDataTypeDictionary(nodeId)) {
throw new Error("Dictionary already registered");
}
this.typeDictionaries[this.makeKey(nodeId)] = typeDictionary;
assert(nodeId.namespace !== 0,
"registerTypeDictionary cannot be used for namespace 0");
assert(!this.typeDictionariesByNamespace.hasOwnProperty(nodeId.namespace),
"already registered");
this.typeDictionariesByNamespace[nodeId.namespace] = typeDictionary;
}
public getTypeDictionaryForNamespace(namespaceIndex: number): TypeDictionary {
assert(namespaceIndex !== 0,
"getTypeDictionaryForNamespace cannot be used for namespace 0");
return this.typeDictionariesByNamespace[namespaceIndex];
}
public getDataTypeFactory(namespaceIndex: number): DataTypeFactory {
if (namespaceIndex === 0) {
return getStandartDataTypeFactory();
}
return this.typeDictionariesByNamespace[namespaceIndex];
}
public getExtensionObjectConstructorFromDataType(
dataTypeNodeId: NodeId
): AnyConstructorFunc {
const typeDictionary = this.getTypeDictionaryForNamespace(dataTypeNodeId.namespace);
// find schema corresponding to dataTypeNodeId in typeDictionary
const schema = findSchemaForDataType(typeDictionary, dataTypeNodeId);
const Constructor = createDynamicObjectConstructor(schema, typeDictionary);
return Constructor;
}
public getExtensionObjectConstructorFromBinaryEncoding(
binaryEncodingNodeId: NodeId
): AnyConstructorFunc {
const typeDictionary = this.getTypeDictionaryForNamespace(binaryEncodingNodeId.namespace);
// find schema corresponding to binaryEncodingNodeId in typeDictionary
const schema = findSchemaForBinaryEncoding(typeDictionary, binaryEncodingNodeId);
const Constructor = createDynamicObjectConstructor(schema, typeDictionary);
return Constructor;
}
private makeKey(nodeId: NodeId): string {
return this.namespaceArray[nodeId.namespace] + "@" + nodeId.value.toString();
}
}
function findSchemaForDataType(
typeDictionary: TypeDictionary,
dataTypeNodeId: NodeId
): StructuredTypeSchema {
for (const k of Object.keys(typeDictionary.structuredTypes)) {
const schema = typeDictionary.structuredTypes[k];
if (schema.id.value === dataTypeNodeId.value) {
assert(schema.id.namespace === dataTypeNodeId.namespace);
return schema;
}
}
throw new Error("findSchemaForDataType: Cannot find schema for " + dataTypeNodeId.toString()
+ " in " +
Object.keys(typeDictionary.structuredTypes).map(
(a) => a + ":" +
typeDictionary.structuredTypes[a].id.toString()).join("\n"));
}
function findSchemaForBinaryEncoding(
typeDictionary: TypeDictionary,
binaryEncodingNodeId: NodeId
): StructuredTypeSchema {
for (const k of Object.keys(typeDictionary.structuredTypes)) {
const schema = typeDictionary.structuredTypes[k];
if (schema.encodingDefaultBinary &&
schema.encodingDefaultBinary!.value === binaryEncodingNodeId.value) {
assert(schema.encodingDefaultBinary!.namespace === binaryEncodingNodeId.namespace);
return schema;
}
}
throw new Error("findSchemaForBinaryEncoding: Cannot find schema for " + binaryEncodingNodeId.toString()
+ " in " +
Object.keys(typeDictionary.structuredTypes).map(
(a) => a + " " +
(typeDictionary.structuredTypes[a].encodingDefaultBinary ?
typeDictionary.structuredTypes[a].encodingDefaultBinary!.toString() : "None")).join("\n"));
}