/
packobject.ts
101 lines (95 loc) · 3.09 KB
/
packobject.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { PackedSimpleValue, PackedValues } from "./pack"
/**
* Unpacked data mapped as an object
* @category Data Packing
*/
export interface PackedObject {
[index: string]: PackedSimpleValue | PackedObject | PackedObject[]
}
/**
* Unrolls an array of packed values into a friendly object structure
* @param data
* @param fields
* @returns
* @category Data Packing
*/
export function unpackedToObject(
data: PackedValues,
fields: jdspec.PacketMember[],
defaultName?: string,
): PackedObject {
if (!data || !fields) return undefined
const r: PackedObject = {}
for (let i = 0; i < data.length; ++i) {
const field = fields[i]
const value = data[i]
const { name, startRepeats } = field
const prettyName = name === "_" && defaultName ? defaultName : name
if (startRepeats) {
const repeatFields = fields.slice(i)
//console.log({ value, repeatFields, data })
r["repeat"] = value.map((rdata: PackedValues) => {
const r: PackedObject = {}
for (let i = 0; i < repeatFields.length; ++i) {
const field = fields[i]
const value = rdata[i]
const { name } = field
const prettyName =
name === "_" && defaultName ? defaultName : name
r[prettyName] = value
}
return r
})
break
} else r[prettyName] = value
}
return r
}
/**
* Converts an object structure into a flat packed data array
* @param pkt
* @param msg
* @returns
* @category Data Packing
*/
export function objectToUnpacked(
pkt: jdspec.PacketInfo,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
msg: any,
): PackedValues {
if (!msg) return []
if (typeof msg === "number" || typeof msg === "string")
return [msg as number]
else if (typeof msg === "boolean") return [msg ? 1 : 0]
else if (Array.isArray(msg)) {
// assume a packaged layout
return msg as PackedValues
} else {
const { fields } = pkt
const r: PackedValues = []
for (let i = 0; i < fields.length; ++i) {
const field = fields[i]
const name = field.name === "_" ? pkt.name : field.name
const value = msg[name]
if (field.startRepeats) {
const repeatFields = fields.slice(i)
r.push(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(value as any[]).map(vrow => {
const arow: PackedSimpleValue[] = []
for (let j = 0; j < repeatFields.length; ++j) {
const rfield = repeatFields[j]
const rname = rfield.name
arow.push(vrow[rname])
}
return arow
}),
)
break
} else {
r.push(value)
}
}
return r
}
}