71 lines
No EOL
1.8 KiB
TypeScript
71 lines
No EOL
1.8 KiB
TypeScript
import type { Message } from './message';
|
|
import type { RawMessage } from './raw';
|
|
import logger from 'App/logger';
|
|
import RawMessageReader from './RawMessageReader';
|
|
|
|
// TODO: composition instead of inheritance
|
|
// needSkipMessage() and next() methods here use buf and p protected properties,
|
|
// which should be probably somehow incapsulated
|
|
export default class MFileReader extends RawMessageReader {
|
|
private pLastMessageID: number = 0
|
|
private currentTime: number = 0
|
|
public error: boolean = false
|
|
constructor(data: Uint8Array, private readonly startTime: number) {
|
|
super(data)
|
|
}
|
|
|
|
private needSkipMessage(): boolean {
|
|
if (this.p === 0) return false
|
|
for (let i = 7; i >= 0; i--) {
|
|
if (this.buf[ this.p + i ] !== this.buf[ this.pLastMessageID + i ]) {
|
|
return this.buf[ this.p + i ] - this.buf[ this.pLastMessageID + i ] < 0
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
private readRawMessage(): RawMessage | null {
|
|
this.skip(8)
|
|
try {
|
|
const msg = super.readMessage()
|
|
if (!msg) {
|
|
this.skip(-8)
|
|
}
|
|
return msg
|
|
} catch (e) {
|
|
this.error = true
|
|
logger.error("Read message error:", e)
|
|
return null
|
|
}
|
|
}
|
|
|
|
next(): [ Message, number] | null {
|
|
if (this.error || !this.hasNextByte()) {
|
|
return null
|
|
}
|
|
|
|
while (this.needSkipMessage()) {
|
|
if (!this.readRawMessage()) {
|
|
return null
|
|
}
|
|
}
|
|
|
|
this.pLastMessageID = this.p
|
|
|
|
const rMsg = this.readRawMessage()
|
|
if (!rMsg) {
|
|
return null
|
|
}
|
|
|
|
if (rMsg.tp === "timestamp") {
|
|
this.currentTime = rMsg.timestamp - this.startTime
|
|
return this.next()
|
|
}
|
|
|
|
const msg = Object.assign(rMsg, {
|
|
time: this.currentTime,
|
|
_index: this.pLastMessageID,
|
|
})
|
|
return [msg, this.pLastMessageID]
|
|
}
|
|
} |