node-opcua-basic-types
Version:
pure nodejs OPCUA SDK - module basic-types
138 lines (113 loc) • 4.54 kB
text/typescript
/***
* @module node-opcua-basic-types
*/
import assert from "node-opcua-assert";
import { BinaryStream, OutputBinaryStream } from "node-opcua-binary-stream";
import { isValidGuid } from "node-opcua-guid";
import { getRandomInt } from "./utils";
export { isValidGuid, emptyGuid } from "node-opcua-guid";
function toHex(i: number, nb: number): string {
return i.toString(16).padStart(nb, "0");
}
export type Guid = string;
export function randomGuid(): Guid {
const b = new BinaryStream(20);
for (let i = 0; i < 20; i++) {
b.writeUInt8(getRandomInt(0, 255));
}
b.rewind();
const value = decodeGuid(b) as Guid;
return value;
}
// 1 2 3
// 012345678901234567890123456789012345
// | | | | | | | | | | |
// 12345678-1234-1234-ABCD-0123456789AB
// 00000000-0000-0000-0000-000000000000";
const hexCharToNum = (h: number): number => {
// tslint:disable-next-line: no-bitwise
const l = h & 0x5f;
const r = l <= 25 ? l - 16 : l - 55;
// xx assert(r >= 0 && r < 16);
return r;
};
assert(hexCharToNum("A".charCodeAt(0)) === 10);
assert(hexCharToNum("a".charCodeAt(0)) === 10);
assert(hexCharToNum("b".charCodeAt(0)) === 11);
assert(hexCharToNum("B".charCodeAt(0)) === 11);
assert(hexCharToNum("0".charCodeAt(0)) === 0);
assert(hexCharToNum("9".charCodeAt(0)) === 9);
function write_UInt32(stream: OutputBinaryStream, guid: string, starts: number[]) {
const n = starts.length;
for (let i = 0; i < n; i++) {
const start = starts[i];
const d1 = hexCharToNum(guid.charCodeAt(start));
const d2 = hexCharToNum(guid.charCodeAt(start + 1));
const d3 = hexCharToNum(guid.charCodeAt(start + 2));
const d4 = hexCharToNum(guid.charCodeAt(start + 3));
const d5 = hexCharToNum(guid.charCodeAt(start + 4));
const d6 = hexCharToNum(guid.charCodeAt(start + 5));
const d7 = hexCharToNum(guid.charCodeAt(start + 6));
const d8 = hexCharToNum(guid.charCodeAt(start + 7));
// tslint:disable-next-line: no-bitwise
const value = (((((((((((((d1 << 4) | d2) << 4) | d3) << 4) | d4) << 4) | d5) << 4) | d6) << 4) | d7) << 4) | d8;
stream.writeInteger(value);
}
}
function write_UInt16(stream: OutputBinaryStream, guid: string, starts: number[]) {
const n = starts.length;
for (let i = 0; i < n; i++) {
const start = starts[i];
const d1 = hexCharToNum(guid.charCodeAt(start));
const d2 = hexCharToNum(guid.charCodeAt(start + 1));
const d3 = hexCharToNum(guid.charCodeAt(start + 2));
const d4 = hexCharToNum(guid.charCodeAt(start + 3));
// tslint:disable-next-line: no-bitwise
const value = (((((d1 << 4) | d2) << 4) | d3) << 4) | d4;
stream.writeUInt16(value);
}
}
function write_UInt8(stream: OutputBinaryStream, guid: string, starts: number[]) {
const n = starts.length;
for (let i = 0; i < n; i++) {
const start = starts[i];
const d1 = hexCharToNum(guid.charCodeAt(start));
const d2 = hexCharToNum(guid.charCodeAt(start + 1));
// tslint:disable-next-line: no-bitwise
const value = (d1 << 4) | d2;
stream.writeUInt8(value);
}
}
export function encodeGuid(guid: Guid, stream: OutputBinaryStream): void {
if (!isValidGuid(guid)) {
throw new Error(" Invalid GUID : '" + JSON.stringify(guid) + ": the format should be 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'");
}
write_UInt32(stream, guid, [0]);
write_UInt16(stream, guid, [9, 14]);
write_UInt8(stream, guid, [19, 21, 24, 26, 28, 30, 32, 34]);
}
function read_UInt32(stream: BinaryStream) {
return toHex(stream.readUInt32(), 8);
}
function read_UInt16(stream: BinaryStream) {
return toHex(stream.readUInt16(), 4);
}
function read_UInt8(stream: BinaryStream) {
return toHex(stream.readUInt8(), 2);
}
function read_many(stream: BinaryStream, func: (stream: BinaryStream) => string, nb: number): string {
let result = "";
for (let i = 0; i < nb; i++) {
result += func(stream);
}
return result;
}
export function decodeGuid(stream: BinaryStream, value?: Guid): Guid {
const data1 = read_UInt32(stream);
const data2 = read_UInt16(stream);
const data3 = read_UInt16(stream);
const data45 = read_many(stream, read_UInt8, 2);
const data6B = read_many(stream, read_UInt8, 6);
const guid = data1 + "-" + data2 + "-" + data3 + "-" + data45 + "-" + data6B;
return guid.toUpperCase();
}