@gmod/cram
Version:
read CRAM files with pure Javascript
48 lines (44 loc) • 1.59 kB
text/typescript
import CramCodec from './_base.ts'
import { CramBufferOverrunError, CramMalformedError } from '../../errors.ts'
import type { Cursor, Cursors } from './_base.ts'
import type { ByteArrayStopCramEncoding } from '../encoding.ts'
import type { CramFileBlock } from '../file.ts'
import type CramSlice from '../slice/index.ts'
export default class ByteArrayStopCodec extends CramCodec<
'byteArray',
ByteArrayStopCramEncoding['parameters']
> {
decode(
_slice: CramSlice,
_coreDataBlock: CramFileBlock,
blocksByContentId: Record<number, CramFileBlock>,
cursors: Cursors,
) {
const { blockContentId } = this.parameters
const contentBlock = blocksByContentId[blockContentId]
if (!contentBlock) {
throw new CramMalformedError(
`no block found with content ID ${blockContentId}`,
)
}
const cursor = cursors.externalBlocks.getCursor(blockContentId)
return this._decodeByteArray(contentBlock, cursor)
}
_decodeByteArray(contentBlock: CramFileBlock, cursor: Cursor) {
const dataBuffer = contentBlock.content
const { stopByte } = this.parameters
const startPosition = cursor.bytePosition
const len = dataBuffer.length
let stopPosition = startPosition
while (stopPosition < len && dataBuffer[stopPosition] !== stopByte) {
stopPosition++
}
if (stopPosition >= len) {
throw new CramBufferOverrunError(
'byteArrayStop reading beyond length of data buffer?',
)
}
cursor.bytePosition = stopPosition + 1
return dataBuffer.subarray(startPosition, stopPosition)
}
}