@gmod/cram
Version:
read CRAM files with pure Javascript
84 lines • 3.99 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_ts_1 = require("../../errors.js");
const index_ts_1 = __importDefault(require("../slice/index.js"));
const util_ts_1 = require("../util.js");
const compressionScheme_ts_1 = __importDefault(require("./compressionScheme.js"));
const sectionParsers_ts_1 = require("../sectionParsers.js");
class CramContainer {
constructor(file, filePosition) {
this.file = file;
this.filePosition = filePosition;
}
getHeader() {
return this._readContainerHeader(this.filePosition);
}
async getCompressionHeaderBlock() {
const containerHeader = await this.getHeader();
// if there are no records in the container, there will be no compression
// header
if (!containerHeader.numRecords) {
return null;
}
const { majorVersion } = await this.file.getDefinition();
const sectionParsers = (0, sectionParsers_ts_1.getSectionParsers)(majorVersion);
const block = await this.getFirstBlock();
if (block.contentType !== 'COMPRESSION_HEADER') {
throw new errors_ts_1.CramMalformedError(`invalid content type ${block.contentType} in compression header block`);
}
const content = (0, util_ts_1.parseItem)(block.content, sectionParsers.cramCompressionHeader.parser, 0, block.contentPosition);
return {
...block,
parsedContent: content,
};
}
async getFirstBlock() {
const containerHeader = await this.getHeader();
return this.file.readBlock(containerHeader._endPosition);
}
// parses the compression header data into a CramContainerCompressionScheme
// object
async getCompressionScheme() {
const header = await this.getCompressionHeaderBlock();
if (!header) {
return undefined;
}
return new compressionScheme_ts_1.default(header.parsedContent);
}
getSlice(slicePosition, sliceSize) {
// note: slicePosition is relative to the end of the container header
// TODO: perhaps we should cache slices?
return new index_ts_1.default(this, slicePosition, sliceSize);
}
async _readContainerHeader(position) {
const { majorVersion } = await this.file.getDefinition();
const sectionParsers = (0, sectionParsers_ts_1.getSectionParsers)(majorVersion);
const { cramContainerHeader1, cramContainerHeader2 } = sectionParsers;
// parse the container header. do it in 2 pieces because you cannot tell
// how much to buffer until you read numLandmarks
const bytes1 = await this.file.read(cramContainerHeader1.maxLength, position);
const header1 = (0, util_ts_1.parseItem)(bytes1, cramContainerHeader1.parser);
const numLandmarksSize = (0, util_ts_1.itf8Size)(header1.numLandmarks);
const bytes2 = await this.file.read(cramContainerHeader2.maxLength(header1.numLandmarks), position + header1._size - numLandmarksSize);
const header2 = (0, util_ts_1.parseItem)(bytes2, cramContainerHeader2.parser);
if (this.file.validateChecksums && header2.crc32 !== undefined) {
await this.file.checkCrc32(position, header1._size + header2._size - numLandmarksSize - 4, header2.crc32, `container header beginning at position ${position}`);
}
return {
...header1,
...header2,
_size: header1._size + header2._size - numLandmarksSize,
_endPosition: header1._size + header2._size - numLandmarksSize + position,
};
}
}
exports.default = CramContainer;
'getHeader getCompressionHeaderBlock getCompressionScheme'
.split(' ')
.forEach(method => {
(0, util_ts_1.tinyMemoize)(CramContainer, method);
});
//# sourceMappingURL=index.js.map