UNPKG

node-opcua-basic-types

Version:

pure nodejs OPCUA SDK - module basic-types

359 lines (310 loc) 9.72 kB
/*** * @module node-opcua-basic-types */ import { assert } from "node-opcua-assert"; import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream"; import { getRandomInt } from "./utils"; export function isValidUInt16(value: number): boolean { if (!isFinite(value)) { return false; } return value >= 0 && value <= 0xffff; } export type UInt8 = number; export type UInt16 = number; export type UInt32 = number; export type UInt64 = UInt32[]; export type Int8 = number; export type Int16 = number; export type Int32 = number; export type Int64 = UInt32[]; export type Byte = UInt8; export type SByte = Int8; // --------------------------------------- export function randomUInt16(): UInt16 { return getRandomInt(0, 0xffff) as UInt16; } export function encodeUInt16(value: UInt16, stream: OutputBinaryStream): void { stream.writeUInt16(value); } export function decodeUInt16(stream: BinaryStream, value?: number): UInt16 { return stream.readUInt16() as UInt16; } export function isValidInt16(value: number): boolean { if (!isFinite(value)) { return false; } return value >= -0x8000 && value <= 0x7fff; } export function randomInt16(): Int16 { return getRandomInt(-0x8000, 0x7fff); } export function encodeInt16(value: Int16, stream: OutputBinaryStream): void { assert(isFinite(value)); stream.writeInt16(value); } export function decodeInt16(stream: BinaryStream, value?: number): Int16 { return stream.readInt16() as Int16; } export function isValidInt32(value: number): boolean { if (!isFinite(value)) { return false; } return value >= -0x80000000 && value <= 0x7fffffff; } export function randomInt32(): Int32 { return getRandomInt(-0x80000000, 0x7fffffff) as Int32; } export function encodeInt32(value: Int32, stream: OutputBinaryStream): void { assert(isFinite(value)); stream.writeInteger(value); } export function decodeInt32(stream: BinaryStream, value?: number): Int32 { return stream.readInteger() as Int32; } export function isValidUInt32(value: number): boolean { if (!isFinite(value)) { return false; } return value >= 0 && value <= 0xffffffff; } export function randomUInt32(): UInt32 { return getRandomInt(0, 0xffffffff); } export function encodeUInt32(value: UInt32, stream: OutputBinaryStream): void { stream.writeUInt32(value); } export function decodeUInt32(stream: BinaryStream, value?: number): UInt32 { return stream.readUInt32() as UInt32; } export function isValidInt8(value: number): boolean { if (!isFinite(value)) { return false; } return value >= -0x80 && value <= 0x7f; } export function randomInt8(): Int8 { return getRandomInt(-0x7f, 0x7e); } export function encodeInt8(value: Int8, stream: OutputBinaryStream): void { assert(isValidInt8(value)); stream.writeInt8(value); } export function decodeInt8(stream: BinaryStream, value?: number): Int8 { return stream.readInt8(); } export const isValidSByte = isValidInt8; export const randomSByte = randomInt8; export const encodeSByte = encodeInt8; export const decodeSByte = decodeInt8; export function isValidUInt8(value: number): boolean { if (!isFinite(value)) { return false; } return value >= 0x00 && value <= 0xff; } export function randomUInt8(): UInt8 { return getRandomInt(0x00, 0xff); } export function encodeUInt8(value: UInt8, stream: OutputBinaryStream): void { stream.writeUInt8(value); } export function decodeUInt8(stream: BinaryStream, value?: number): UInt8 { return stream.readUInt8(); } export const isValidByte = isValidUInt8; export const randomByte = randomUInt8; export const encodeByte = encodeUInt8; export const decodeByte = decodeUInt8; export function isValidUInt64(value?: number | number[]): boolean { return value instanceof Array && value.length === 2; } export function randomUInt64(): UInt64 { return [getRandomInt(0, 0xffffffff), getRandomInt(0, 0xffffffff)]; } export function encodeUInt64(value: UInt64 | number, stream: OutputBinaryStream): void { if (typeof value === "number") { const arr = coerceUInt64(value); stream.writeUInt32(arr[1]); stream.writeUInt32(arr[0]); } else { stream.writeUInt32((value as number[])[1]); stream.writeUInt32((value as number[])[0]); } } export function decodeUInt64(stream: BinaryStream, value?: UInt64): UInt64 { const low = stream.readUInt32() as UInt32; const high = stream.readUInt32() as UInt32; return constructInt64(high, low); } export function constructInt64(high: UInt32, low: UInt32): Int64 { if (high === 0 && low < 0) { high = 0xffffffff; low = 0xffffffff + low + 1; } assert(low >= 0 && low <= 0xffffffff); assert(high >= 0 && high <= 0xffffffff); return [high, low]; } export function coerceUInt64(value: number | UInt64 | Int32 | string | null): UInt64 { let high; let low; let v; if (value === null || value === undefined) { return [0, 0]; } if (value instanceof Array) { assert(typeof value[0] === "number"); assert(typeof value[1] === "number"); return value; } if (typeof value === "string") { v = value.split(","); if (v.length === 1) { // was a single string, good news ! BigInt can be used with nodejs >=12 let a = BigInt(value); if (a < BigInt(0)) { const mask = BigInt("0xFFFFFFFFFFFFFFFF"); a = (mask + a + BigInt(1)) & mask; } high = Number(a >> BigInt(32)); low = Number(a & BigInt(0xffffffff)); } else { high = parseInt(v[0], 10); low = parseInt(v[1], 10); } return constructInt64(high, low); } if (value > 0xffffffff) { // beware : as per javascript, value is a double here ! // our conversion will suffer from some inaccuracy high = Math.floor(value / 0x100000000); low = value - high * 0x100000000; return constructInt64(high, low); } return constructInt64(0, value); } export function randomInt64(): Int64 { // High, low return [getRandomInt(0, 0xffffffff), getRandomInt(0, 0xffffffff)]; } export const coerceInt64 = coerceUInt64; export const isValidInt64 = isValidUInt64; export const encodeInt64 = encodeUInt64; export const decodeInt64 = decodeUInt64; export function coerceInt8(value: number | string | null): Int8 { if (value === null || value === undefined) { return 0; } if (typeof value === "number") { return value; } return parseInt(value, 10); } export function coerceUInt8(value: number | string | null): UInt8 { if (value === null || value === undefined) { return 0; } if (typeof value === "number") { return value; } return parseInt(value, 10); } export function coerceByte(value: number | string | null): UInt8 { if (value === null || value === undefined) { return 0; } if (typeof value === "number") { return value; } return parseInt(value, 10); } export function coerceSByte(value: number | string | null): Int8 { if (value === null || value === undefined) { return 0; } if (typeof value === "number") { return value; } return parseInt(value, 10); } export function coerceUInt16(value: number | string | null): UInt16 { if (value === null || value === undefined) { return 0; } if (typeof value === "number") { return value; } return parseInt(value, 10); } export function coerceInt16(value: number | string | null): Int16 { if (value === null || value === undefined) { return 0; } if (typeof value === "number") { return value; } return parseInt(value, 10); } interface EnumItemLike { value: number; } export function coerceUInt32(value: null | string | number | EnumItemLike): UInt32 { if (value === null || value === undefined) { return 0; } if (value && Object.prototype.hasOwnProperty.call(value, "value")) { return coerceUInt32((value as EnumItemLike).value); } if (typeof value === "number") { return value; } return parseInt(value as string, 10); } export function coerceInt32(value: null | Int64 | UInt64 | number | string): Int32 { if (value === null || value === undefined) { return 0; } if (value instanceof Array) { // Int64 as a [high,low] return coerceInt64toInt32(value); } if (typeof value === "number") { return value; } return parseInt(value, 10); } const signMask = 1n << 31n; const shiftHigh = 1n << 32n; export function Int64ToBigInt(value: Int64): bigint { const h = BigInt(value[0]); const l = BigInt(value[1]); if ((h & signMask) === signMask) { const v = (h & ~signMask) * shiftHigh + l - 0x8000000000000000n; return v; } else { const v = h * shiftHigh + l; return v; } } export function UInt64ToBigInt(value: UInt64): bigint { const h = BigInt(value[0]); const l = BigInt(value[1]); const v = h * shiftHigh + l; return v; } export function coerceInt64toInt32(value: Int64 | Int32): Int32 { if (value instanceof Array) { const b = Int64ToBigInt(value); return Number(b); } return value; } export function coerceUInt64toInt32(value: UInt64 | UInt32): Int32 { if (value instanceof Array) { const b = UInt64ToBigInt(value); return Number(b); } return value; }