export enum IntegerSize {
Eight = 8,
Sixteen = 16
}
export interface CommandValue {
size: IntegerSize;
value: number;
}
/**
This class lets us encode byte sequences in an easy to use manner and then view multiple different representations of them later (i.e. as usigned 8bit integers, hex strings, as byte-words etc.)
*/
export class CommandEncoder {
values: CommandValue[] = [];
hasHeader: boolean = false;
constructor() {
this.values.length = 4 // Minimum length is the length of the header
}
/**
Request headers all follow a known format
1. sid
2. cid
3. sequence byte ( for associating request to response, will be set before command is sent )
4. length byte ( of data payload, will also be automatically filled when the command is serialized )
*/
setHeader = (sid: number, cid: number) => {
this.hasHeader = true;
this.values[0] = {
size: IntegerSize.Eight,
value: sid
};
this.values[1] = {
size: IntegerSize.Eight,
value: cid
};
// this will eventually be sequence id
this.values[2] = {
size: IntegerSize.Eight,
value: 0x00
};
// this will eventually be length
this.values[3] = {
size: IntegerSize.Eight,
value: 0x00
};
}
/// Encode a UInt8
addUInt8 = (value: number) => {
this.values.push({
size: IntegerSize.Eight,
value: value
});
}
/// Encode a UInt16
addUInt16 = (value: number) => {
this.values.push({
size: IntegerSize.Sixteen,
value
});
}
addASCIIArray = (value: string) => {
for (var i = 0; i < value.length; i++) {
var charcode = value.charCodeAt(i);
this.addUInt8(charcode);
}
}
/// Update the length byte to match the payload size
updateLength = () => {
this.values[3] = {
size: IntegerSize.Eight,
value: this.byteCount() - 4 // minus the header length
}
}
/// Set the sequence number of this command
setSequence = (seq: number) => {
this.values[2] = {
size: IntegerSize.Eight,
value: seq
}
}
/// Return the sequence number of this command
getSequence = (): number => {
return this.values[2].value;
}
/// Returns the payload byte size
byteCount = (): number => {
let i = 0;
for ( let value of this.values ) {
if ( value === undefined ) { continue; }
if ( value.size === IntegerSize.Eight ) {
i = i + 1;
} else {
i = i + 2;
}
}
return i;
}
}
|