@lichtblick/cdr
Version:
Common Data Representation serialization and deserialization library
202 lines • 9.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const CdrReader_1 = require("./CdrReader");
const CdrWriter_1 = require("./CdrWriter");
const EncapsulationKind_1 = require("./EncapsulationKind");
const tf2_msg__TFMessage = "0001000001000000cce0d158f08cf9060a000000626173655f6c696e6b000000060000007261646172000000ae47e17a14ae0e4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f03f";
function writeExampleMessage(writer) {
// geometry_msgs/TransformStamped[] transforms
writer.sequenceLength(1);
// std_msgs/Header header
// time stamp
writer.uint32(1490149580); // uint32 sec
writer.uint32(117017840); // uint32 nsec
writer.string("base_link"); // string frame_id
writer.string("radar"); // string child_frame_id
// geometry_msgs/Transform transform
// geometry_msgs/Vector3 translation
writer.float64(3.835); // float64 x
writer.float64(0); // float64 y
writer.float64(0); // float64 z
// geometry_msgs/Quaternion rotation
writer.float64(0); // float64 x
writer.float64(0); // float64 y
writer.float64(0); // float64 z
writer.float64(1); // float64 w
}
function toHex(data) {
return Buffer.from(data).toString("hex");
}
function decimalToHex(value) {
return value.toString(16).padStart(2, "0");
}
const CDR2EncapsulationKinds = new Set([
EncapsulationKind_1.EncapsulationKind.CDR2_BE,
EncapsulationKind_1.EncapsulationKind.CDR2_LE,
EncapsulationKind_1.EncapsulationKind.PL_CDR2_BE,
EncapsulationKind_1.EncapsulationKind.PL_CDR2_LE,
EncapsulationKind_1.EncapsulationKind.DELIMITED_CDR2_BE,
EncapsulationKind_1.EncapsulationKind.DELIMITED_CDR2_LE,
EncapsulationKind_1.EncapsulationKind.RTPS_CDR2_BE,
EncapsulationKind_1.EncapsulationKind.RTPS_CDR2_LE,
EncapsulationKind_1.EncapsulationKind.RTPS_PL_CDR2_BE,
EncapsulationKind_1.EncapsulationKind.RTPS_PL_CDR2_LE,
EncapsulationKind_1.EncapsulationKind.RTPS_DELIMITED_CDR2_BE,
EncapsulationKind_1.EncapsulationKind.RTPS_DELIMITED_CDR2_LE,
]);
const AllCdrWriterKinds = enumKeys(EncapsulationKind_1.EncapsulationKind);
describe("CdrWriter", () => {
it("serializes an example message with internal preallocation", () => {
// Example tf2_msgs/TFMessage
for (const writer of [
new CdrWriter_1.CdrWriter({ size: 100 }),
new CdrWriter_1.CdrWriter({ size: 100, kind: EncapsulationKind_1.EncapsulationKind.CDR2_LE }),
]) {
// Set the EncapsulationKind in the test data to match the writer
const tf2Msg = `00${decimalToHex(writer.kind)}${tf2_msg__TFMessage.substring(4)}`;
writeExampleMessage(writer);
expect(writer.size).toEqual(100);
expect(toHex(writer.data)).toEqual(tf2Msg);
}
});
it("serializes an example message with external preallocation", () => {
// Example tf2_msgs/TFMessage
for (const writer of [
new CdrWriter_1.CdrWriter({ buffer: new ArrayBuffer(100) }),
new CdrWriter_1.CdrWriter({ buffer: new ArrayBuffer(100), kind: EncapsulationKind_1.EncapsulationKind.CDR2_LE }),
]) {
// Set the EncapsulationKind in the test data to match the writer
const tf2Msg = `00${decimalToHex(writer.kind)}${tf2_msg__TFMessage.substring(4)}`;
writeExampleMessage(writer);
expect(writer.size).toEqual(100);
expect(toHex(writer.data)).toEqual(tf2Msg);
}
});
it("serializes an example message with no preallocation", () => {
// Example tf2_msgs/TFMessage
const writer = new CdrWriter_1.CdrWriter();
writeExampleMessage(writer);
expect(writer.size).toEqual(100);
expect(toHex(writer.data)).toEqual(tf2_msg__TFMessage);
});
it.each(AllCdrWriterKinds)("round trips all data types: {kind: %s}", (kindKey) => {
const writer = new CdrWriter_1.CdrWriter({ kind: EncapsulationKind_1.EncapsulationKind[kindKey] });
writer.int8(-1);
writer.uint8(2);
writer.int16(-300);
writer.uint16(400);
writer.int32(-500000);
writer.uint32(600000);
writer.int64(-7000000001n);
writer.uint64(8000000003n);
writer.uint16BE(0x1234);
writer.uint32BE(0x12345678);
writer.uint64BE(0x123456789abcdef0n);
writer.float32(-9.14);
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
writer.float64(1.7976931348623158e100);
writer.string("abc");
writer.sequenceLength(42);
const data = writer.data;
expect(data.byteLength).toEqual(CDR2EncapsulationKinds.has(writer.kind) ? 76 : 80);
const reader = new CdrReader_1.CdrReader(data);
expect(reader.int8()).toEqual(-1);
expect(reader.uint8()).toEqual(2);
expect(reader.int16()).toEqual(-300);
expect(reader.uint16()).toEqual(400);
expect(reader.int32()).toEqual(-500000);
expect(reader.uint32()).toEqual(600000);
expect(reader.int64()).toEqual(-7000000001n);
expect(reader.uint64()).toEqual(8000000003n);
expect(reader.uint16BE()).toEqual(0x1234);
expect(reader.uint32BE()).toEqual(0x12345678);
expect(reader.uint64BE()).toEqual(0x123456789abcdef0n);
expect(reader.float32()).toBeCloseTo(-9.14);
// eslint-disable-next-line @typescript-eslint/no-loss-of-precision
expect(reader.float64()).toBeCloseTo(1.7976931348623158e100);
expect(reader.string()).toEqual("abc");
expect(reader.sequenceLength()).toEqual(42);
});
it.each(AllCdrWriterKinds)("round trips all array types: {kind: %s}", (kindKey) => {
const writer = new CdrWriter_1.CdrWriter({ kind: EncapsulationKind_1.EncapsulationKind[kindKey] });
writer.int8Array([-128, 127, 3], true);
writer.uint8Array([0, 255, 3], true);
writer.int16Array([-32768, 32767, -3], true);
writer.uint16Array([0, 65535, 3], true);
writer.int32Array([-2147483648, 2147483647, 3], true);
writer.uint32Array([0, 4294967295, 3], true);
writer.int64Array([-9223372036854775808n, 9223372036854775807n, 3n], true);
writer.uint64Array([0n, 18446744073709551615n, 3n], true);
const reader = new CdrReader_1.CdrReader(writer.data);
expect(Array.from(reader.int8Array().values())).toEqual([-128, 127, 3]);
expect(Array.from(reader.uint8Array().values())).toEqual([0, 255, 3]);
expect(Array.from(reader.int16Array().values())).toEqual([-32768, 32767, -3]);
expect(Array.from(reader.uint16Array().values())).toEqual([0, 65535, 3]);
expect(Array.from(reader.int32Array().values())).toEqual([-2147483648, 2147483647, 3]);
expect(Array.from(reader.uint32Array().values())).toEqual([0, 4294967295, 3]);
expect(Array.from(reader.int64Array().values())).toEqual([-9223372036854775808n, 9223372036854775807n, 3n]); // prettier-ignore
expect(Array.from(reader.uint64Array().values())).toEqual([0n, 18446744073709551615n, 3n]);
});
it("writes parameter lists", () => {
const writer = new CdrWriter_1.CdrWriter({ kind: EncapsulationKind_1.EncapsulationKind.PL_CDR_LE });
writer.uint8(0x42);
expect(toHex(writer.data)).toEqual("0003000042");
});
it("writes all EncapsulationKind values", () => {
for (const key of enumKeys(EncapsulationKind_1.EncapsulationKind)) {
const kind = EncapsulationKind_1.EncapsulationKind[key];
const writer = new CdrWriter_1.CdrWriter({ kind });
writer.uint8(0x42);
expect(toHex(writer.data)).toEqual(`00${decimalToHex(kind)}000042`);
}
});
it("aligns cdr1", () => {
const writer = new CdrWriter_1.CdrWriter();
writer.align(0);
expect(toHex(writer.data)).toEqual("00010000");
writer.align(8);
expect(toHex(writer.data)).toEqual("00010000");
writer.uint8(1); // one byte
writer.align(8); // seven bytes of padding
writer.uint32(2); // four bytes
writer.align(4); // no-op, already aligned
expect(toHex(writer.data)).toEqual("00010000010000000000000002000000");
});
it("aligns cdr2", () => {
const writer = new CdrWriter_1.CdrWriter({ kind: EncapsulationKind_1.EncapsulationKind.RTPS_PL_CDR2_LE });
writer.align(0);
expect(toHex(writer.data)).toEqual("000b0000");
writer.align(4);
expect(toHex(writer.data)).toEqual("000b0000");
writer.uint8(1); // one byte
writer.align(4); // three bytes of padding
writer.uint32(2); // four bytes
writer.align(4); // no-op, already aligned
expect(toHex(writer.data)).toEqual("000b00000100000002000000");
});
it("aligns 8 byte values in xcdr PL_CDR without emheader using padding", () => {
const writer = new CdrWriter_1.CdrWriter({ kind: EncapsulationKind_1.EncapsulationKind.PL_CDR_LE }); // origin= 4
writer.uint32(1);
writer.uint64(0x0fn);
//prettier-ignore
expect(toHex(writer.data)).toEqual("00030000" + // header
"01000000" + // uint32
"00000000" + // padding
"0f00000000000000" //uint64
);
});
it("emHeaders resets origin for 8 byte value alignment", () => {
const writer = new CdrWriter_1.CdrWriter({ kind: EncapsulationKind_1.EncapsulationKind.PL_CDR_LE }); // origin= 4
writer.emHeader(true, 5, 8);
writer.uint64(0x0fn);
//prettier-ignore
expect(toHex(writer.data)).toEqual("00030000" + // header
"05400800" + // uint32
"0f00000000000000" //uint64
);
});
});
function enumKeys(obj) {
return Object.keys(obj).filter((k) => Number.isNaN(+k));
}
//# sourceMappingURL=CdrWriter.test.js.map