node-opcua-variant
Advanced tools
Comparing version 2.3.0 to 2.4.0
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ /** |
@@ -155,3 +155,3 @@ "use strict"; | ||
let data = VariantArrayType_enum_1.VariantArrayType[self.arrayType]; | ||
if (self.dimensions && self.dimensions.length > 0) { | ||
if (self.dimensions && self.dimensions.length >= 0) { | ||
data += "[ " + self.dimensions.join(",") + " ]"; | ||
@@ -203,3 +203,3 @@ } | ||
node_opcua_assert_1.assert(variant.arrayType === VariantArrayType_enum_1.VariantArrayType.Matrix); | ||
node_opcua_assert_1.assert(variant.dimensions.length >= 1); | ||
node_opcua_assert_1.assert(variant.dimensions.length >= 0); | ||
encodingByte |= exports.VARIANT_ARRAY_DIMENSIONS_MASK; | ||
@@ -379,3 +379,5 @@ } | ||
if (options.value.length !== calculate_product(options.dimensions)) { | ||
throw new Error("Matrix Variant : invalid value size"); | ||
throw new Error("Matrix Variant : invalid value size = options.value.length " | ||
+ options.value.length + "!=" + calculate_product(options.dimensions) | ||
+ " => " + JSON.stringify(options.dimensions)); | ||
} | ||
@@ -403,3 +405,3 @@ } | ||
/* istanbul ignore next */ | ||
if (!array) { | ||
if (!array || array.length === 0) { | ||
return 0; | ||
@@ -429,2 +431,5 @@ } | ||
function convertTo(dataType, arrayTypeConstructor, value) { | ||
if (value === undefined || value === null) { | ||
value = []; | ||
} | ||
if (arrayTypeConstructor && value instanceof arrayTypeConstructor) { | ||
@@ -431,0 +436,0 @@ const newArray = new value.constructor(value.length); // deep copy |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ "use strict"; |
@@ -0,0 +0,0 @@ module.exports = { |
{ | ||
"name": "node-opcua-variant", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"description": "pure nodejs OPCUA SDK - module -variant", | ||
@@ -14,9 +14,9 @@ "main": "./dist/index.js", | ||
"node-opcua-assert": "^2.3.0", | ||
"node-opcua-basic-types": "^2.3.0", | ||
"node-opcua-data-model": "^2.3.0", | ||
"node-opcua-basic-types": "^2.4.0", | ||
"node-opcua-data-model": "^2.4.0", | ||
"node-opcua-enum": "^2.3.0", | ||
"node-opcua-extension-object": "^2.3.0", | ||
"node-opcua-factory": "^2.3.0", | ||
"node-opcua-extension-object": "^2.4.0", | ||
"node-opcua-factory": "^2.4.0", | ||
"node-opcua-nodeid": "^2.3.0", | ||
"node-opcua-utils": "^2.3.0", | ||
"node-opcua-utils": "^2.4.0", | ||
"underscore": "^1.9.1" | ||
@@ -28,4 +28,4 @@ }, | ||
"node-opcua-debug": "^2.3.0", | ||
"node-opcua-numeric-range": "^2.3.0", | ||
"node-opcua-packet-analyzer": "^2.3.0", | ||
"node-opcua-numeric-range": "^2.4.0", | ||
"node-opcua-packet-analyzer": "^2.4.0", | ||
"node-opcua-status-code": "^2.3.0", | ||
@@ -50,3 +50,3 @@ "should": "13.2.3", | ||
"homepage": "http://node-opcua.github.io/", | ||
"gitHead": "3fc22180b26cd0d0481e57e7bb6a2cab7623e6d1" | ||
"gitHead": "21f5967e799ef2b4d6491b8fc670964127c11431" | ||
} |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ /** |
@@ -9,29 +9,29 @@ /** | ||
import { | ||
coerceInt64, | ||
coerceUInt64, | ||
decodeUInt32, | ||
decodeUInt8, | ||
encodeUInt32, | ||
encodeUInt8, | ||
isValidBoolean, | ||
isValidByteString, | ||
isValidInt16, | ||
isValidInt32, | ||
isValidInt64, | ||
isValidInt8, | ||
isValidNodeId, | ||
isValidUInt16, | ||
isValidUInt32, | ||
isValidUInt64, | ||
isValidUInt8 | ||
coerceInt64, | ||
coerceUInt64, | ||
decodeUInt32, | ||
decodeUInt8, | ||
encodeUInt32, | ||
encodeUInt8, | ||
isValidBoolean, | ||
isValidByteString, | ||
isValidInt16, | ||
isValidInt32, | ||
isValidInt64, | ||
isValidInt8, | ||
isValidNodeId, | ||
isValidUInt16, | ||
isValidUInt32, | ||
isValidUInt64, | ||
isValidUInt8 | ||
} from "node-opcua-basic-types"; | ||
import { LocalizedText, QualifiedName } from "node-opcua-data-model"; | ||
import { | ||
BaseUAObject, | ||
buildStructuredType, | ||
findBuiltInType, | ||
initialize_field, | ||
initialize_field_array, | ||
registerSpecialVariantEncoder, | ||
StructuredTypeSchema | ||
BaseUAObject, | ||
buildStructuredType, | ||
findBuiltInType, | ||
initialize_field, | ||
initialize_field_array, | ||
registerSpecialVariantEncoder, | ||
StructuredTypeSchema | ||
} from "node-opcua-factory"; | ||
@@ -48,37 +48,37 @@ | ||
const schemaVariant: StructuredTypeSchema = buildStructuredType({ | ||
baseType: "BaseUAObject", | ||
fields: [{ | ||
defaultValue: () => DataType.Null, | ||
documentation: "the variant type.", | ||
fieldType: "DataType", | ||
name: "dataType", | ||
}, { | ||
defaultValue: VariantArrayType.Scalar, | ||
fieldType: "VariantArrayType", | ||
name: "arrayType", | ||
}, { | ||
defaultValue: null, | ||
fieldType: "Any", | ||
name: "value", | ||
}, { | ||
defaultValue: null, | ||
documentation: "the matrix dimensions", | ||
fieldType: "UInt32", | ||
isArray: true, | ||
name: "dimensions", | ||
}], | ||
name: "Variant", | ||
baseType: "BaseUAObject", | ||
fields: [{ | ||
defaultValue: () => DataType.Null, | ||
documentation: "the variant type.", | ||
fieldType: "DataType", | ||
name: "dataType", | ||
}, { | ||
defaultValue: VariantArrayType.Scalar, | ||
fieldType: "VariantArrayType", | ||
name: "arrayType", | ||
}, { | ||
defaultValue: null, | ||
fieldType: "Any", | ||
name: "value", | ||
}, { | ||
defaultValue: null, | ||
documentation: "the matrix dimensions", | ||
fieldType: "UInt32", | ||
isArray: true, | ||
name: "dimensions", | ||
}], | ||
name: "Variant", | ||
}); | ||
function _coerceVariant(variantLike: any): Variant { | ||
const value = (variantLike instanceof Variant) ? variantLike : new Variant(variantLike); | ||
assert(value instanceof Variant); | ||
return value; | ||
const value = (variantLike instanceof Variant) ? variantLike : new Variant(variantLike); | ||
assert(value instanceof Variant); | ||
return value; | ||
} | ||
export interface VariantOptions { | ||
dataType?: DataType | string; | ||
arrayType?: VariantArrayType | string; | ||
value?: any; | ||
dimensions?: number[] | null; | ||
dataType?: DataType | string; | ||
arrayType?: VariantArrayType | string; | ||
value?: any; | ||
dimensions?: number[] | null; | ||
} | ||
@@ -88,110 +88,110 @@ | ||
public static schema = schemaVariant; | ||
public static coerce = _coerceVariant; | ||
public static schema = schemaVariant; | ||
public static coerce = _coerceVariant; | ||
public dataType: DataType; | ||
public arrayType: VariantArrayType; | ||
public value: any; | ||
public dimensions: number[] | null; | ||
public dataType: DataType; | ||
public arrayType: VariantArrayType; | ||
public value: any; | ||
public dimensions: number[] | null; | ||
constructor(options?: VariantOptions) { | ||
super(); | ||
options = constructHook(options) as any; | ||
options = options ? options : {}; | ||
constructor(options?: VariantOptions) { | ||
super(); | ||
options = constructHook(options) as any; | ||
options = options ? options : {}; | ||
this.dataType = DataType.Null; | ||
this.arrayType = VariantArrayType.Scalar; | ||
this.dataType = DataType.Null; | ||
this.arrayType = VariantArrayType.Scalar; | ||
const schema = schemaVariant; | ||
/** | ||
* the variant type. | ||
* @property dataType | ||
* @type {DataType} | ||
* @default 0 | ||
*/ | ||
this.setDataType(initialize_field(schema.fields[0], options.dataType)); | ||
const schema = schemaVariant; | ||
/** | ||
* the variant type. | ||
* @property dataType | ||
* @type {DataType} | ||
* @default 0 | ||
*/ | ||
this.setDataType(initialize_field(schema.fields[0], options.dataType)); | ||
/** | ||
* @property arrayType | ||
* @type {VariantArrayType} | ||
* @default 0 | ||
*/ | ||
this.setArrayType(initialize_field(schema.fields[1], options.arrayType)); | ||
/** | ||
* @property arrayType | ||
* @type {VariantArrayType} | ||
* @default 0 | ||
*/ | ||
this.setArrayType(initialize_field(schema.fields[1], options.arrayType)); | ||
/** | ||
* @property value | ||
* @default null | ||
*/ | ||
this.value = initialize_field(schema.fields[2], options.value); | ||
/** | ||
* @property value | ||
* @default null | ||
*/ | ||
this.value = initialize_field(schema.fields[2], options.value); | ||
/** | ||
* the matrix dimensions | ||
* @property dimensions | ||
* @type {UInt32[]} | ||
* @default null | ||
*/ | ||
this.dimensions = initialize_field_array( | ||
schema.fields[3], | ||
options.dimensions | ||
); | ||
/** | ||
* the matrix dimensions | ||
* @property dimensions | ||
* @type {UInt32[]} | ||
* @default null | ||
*/ | ||
this.dimensions = initialize_field_array( | ||
schema.fields[3], | ||
options.dimensions | ||
); | ||
if ( options.dataType === DataType.ExtensionObject) { | ||
if (this.arrayType === VariantArrayType.Scalar) { | ||
/* istanbul ignore next */ | ||
if (this.value && !(this.value instanceof ExtensionObject)) { | ||
throw new Error("A variant with DataType.ExtensionObject must have a ExtensionObject value"); | ||
} | ||
} else { | ||
for (const e of this.value) { | ||
/* istanbul ignore next */ | ||
if (e && !(e instanceof ExtensionObject)) { | ||
throw new Error("A variant with DataType.ExtensionObject must have a ExtensionObject value"); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
// Define Enumeration setters | ||
public setDataType(value: any) { | ||
const coercedValue = _enumerationDataType.get(value); | ||
if (options.dataType === DataType.ExtensionObject) { | ||
if (this.arrayType === VariantArrayType.Scalar) { | ||
/* istanbul ignore next */ | ||
if (coercedValue === undefined || coercedValue === null) { | ||
throw new Error("value cannot be coerced to DataType: " + value); | ||
if (this.value && !(this.value instanceof ExtensionObject)) { | ||
throw new Error("A variant with DataType.ExtensionObject must have a ExtensionObject value"); | ||
} | ||
this.dataType = coercedValue.value as DataType; | ||
} | ||
public setArrayType(value: any) { | ||
const coercedValue = _enumerationVariantArrayType.get(value); | ||
/* istanbul ignore next */ | ||
if (coercedValue === undefined || coercedValue === null) { | ||
throw new Error("value cannot be coerced to VariantArrayType: " + value); | ||
} else { | ||
for (const e of this.value) { | ||
/* istanbul ignore next */ | ||
if (e && !(e instanceof ExtensionObject)) { | ||
throw new Error("A variant with DataType.ExtensionObject must have a ExtensionObject value"); | ||
} | ||
} | ||
this.arrayType = coercedValue.value as VariantArrayType; | ||
} | ||
} | ||
} | ||
public encode(stream: OutputBinaryStream) { | ||
encodeVariant(this, stream); | ||
// Define Enumeration setters | ||
public setDataType(value: any) { | ||
const coercedValue = _enumerationDataType.get(value); | ||
/* istanbul ignore next */ | ||
if (coercedValue === undefined || coercedValue === null) { | ||
throw new Error("value cannot be coerced to DataType: " + value); | ||
} | ||
this.dataType = coercedValue.value as DataType; | ||
} | ||
public decode(stream: BinaryStream) { | ||
internalDecodeVariant(this, stream); | ||
public setArrayType(value: any) { | ||
const coercedValue = _enumerationVariantArrayType.get(value); | ||
/* istanbul ignore next */ | ||
if (coercedValue === undefined || coercedValue === null) { | ||
throw new Error("value cannot be coerced to VariantArrayType: " + value); | ||
} | ||
this.arrayType = coercedValue.value as VariantArrayType; | ||
} | ||
public decodeDebug(stream: BinaryStream, options: any) { | ||
decodeDebugVariant(this, stream, options); | ||
} | ||
public encode(stream: OutputBinaryStream) { | ||
encodeVariant(this, stream); | ||
} | ||
public toString(): string { | ||
return variantToString(this); | ||
} | ||
public isValid(): boolean { | ||
return isValidVariant(this.arrayType, this.dataType, this.value, this.dimensions); | ||
} | ||
public decode(stream: BinaryStream) { | ||
internalDecodeVariant(this, stream); | ||
} | ||
public clone(): Variant { | ||
return new Variant(this); | ||
} | ||
public decodeDebug(stream: BinaryStream, options: any) { | ||
decodeDebugVariant(this, stream, options); | ||
} | ||
public toString(): string { | ||
return variantToString(this); | ||
} | ||
public isValid(): boolean { | ||
return isValidVariant(this.arrayType, this.dataType, this.value, this.dimensions); | ||
} | ||
public clone(): Variant { | ||
return new Variant(this); | ||
} | ||
} | ||
@@ -205,49 +205,49 @@ | ||
function toString(value: any): string { | ||
switch (self.dataType) { | ||
case DataType.ByteString: | ||
return value ? "0x" + value.toString("hex") : "<null>"; | ||
case DataType.Boolean: | ||
return value.toString(); | ||
case DataType.DateTime: | ||
return value ? (value.toISOString ? value.toISOString() : value.toString()) : "<null>"; | ||
default: | ||
return value ? value.toString(options) : "0"; | ||
} | ||
function toString(value: any): string { | ||
switch (self.dataType) { | ||
case DataType.ByteString: | ||
return value ? "0x" + value.toString("hex") : "<null>"; | ||
case DataType.Boolean: | ||
return value.toString(); | ||
case DataType.DateTime: | ||
return value ? (value.toISOString ? value.toISOString() : value.toString()) : "<null>"; | ||
default: | ||
return value ? value.toString(options) : "0"; | ||
} | ||
} | ||
function f(value: any) { | ||
if (value === undefined || (value === null && typeof value === "object")) { | ||
return "<null>"; | ||
} | ||
return toString(value); | ||
function f(value: any) { | ||
if (value === undefined || (value === null && typeof value === "object")) { | ||
return "<null>"; | ||
} | ||
return toString(value); | ||
} | ||
let data = VariantArrayType[self.arrayType]; | ||
let data = VariantArrayType[self.arrayType]; | ||
if (self.dimensions && self.dimensions.length > 0) { | ||
data += "[ " + self.dimensions.join(",") + " ]"; | ||
} | ||
if (self.dimensions && self.dimensions.length >= 0) { | ||
data += "[ " + self.dimensions.join(",") + " ]"; | ||
} | ||
data += "<" + DataType[self.dataType] + ">"; | ||
if (self.arrayType === VariantArrayType.Scalar) { | ||
data += ", value: " + f(self.value); | ||
data += "<" + DataType[self.dataType] + ">"; | ||
if (self.arrayType === VariantArrayType.Scalar) { | ||
data += ", value: " + f(self.value); | ||
} else if ((self.arrayType === VariantArrayType.Array) || (self.arrayType === VariantArrayType.Matrix)) { | ||
} else if ((self.arrayType === VariantArrayType.Array) || (self.arrayType === VariantArrayType.Matrix)) { | ||
if (!self.value) { | ||
data += ", null"; | ||
} else { | ||
const a = []; | ||
assert(_.isArray(self.value) || (self.value.buffer instanceof ArrayBuffer)); | ||
for (let i = 0; i < Math.min(10, self.value.length); i++) { | ||
a[i] = self.value[i]; | ||
} | ||
if (self.value.length > 10) { | ||
a.push("..."); | ||
} | ||
data += ", l= " + self.value.length + ", value=[" + a.map(f).join(",") + "]"; | ||
} | ||
if (!self.value) { | ||
data += ", null"; | ||
} else { | ||
const a = []; | ||
assert(_.isArray(self.value) || (self.value.buffer instanceof ArrayBuffer)); | ||
for (let i = 0; i < Math.min(10, self.value.length); i++) { | ||
a[i] = self.value[i]; | ||
} | ||
if (self.value.length > 10) { | ||
a.push("..."); | ||
} | ||
data += ", l= " + self.value.length + ", value=[" + a.map(f).join(",") + "]"; | ||
} | ||
return "Variant(" + data + ")"; | ||
} | ||
return "Variant(" + data + ")"; | ||
} | ||
@@ -273,24 +273,24 @@ | ||
let encodingByte = variant.dataType; | ||
let encodingByte = variant.dataType; | ||
if (variant.arrayType === VariantArrayType.Array || variant.arrayType === VariantArrayType.Matrix) { | ||
encodingByte |= VARIANT_ARRAY_MASK; | ||
} | ||
if (variant.dimensions) { | ||
assert(variant.arrayType === VariantArrayType.Matrix); | ||
assert(variant.dimensions.length >= 1); | ||
encodingByte |= VARIANT_ARRAY_DIMENSIONS_MASK; | ||
} | ||
encodeUInt8(encodingByte, stream); | ||
if (variant.arrayType === VariantArrayType.Array || variant.arrayType === VariantArrayType.Matrix) { | ||
encodingByte |= VARIANT_ARRAY_MASK; | ||
} | ||
if (variant.dimensions) { | ||
assert(variant.arrayType === VariantArrayType.Matrix); | ||
assert(variant.dimensions.length >= 0); | ||
encodingByte |= VARIANT_ARRAY_DIMENSIONS_MASK; | ||
} | ||
encodeUInt8(encodingByte, stream); | ||
if (variant.arrayType === VariantArrayType.Array || variant.arrayType === VariantArrayType.Matrix) { | ||
encodeVariantArray(variant.dataType, stream, variant.value); | ||
} else { | ||
const encode = get_encoder(variant.dataType); | ||
encode(variant.value, stream); | ||
} | ||
if (variant.arrayType === VariantArrayType.Array || variant.arrayType === VariantArrayType.Matrix) { | ||
encodeVariantArray(variant.dataType, stream, variant.value); | ||
} else { | ||
const encode = get_encoder(variant.dataType); | ||
encode(variant.value, stream); | ||
} | ||
if ((encodingByte & VARIANT_ARRAY_DIMENSIONS_MASK) === VARIANT_ARRAY_DIMENSIONS_MASK && variant.dimensions) { | ||
encodeDimension(variant.dimensions, stream); | ||
} | ||
if ((encodingByte & VARIANT_ARRAY_DIMENSIONS_MASK) === VARIANT_ARRAY_DIMENSIONS_MASK && variant.dimensions) { | ||
encodeDimension(variant.dimensions, stream); | ||
} | ||
@@ -304,45 +304,45 @@ } | ||
const tracer = options.tracer; | ||
const tracer = options.tracer; | ||
const encodingByte = decodeUInt8(stream); | ||
const encodingByte = decodeUInt8(stream); | ||
const isArray = ((encodingByte & VARIANT_ARRAY_MASK) === VARIANT_ARRAY_MASK); | ||
const hasDimension = ((encodingByte & VARIANT_ARRAY_DIMENSIONS_MASK) === VARIANT_ARRAY_DIMENSIONS_MASK); | ||
const isArray = ((encodingByte & VARIANT_ARRAY_MASK) === VARIANT_ARRAY_MASK); | ||
const hasDimension = ((encodingByte & VARIANT_ARRAY_DIMENSIONS_MASK) === VARIANT_ARRAY_DIMENSIONS_MASK); | ||
self.dataType = (encodingByte & VARIANT_TYPE_MASK) as DataType; | ||
self.dataType = (encodingByte & VARIANT_TYPE_MASK) as DataType; | ||
tracer.dump("dataType: ", self.dataType); | ||
tracer.dump("isArray: ", isArray ? "true" : "false"); | ||
tracer.dump("dimension: ", hasDimension); | ||
tracer.dump("dataType: ", self.dataType); | ||
tracer.dump("isArray: ", isArray ? "true" : "false"); | ||
tracer.dump("dimension: ", hasDimension); | ||
const decode = findBuiltInType(DataType[self.dataType]).decode; | ||
const decode = findBuiltInType(DataType[self.dataType]).decode; | ||
/* istanbul ignore next */ | ||
if (!decode) { | ||
throw new Error("Variant.decode : cannot find decoder for type " + DataType[self.dataType]); | ||
} | ||
/* istanbul ignore next */ | ||
if (!decode) { | ||
throw new Error("Variant.decode : cannot find decoder for type " + DataType[self.dataType]); | ||
} | ||
const cursorBefore = stream.length; | ||
const cursorBefore = stream.length; | ||
if (isArray) { | ||
self.arrayType = hasDimension ? VariantArrayType.Matrix : VariantArrayType.Array; | ||
_decodeVariantArrayDebug(stream, decode, tracer, self.dataType); | ||
} else { | ||
self.arrayType = VariantArrayType.Scalar; | ||
self.value = decode(stream); | ||
tracer.trace("member", "Variant", self.value, cursorBefore, stream.length, DataType[self.dataType]); | ||
} | ||
if (isArray) { | ||
self.arrayType = hasDimension ? VariantArrayType.Matrix : VariantArrayType.Array; | ||
_decodeVariantArrayDebug(stream, decode, tracer, self.dataType); | ||
} else { | ||
self.arrayType = VariantArrayType.Scalar; | ||
self.value = decode(stream); | ||
tracer.trace("member", "Variant", self.value, cursorBefore, stream.length, DataType[self.dataType]); | ||
} | ||
// ArrayDimensions | ||
// Int32[] | ||
// The length of each dimension. | ||
// This field is only present if the array dimensions flag is set in the encoding mask. | ||
// The lower rank dimensions appear first in the array. | ||
// All dimensions shall be specified and shall be greater than zero. | ||
// If ArrayDimensions are inconsistent with the ArrayLength then the decoder shall | ||
// stop and raise a BadDecodingError. | ||
if (hasDimension) { | ||
self.dimensions = decodeDimension(stream); | ||
const verification = calculate_product(self.dimensions); | ||
} | ||
// ArrayDimensions | ||
// Int32[] | ||
// The length of each dimension. | ||
// This field is only present if the array dimensions flag is set in the encoding mask. | ||
// The lower rank dimensions appear first in the array. | ||
// All dimensions shall be specified and shall be greater than zero. | ||
// If ArrayDimensions are inconsistent with the ArrayLength then the decoder shall | ||
// stop and raise a BadDecodingError. | ||
if (hasDimension) { | ||
self.dimensions = decodeDimension(stream); | ||
const verification = calculate_product(self.dimensions); | ||
} | ||
} | ||
@@ -352,26 +352,26 @@ | ||
const encodingByte = decodeUInt8(stream); | ||
const encodingByte = decodeUInt8(stream); | ||
const isArray: boolean = ((encodingByte & VARIANT_ARRAY_MASK) === VARIANT_ARRAY_MASK); | ||
const isArray: boolean = ((encodingByte & VARIANT_ARRAY_MASK) === VARIANT_ARRAY_MASK); | ||
const hasDimension: boolean = ((encodingByte & VARIANT_ARRAY_DIMENSIONS_MASK) === VARIANT_ARRAY_DIMENSIONS_MASK); | ||
const hasDimension: boolean = ((encodingByte & VARIANT_ARRAY_DIMENSIONS_MASK) === VARIANT_ARRAY_DIMENSIONS_MASK); | ||
self.dataType = (encodingByte & VARIANT_TYPE_MASK) as DataType; | ||
self.dataType = (encodingByte & VARIANT_TYPE_MASK) as DataType; | ||
if (isArray) { | ||
self.arrayType = hasDimension ? VariantArrayType.Matrix : VariantArrayType.Array; | ||
self.value = decodeVariantArray(self.dataType, stream); | ||
} else { | ||
self.arrayType = VariantArrayType.Scalar; | ||
const decode = get_decoder(self.dataType); | ||
self.value = decode(stream); | ||
if (isArray) { | ||
self.arrayType = hasDimension ? VariantArrayType.Matrix : VariantArrayType.Array; | ||
self.value = decodeVariantArray(self.dataType, stream); | ||
} else { | ||
self.arrayType = VariantArrayType.Scalar; | ||
const decode = get_decoder(self.dataType); | ||
self.value = decode(stream); | ||
} | ||
if (hasDimension) { | ||
self.dimensions = decodeDimension(stream); | ||
const verification = calculate_product(self.dimensions); | ||
/* istanbul ignore next */ | ||
if (verification !== self.value.length) { | ||
throw new Error("BadDecodingError"); | ||
} | ||
if (hasDimension) { | ||
self.dimensions = decodeDimension(stream); | ||
const verification = calculate_product(self.dimensions); | ||
/* istanbul ignore next */ | ||
if (verification !== self.value.length) { | ||
throw new Error("BadDecodingError"); | ||
} | ||
} | ||
} | ||
} | ||
@@ -383,5 +383,5 @@ | ||
export function decodeVariant(stream: BinaryStream): Variant { | ||
const value = new Variant({}); | ||
value.decode(stream); | ||
return value; | ||
const value = new Variant({}); | ||
value.decode(stream); | ||
return value; | ||
} | ||
@@ -391,116 +391,118 @@ | ||
options = options || {}; | ||
options = options || {}; | ||
let isArrayTypeUnspecified = (options.arrayType === undefined); | ||
let isArrayTypeUnspecified = (options.arrayType === undefined); | ||
if (options.constructor.name === "Variant") { | ||
const opts = { | ||
arrayType: options.arrayType, | ||
dataType: options.dataType, | ||
dimensions: options.dimensions, | ||
value: options.value, | ||
}; | ||
if (opts.dataType === DataType.ExtensionObject) { | ||
if (opts.arrayType === VariantArrayType.Scalar) { | ||
if (opts.value && opts.value.constructor) { | ||
opts.value = new opts.value.constructor(opts.value); | ||
} | ||
} else { | ||
opts.value = opts.value.map( (e: any) => { | ||
if (e && e.constructor) { | ||
return new e.constructor(e); | ||
} | ||
return null; | ||
}); | ||
} | ||
} else if (opts.arrayType !== VariantArrayType.Scalar) { | ||
opts.value = coerceVariantArray(options.dataType, options.value); | ||
if (options.constructor.name === "Variant") { | ||
const opts = { | ||
arrayType: options.arrayType, | ||
dataType: options.dataType, | ||
dimensions: options.dimensions, | ||
value: options.value, | ||
}; | ||
if (opts.dataType === DataType.ExtensionObject) { | ||
if (opts.arrayType === VariantArrayType.Scalar) { | ||
if (opts.value && opts.value.constructor) { | ||
opts.value = new opts.value.constructor(opts.value); | ||
} | ||
return opts; | ||
} else { | ||
opts.value = opts.value.map((e: any) => { | ||
if (e && e.constructor) { | ||
return new e.constructor(e); | ||
} | ||
return null; | ||
}); | ||
} | ||
} else if (opts.arrayType !== VariantArrayType.Scalar) { | ||
opts.value = coerceVariantArray(options.dataType, options.value); | ||
} | ||
assert(options); | ||
options.dataType = options.dataType || DataType.Null; | ||
return opts; | ||
} | ||
assert(options); | ||
options.dataType = options.dataType || DataType.Null; | ||
// dataType could be a string | ||
if (typeof options.dataType === "string") { | ||
// dataType could be a string | ||
if (typeof options.dataType === "string") { | ||
const d = findBuiltInType(options.dataType); | ||
/* istanbul ignore next */ | ||
if (!d) { | ||
throw new Error("Cannot find data type buildIn"); | ||
} | ||
const t = _enumerationDataType.get(d.name); | ||
/* istanbul ignore next */ | ||
if (t === null) { | ||
throw new Error("DataType: invalid " + options.dataType); | ||
} | ||
options.dataType = t.value as DataType; | ||
const d = findBuiltInType(options.dataType); | ||
/* istanbul ignore next */ | ||
if (!d) { | ||
throw new Error("Cannot find data type buildIn"); | ||
} | ||
const t = _enumerationDataType.get(d.name); | ||
/* istanbul ignore next */ | ||
if (t === null) { | ||
throw new Error("DataType: invalid " + options.dataType); | ||
} | ||
options.dataType = t.value as DataType; | ||
} | ||
// array type could be a string | ||
if (typeof options.arrayType === "string") { | ||
// array type could be a string | ||
if (typeof options.arrayType === "string") { | ||
const at = VariantArrayType[options.arrayType]; | ||
/* istanbul ignore next */ | ||
if (utils.isNullOrUndefined(at)) { | ||
throw new Error("ArrayType: invalid " + options.arrayType); | ||
} | ||
options.arrayType = at; | ||
const at = VariantArrayType[options.arrayType]; | ||
/* istanbul ignore next */ | ||
if (utils.isNullOrUndefined(at)) { | ||
throw new Error("ArrayType: invalid " + options.arrayType); | ||
} | ||
options.arrayType = at; | ||
} | ||
if (isArrayTypeUnspecified && _.isArray(options.value)) { | ||
// when using UInt64 ou Int64 arrayType must be specified , as automatic detection cannot be made | ||
if (isArrayTypeUnspecified && _.isArray(options.value)) { | ||
// when using UInt64 ou Int64 arrayType must be specified , as automatic detection cannot be made | ||
/* istanbul ignore next */ | ||
if ((options.dataType === DataType.UInt64 || options.dataType === DataType.Int64)) { | ||
// we do nothing here .... | ||
throw new Error("Variant#constructor : when using UInt64 ou Int64" + | ||
" arrayType must be specified , as automatic detection cannot be made"); | ||
} else { | ||
options.arrayType = VariantArrayType.Array; | ||
isArrayTypeUnspecified = false; | ||
} | ||
/* istanbul ignore next */ | ||
if ((options.dataType === DataType.UInt64 || options.dataType === DataType.Int64)) { | ||
// we do nothing here .... | ||
throw new Error("Variant#constructor : when using UInt64 ou Int64" + | ||
" arrayType must be specified , as automatic detection cannot be made"); | ||
} else { | ||
options.arrayType = VariantArrayType.Array; | ||
isArrayTypeUnspecified = false; | ||
} | ||
} | ||
if (options.arrayType !== VariantArrayType.Scalar && !isArrayTypeUnspecified) { | ||
assert(options.arrayType === VariantArrayType.Array || options.arrayType === VariantArrayType.Matrix); | ||
/* istanbul ignore else */ | ||
if (options.arrayType === VariantArrayType.Array) { | ||
if (options.arrayType !== VariantArrayType.Scalar && !isArrayTypeUnspecified) { | ||
assert(options.arrayType === VariantArrayType.Array || options.arrayType === VariantArrayType.Matrix); | ||
/* istanbul ignore else */ | ||
if (options.arrayType === VariantArrayType.Array) { | ||
options.value = options.value || []; | ||
const value1 = coerceVariantArray(options.dataType, options.value); | ||
assert(value1 !== options.value); | ||
options.value = value1; | ||
} else { | ||
assert(options.arrayType === VariantArrayType.Matrix); | ||
options.value = options.value || []; | ||
options.value = options.value || []; | ||
const value1 = coerceVariantArray(options.dataType, options.value); | ||
assert(value1 !== options.value); | ||
options.value = value1; | ||
} else { | ||
assert(options.arrayType === VariantArrayType.Matrix); | ||
options.value = options.value || []; | ||
options.value = coerceVariantArray(options.dataType, options.value); | ||
options.value = coerceVariantArray(options.dataType, options.value); | ||
/* istanbul ignore next */ | ||
if (!options.dimensions) { | ||
throw new Error("Matrix Variant : missing dimensions"); | ||
} | ||
/* istanbul ignore next */ | ||
if (options.value.length !== calculate_product(options.dimensions)) { | ||
throw new Error("Matrix Variant : invalid value size"); | ||
} | ||
} | ||
} else { | ||
assert(options.arrayType === VariantArrayType.Scalar || options.arrayType === undefined); | ||
options.arrayType = VariantArrayType.Scalar; | ||
const tmp = options.value; | ||
// scalar | ||
options.value = coerceVariantType(options.dataType, options.value); | ||
/* istanbul ignore next */ | ||
if (!options.dimensions) { | ||
throw new Error("Matrix Variant : missing dimensions"); | ||
} | ||
/* istanbul ignore next */ | ||
if (options.value.length !== calculate_product(options.dimensions)) { | ||
throw new Error("Matrix Variant : invalid value size = options.value.length " | ||
+ options.value.length + "!=" + calculate_product(options.dimensions) | ||
+ " => " + JSON.stringify(options.dimensions)); | ||
} | ||
} | ||
} else { | ||
assert(options.arrayType === VariantArrayType.Scalar || options.arrayType === undefined); | ||
options.arrayType = VariantArrayType.Scalar; | ||
const tmp = options.value; | ||
// scalar | ||
options.value = coerceVariantType(options.dataType, options.value); | ||
/* istanbul ignore next */ | ||
if (!isValidVariant(options.arrayType, options.dataType, options.value, null)) { | ||
throw new Error("Invalid variant arrayType: " + options.arrayType.toString() + | ||
" dataType: " + options.dataType.toString() + " value:" + options.value + " type= " + (typeof options.value)); | ||
} | ||
/* istanbul ignore next */ | ||
if (!isValidVariant(options.arrayType, options.dataType, options.value, null)) { | ||
throw new Error("Invalid variant arrayType: " + options.arrayType.toString() + | ||
" dataType: " + options.dataType.toString() + " value:" + options.value + " type= " + (typeof options.value)); | ||
} | ||
if (options.dimensions) { | ||
assert(options.arrayType === VariantArrayType.Matrix, "dimension can only provided if variant is a matrix"); | ||
} | ||
return options; | ||
} | ||
if (options.dimensions) { | ||
assert(options.arrayType === VariantArrayType.Matrix, "dimension can only provided if variant is a matrix"); | ||
} | ||
return options; | ||
} | ||
@@ -510,7 +512,7 @@ | ||
/* istanbul ignore next */ | ||
if (!array) { | ||
return 0; | ||
} | ||
return array.reduce((n: number, p: number) => n * p, 1); | ||
/* istanbul ignore next */ | ||
if (!array || array.length === 0) { | ||
return 0; | ||
} | ||
return array.reduce((n: number, p: number) => n * p, 1); | ||
} | ||
@@ -520,19 +522,19 @@ | ||
const dataTypeAsString = DataType[dataType]; | ||
const encode = findBuiltInType(dataTypeAsString).encode; | ||
/* istanbul ignore next */ | ||
if (!encode) { | ||
throw new Error("Cannot find encode function for dataType " + dataTypeAsString); | ||
} | ||
return encode; | ||
const dataTypeAsString = DataType[dataType]; | ||
const encode = findBuiltInType(dataTypeAsString).encode; | ||
/* istanbul ignore next */ | ||
if (!encode) { | ||
throw new Error("Cannot find encode function for dataType " + dataTypeAsString); | ||
} | ||
return encode; | ||
} | ||
function get_decoder(dataType: DataType) { | ||
const dataTypeAsString = DataType[dataType]; | ||
const decode = findBuiltInType(dataTypeAsString).decode; | ||
/* istanbul ignore next */ | ||
if (!decode) { | ||
throw new Error("Variant.decode : cannot find decoder for type " + dataTypeAsString); | ||
} | ||
return decode; | ||
const dataTypeAsString = DataType[dataType]; | ||
const decode = findBuiltInType(dataTypeAsString).decode; | ||
/* istanbul ignore next */ | ||
if (!decode) { | ||
throw new Error("Variant.decode : cannot find decoder for type " + dataTypeAsString); | ||
} | ||
return decode; | ||
} | ||
@@ -546,14 +548,14 @@ | ||
export type BufferedArray2 = | ||
Float32Array | ||
| Float64Array | ||
| Int8Array | ||
| Int16Array | ||
| Int32Array | ||
| Uint8Array | ||
| Uint16Array | ||
| Uint32Array ; | ||
Float32Array | ||
| Float64Array | ||
| Int8Array | ||
| Int16Array | ||
| Int32Array | ||
| Uint8Array | ||
| Uint16Array | ||
| Uint32Array; | ||
interface BufferedArrayConstructor { | ||
BYTES_PER_ELEMENT: number; | ||
new(buffer: any): any; | ||
BYTES_PER_ELEMENT: number; | ||
new(buffer: any): any; | ||
} | ||
@@ -563,42 +565,46 @@ | ||
if (arrayTypeConstructor && value instanceof arrayTypeConstructor) { | ||
const newArray = new value.constructor(value.length); // deep copy | ||
if (value === undefined || value === null) { | ||
value = []; | ||
} | ||
/* istanbul ignore if */ | ||
if (newArray instanceof Buffer) { | ||
// required for nodejs 4.x | ||
value.copy(newArray); | ||
} else { | ||
newArray.set(value); | ||
} | ||
if (arrayTypeConstructor && value instanceof arrayTypeConstructor) { | ||
const newArray = new value.constructor(value.length); // deep copy | ||
return newArray; | ||
/* istanbul ignore if */ | ||
if (newArray instanceof Buffer) { | ||
// required for nodejs 4.x | ||
value.copy(newArray); | ||
} else { | ||
newArray.set(value); | ||
} | ||
const coerceFunc = coerceVariantType.bind(null, dataType); | ||
const n = value.length; | ||
const newArr: any = arrayTypeConstructor ? new arrayTypeConstructor(n) : new Array(n); | ||
for (let i = 0; i < n; i++) { | ||
newArr[i] = coerceFunc(value[i]); | ||
} | ||
// istanbul ignore next | ||
if (arrayTypeConstructor && displayWarning && n > 10) { | ||
// tslint:disable-next-line:no-console | ||
console.log("Warning ! an array containing " + DataType[dataType] + | ||
" elements has been provided as a generic array. "); | ||
// tslint:disable-next-line:no-console | ||
console.log(" This is inefficient as every array value will " + | ||
"have to be coerced and verified against the expected type"); | ||
// tslint:disable-next-line:no-console | ||
console.log(" It is highly recommended that you use a " + | ||
" typed array ", arrayTypeConstructor.constructor.name, " instead"); | ||
} | ||
return newArr; | ||
return newArray; | ||
} | ||
const coerceFunc = coerceVariantType.bind(null, dataType); | ||
const n = value.length; | ||
const newArr: any = arrayTypeConstructor ? new arrayTypeConstructor(n) : new Array(n); | ||
for (let i = 0; i < n; i++) { | ||
newArr[i] = coerceFunc(value[i]); | ||
} | ||
// istanbul ignore next | ||
if (arrayTypeConstructor && displayWarning && n > 10) { | ||
// tslint:disable-next-line:no-console | ||
console.log("Warning ! an array containing " + DataType[dataType] + | ||
" elements has been provided as a generic array. "); | ||
// tslint:disable-next-line:no-console | ||
console.log(" This is inefficient as every array value will " + | ||
"have to be coerced and verified against the expected type"); | ||
// tslint:disable-next-line:no-console | ||
console.log(" It is highly recommended that you use a " + | ||
" typed array ", arrayTypeConstructor.constructor.name, " instead"); | ||
} | ||
return newArr; | ||
} | ||
interface DataTypeHelper { | ||
coerce: (value: any) => any; | ||
encode: (stream: OutputBinaryStream, value: any) => void; | ||
decode: (stream: BinaryStream) => any; | ||
coerce: (value: any) => any; | ||
encode: (stream: OutputBinaryStream, value: any) => void; | ||
decode: (stream: BinaryStream) => any; | ||
} | ||
@@ -609,3 +615,3 @@ | ||
function _getHelper(dataType: DataType) { | ||
return typedArrayHelpers[DataType[dataType]]; | ||
return typedArrayHelpers[DataType[dataType]]; | ||
} | ||
@@ -615,8 +621,8 @@ | ||
const helper = _getHelper(dataType); | ||
if (helper) { | ||
return helper.coerce(value); | ||
} else { | ||
return convertTo(dataType, null, value); | ||
} | ||
const helper = _getHelper(dataType); | ||
if (helper) { | ||
return helper.coerce(value); | ||
} else { | ||
return convertTo(dataType, null, value); | ||
} | ||
} | ||
@@ -626,6 +632,6 @@ | ||
assert(value instanceof arrayTypeConstructor); | ||
assert(value.buffer instanceof ArrayBuffer); | ||
encodeUInt32(value.length, stream); | ||
stream.writeArrayBuffer(value.buffer, value.byteOffset, value.byteLength); | ||
assert(value instanceof arrayTypeConstructor); | ||
assert(value.buffer instanceof ArrayBuffer); | ||
encodeUInt32(value.length, stream); | ||
stream.writeArrayBuffer(value.buffer, value.byteOffset, value.byteLength); | ||
@@ -635,12 +641,12 @@ } | ||
function encodeGeneralArray(dataType: DataType, stream: OutputBinaryStream, value: any) { | ||
const arr = value || []; | ||
assert(arr instanceof Array); | ||
assert(_.isFinite(arr.length)); | ||
encodeUInt32(arr.length, stream); | ||
const encode = get_encoder(dataType); | ||
let i; | ||
const n = arr.length; | ||
for (i = 0; i < n; i++) { | ||
encode(arr[i], stream); | ||
} | ||
const arr = value || []; | ||
assert(arr instanceof Array); | ||
assert(_.isFinite(arr.length)); | ||
encodeUInt32(arr.length, stream); | ||
const encode = get_encoder(dataType); | ||
let i; | ||
const n = arr.length; | ||
for (i = 0; i < n; i++) { | ||
encode(arr[i], stream); | ||
} | ||
} | ||
@@ -650,12 +656,12 @@ | ||
if (value.buffer) { | ||
try { | ||
return _getHelper(dataType).encode(stream, value); | ||
} catch (err) { | ||
/* istanbul ignore next */ | ||
// tslint:disable-next-line:no-console | ||
console.log("encodeVariantArray error : DATATYPE", dataType, "\nvalue", value.length); | ||
} | ||
if (value.buffer) { | ||
try { | ||
return _getHelper(dataType).encode(stream, value); | ||
} catch (err) { | ||
/* istanbul ignore next */ | ||
// tslint:disable-next-line:no-console | ||
console.log("encodeVariantArray error : DATATYPE", dataType, "\nvalue", value.length); | ||
} | ||
return encodeGeneralArray(dataType, stream, value); | ||
} | ||
return encodeGeneralArray(dataType, stream, value); | ||
} | ||
@@ -665,13 +671,13 @@ | ||
const length = decodeUInt32(stream); | ||
const length = decodeUInt32(stream); | ||
/* istanbul ignore next */ | ||
if (length === 0xFFFFFFFF) { | ||
return null; | ||
} | ||
const byteLength = length * arrayTypeConstructor.BYTES_PER_ELEMENT; | ||
const arr = stream.readArrayBuffer(byteLength); | ||
const value = new arrayTypeConstructor(arr.buffer); | ||
assert(value.length === length); | ||
return value; | ||
/* istanbul ignore next */ | ||
if (length === 0xFFFFFFFF) { | ||
return null; | ||
} | ||
const byteLength = length * arrayTypeConstructor.BYTES_PER_ELEMENT; | ||
const arr = stream.readArrayBuffer(byteLength); | ||
const value = new arrayTypeConstructor(arr.buffer); | ||
assert(value.length === length); | ||
return value; | ||
} | ||
@@ -681,33 +687,33 @@ | ||
const length = decodeUInt32(stream); | ||
const length = decodeUInt32(stream); | ||
/* istanbul ignore next */ | ||
if (length === 0xFFFFFFFF) { | ||
return null; | ||
} | ||
/* istanbul ignore next */ | ||
if (length === 0xFFFFFFFF) { | ||
return null; | ||
} | ||
const decode = get_decoder(dataType); | ||
const decode = get_decoder(dataType); | ||
const arr = []; | ||
for (let i = 0; i < length; i++) { | ||
arr.push(decode(stream)); | ||
} | ||
return arr; | ||
const arr = []; | ||
for (let i = 0; i < length; i++) { | ||
arr.push(decode(stream)); | ||
} | ||
return arr; | ||
} | ||
function decodeVariantArray(dataType: DataType, stream: BinaryStream) { | ||
const helper = _getHelper(dataType); | ||
if (helper) { | ||
return helper.decode(stream); | ||
} else { | ||
return decodeGeneralArray(dataType, stream); | ||
} | ||
const helper = _getHelper(dataType); | ||
if (helper) { | ||
return helper.decode(stream); | ||
} else { | ||
return decodeGeneralArray(dataType, stream); | ||
} | ||
} | ||
function _declareTypeArrayHelper(dataType: DataType, typedArrayConstructor: any) { | ||
typedArrayHelpers[DataType[dataType]] = { | ||
coerce: convertTo.bind(null, dataType, typedArrayConstructor), | ||
decode: decodeTypedArray.bind(null, typedArrayConstructor), | ||
encode: encodeTypedArray.bind(null, typedArrayConstructor), | ||
}; | ||
typedArrayHelpers[DataType[dataType]] = { | ||
coerce: convertTo.bind(null, dataType, typedArrayConstructor), | ||
decode: decodeTypedArray.bind(null, typedArrayConstructor), | ||
encode: encodeTypedArray.bind(null, typedArrayConstructor), | ||
}; | ||
} | ||
@@ -726,125 +732,125 @@ | ||
let cursorBefore = stream.length; | ||
const length = decodeUInt32(stream); | ||
let cursorBefore = stream.length; | ||
const length = decodeUInt32(stream); | ||
let i; | ||
let element; | ||
tracer.trace("start_array", "Variant", length, cursorBefore, stream.length); | ||
let i; | ||
let element; | ||
tracer.trace("start_array", "Variant", length, cursorBefore, stream.length); | ||
const n1 = Math.min(10, length); | ||
const n1 = Math.min(10, length); | ||
// display a maximum of 10 elements | ||
for (i = 0; i < n1; i++) { | ||
tracer.trace("start_element", "", i); | ||
cursorBefore = stream.length; | ||
element = decode(stream); | ||
// arr.push(element); | ||
tracer.trace("member", "Variant", element, cursorBefore, stream.length, DataType[dataType]); | ||
tracer.trace("end_element", "", i); | ||
// display a maximum of 10 elements | ||
for (i = 0; i < n1; i++) { | ||
tracer.trace("start_element", "", i); | ||
cursorBefore = stream.length; | ||
element = decode(stream); | ||
// arr.push(element); | ||
tracer.trace("member", "Variant", element, cursorBefore, stream.length, DataType[dataType]); | ||
tracer.trace("end_element", "", i); | ||
} | ||
// keep reading | ||
if (length >= n1) { | ||
for (i = n1; i < length; i++) { | ||
decode(stream); | ||
} | ||
// keep reading | ||
if (length >= n1) { | ||
for (i = n1; i < length; i++) { | ||
decode(stream); | ||
} | ||
tracer.trace("start_element", "", n1); | ||
tracer.trace("member", "Variant", "...", cursorBefore, stream.length, DataType[dataType]); | ||
tracer.trace("end_element", "", n1); | ||
} | ||
tracer.trace("end_array", "Variant", stream.length); | ||
tracer.trace("start_element", "", n1); | ||
tracer.trace("member", "Variant", "...", cursorBefore, stream.length, DataType[dataType]); | ||
tracer.trace("end_element", "", n1); | ||
} | ||
tracer.trace("end_array", "Variant", stream.length); | ||
} | ||
function decodeDimension(stream: BinaryStream) { | ||
return decodeGeneralArray(DataType.UInt32, stream); | ||
return decodeGeneralArray(DataType.UInt32, stream); | ||
} | ||
function encodeDimension(dimensions: number[], stream: OutputBinaryStream) { | ||
return encodeGeneralArray(DataType.UInt32, stream, dimensions); | ||
return encodeGeneralArray(DataType.UInt32, stream, dimensions); | ||
} | ||
function isEnumerationItem(value: any): boolean { | ||
return (value instanceof Object && (value.hasOwnProperty("value")) && value.hasOwnProperty("key")); | ||
return (value instanceof Object && (value.hasOwnProperty("value")) && value.hasOwnProperty("key")); | ||
} | ||
export function coerceVariantType(dataType: DataType, value: any): any { | ||
/* eslint max-statements: ["error",1000], complexity: ["error",1000]*/ | ||
if (value === undefined) { | ||
value = null; | ||
} | ||
if (isEnumerationItem(value)) { | ||
// OPCUA Specification 1.0.3 5.8.2 encoding rules for various dataType: | ||
// [...]Enumeration are always encoded as Int32 on the wire [...] | ||
/* eslint max-statements: ["error",1000], complexity: ["error",1000]*/ | ||
if (value === undefined) { | ||
value = null; | ||
} | ||
if (isEnumerationItem(value)) { | ||
// OPCUA Specification 1.0.3 5.8.2 encoding rules for various dataType: | ||
// [...]Enumeration are always encoded as Int32 on the wire [...] | ||
/* istanbul ignore next */ | ||
if (dataType !== DataType.Int32) { | ||
throw new Error("expecting DataType.Int32 for enumeration values ;" + | ||
" got DataType." + dataType.toString() + " instead"); | ||
} | ||
/* istanbul ignore next */ | ||
if (dataType !== DataType.Int32) { | ||
throw new Error("expecting DataType.Int32 for enumeration values ;" + | ||
" got DataType." + dataType.toString() + " instead"); | ||
} | ||
} | ||
switch (dataType) { | ||
case DataType.Null: | ||
value = null; | ||
break; | ||
switch (dataType) { | ||
case DataType.Null: | ||
value = null; | ||
break; | ||
case DataType.LocalizedText: | ||
if (!value || !value.schema || value.schema !== LocalizedText.schema) { | ||
value = new LocalizedText(value); | ||
} | ||
break; | ||
case DataType.LocalizedText: | ||
if (!value || !value.schema || value.schema !== LocalizedText.schema) { | ||
value = new LocalizedText(value); | ||
} | ||
break; | ||
case DataType.QualifiedName: | ||
if (!value || !value.schema || value.schema !== QualifiedName.schema) { | ||
value = new QualifiedName(value); | ||
} | ||
break; | ||
case DataType.Int16: | ||
case DataType.UInt16: | ||
case DataType.Int32: | ||
case DataType.UInt32: | ||
assert(value !== undefined); | ||
case DataType.QualifiedName: | ||
if (!value || !value.schema || value.schema !== QualifiedName.schema) { | ||
value = new QualifiedName(value); | ||
} | ||
break; | ||
case DataType.Int16: | ||
case DataType.UInt16: | ||
case DataType.Int32: | ||
case DataType.UInt32: | ||
assert(value !== undefined); | ||
if (isEnumerationItem(value)) { | ||
// value is a enumeration of some sort | ||
value = value.value; | ||
} else { | ||
value = parseInt(value, 10); | ||
} | ||
/* istanbul ignore next */ | ||
if (!_.isFinite(value)) { | ||
// xx console.log("xxx ", value, ttt); | ||
throw new Error("expecting a number " + value); | ||
} | ||
break; | ||
case DataType.UInt64: | ||
value = coerceUInt64(value); | ||
break; | ||
case DataType.Int64: | ||
value = coerceInt64(value); | ||
break; | ||
case DataType.ExtensionObject: | ||
break; | ||
case DataType.DateTime: | ||
assert(value === null || value instanceof Date); | ||
break; | ||
case DataType.String: | ||
assert(typeof value === "string" || value === null); | ||
break; | ||
case DataType.ByteString: | ||
value = (typeof value === "string") ? Buffer.from(value) : value; | ||
if (isEnumerationItem(value)) { | ||
// value is a enumeration of some sort | ||
value = value.value; | ||
} else { | ||
value = parseInt(value, 10); | ||
} | ||
/* istanbul ignore next */ | ||
if (!_.isFinite(value)) { | ||
// xx console.log("xxx ", value, ttt); | ||
throw new Error("expecting a number " + value); | ||
} | ||
break; | ||
case DataType.UInt64: | ||
value = coerceUInt64(value); | ||
break; | ||
case DataType.Int64: | ||
value = coerceInt64(value); | ||
break; | ||
case DataType.ExtensionObject: | ||
break; | ||
case DataType.DateTime: | ||
assert(value === null || value instanceof Date); | ||
break; | ||
case DataType.String: | ||
assert(typeof value === "string" || value === null); | ||
break; | ||
case DataType.ByteString: | ||
value = (typeof value === "string") ? Buffer.from(value) : value; | ||
// istanbul ignore next | ||
if (!(value === null || value instanceof Buffer)) { | ||
throw new Error("ByteString should be null or a Buffer"); | ||
} | ||
assert(value === null || value instanceof Buffer); | ||
break; | ||
default: | ||
assert(dataType !== undefined && dataType !== null, "Invalid DataType"); | ||
break; | ||
case DataType.NodeId: | ||
break; | ||
// istanbul ignore next | ||
if (!(value === null || value instanceof Buffer)) { | ||
throw new Error("ByteString should be null or a Buffer"); | ||
} | ||
assert(value === null || value instanceof Buffer); | ||
break; | ||
default: | ||
assert(dataType !== undefined && dataType !== null, "Invalid DataType"); | ||
break; | ||
case DataType.NodeId: | ||
break; | ||
} | ||
return value; | ||
} | ||
return value; | ||
} | ||
@@ -854,37 +860,37 @@ | ||
assert(value === null | ||
|| DataType.Int64 === dataType | ||
|| DataType.ByteString === dataType | ||
|| DataType.UInt64 === dataType | ||
|| !(value instanceof Array)); | ||
assert(value === null || !(value instanceof Int32Array)); | ||
assert(value === null || !(value instanceof Uint32Array)); | ||
switch (dataType) { | ||
case DataType.NodeId: | ||
return isValidNodeId(value); | ||
case DataType.String: | ||
return typeof value === "string" || utils.isNullOrUndefined(value); | ||
case DataType.Int64: | ||
return isValidInt64(value); | ||
case DataType.UInt64: | ||
return isValidUInt64(value); | ||
case DataType.UInt32: | ||
return isValidUInt32(value); | ||
case DataType.Int32: | ||
return isValidInt32(value); | ||
case DataType.UInt16: | ||
return isValidUInt16(value); | ||
case DataType.Int16: | ||
return isValidInt16(value); | ||
case DataType.Byte: | ||
return isValidUInt8(value); | ||
case DataType.SByte: | ||
return isValidInt8(value); | ||
case DataType.Boolean: | ||
return isValidBoolean(value); | ||
case DataType.ByteString: | ||
return isValidByteString(value); | ||
default: | ||
return true; | ||
} | ||
assert(value === null | ||
|| DataType.Int64 === dataType | ||
|| DataType.ByteString === dataType | ||
|| DataType.UInt64 === dataType | ||
|| !(value instanceof Array)); | ||
assert(value === null || !(value instanceof Int32Array)); | ||
assert(value === null || !(value instanceof Uint32Array)); | ||
switch (dataType) { | ||
case DataType.NodeId: | ||
return isValidNodeId(value); | ||
case DataType.String: | ||
return typeof value === "string" || utils.isNullOrUndefined(value); | ||
case DataType.Int64: | ||
return isValidInt64(value); | ||
case DataType.UInt64: | ||
return isValidUInt64(value); | ||
case DataType.UInt32: | ||
return isValidUInt32(value); | ||
case DataType.Int32: | ||
return isValidInt32(value); | ||
case DataType.UInt16: | ||
return isValidUInt16(value); | ||
case DataType.Int16: | ||
return isValidInt16(value); | ||
case DataType.Byte: | ||
return isValidUInt8(value); | ||
case DataType.SByte: | ||
return isValidInt8(value); | ||
case DataType.Boolean: | ||
return isValidBoolean(value); | ||
case DataType.ByteString: | ||
return isValidByteString(value); | ||
default: | ||
return true; | ||
} | ||
} | ||
@@ -894,55 +900,55 @@ | ||
if (dataType === DataType.Float && value instanceof Float32Array) { | ||
return true; | ||
} else if (dataType === DataType.Double && value instanceof Float64Array) { | ||
return true; | ||
} else if (dataType === DataType.SByte && (value instanceof Int8Array)) { | ||
return true; | ||
} else if (dataType === DataType.Byte && (value instanceof Buffer || value instanceof Uint8Array)) { | ||
return true; | ||
} else if (dataType === DataType.Int16 && value instanceof Int16Array) { | ||
return true; | ||
} else if (dataType === DataType.Int32 && value instanceof Int32Array) { | ||
return true; | ||
} else if (dataType === DataType.UInt16 && value instanceof Uint16Array) { | ||
return true; | ||
} else if (dataType === DataType.UInt32 && value instanceof Uint32Array) { | ||
return true; | ||
if (dataType === DataType.Float && value instanceof Float32Array) { | ||
return true; | ||
} else if (dataType === DataType.Double && value instanceof Float64Array) { | ||
return true; | ||
} else if (dataType === DataType.SByte && (value instanceof Int8Array)) { | ||
return true; | ||
} else if (dataType === DataType.Byte && (value instanceof Buffer || value instanceof Uint8Array)) { | ||
return true; | ||
} else if (dataType === DataType.Int16 && value instanceof Int16Array) { | ||
return true; | ||
} else if (dataType === DataType.Int32 && value instanceof Int32Array) { | ||
return true; | ||
} else if (dataType === DataType.UInt16 && value instanceof Uint16Array) { | ||
return true; | ||
} else if (dataType === DataType.UInt32 && value instanceof Uint32Array) { | ||
return true; | ||
} | ||
// array values can be store in Buffer, Float32Array | ||
assert(_.isArray(value)); | ||
for (const valueItem of value) { | ||
if (!isValidScalarVariant(dataType, valueItem)) { | ||
return false; | ||
} | ||
// array values can be store in Buffer, Float32Array | ||
assert(_.isArray(value)); | ||
for (const valueItem of value) { | ||
if (!isValidScalarVariant(dataType, valueItem)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return true; | ||
} | ||
/*istanbul ignore next*/ | ||
function isValidMatrixVariant(dataType: DataType, value: any, dimensions: number[]| null) { | ||
function isValidMatrixVariant(dataType: DataType, value: any, dimensions: number[] | null) { | ||
if (!dimensions) { | ||
return false; | ||
} | ||
if (!isValidArrayVariant(dataType, value)) { | ||
return false; | ||
} | ||
return true; | ||
if (!dimensions) { | ||
return false; | ||
} | ||
if (!isValidArrayVariant(dataType, value)) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
export function isValidVariant( | ||
arrayType: VariantArrayType, | ||
dataType: DataType, | ||
value: any, dimensions?: number[] | null): boolean { | ||
arrayType: VariantArrayType, | ||
dataType: DataType, | ||
value: any, dimensions?: number[] | null): boolean { | ||
switch (arrayType) { | ||
case VariantArrayType.Scalar: | ||
return isValidScalarVariant(dataType, value); | ||
case VariantArrayType.Array: | ||
return isValidArrayVariant(dataType, value); | ||
default: | ||
assert(arrayType === VariantArrayType.Matrix); | ||
return isValidMatrixVariant(dataType, value, dimensions!); | ||
} | ||
switch (arrayType) { | ||
case VariantArrayType.Scalar: | ||
return isValidScalarVariant(dataType, value); | ||
case VariantArrayType.Array: | ||
return isValidArrayVariant(dataType, value); | ||
default: | ||
assert(arrayType === VariantArrayType.Matrix); | ||
return isValidMatrixVariant(dataType, value, dimensions!); | ||
} | ||
} | ||
@@ -952,37 +958,37 @@ | ||
let value; | ||
switch (dataType) { | ||
case DataType.Float: | ||
value = new Float32Array(nbElements); | ||
break; | ||
case DataType.Double: | ||
value = new Float64Array(nbElements); | ||
break; | ||
case DataType.UInt32: | ||
value = new Uint32Array(nbElements); | ||
break; | ||
case DataType.Int32: | ||
value = new Int32Array(nbElements); | ||
break; | ||
case DataType.UInt16: | ||
value = new Uint16Array(nbElements); | ||
break; | ||
case DataType.Int16: | ||
value = new Int16Array(nbElements); | ||
break; | ||
case DataType.Byte: | ||
value = new Uint8Array(nbElements); | ||
break; | ||
case DataType.SByte: | ||
value = new Int8Array(nbElements); | ||
break; | ||
default: | ||
value = new Array(nbElements); | ||
let value; | ||
switch (dataType) { | ||
case DataType.Float: | ||
value = new Float32Array(nbElements); | ||
break; | ||
case DataType.Double: | ||
value = new Float64Array(nbElements); | ||
break; | ||
case DataType.UInt32: | ||
value = new Uint32Array(nbElements); | ||
break; | ||
case DataType.Int32: | ||
value = new Int32Array(nbElements); | ||
break; | ||
case DataType.UInt16: | ||
value = new Uint16Array(nbElements); | ||
break; | ||
case DataType.Int16: | ||
value = new Int16Array(nbElements); | ||
break; | ||
case DataType.Byte: | ||
value = new Uint8Array(nbElements); | ||
break; | ||
case DataType.SByte: | ||
value = new Int8Array(nbElements); | ||
break; | ||
default: | ||
value = new Array(nbElements); | ||
} | ||
if (defaultValue !== undefined) { | ||
for (let i = 0; i < nbElements; i++) { | ||
value[i] = defaultValue; | ||
} | ||
if (defaultValue !== undefined) { | ||
for (let i = 0; i < nbElements; i++) { | ||
value[i] = defaultValue; | ||
} | ||
} | ||
return value; | ||
} | ||
return value; | ||
} | ||
@@ -995,28 +1001,28 @@ | ||
if (!arr1 || !arr2) { | ||
return !arr1 && !arr2; | ||
} | ||
if (arr1.length !== arr2.length) { | ||
return false; | ||
} | ||
if (arr1.length === 0 && 0 === arr2.length) { | ||
return true; | ||
} | ||
if (!oldNodeVersion && arr1.buffer) { | ||
if (!arr1 || !arr2) { | ||
return !arr1 && !arr2; | ||
} | ||
if (arr1.length !== arr2.length) { | ||
return false; | ||
} | ||
if (arr1.length === 0 && 0 === arr2.length) { | ||
return true; | ||
} | ||
if (!oldNodeVersion && arr1.buffer) { | ||
// v1 and v2 are TypedArray (such as Int32Array...) | ||
// this is the most efficient way to compare 2 buffers but it doesn't work with node <= 0.12 | ||
assert(arr2.buffer); | ||
// compare byte by byte | ||
const b1 = Buffer.from(arr1.buffer, arr1.byteOffset, arr1.byteLength); | ||
const b2 = Buffer.from(arr2.buffer, arr2.byteOffset, arr2.byteLength); | ||
return b1.equals(b2); | ||
// v1 and v2 are TypedArray (such as Int32Array...) | ||
// this is the most efficient way to compare 2 buffers but it doesn't work with node <= 0.12 | ||
assert(arr2.buffer); | ||
// compare byte by byte | ||
const b1 = Buffer.from(arr1.buffer, arr1.byteOffset, arr1.byteLength); | ||
const b2 = Buffer.from(arr2.buffer, arr2.byteOffset, arr2.byteLength); | ||
return b1.equals(b2); | ||
} | ||
const n = arr1.length; | ||
for (let i = 0; i < n; i++) { | ||
if (!_.isEqual(arr1[i], arr2[i])) { | ||
return false; | ||
} | ||
const n = arr1.length; | ||
for (let i = 0; i < n; i++) { | ||
if (!_.isEqual(arr1[i], arr2[i])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return true; | ||
@@ -1032,35 +1038,35 @@ } | ||
if (v1 === v2) { | ||
return true; | ||
if (v1 === v2) { | ||
return true; | ||
} | ||
if ((!v1 && v2) || (v1 && !v2)) { | ||
return false; | ||
} | ||
if (v1.arrayType !== v2.arrayType) { | ||
return false; | ||
} | ||
if (v1.dataType !== v2.dataType) { | ||
return false; | ||
} | ||
if (v1.value === v2.value) { | ||
return true; | ||
} | ||
if (v1.arrayType === VariantArrayType.Scalar) { | ||
if (Array.isArray(v1.value) && Array.isArray(v2.value)) { | ||
return __check_same_array(v1.value, v2.value); | ||
} | ||
if ((!v1 && v2) || (v1 && !v2)) { | ||
return false; | ||
if (Buffer.isBuffer(v1.value) && Buffer.isBuffer(v2.value)) { | ||
return v1.value.equals(v2.value); | ||
} | ||
if (v1.arrayType !== v2.arrayType) { | ||
return false; | ||
} | ||
if (v1.dataType !== v2.dataType) { | ||
return false; | ||
} | ||
if (v1.value === v2.value) { | ||
return true; | ||
} | ||
if (v1.arrayType === VariantArrayType.Scalar) { | ||
if (Array.isArray(v1.value) && Array.isArray(v2.value)) { | ||
return __check_same_array(v1.value, v2.value); | ||
} | ||
if (Buffer.isBuffer(v1.value) && Buffer.isBuffer(v2.value)) { | ||
return v1.value.equals(v2.value); | ||
} | ||
} | ||
if (v1.arrayType === VariantArrayType.Array) { | ||
return __check_same_array(v1.value, v2.value); | ||
} | ||
if (v1.arrayType === VariantArrayType.Array) { | ||
return __check_same_array(v1.value, v2.value); | ||
} else if (v1.arrayType === VariantArrayType.Matrix) { | ||
if (!__check_same_array(v1.dimensions, v2.dimensions)) { | ||
return false; | ||
} | ||
return __check_same_array(v1.value, v2.value); | ||
} else if (v1.arrayType === VariantArrayType.Matrix) { | ||
if (!__check_same_array(v1.dimensions, v2.dimensions)) { | ||
return false; | ||
} | ||
return false; | ||
return __check_same_array(v1.value, v2.value); | ||
} | ||
return false; | ||
} | ||
@@ -1072,13 +1078,13 @@ | ||
export interface VariantOptionsT<T, DT extends DataType> extends VariantOptions { | ||
dataType: DT; | ||
arrayType?: VariantArrayType | string; | ||
value: T; | ||
dimensions?: number[] | null; | ||
dataType: DT; | ||
arrayType?: VariantArrayType | string; | ||
value: T; | ||
dimensions?: number[] | null; | ||
} | ||
export interface VariantT<T, DT extends DataType> extends Variant { | ||
value: T; | ||
dataType: DT; | ||
value: T; | ||
dataType: DT; | ||
} | ||
export declare type VariantByteString = VariantT<Buffer, DataType.ByteString>; | ||
export declare type VariantDouble = VariantT<number, DataType.Double>; |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
280745
2066
Updatednode-opcua-data-model@^2.4.0
Updatednode-opcua-factory@^2.4.0
Updatednode-opcua-utils@^2.4.0