@its-c10/dis-codec 0.1.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/README.md +86 -0
- package/dist/binary/BinaryReader.d.ts +21 -0
- package/dist/binary/BinaryReader.js +92 -0
- package/dist/binary/BinaryWriter.d.ts +24 -0
- package/dist/binary/BinaryWriter.js +88 -0
- package/dist/binary.d.ts +36 -0
- package/dist/binary.js +144 -0
- package/dist/codecs/common/decodeEntityId.d.ts +3 -0
- package/dist/codecs/common/decodeEntityId.js +7 -0
- package/dist/codecs/common/encodeEntityId.d.ts +3 -0
- package/dist/codecs/common/encodeEntityId.js +5 -0
- package/dist/codecs/entityId.d.ts +10 -0
- package/dist/codecs/entityId.js +12 -0
- package/dist/core/entityId.d.ts +14 -0
- package/dist/core/entityId.js +14 -0
- package/dist/core/eventId.d.ts +12 -0
- package/dist/core/eventId.js +14 -0
- package/dist/dis/clockTime.d.ts +14 -0
- package/dist/dis/clockTime.js +10 -0
- package/dist/dis7/constants.d.ts +41 -0
- package/dist/dis7/constants.js +41 -0
- package/dist/dis7/createEntityPdu.d.ts +13 -0
- package/dist/dis7/createEntityPdu.js +17 -0
- package/dist/dis7/electromagneticEmissionPdu.d.ts +72 -0
- package/dist/dis7/electromagneticEmissionPdu.js +133 -0
- package/dist/dis7/entityStatePdu.d.ts +80 -0
- package/dist/dis7/entityStatePdu.js +149 -0
- package/dist/dis7/index.d.ts +12 -0
- package/dist/dis7/index.js +12 -0
- package/dist/dis7/pduHeader.d.ts +18 -0
- package/dist/dis7/pduHeader.js +22 -0
- package/dist/dis7/removeEntityPdu.d.ts +13 -0
- package/dist/dis7/removeEntityPdu.js +17 -0
- package/dist/dis7/startResumePdu.d.ts +16 -0
- package/dist/dis7/startResumePdu.js +22 -0
- package/dist/dis7/stopFreezePdu.d.ts +21 -0
- package/dist/dis7/stopFreezePdu.js +26 -0
- package/dist/dis7/transmitterPdu.d.ts +110 -0
- package/dist/dis7/transmitterPdu.js +200 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +5 -0
- package/dist/types/EntityId.d.ts +6 -0
- package/dist/types/EntityId.js +1 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# dis-codec
|
|
2
|
+
|
|
3
|
+
Spec-accurate **Distributed Interactive Simulation (DIS)** encode/decode library in TypeScript. Wire format follows IEEE 1278.1 (DIS application protocols). PDUs are encoded with correct header length for UDP/DIS feeds.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install dis-codec
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
**Encode a PDU and get bytes for UDP:**
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { BinaryWriter, dis7 } from "dis-codec";
|
|
17
|
+
|
|
18
|
+
const writer = new BinaryWriter();
|
|
19
|
+
dis7.encodeCreateEntityPdu(writer, {
|
|
20
|
+
header: {
|
|
21
|
+
protocolVersion: dis7.PROTOCOL_VERSION,
|
|
22
|
+
exerciseId: 1,
|
|
23
|
+
pduType: dis7.PDU_TYPE_CREATE_ENTITY,
|
|
24
|
+
protocolFamily: dis7.PROTOCOL_FAMILY_SIMULATION_MANAGEMENT,
|
|
25
|
+
timestamp: 0,
|
|
26
|
+
length: 0, // ignored; encoder sets correct length automatically
|
|
27
|
+
pduStatus: 0,
|
|
28
|
+
padding: 0,
|
|
29
|
+
},
|
|
30
|
+
originatingId: { simulationAddress: { site: 1, application: 2 }, entity: 10 },
|
|
31
|
+
receivingId: { simulationAddress: { site: 0, application: 0 }, entity: 0 },
|
|
32
|
+
requestId: 1,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const bytes = new Uint8Array(writer.toArrayBuffer());
|
|
36
|
+
// Send bytes over UDP
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Decode a PDU from received bytes:**
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { BinaryReader, dis7 } from "dis-codec";
|
|
43
|
+
|
|
44
|
+
const reader = new BinaryReader(udpPacketBuffer);
|
|
45
|
+
const pdu = dis7.decodeEntityStatePdu(reader);
|
|
46
|
+
// Use pdu.entityId, pdu.entityLocation, etc.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Switch on PDU type:**
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const reader = new BinaryReader(buffer);
|
|
53
|
+
const header = dis7.decodePduHeader(reader);
|
|
54
|
+
reader.setOffset(0); // rewind to decode full PDU
|
|
55
|
+
|
|
56
|
+
if (header.pduType === dis7.PDU_TYPE_ENTITY_STATE) {
|
|
57
|
+
const pdu = dis7.decodeEntityStatePdu(reader);
|
|
58
|
+
// ...
|
|
59
|
+
} else if (header.pduType === dis7.PDU_TYPE_ELECTROMAGNETIC_EMISSION) {
|
|
60
|
+
const pdu = dis7.decodeElectromagneticEmissionPdu(reader);
|
|
61
|
+
// ...
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## DIS 7 PDUs
|
|
66
|
+
|
|
67
|
+
| PDU | Encode / Decode | Notes |
|
|
68
|
+
|-----|-----------------|--------|
|
|
69
|
+
| Entity State | `encodeEntityStatePdu` / `decodeEntityStatePdu` | Variable length |
|
|
70
|
+
| Create Entity | `encodeCreateEntityPdu` / `decodeCreateEntityPdu` | 28 bytes |
|
|
71
|
+
| Remove Entity | `encodeRemoveEntityPdu` / `decodeRemoveEntityPdu` | 28 bytes |
|
|
72
|
+
| Start/Resume | `encodeStartResumePdu` / `decodeStartResumePdu` | 44 bytes |
|
|
73
|
+
| Stop/Freeze | `encodeStopFreezePdu` / `decodeStopFreezePdu` | 40 bytes |
|
|
74
|
+
| Electromagnetic Emission | `encodeElectromagneticEmissionPdu` / `decodeElectromagneticEmissionPdu` | Variable length |
|
|
75
|
+
| Transmitter | `encodeTransmitterPdu` / `decodeTransmitterPdu` | Variable length |
|
|
76
|
+
|
|
77
|
+
Constants for PDU types, protocol families, and fixed lengths are on `dis7` (e.g. `dis7.PDU_TYPE_ENTITY_STATE`, `dis7.CREATE_ENTITY_PDU_LENGTH`).
|
|
78
|
+
|
|
79
|
+
## Requirements
|
|
80
|
+
|
|
81
|
+
- ES2020+ (Node or browser)
|
|
82
|
+
- TypeScript types included
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
MIT
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Big-endian binary reader (DIS network byte order). */
|
|
2
|
+
export declare class BinaryReader {
|
|
3
|
+
private readonly view;
|
|
4
|
+
private offset;
|
|
5
|
+
constructor(buffer: ArrayBuffer);
|
|
6
|
+
getOffset(): number;
|
|
7
|
+
setOffset(pos: number): void;
|
|
8
|
+
skip(bytes: number): void;
|
|
9
|
+
private ensureReadable;
|
|
10
|
+
readUint8(): number;
|
|
11
|
+
readUint16(): number;
|
|
12
|
+
readUint32(): number;
|
|
13
|
+
readUint64(): bigint;
|
|
14
|
+
readInt8(): number;
|
|
15
|
+
readInt16(): number;
|
|
16
|
+
readInt32(): number;
|
|
17
|
+
readFloat32(): number;
|
|
18
|
+
readFloat64(): number;
|
|
19
|
+
/** Read a fixed number of bytes as a new Uint8Array. */
|
|
20
|
+
readBytes(byteCount: number): Uint8Array;
|
|
21
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/** Big-endian binary reader (DIS network byte order). */
|
|
2
|
+
export class BinaryReader {
|
|
3
|
+
constructor(buffer) {
|
|
4
|
+
this.offset = 0;
|
|
5
|
+
this.view = new DataView(buffer);
|
|
6
|
+
}
|
|
7
|
+
getOffset() {
|
|
8
|
+
return this.offset;
|
|
9
|
+
}
|
|
10
|
+
setOffset(pos) {
|
|
11
|
+
if (pos < 0 || pos > this.view.byteLength) {
|
|
12
|
+
throw new RangeError(`BinaryReader.setOffset: offset ${pos} out of range [0, ${this.view.byteLength}]`);
|
|
13
|
+
}
|
|
14
|
+
this.offset = pos;
|
|
15
|
+
}
|
|
16
|
+
skip(bytes) {
|
|
17
|
+
if (bytes < 0) {
|
|
18
|
+
throw new RangeError(`BinaryReader.skip: negative bytes (${bytes})`);
|
|
19
|
+
}
|
|
20
|
+
this.ensureReadable(bytes);
|
|
21
|
+
this.offset += bytes;
|
|
22
|
+
}
|
|
23
|
+
ensureReadable(byteCount) {
|
|
24
|
+
if (this.offset + byteCount > this.view.byteLength) {
|
|
25
|
+
throw new RangeError(`BinaryReader: read past end (need ${byteCount} bytes at offset ${this.offset}, length ${this.view.byteLength})`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
readUint8() {
|
|
29
|
+
this.ensureReadable(1);
|
|
30
|
+
const v = this.view.getUint8(this.offset);
|
|
31
|
+
this.offset += 1;
|
|
32
|
+
return v;
|
|
33
|
+
}
|
|
34
|
+
readUint16() {
|
|
35
|
+
this.ensureReadable(2);
|
|
36
|
+
const v = this.view.getUint16(this.offset, false);
|
|
37
|
+
this.offset += 2;
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
readUint32() {
|
|
41
|
+
this.ensureReadable(4);
|
|
42
|
+
const v = this.view.getUint32(this.offset, false);
|
|
43
|
+
this.offset += 4;
|
|
44
|
+
return v;
|
|
45
|
+
}
|
|
46
|
+
readUint64() {
|
|
47
|
+
this.ensureReadable(8);
|
|
48
|
+
const v = this.view.getBigUint64(this.offset, false);
|
|
49
|
+
this.offset += 8;
|
|
50
|
+
return v;
|
|
51
|
+
}
|
|
52
|
+
readInt8() {
|
|
53
|
+
this.ensureReadable(1);
|
|
54
|
+
const v = this.view.getInt8(this.offset);
|
|
55
|
+
this.offset += 1;
|
|
56
|
+
return v;
|
|
57
|
+
}
|
|
58
|
+
readInt16() {
|
|
59
|
+
this.ensureReadable(2);
|
|
60
|
+
const v = this.view.getInt16(this.offset, false);
|
|
61
|
+
this.offset += 2;
|
|
62
|
+
return v;
|
|
63
|
+
}
|
|
64
|
+
readInt32() {
|
|
65
|
+
this.ensureReadable(4);
|
|
66
|
+
const v = this.view.getInt32(this.offset, false);
|
|
67
|
+
this.offset += 4;
|
|
68
|
+
return v;
|
|
69
|
+
}
|
|
70
|
+
readFloat32() {
|
|
71
|
+
this.ensureReadable(4);
|
|
72
|
+
const v = this.view.getFloat32(this.offset, false);
|
|
73
|
+
this.offset += 4;
|
|
74
|
+
return v;
|
|
75
|
+
}
|
|
76
|
+
readFloat64() {
|
|
77
|
+
this.ensureReadable(8);
|
|
78
|
+
const v = this.view.getFloat64(this.offset, false);
|
|
79
|
+
this.offset += 8;
|
|
80
|
+
return v;
|
|
81
|
+
}
|
|
82
|
+
/** Read a fixed number of bytes as a new Uint8Array. */
|
|
83
|
+
readBytes(byteCount) {
|
|
84
|
+
this.ensureReadable(byteCount);
|
|
85
|
+
const out = new Uint8Array(byteCount);
|
|
86
|
+
for (let i = 0; i < byteCount; i++) {
|
|
87
|
+
out[i] = this.view.getUint8(this.offset + i);
|
|
88
|
+
}
|
|
89
|
+
this.offset += byteCount;
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Big-endian binary writer with growable buffer (DIS network byte order). */
|
|
2
|
+
export declare class BinaryWriter {
|
|
3
|
+
private buf;
|
|
4
|
+
private view;
|
|
5
|
+
private offset;
|
|
6
|
+
constructor(initialCapacity?: number);
|
|
7
|
+
getOffset(): number;
|
|
8
|
+
/** Returns a copy of written bytes as ArrayBuffer. */
|
|
9
|
+
toArrayBuffer(): ArrayBuffer;
|
|
10
|
+
/** Overwrite a uint16 at the given offset (does not advance write position). Used to patch PDU length. */
|
|
11
|
+
patchUint16(offset: number, value: number): void;
|
|
12
|
+
private ensureWritable;
|
|
13
|
+
writeUint8(value: number): void;
|
|
14
|
+
writeUint16(value: number): void;
|
|
15
|
+
writeUint32(value: number): void;
|
|
16
|
+
writeUint64(value: bigint): void;
|
|
17
|
+
writeInt8(value: number): void;
|
|
18
|
+
writeInt16(value: number): void;
|
|
19
|
+
writeInt32(value: number): void;
|
|
20
|
+
writeFloat32(value: number): void;
|
|
21
|
+
writeFloat64(value: number): void;
|
|
22
|
+
/** Write raw bytes from a Uint8Array or ArrayBuffer. */
|
|
23
|
+
writeBytes(data: Uint8Array | ArrayBuffer): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Big-endian binary writer with growable buffer (DIS network byte order). */
|
|
2
|
+
export class BinaryWriter {
|
|
3
|
+
constructor(initialCapacity = 64) {
|
|
4
|
+
this.offset = 0;
|
|
5
|
+
this.buf = new Uint8Array(initialCapacity);
|
|
6
|
+
this.view = new DataView(this.buf.buffer, 0, this.buf.byteLength);
|
|
7
|
+
}
|
|
8
|
+
getOffset() {
|
|
9
|
+
return this.offset;
|
|
10
|
+
}
|
|
11
|
+
/** Returns a copy of written bytes as ArrayBuffer. */
|
|
12
|
+
toArrayBuffer() {
|
|
13
|
+
const out = new ArrayBuffer(this.offset);
|
|
14
|
+
new Uint8Array(out).set(this.buf.subarray(0, this.offset));
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
17
|
+
/** Overwrite a uint16 at the given offset (does not advance write position). Used to patch PDU length. */
|
|
18
|
+
patchUint16(offset, value) {
|
|
19
|
+
if (offset < 0 || offset + 2 > this.offset) {
|
|
20
|
+
throw new RangeError(`BinaryWriter.patchUint16: offset ${offset} out of range [0, ${this.offset - 2}]`);
|
|
21
|
+
}
|
|
22
|
+
this.view.setUint16(offset, value, false);
|
|
23
|
+
}
|
|
24
|
+
ensureWritable(byteCount) {
|
|
25
|
+
const need = this.offset + byteCount;
|
|
26
|
+
if (need <= this.buf.byteLength)
|
|
27
|
+
return;
|
|
28
|
+
let cap = this.buf.byteLength;
|
|
29
|
+
while (cap < need)
|
|
30
|
+
cap = Math.max(cap * 2, need);
|
|
31
|
+
const next = new Uint8Array(cap);
|
|
32
|
+
next.set(this.buf.subarray(0, this.offset));
|
|
33
|
+
this.buf = next;
|
|
34
|
+
this.view = new DataView(this.buf.buffer, 0, this.buf.byteLength);
|
|
35
|
+
}
|
|
36
|
+
writeUint8(value) {
|
|
37
|
+
this.ensureWritable(1);
|
|
38
|
+
this.view.setUint8(this.offset, value);
|
|
39
|
+
this.offset += 1;
|
|
40
|
+
}
|
|
41
|
+
writeUint16(value) {
|
|
42
|
+
this.ensureWritable(2);
|
|
43
|
+
this.view.setUint16(this.offset, value, false);
|
|
44
|
+
this.offset += 2;
|
|
45
|
+
}
|
|
46
|
+
writeUint32(value) {
|
|
47
|
+
this.ensureWritable(4);
|
|
48
|
+
this.view.setUint32(this.offset, value, false);
|
|
49
|
+
this.offset += 4;
|
|
50
|
+
}
|
|
51
|
+
writeUint64(value) {
|
|
52
|
+
this.ensureWritable(8);
|
|
53
|
+
this.view.setBigUint64(this.offset, value, false);
|
|
54
|
+
this.offset += 8;
|
|
55
|
+
}
|
|
56
|
+
writeInt8(value) {
|
|
57
|
+
this.ensureWritable(1);
|
|
58
|
+
this.view.setInt8(this.offset, value);
|
|
59
|
+
this.offset += 1;
|
|
60
|
+
}
|
|
61
|
+
writeInt16(value) {
|
|
62
|
+
this.ensureWritable(2);
|
|
63
|
+
this.view.setInt16(this.offset, value, false);
|
|
64
|
+
this.offset += 2;
|
|
65
|
+
}
|
|
66
|
+
writeInt32(value) {
|
|
67
|
+
this.ensureWritable(4);
|
|
68
|
+
this.view.setInt32(this.offset, value, false);
|
|
69
|
+
this.offset += 4;
|
|
70
|
+
}
|
|
71
|
+
writeFloat32(value) {
|
|
72
|
+
this.ensureWritable(4);
|
|
73
|
+
this.view.setFloat32(this.offset, value, false);
|
|
74
|
+
this.offset += 4;
|
|
75
|
+
}
|
|
76
|
+
writeFloat64(value) {
|
|
77
|
+
this.ensureWritable(8);
|
|
78
|
+
this.view.setFloat64(this.offset, value, false);
|
|
79
|
+
this.offset += 8;
|
|
80
|
+
}
|
|
81
|
+
/** Write raw bytes from a Uint8Array or ArrayBuffer. */
|
|
82
|
+
writeBytes(data) {
|
|
83
|
+
const u8 = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
84
|
+
this.ensureWritable(u8.byteLength);
|
|
85
|
+
this.buf.set(u8, this.offset);
|
|
86
|
+
this.offset += u8.byteLength;
|
|
87
|
+
}
|
|
88
|
+
}
|
package/dist/binary.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Big-endian binary I/O (DIS network byte order). */
|
|
2
|
+
export declare class BinaryReader {
|
|
3
|
+
private readonly view;
|
|
4
|
+
private offset;
|
|
5
|
+
constructor(buffer: ArrayBuffer);
|
|
6
|
+
getOffset(): number;
|
|
7
|
+
setOffset(pos: number): void;
|
|
8
|
+
skip(bytes: number): void;
|
|
9
|
+
private ensureReadable;
|
|
10
|
+
readUint8(): number;
|
|
11
|
+
readUint16(): number;
|
|
12
|
+
readUint32(): number;
|
|
13
|
+
readInt8(): number;
|
|
14
|
+
readInt16(): number;
|
|
15
|
+
readInt32(): number;
|
|
16
|
+
readFloat32(): number;
|
|
17
|
+
readFloat64(): number;
|
|
18
|
+
}
|
|
19
|
+
export declare class BinaryWriter {
|
|
20
|
+
private buf;
|
|
21
|
+
private view;
|
|
22
|
+
private offset;
|
|
23
|
+
constructor(initialCapacity?: number);
|
|
24
|
+
getOffset(): number;
|
|
25
|
+
/** Returns a copy of written bytes as ArrayBuffer. */
|
|
26
|
+
toArrayBuffer(): ArrayBuffer;
|
|
27
|
+
private ensureWritable;
|
|
28
|
+
writeUint8(value: number): void;
|
|
29
|
+
writeUint16(value: number): void;
|
|
30
|
+
writeUint32(value: number): void;
|
|
31
|
+
writeInt8(value: number): void;
|
|
32
|
+
writeInt16(value: number): void;
|
|
33
|
+
writeInt32(value: number): void;
|
|
34
|
+
writeFloat32(value: number): void;
|
|
35
|
+
writeFloat64(value: number): void;
|
|
36
|
+
}
|
package/dist/binary.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/** Big-endian binary I/O (DIS network byte order). */
|
|
2
|
+
export class BinaryReader {
|
|
3
|
+
constructor(buffer) {
|
|
4
|
+
this.offset = 0;
|
|
5
|
+
this.view = new DataView(buffer);
|
|
6
|
+
}
|
|
7
|
+
getOffset() {
|
|
8
|
+
return this.offset;
|
|
9
|
+
}
|
|
10
|
+
setOffset(pos) {
|
|
11
|
+
if (pos < 0 || pos > this.view.byteLength) {
|
|
12
|
+
throw new RangeError(`BinaryReader.setOffset: offset ${pos} out of range [0, ${this.view.byteLength}]`);
|
|
13
|
+
}
|
|
14
|
+
this.offset = pos;
|
|
15
|
+
}
|
|
16
|
+
skip(bytes) {
|
|
17
|
+
if (bytes < 0) {
|
|
18
|
+
throw new RangeError(`BinaryReader.skip: negative bytes (${bytes})`);
|
|
19
|
+
}
|
|
20
|
+
this.ensureReadable(bytes);
|
|
21
|
+
this.offset += bytes;
|
|
22
|
+
}
|
|
23
|
+
ensureReadable(byteCount) {
|
|
24
|
+
if (this.offset + byteCount > this.view.byteLength) {
|
|
25
|
+
throw new RangeError(`BinaryReader: read past end (need ${byteCount} bytes at offset ${this.offset}, length ${this.view.byteLength})`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
readUint8() {
|
|
29
|
+
this.ensureReadable(1);
|
|
30
|
+
const v = this.view.getUint8(this.offset);
|
|
31
|
+
this.offset += 1;
|
|
32
|
+
return v;
|
|
33
|
+
}
|
|
34
|
+
readUint16() {
|
|
35
|
+
this.ensureReadable(2);
|
|
36
|
+
const v = this.view.getUint16(this.offset, false);
|
|
37
|
+
this.offset += 2;
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
readUint32() {
|
|
41
|
+
this.ensureReadable(4);
|
|
42
|
+
const v = this.view.getUint32(this.offset, false);
|
|
43
|
+
this.offset += 4;
|
|
44
|
+
return v;
|
|
45
|
+
}
|
|
46
|
+
readInt8() {
|
|
47
|
+
this.ensureReadable(1);
|
|
48
|
+
const v = this.view.getInt8(this.offset);
|
|
49
|
+
this.offset += 1;
|
|
50
|
+
return v;
|
|
51
|
+
}
|
|
52
|
+
readInt16() {
|
|
53
|
+
this.ensureReadable(2);
|
|
54
|
+
const v = this.view.getInt16(this.offset, false);
|
|
55
|
+
this.offset += 2;
|
|
56
|
+
return v;
|
|
57
|
+
}
|
|
58
|
+
readInt32() {
|
|
59
|
+
this.ensureReadable(4);
|
|
60
|
+
const v = this.view.getInt32(this.offset, false);
|
|
61
|
+
this.offset += 4;
|
|
62
|
+
return v;
|
|
63
|
+
}
|
|
64
|
+
readFloat32() {
|
|
65
|
+
this.ensureReadable(4);
|
|
66
|
+
const v = this.view.getFloat32(this.offset, false);
|
|
67
|
+
this.offset += 4;
|
|
68
|
+
return v;
|
|
69
|
+
}
|
|
70
|
+
readFloat64() {
|
|
71
|
+
this.ensureReadable(8);
|
|
72
|
+
const v = this.view.getFloat64(this.offset, false);
|
|
73
|
+
this.offset += 8;
|
|
74
|
+
return v;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export class BinaryWriter {
|
|
78
|
+
constructor(initialCapacity = 64) {
|
|
79
|
+
this.offset = 0;
|
|
80
|
+
this.buf = new Uint8Array(initialCapacity);
|
|
81
|
+
this.view = new DataView(this.buf.buffer, 0, this.buf.byteLength);
|
|
82
|
+
}
|
|
83
|
+
getOffset() {
|
|
84
|
+
return this.offset;
|
|
85
|
+
}
|
|
86
|
+
/** Returns a copy of written bytes as ArrayBuffer. */
|
|
87
|
+
toArrayBuffer() {
|
|
88
|
+
const out = new ArrayBuffer(this.offset);
|
|
89
|
+
new Uint8Array(out).set(this.buf.subarray(0, this.offset));
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
ensureWritable(byteCount) {
|
|
93
|
+
const need = this.offset + byteCount;
|
|
94
|
+
if (need <= this.buf.byteLength)
|
|
95
|
+
return;
|
|
96
|
+
let cap = this.buf.byteLength;
|
|
97
|
+
while (cap < need)
|
|
98
|
+
cap = Math.max(cap * 2, need);
|
|
99
|
+
const next = new Uint8Array(cap);
|
|
100
|
+
next.set(this.buf.subarray(0, this.offset));
|
|
101
|
+
this.buf = next;
|
|
102
|
+
this.view = new DataView(this.buf.buffer, 0, this.buf.byteLength);
|
|
103
|
+
}
|
|
104
|
+
writeUint8(value) {
|
|
105
|
+
this.ensureWritable(1);
|
|
106
|
+
this.view.setUint8(this.offset, value);
|
|
107
|
+
this.offset += 1;
|
|
108
|
+
}
|
|
109
|
+
writeUint16(value) {
|
|
110
|
+
this.ensureWritable(2);
|
|
111
|
+
this.view.setUint16(this.offset, value, false);
|
|
112
|
+
this.offset += 2;
|
|
113
|
+
}
|
|
114
|
+
writeUint32(value) {
|
|
115
|
+
this.ensureWritable(4);
|
|
116
|
+
this.view.setUint32(this.offset, value, false);
|
|
117
|
+
this.offset += 4;
|
|
118
|
+
}
|
|
119
|
+
writeInt8(value) {
|
|
120
|
+
this.ensureWritable(1);
|
|
121
|
+
this.view.setInt8(this.offset, value);
|
|
122
|
+
this.offset += 1;
|
|
123
|
+
}
|
|
124
|
+
writeInt16(value) {
|
|
125
|
+
this.ensureWritable(2);
|
|
126
|
+
this.view.setInt16(this.offset, value, false);
|
|
127
|
+
this.offset += 2;
|
|
128
|
+
}
|
|
129
|
+
writeInt32(value) {
|
|
130
|
+
this.ensureWritable(4);
|
|
131
|
+
this.view.setInt32(this.offset, value, false);
|
|
132
|
+
this.offset += 4;
|
|
133
|
+
}
|
|
134
|
+
writeFloat32(value) {
|
|
135
|
+
this.ensureWritable(4);
|
|
136
|
+
this.view.setFloat32(this.offset, value, false);
|
|
137
|
+
this.offset += 4;
|
|
138
|
+
}
|
|
139
|
+
writeFloat64(value) {
|
|
140
|
+
this.ensureWritable(8);
|
|
141
|
+
this.view.setFloat64(this.offset, value, false);
|
|
142
|
+
this.offset += 8;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BinaryReader } from "../binary.js";
|
|
2
|
+
import type { BinaryWriter } from "../binary.js";
|
|
3
|
+
/** DIS Entity ID: site, application, entity — each uint16, 6 bytes on wire. */
|
|
4
|
+
export interface EntityId {
|
|
5
|
+
site: number;
|
|
6
|
+
application: number;
|
|
7
|
+
entity: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function decodeEntityId(reader: BinaryReader): EntityId;
|
|
10
|
+
export declare function encodeEntityId(writer: BinaryWriter, value: EntityId): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function decodeEntityId(reader) {
|
|
2
|
+
return {
|
|
3
|
+
site: reader.readUint16(),
|
|
4
|
+
application: reader.readUint16(),
|
|
5
|
+
entity: reader.readUint16(),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function encodeEntityId(writer, value) {
|
|
9
|
+
writer.writeUint16(value.site);
|
|
10
|
+
writer.writeUint16(value.application);
|
|
11
|
+
writer.writeUint16(value.entity);
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BinaryReader } from "../binary/BinaryReader.js";
|
|
2
|
+
import type { BinaryWriter } from "../binary/BinaryWriter.js";
|
|
3
|
+
/** Site + application (uint16 each), 4 bytes on wire before entity number. */
|
|
4
|
+
export interface SimulationAddress {
|
|
5
|
+
site: number;
|
|
6
|
+
application: number;
|
|
7
|
+
}
|
|
8
|
+
/** DIS Entity ID: simulation address then entity (uint16), 6 bytes total. */
|
|
9
|
+
export interface EntityId {
|
|
10
|
+
simulationAddress: SimulationAddress;
|
|
11
|
+
entity: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function decodeEntityId(reader: BinaryReader): EntityId;
|
|
14
|
+
export declare function encodeEntityId(writer: BinaryWriter, value: EntityId): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function decodeEntityId(reader) {
|
|
2
|
+
return {
|
|
3
|
+
simulationAddress: {
|
|
4
|
+
site: reader.readUint16(),
|
|
5
|
+
application: reader.readUint16(),
|
|
6
|
+
},
|
|
7
|
+
entity: reader.readUint16(),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function encodeEntityId(writer, value) {
|
|
11
|
+
writer.writeUint16(value.simulationAddress.site);
|
|
12
|
+
writer.writeUint16(value.simulationAddress.application);
|
|
13
|
+
writer.writeUint16(value.entity);
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BinaryReader } from "../binary/BinaryReader.js";
|
|
2
|
+
import type { BinaryWriter } from "../binary/BinaryWriter.js";
|
|
3
|
+
/** DIS Event ID: simulation address then event number (uint16 each), 6 bytes total. */
|
|
4
|
+
export interface EventId {
|
|
5
|
+
simulationAddress: {
|
|
6
|
+
site: number;
|
|
7
|
+
application: number;
|
|
8
|
+
};
|
|
9
|
+
event: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function decodeEventId(reader: BinaryReader): EventId;
|
|
12
|
+
export declare function encodeEventId(writer: BinaryWriter, value: EventId): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function decodeEventId(reader) {
|
|
2
|
+
return {
|
|
3
|
+
simulationAddress: {
|
|
4
|
+
site: reader.readUint16(),
|
|
5
|
+
application: reader.readUint16(),
|
|
6
|
+
},
|
|
7
|
+
event: reader.readUint16(),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function encodeEventId(writer, value) {
|
|
11
|
+
writer.writeUint16(value.simulationAddress.site);
|
|
12
|
+
writer.writeUint16(value.simulationAddress.application);
|
|
13
|
+
writer.writeUint16(value.event);
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BinaryReader } from "../binary/BinaryReader.js";
|
|
2
|
+
import type { BinaryWriter } from "../binary/BinaryWriter.js";
|
|
3
|
+
/**
|
|
4
|
+
* DIS Clock Time record (hour + time past the hour).
|
|
5
|
+
* Wire: int32 hour, uint32 time-past-hour (big-endian). Shared across many PDUs.
|
|
6
|
+
*/
|
|
7
|
+
export interface ClockTime {
|
|
8
|
+
/** Whole hours since origin (signed). */
|
|
9
|
+
hour: number;
|
|
10
|
+
/** Microseconds (or PDU-specific unit) past the hour (unsigned). */
|
|
11
|
+
timePastHour: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function decodeClockTime(reader: BinaryReader): ClockTime;
|
|
14
|
+
export declare function encodeClockTime(writer: BinaryWriter, value: ClockTime): void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DIS protocol version 7 (IEEE 1278.1-2012 application protocols).
|
|
3
|
+
* Version is implied by module path; add `dis8/constants.ts` etc. for other editions.
|
|
4
|
+
*/
|
|
5
|
+
export declare const PROTOCOL_VERSION = 7;
|
|
6
|
+
/** Entity Information protocol family. */
|
|
7
|
+
export declare const PROTOCOL_FAMILY_ENTITY_INFORMATION = 1;
|
|
8
|
+
/** Simulation Management protocol family. */
|
|
9
|
+
export declare const PROTOCOL_FAMILY_SIMULATION_MANAGEMENT = 5;
|
|
10
|
+
/** PDU type: Entity State. */
|
|
11
|
+
export declare const PDU_TYPE_ENTITY_STATE = 1;
|
|
12
|
+
/** PDU type: Create Entity. */
|
|
13
|
+
export declare const PDU_TYPE_CREATE_ENTITY = 11;
|
|
14
|
+
/** PDU type: Remove Entity. */
|
|
15
|
+
export declare const PDU_TYPE_REMOVE_ENTITY = 12;
|
|
16
|
+
/** PDU type: Start/Resume. */
|
|
17
|
+
export declare const PDU_TYPE_START_RESUME = 13;
|
|
18
|
+
/** PDU type: Stop/Freeze. */
|
|
19
|
+
export declare const PDU_TYPE_STOP_FREEZE = 14;
|
|
20
|
+
/** PDU type: Electromagnetic Emission. */
|
|
21
|
+
export declare const PDU_TYPE_ELECTROMAGNETIC_EMISSION = 23;
|
|
22
|
+
/** PDU type: Transmitter. */
|
|
23
|
+
export declare const PDU_TYPE_TRANSMITTER = 25;
|
|
24
|
+
/** Electromagnetic Emission protocol family. */
|
|
25
|
+
export declare const PROTOCOL_FAMILY_ELECTROMAGNETIC_EMISSION = 6;
|
|
26
|
+
/** Radio Communications protocol family. */
|
|
27
|
+
export declare const PROTOCOL_FAMILY_RADIO_COMMUNICATIONS = 4;
|
|
28
|
+
/** Start/Resume PDU total length on wire (bytes). */
|
|
29
|
+
export declare const START_RESUME_PDU_LENGTH = 44;
|
|
30
|
+
/** Stop/Freeze PDU total length on wire (bytes). */
|
|
31
|
+
export declare const STOP_FREEZE_PDU_LENGTH = 40;
|
|
32
|
+
/** Create Entity PDU total length on wire (bytes). */
|
|
33
|
+
export declare const CREATE_ENTITY_PDU_LENGTH = 28;
|
|
34
|
+
/** Remove Entity PDU total length on wire (bytes). */
|
|
35
|
+
export declare const REMOVE_ENTITY_PDU_LENGTH = 28;
|
|
36
|
+
/** Entity State PDU fixed portion in bytes (144). Total = 144 + 16*N for N variable parameters. */
|
|
37
|
+
export declare const ENTITY_STATE_PDU_FIXED_LENGTH = 144;
|
|
38
|
+
/** Variable parameter record size in bytes. */
|
|
39
|
+
export declare const ENTITY_STATE_VARIABLE_PARAMETER_RECORD_LENGTH = 16;
|
|
40
|
+
/** Transmitter PDU fixed portion in bytes (104). Total = 104 + M + A + sum of variable record sizes. */
|
|
41
|
+
export declare const TRANSMITTER_PDU_FIXED_LENGTH = 104;
|