Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* ****************************************************************************
* Copyright 2013 EMBL-EBI
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ****************************************************************************
*/
package htsjdk.samtools.cram.structure;
import htsjdk.samtools.*;
import htsjdk.samtools.cram.common.CramVersions;
import htsjdk.samtools.cram.io.CramIntArray;
import htsjdk.samtools.cram.io.ITF8;
import htsjdk.samtools.cram.io.InputStreamUtils;
import htsjdk.samtools.cram.io.LTF8;
import htsjdk.samtools.cram.ref.ReferenceContext;
import htsjdk.samtools.cram.structure.block.*;
import htsjdk.samtools.util.BinaryCodec;
import htsjdk.samtools.util.Log;
import htsjdk.samtools.util.RuntimeIOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
class SliceIO {
private static final Log log = Log.getInstance(SliceIO.class);
private static Slice readSliceHeader(final int major, final InputStream readInputStream) {
final Block sliceHeaderBlock = Block.read(major, readInputStream);
if (sliceHeaderBlock.getContentType() != BlockContentType.MAPPED_SLICE)
throw new RuntimeException("Slice Header Block expected, found: " + sliceHeaderBlock.getContentType().name());
final InputStream parseInputStream = new ByteArrayInputStream(sliceHeaderBlock.getUncompressedContent());
final ReferenceContext refContext = new ReferenceContext(ITF8.readUnsignedITF8(parseInputStream));
final Slice slice = new Slice(refContext);
slice.alignmentStart = ITF8.readUnsignedITF8(parseInputStream);
slice.alignmentSpan = ITF8.readUnsignedITF8(parseInputStream);
slice.nofRecords = ITF8.readUnsignedITF8(parseInputStream);
slice.globalRecordCounter = LTF8.readUnsignedLTF8(parseInputStream);
slice.nofBlocks = ITF8.readUnsignedITF8(parseInputStream);
slice.contentIDs = CramIntArray.array(parseInputStream);
slice.embeddedRefBlockContentID = ITF8.readUnsignedITF8(parseInputStream);
slice.refMD5 = new byte[16];
InputStreamUtils.readFully(parseInputStream, slice.refMD5, 0, slice.refMD5.length);
final byte[] bytes = InputStreamUtils.readFully(parseInputStream);
if (major >= CramVersions.CRAM_v3.major) {
slice.sliceTags = BinaryTagCodec.readTags(bytes, 0, bytes.length, ValidationStringency.DEFAULT_STRINGENCY);
SAMBinaryTagAndValue tags = slice.sliceTags;
while (tags != null) {
log.debug(String.format("Found slice tag: %s", SAMTag.makeStringTag(tags.tag)));
tags = tags.getNext();
}
}
slice.headerBlock = sliceHeaderBlock;
return slice;
}
private static byte[] createSliceHeaderBlockContent(final int major, final Slice slice) {
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ITF8.writeUnsignedITF8(slice.getReferenceContext().getSerializableId(), byteArrayOutputStream);
ITF8.writeUnsignedITF8(slice.alignmentStart, byteArrayOutputStream);
ITF8.writeUnsignedITF8(slice.alignmentSpan, byteArrayOutputStream);
ITF8.writeUnsignedITF8(slice.nofRecords, byteArrayOutputStream);
LTF8.writeUnsignedLTF8(slice.globalRecordCounter, byteArrayOutputStream);
ITF8.writeUnsignedITF8(slice.nofBlocks, byteArrayOutputStream);
slice.contentIDs = new int[slice.external.size()];
int i = 0;
for (final int id : slice.external.keySet())
slice.contentIDs[i++] = id;
CramIntArray.write(slice.contentIDs, byteArrayOutputStream);
ITF8.writeUnsignedITF8(slice.embeddedRefBlockContentID, byteArrayOutputStream);
try {
byteArrayOutputStream.write(slice.refMD5 == null ? new byte[16] : slice.refMD5);
} catch (final IOException e) {
throw new RuntimeIOException(e);
}
if (major >= CramVersions.CRAM_v3.major) {
if (slice.sliceTags != null) {
final BinaryCodec binaryCoded = new BinaryCodec(byteArrayOutputStream);
final BinaryTagCodec binaryTagCodec = new BinaryTagCodec(binaryCoded);
SAMBinaryTagAndValue samBinaryTagAndValue = slice.sliceTags;
do {
log.debug("Writing slice tag: " + SAMTag.makeStringTag(samBinaryTagAndValue.tag));
binaryTagCodec.writeTag(samBinaryTagAndValue.tag, samBinaryTagAndValue.value, samBinaryTagAndValue.isUnsignedArray());
} while ((samBinaryTagAndValue = samBinaryTagAndValue.getNext()) != null);
// BinaryCodec doesn't seem to cache things.
// In any case, not calling baseCodec.close() because it's behaviour is
// irrelevant here.
}
}
return byteArrayOutputStream.toByteArray();
}
private static void readSliceBlocks(final int major, final Slice slice, final InputStream inputStream) {
slice.external = new HashMap<>();
for (int i = 0; i < slice.nofBlocks; i++) {
final Block block = Block.read(major, inputStream);
switch (block.getContentType()) {
case CORE:
slice.coreBlock = block;
break;
case EXTERNAL:
if (slice.embeddedRefBlockContentID == block.getContentId()) {
slice.embeddedRefBlock = block;
}
slice.external.put(block.getContentId(), block);
break;
default:
throw new RuntimeException("Not a slice block, content type id " + block.getContentType().name());
}
}
}
public static void write(final int major, final Slice slice, final OutputStream outputStream) {
// TODO: ensure that the Slice blockCount stays in sync with the
// Container's blockCount in ContainerIO.writeContainer()
// 1 Core Data Block per Slice
// Each Slice has a variable number of External Data Blocks
// TODO: should we count the embedded reference block as an additional block?
slice.nofBlocks = 1 + slice.external.size() + (slice.embeddedRefBlock == null ? 0 : 1);
{
slice.contentIDs = new int[slice.external.size()];
final int i = 0;
for (final int id : slice.external.keySet())
slice.contentIDs[i] = id;
}
slice.headerBlock = Block.createRawSliceHeaderBlock(createSliceHeaderBlockContent(major, slice));
slice.headerBlock.write(major, outputStream);
slice.coreBlock.write(major, outputStream);
for (final Block block : slice.external.values())
block.write(major, outputStream);
}
public static Slice read(final int major, final InputStream inputStream) {
final Slice slice = readSliceHeader(major, inputStream);
readSliceBlocks(major, slice, inputStream);
return slice;
}
}