diff --git a/src/main/java/htsjdk/samtools/BAMSBIIndexer.java b/src/main/java/htsjdk/samtools/BAMSBIIndexer.java index 7629bb65af..92b4678d25 100644 --- a/src/main/java/htsjdk/samtools/BAMSBIIndexer.java +++ b/src/main/java/htsjdk/samtools/BAMSBIIndexer.java @@ -28,8 +28,8 @@ import htsjdk.samtools.seekablestream.SeekableStream; import htsjdk.samtools.util.BlockCompressedInputStream; import htsjdk.samtools.util.IOUtil; +import htsjdk.samtools.util.RuntimeEOFException; -import java.io.EOFException; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; @@ -80,7 +80,7 @@ public static void createIndex(final SeekableStream in, final OutputStream out, // Process the record start position, then skip to the start of the next BAM record indexWriter.processRecord(recordStart); InputStreamUtils.skipFully(blockIn, blockSize); - } catch (EOFException e) { + } catch (RuntimeEOFException e) { break; } } diff --git a/src/main/java/htsjdk/samtools/CRAMBAIIndexer.java b/src/main/java/htsjdk/samtools/CRAMBAIIndexer.java index 352e9e1345..8a08c2c828 100755 --- a/src/main/java/htsjdk/samtools/CRAMBAIIndexer.java +++ b/src/main/java/htsjdk/samtools/CRAMBAIIndexer.java @@ -115,56 +115,51 @@ public CRAMBAIIndexer(final OutputStream output, final SAMFileHeader fileHeader) * @param container container to be indexed */ public void processContainer(final Container container, final ValidationStringency validationStringency) { - try { - if (container == null || container.isEOF()) { - return; - } + if (container == null || container.isEOF()) { + return; + } - int sliceIndex = 0; - for (final Slice slice : container.slices) { + int sliceIndex = 0; + for (final Slice slice : container.slices) { + slice.containerOffset = container.offset; + slice.index = sliceIndex++; + if (slice.isMultiref()) { + final ContainerParser parser = new ContainerParser(indexBuilder.bamHeader); + final Map refSet = parser.getReferences(container, validationStringency); + final Slice fakeSlice = new Slice(); slice.containerOffset = container.offset; slice.index = sliceIndex++; - if (slice.isMultiref()) { - final ContainerParser parser = new ContainerParser(indexBuilder.bamHeader); - final Map refSet = parser.getReferences(container, validationStringency); - final Slice fakeSlice = new Slice(); - slice.containerOffset = container.offset; - slice.index = sliceIndex++; - /** - * Unmapped span must be processed after mapped spans: - */ - AlignmentSpan unmappedSpan = refSet.remove(SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX); - for (final int refId : new TreeSet<>(refSet.keySet())) { - final AlignmentSpan span = refSet.get(refId); - fakeSlice.sequenceId = refId; - fakeSlice.containerOffset = slice.containerOffset; - fakeSlice.offset = slice.offset; - fakeSlice.index = slice.index; - - fakeSlice.alignmentStart = span.getStart(); - fakeSlice.alignmentSpan = span.getSpan(); - fakeSlice.nofRecords = span.getCount(); - processSingleReferenceSlice(fakeSlice); - } - if (unmappedSpan != null) { - final AlignmentSpan span = unmappedSpan; - fakeSlice.sequenceId = SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX; - fakeSlice.containerOffset = slice.containerOffset; - fakeSlice.offset = slice.offset; - fakeSlice.index = slice.index; - - fakeSlice.alignmentStart = SAMRecord.NO_ALIGNMENT_START; - fakeSlice.alignmentSpan = 0; - fakeSlice.nofRecords = span.getCount(); - processSingleReferenceSlice(fakeSlice); - } - } else { - processSingleReferenceSlice(slice); + /** + * Unmapped span must be processed after mapped spans: + */ + AlignmentSpan unmappedSpan = refSet.remove(SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX); + for (final int refId : new TreeSet<>(refSet.keySet())) { + final AlignmentSpan span = refSet.get(refId); + fakeSlice.sequenceId = refId; + fakeSlice.containerOffset = slice.containerOffset; + fakeSlice.offset = slice.offset; + fakeSlice.index = slice.index; + + fakeSlice.alignmentStart = span.getStart(); + fakeSlice.alignmentSpan = span.getSpan(); + fakeSlice.nofRecords = span.getCount(); + processSingleReferenceSlice(fakeSlice); + } + if (unmappedSpan != null) { + final AlignmentSpan span = unmappedSpan; + fakeSlice.sequenceId = SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX; + fakeSlice.containerOffset = slice.containerOffset; + fakeSlice.offset = slice.offset; + fakeSlice.index = slice.index; + + fakeSlice.alignmentStart = SAMRecord.NO_ALIGNMENT_START; + fakeSlice.alignmentSpan = 0; + fakeSlice.nofRecords = span.getCount(); + processSingleReferenceSlice(fakeSlice); } + } else { + processSingleReferenceSlice(slice); } - - } catch (final IOException e) { - throw new RuntimeIOException("Failed to read cram container", e); } } diff --git a/src/main/java/htsjdk/samtools/CRAMFileReader.java b/src/main/java/htsjdk/samtools/CRAMFileReader.java index 70eeb3074c..1115d6d32a 100644 --- a/src/main/java/htsjdk/samtools/CRAMFileReader.java +++ b/src/main/java/htsjdk/samtools/CRAMFileReader.java @@ -315,13 +315,10 @@ public SAMRecordIterator iterator(final SAMFileSpan fileSpan) { // get the file coordinates for the span: final long[] coordinateArray = ((BAMFileSpan) fileSpan).toCoordinateArray(); if (coordinateArray == null || coordinateArray.length == 0) return emptyIterator; - try { - // create an input stream that reads the source cram stream only within the coordinate pairs: - final SeekableStream seekableStream = getSeekableStreamOrFailWithRTE(); - return new CRAMIterator(seekableStream, referenceSource, coordinateArray, validationStringency); - } catch (final IOException e) { - throw new RuntimeException(e); - } + + // create an input stream that reads the source cram stream only within the coordinate pairs: + final SeekableStream seekableStream = getSeekableStreamOrFailWithRTE(); + return new CRAMIterator(seekableStream, referenceSource, coordinateArray, validationStringency); } @Override @@ -508,16 +505,14 @@ public CRAMIntervalIterator(final QueryInterval[] queries, final boolean contain super(queries, contained); if (coordinates != null && coordinates.length != 0) { - try { - unfilteredIterator = new CRAMIterator( - getSeekableStreamOrFailWithRTE(), - referenceSource, - coordinates, - validationStringency - ); - } catch (final IOException e) { - throw new RuntimeEOFException(e); - } + + unfilteredIterator = new CRAMIterator( + getSeekableStreamOrFailWithRTE(), + referenceSource, + coordinates, + validationStringency + ); + getNextRecord(); // advance to the first record that matches the filter criteria } } diff --git a/src/main/java/htsjdk/samtools/CRAMIterator.java b/src/main/java/htsjdk/samtools/CRAMIterator.java index b2a748a648..aba0462cc2 100644 --- a/src/main/java/htsjdk/samtools/CRAMIterator.java +++ b/src/main/java/htsjdk/samtools/CRAMIterator.java @@ -29,17 +29,15 @@ import htsjdk.samtools.cram.structure.CramHeader; import htsjdk.samtools.cram.structure.Slice; import htsjdk.samtools.seekablestream.SeekableStream; -import htsjdk.samtools.util.Log; -import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.*; import htsjdk.samtools.cram.CRAMException; +import htsjdk.samtools.util.RuntimeIOException; public class CRAMIterator implements SAMRecordIterator { - private static final Log log = Log.getInstance(CRAMIterator.class); private final CountingInputStream countingInputStream; private final CramHeader cramHeader; private final ArrayList records; @@ -63,8 +61,7 @@ public ValidationStringency getValidationStringency() { return validationStringency; } - public void setValidationStringency( - final ValidationStringency validationStringency) { + public void setValidationStringency(final ValidationStringency validationStringency) { this.validationStringency = validationStringency; } @@ -75,11 +72,13 @@ public void setValidationStringency( private long samRecordIndex; private ArrayList cramRecords; - public CRAMIterator(final InputStream inputStream, final CRAMReferenceSource referenceSource, final ValidationStringency validationStringency) - throws IOException { + public CRAMIterator(final InputStream inputStream, + final CRAMReferenceSource referenceSource, + final ValidationStringency validationStringency) { if (null == referenceSource) { throw new CRAMException("A reference source is required for CRAM files"); } + this.countingInputStream = new CountingInputStream(inputStream); this.referenceSource = referenceSource; this.validationStringency = validationStringency; @@ -88,17 +87,20 @@ public CRAMIterator(final InputStream inputStream, final CRAMReferenceSource ref this.containerIterator = containerIterator; firstContainerOffset = this.countingInputStream.getCount(); - records = new ArrayList(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); + records = new ArrayList<>(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); normalizer = new CramNormalizer(cramHeader.getSamFileHeader(), referenceSource); parser = new ContainerParser(cramHeader.getSamFileHeader()); } - public CRAMIterator(final SeekableStream seekableStream, final CRAMReferenceSource referenceSource, final long[] coordinates, final ValidationStringency validationStringency) - throws IOException { + public CRAMIterator(final SeekableStream seekableStream, + final CRAMReferenceSource referenceSource, + final long[] coordinates, + final ValidationStringency validationStringency) { if (null == referenceSource) { throw new CRAMException("A reference source is required for CRAM files"); } + this.countingInputStream = new CountingInputStream(seekableStream); this.referenceSource = referenceSource; this.validationStringency = validationStringency; @@ -107,15 +109,16 @@ public CRAMIterator(final SeekableStream seekableStream, final CRAMReferenceSour this.containerIterator = containerIterator; firstContainerOffset = containerIterator.getFirstContainerOffset(); - records = new ArrayList(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); + records = new ArrayList<>(CRAMContainerStreamWriter.DEFAULT_RECORDS_PER_SLICE); normalizer = new CramNormalizer(cramHeader.getSamFileHeader(), referenceSource); parser = new ContainerParser(cramHeader.getSamFileHeader()); } @Deprecated - public CRAMIterator(final SeekableStream seekableStream, final CRAMReferenceSource referenceSource, final long[] coordinates) - throws IOException { + public CRAMIterator(final SeekableStream seekableStream, + final CRAMReferenceSource referenceSource, + final long[] coordinates) { this(seekableStream, referenceSource, coordinates, ValidationStringency.DEFAULT_STRINGENCY); } @@ -123,8 +126,7 @@ public CramHeader getCramHeader() { return cramHeader; } - void nextContainer() throws IOException, IllegalArgumentException, - IllegalAccessException, CRAMException { + void nextContainer() throws IllegalArgumentException, CRAMException { if (containerIterator != null) { if (!containerIterator.hasNext()) { @@ -149,7 +151,7 @@ void nextContainer() throws IOException, IllegalArgumentException, records.clear(); if (cramRecords == null) - cramRecords = new ArrayList(container.nofRecords); + cramRecords = new ArrayList<>(container.nofRecords); else cramRecords.clear(); @@ -250,11 +252,7 @@ public boolean advanceToAlignmentInContainer(final int refIndex, final int pos) public boolean hasNext() { if (container != null && container.isEOF()) return false; if (!iterator.hasNext()) { - try { - nextContainer(); - } catch (IOException | IllegalAccessException e) { - throw new SAMException(e); - } + nextContainer(); } return !records.isEmpty(); @@ -287,10 +285,10 @@ public void close() { records.clear(); //noinspection EmptyCatchBlock try { - if (countingInputStream != null) + if (countingInputStream != null) { countingInputStream.close(); - } catch (final IOException e) { - } + } + } catch (final RuntimeIOException e) { } } @Override diff --git a/src/main/java/htsjdk/samtools/cram/CRAIEntry.java b/src/main/java/htsjdk/samtools/cram/CRAIEntry.java index 6a31fad1bd..6e2073785a 100644 --- a/src/main/java/htsjdk/samtools/cram/CRAIEntry.java +++ b/src/main/java/htsjdk/samtools/cram/CRAIEntry.java @@ -50,7 +50,7 @@ public CRAIEntry(final int sequenceId, * @param line string formatted as a CRAI index entry * @throws CRAIIndex.CRAIIndexException */ - public CRAIEntry(final String line) throws CRAIIndex.CRAIIndexException { + public CRAIEntry(final String line) { final String[] chunks = line.split("\t"); if (chunks.length != CRAI_INDEX_COLUMNS) { throw new CRAIIndex.CRAIIndexException( diff --git a/src/main/java/htsjdk/samtools/cram/CRAIIndex.java b/src/main/java/htsjdk/samtools/cram/CRAIIndex.java index 964023e6d8..030db37eee 100644 --- a/src/main/java/htsjdk/samtools/cram/CRAIIndex.java +++ b/src/main/java/htsjdk/samtools/cram/CRAIIndex.java @@ -8,6 +8,7 @@ import htsjdk.samtools.seekablestream.SeekableMemoryStream; import htsjdk.samtools.seekablestream.SeekableStream; import htsjdk.samtools.ValidationStringency; +import htsjdk.samtools.util.RuntimeIOException; import java.io.*; import java.util.*; @@ -70,11 +71,16 @@ public void processContainer(final Container container) { } } - public static SeekableStream openCraiFileAsBaiStream(final File cramIndexFile, final SAMSequenceDictionary dictionary) throws IOException { - return openCraiFileAsBaiStream(new FileInputStream(cramIndexFile), dictionary); + public static SeekableStream openCraiFileAsBaiStream(final File cramIndexFile, final SAMSequenceDictionary dictionary) { + try { + return openCraiFileAsBaiStream(new FileInputStream(cramIndexFile), dictionary); + } + catch (final FileNotFoundException e) { + throw new RuntimeIOException(e); + } } - public static SeekableStream openCraiFileAsBaiStream(final InputStream indexStream, final SAMSequenceDictionary dictionary) throws IOException, CRAIIndexException { + public static SeekableStream openCraiFileAsBaiStream(final InputStream indexStream, final SAMSequenceDictionary dictionary) { final List full = CRAMCRAIIndexer.readIndex(indexStream).getCRAIEntries(); Collections.sort(full); diff --git a/src/main/java/htsjdk/samtools/cram/build/ContainerFactory.java b/src/main/java/htsjdk/samtools/cram/build/ContainerFactory.java index b19f2c379a..ccc3865744 100644 --- a/src/main/java/htsjdk/samtools/cram/build/ContainerFactory.java +++ b/src/main/java/htsjdk/samtools/cram/build/ContainerFactory.java @@ -24,7 +24,6 @@ import htsjdk.samtools.cram.compression.ExternalCompressor; import htsjdk.samtools.cram.encoding.writer.CramRecordWriter; import htsjdk.samtools.cram.io.DefaultBitOutputStream; -import htsjdk.samtools.cram.io.ExposedByteArrayOutputStream; import htsjdk.samtools.cram.structure.block.ExternalBlock; import htsjdk.samtools.cram.structure.block.Block; import htsjdk.samtools.cram.structure.CompressionHeader; diff --git a/src/main/java/htsjdk/samtools/cram/build/ContainerParser.java b/src/main/java/htsjdk/samtools/cram/build/ContainerParser.java index b18ec7507f..c72573185d 100644 --- a/src/main/java/htsjdk/samtools/cram/build/ContainerParser.java +++ b/src/main/java/htsjdk/samtools/cram/build/ContainerParser.java @@ -23,13 +23,11 @@ import htsjdk.samtools.ValidationStringency; import htsjdk.samtools.cram.structure.AlignmentSpan; import htsjdk.samtools.cram.encoding.reader.CramRecordReader; -import htsjdk.samtools.cram.encoding.reader.MultiRefSliceAlignmentSpanReader; import htsjdk.samtools.cram.structure.CompressionHeader; import htsjdk.samtools.cram.structure.Container; import htsjdk.samtools.cram.structure.CramCompressionRecord; import htsjdk.samtools.cram.structure.Slice; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -44,8 +42,8 @@ public ContainerParser(final SAMFileHeader samFileHeader) { } public List getRecords(final Container container, - ArrayList records, final ValidationStringency validationStringency) throws IllegalArgumentException, - IllegalAccessException { + ArrayList records, + final ValidationStringency validationStringency) { if (container.isEOF()) { return Collections.emptyList(); } @@ -61,7 +59,7 @@ public List getRecords(final Container container, return records; } - public Map getReferences(final Container container, final ValidationStringency validationStringency) throws IOException { + public Map getReferences(final Container container, final ValidationStringency validationStringency) { final Map containerSpanMap = new HashMap<>(); for (final Slice slice : container.slices) { addAllSpans(containerSpanMap, getReferences(slice, container.header, validationStringency)); @@ -84,7 +82,7 @@ private static Map addAllSpans(final Map getReferences(final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) throws IOException { + Map getReferences(final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) { final Map spanMap = new HashMap<>(); switch (slice.sequenceId) { case SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX: @@ -102,7 +100,9 @@ Map getReferences(final Slice slice, final CompressionHe } ArrayList getRecords(ArrayList records, - final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) throws IllegalArgumentException { + final Slice slice, + final CompressionHeader header, + final ValidationStringency validationStringency) { String seqName = SAMRecord.NO_ALIGNMENT_REFERENCE_NAME; switch (slice.sequenceId) { case SAMRecord.NO_ALIGNMENT_REFERENCE_INDEX: @@ -153,8 +153,9 @@ ArrayList getRecords(ArrayList rec return records; } - List getRecords(final Slice slice, final CompressionHeader header, final ValidationStringency validationStringency) - throws IllegalArgumentException, IllegalAccessException { + List getRecords(final Slice slice, + final CompressionHeader header, + final ValidationStringency validationStringency) { return getRecords(null, slice, header, validationStringency); } } diff --git a/src/main/java/htsjdk/samtools/cram/build/CramContainerHeaderIterator.java b/src/main/java/htsjdk/samtools/cram/build/CramContainerHeaderIterator.java index 4c3264596a..7a57aa0029 100644 --- a/src/main/java/htsjdk/samtools/cram/build/CramContainerHeaderIterator.java +++ b/src/main/java/htsjdk/samtools/cram/build/CramContainerHeaderIterator.java @@ -6,7 +6,6 @@ import htsjdk.samtools.cram.structure.Container; import htsjdk.samtools.cram.structure.ContainerIO; -import java.io.IOException; import java.io.InputStream; /** @@ -19,11 +18,11 @@ */ public class CramContainerHeaderIterator extends CramContainerIterator { - public CramContainerHeaderIterator(final InputStream inputStream) throws IOException { + public CramContainerHeaderIterator(final InputStream inputStream) { super(inputStream); } - protected Container containerFromStream(final Version cramVersion, final CountingInputStream countingStream) throws IOException { + protected Container containerFromStream(final Version cramVersion, final CountingInputStream countingStream) { final Container container = ContainerIO.readContainerHeader(cramVersion.major, countingStream); InputStreamUtils.skipFully(countingStream, container.containerByteSize); return container; diff --git a/src/main/java/htsjdk/samtools/cram/build/CramContainerIterator.java b/src/main/java/htsjdk/samtools/cram/build/CramContainerIterator.java index 159de03f90..88468b0dba 100644 --- a/src/main/java/htsjdk/samtools/cram/build/CramContainerIterator.java +++ b/src/main/java/htsjdk/samtools/cram/build/CramContainerIterator.java @@ -6,7 +6,6 @@ import htsjdk.samtools.cram.structure.ContainerIO; import htsjdk.samtools.cram.structure.CramHeader; -import java.io.IOException; import java.io.InputStream; import java.util.Iterator; @@ -20,22 +19,18 @@ public class CramContainerIterator implements Iterator { private boolean eof = false; private long offset = 0; - public CramContainerIterator(final InputStream inputStream) throws IOException { + public CramContainerIterator(final InputStream inputStream) { this.countingInputStream = new CountingInputStream(inputStream); cramHeader = CramIO.readCramHeader(countingInputStream); this.offset = countingInputStream.getCount(); } void readNextContainer() { - try { - nextContainer = containerFromStream(cramHeader.getVersion(), countingInputStream); - final long containerSizeInBytes = countingInputStream.getCount() - offset; + nextContainer = containerFromStream(cramHeader.getVersion(), countingInputStream); + final long containerSizeInBytes = countingInputStream.getCount() - offset; - nextContainer.offset = offset; - offset += containerSizeInBytes; - } catch (final IOException e) { - throw new RuntimeException(e); - } + nextContainer.offset = offset; + offset += containerSizeInBytes; if (nextContainer.isEOF()) { eof = true; @@ -48,9 +43,8 @@ void readNextContainer() { * @param cramVersion * @param countingStream * @return The next Container from the stream. - * @throws IOException */ - protected Container containerFromStream(final Version cramVersion, final CountingInputStream countingStream) throws IOException { + protected Container containerFromStream(final Version cramVersion, final CountingInputStream countingStream) { return ContainerIO.readContainer(cramHeader.getVersion(), countingStream); } diff --git a/src/main/java/htsjdk/samtools/cram/build/CramIO.java b/src/main/java/htsjdk/samtools/cram/build/CramIO.java index e8b9d733fb..78c4f94e35 100644 --- a/src/main/java/htsjdk/samtools/cram/build/CramIO.java +++ b/src/main/java/htsjdk/samtools/cram/build/CramIO.java @@ -22,7 +22,6 @@ import htsjdk.samtools.cram.common.CramVersions; import htsjdk.samtools.cram.common.Version; import htsjdk.samtools.cram.io.CountingInputStream; -import htsjdk.samtools.cram.io.ExposedByteArrayOutputStream; import htsjdk.samtools.cram.io.InputStreamUtils; import htsjdk.samtools.cram.structure.block.Block; import htsjdk.samtools.cram.structure.Container; @@ -87,18 +86,22 @@ private static byte[] bytesFromHex(final String string) { * @param version the CRAM version to assume * @param outputStream the stream to write to * @return the number of bytes written out - * @throws IOException as per java IO contract */ - public static long issueEOF(final Version version, final OutputStream outputStream) throws IOException { - if (version.compatibleWith(CramVersions.CRAM_v3)) { - outputStream.write(ZERO_F_EOF_MARKER); - return ZERO_F_EOF_MARKER.length; - } + public static long issueEOF(final Version version, final OutputStream outputStream) { + try { + if (version.compatibleWith(CramVersions.CRAM_v3)) { + outputStream.write(ZERO_F_EOF_MARKER); + return ZERO_F_EOF_MARKER.length; + } - if (version.compatibleWith(CramVersions.CRAM_v2_1)) { - outputStream.write(ZERO_B_EOF_MARKER); - return ZERO_B_EOF_MARKER.length; + if (version.compatibleWith(CramVersions.CRAM_v2_1)) { + outputStream.write(ZERO_B_EOF_MARKER); + return ZERO_B_EOF_MARKER.length; + } + } catch (final IOException e) { + throw new RuntimeIOException(e); } + return 0; } @@ -114,11 +117,7 @@ public static long issueEOF(final Version version, final OutputStream outputStre public static long writeHeader(final Version cramVersion, final OutputStream outStream, final SAMFileHeader samFileHeader, String cramID) { final CramHeader cramHeader = new CramHeader(cramVersion, cramID, samFileHeader); - try { - return CramIO.writeCramHeader(cramHeader, outStream); - } catch (final IOException e) { - throw new RuntimeIOException(e); - } + return CramIO.writeCramHeader(cramHeader, outStream); } private static boolean streamEndsWith(final SeekableStream seekableStream, final byte[] marker) throws IOException { @@ -155,12 +154,14 @@ private static boolean checkEOF(final Version version, final SeekableStream seek * * @param file the CRAM file to check * @return true if the file is a valid CRAM file and is properly terminated with respect to the version. - * @throws IOException as per java IO contract */ - public static boolean checkHeaderAndEOF(final File file) throws IOException { - final SeekableStream seekableStream = new SeekableFileStream(file); - final CramHeader cramHeader = readCramHeader(seekableStream); - return checkEOF(cramHeader.getVersion(), seekableStream); + public static boolean checkHeaderAndEOF(final File file) { + try (final SeekableStream seekableStream = new SeekableFileStream(file)) { + final CramHeader cramHeader = readCramHeader(seekableStream); + return checkEOF(cramHeader.getVersion(), seekableStream); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } /** @@ -169,20 +170,23 @@ public static boolean checkHeaderAndEOF(final File file) throws IOException { * @param cramHeader the {@link CramHeader} object to write * @param outputStream the output stream to write to * @return the number of bytes written out - * @throws IOException as per java IO contract */ - public static long writeCramHeader(final CramHeader cramHeader, final OutputStream outputStream) throws IOException { + public static long writeCramHeader(final CramHeader cramHeader, final OutputStream outputStream) { // if (cramHeader.getVersion().major < 3) throw new RuntimeException("Deprecated CRAM version: " + cramHeader.getVersion().major); - outputStream.write("CRAM".getBytes("US-ASCII")); - outputStream.write(cramHeader.getVersion().major); - outputStream.write(cramHeader.getVersion().minor); - outputStream.write(cramHeader.getId()); - for (int i = cramHeader.getId().length; i < 20; i++) - outputStream.write(0); + try { + outputStream.write("CRAM".getBytes("US-ASCII")); + outputStream.write(cramHeader.getVersion().major); + outputStream.write(cramHeader.getVersion().minor); + outputStream.write(cramHeader.getId()); + for (int i = cramHeader.getId().length; i < 20; i++) + outputStream.write(0); - final long length = CramIO.writeContainerForSamFileHeader(cramHeader.getVersion().major, cramHeader.getSamFileHeader(), outputStream); + final long length = CramIO.writeContainerForSamFileHeader(cramHeader.getVersion().major, cramHeader.getSamFileHeader(), outputStream); - return CramIO.DEFINITION_LENGTH + length; + return CramIO.DEFINITION_LENGTH + length; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } private static CramHeader readFormatDefinition(final InputStream inputStream) throws IOException { @@ -205,24 +209,27 @@ private static CramHeader readFormatDefinition(final InputStream inputStream) th * * @param inputStream input stream to read from * @return complete {@link CramHeader} object - * @throws IOException as per java IO contract */ - public static CramHeader readCramHeader(final InputStream inputStream) throws IOException { - final CramHeader header = readFormatDefinition(inputStream); + public static CramHeader readCramHeader(final InputStream inputStream) { + try { + final CramHeader header = readFormatDefinition(inputStream); - final SAMFileHeader samFileHeader = readSAMFileHeader(header.getVersion(), inputStream, new String(header.getId())); + final SAMFileHeader samFileHeader = readSAMFileHeader(header.getVersion(), inputStream, new String(header.getId())); - return new CramHeader(header.getVersion(), new String(header.getId()), samFileHeader); + return new CramHeader(header.getVersion(), new String(header.getId()), samFileHeader); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } private static byte[] toByteArray(final SAMFileHeader samFileHeader) { - final ExposedByteArrayOutputStream headerBodyOS = new ExposedByteArrayOutputStream(); + final ByteArrayOutputStream headerBodyOS = new ByteArrayOutputStream(); final OutputStreamWriter outStreamWriter = new OutputStreamWriter(headerBodyOS); new SAMTextHeaderCodec().encode(outStreamWriter, samFileHeader); try { outStreamWriter.close(); } catch (final IOException e) { - throw new RuntimeException(e); + throw new RuntimeIOException(e); } final ByteBuffer buf = ByteBuffer.allocate(4); @@ -235,15 +242,15 @@ private static byte[] toByteArray(final SAMFileHeader samFileHeader) { final ByteArrayOutputStream headerOS = new ByteArrayOutputStream(); try { headerOS.write(bytes); - headerOS.write(headerBodyOS.getBuffer(), 0, headerBodyOS.size()); + headerOS.write(headerBodyOS.toByteArray(), 0, headerBodyOS.size()); } catch (final IOException e) { - throw new RuntimeException(e); + throw new RuntimeIOException(e); } return headerOS.toByteArray(); } - private static long writeContainerForSamFileHeader(final int major, final SAMFileHeader samFileHeader, final OutputStream os) throws IOException { + private static long writeContainerForSamFileHeader(final int major, final SAMFileHeader samFileHeader, final OutputStream os) { final byte[] data = toByteArray(samFileHeader); final int length = Math.max(1024, data.length + data.length / 2); final byte[] blockContent = new byte[length]; @@ -262,17 +269,21 @@ private static long writeContainerForSamFileHeader(final int major, final SAMFil container.nofRecords = 0; container.sequenceId = 0; - final ExposedByteArrayOutputStream byteArrayOutputStream = new ExposedByteArrayOutputStream(); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); block.write(major, byteArrayOutputStream); container.containerByteSize = byteArrayOutputStream.size(); final int containerHeaderByteSize = ContainerIO.writeContainerHeader(major, container, os); - os.write(byteArrayOutputStream.getBuffer(), 0, byteArrayOutputStream.size()); + try { + os.write(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size()); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } return containerHeaderByteSize + byteArrayOutputStream.size(); } - private static SAMFileHeader readSAMFileHeader(final Version version, InputStream inputStream, final String id) throws IOException { + private static SAMFileHeader readSAMFileHeader(final Version version, InputStream inputStream, final String id) { final Container container = ContainerIO.readContainerHeader(version.major, inputStream); final Block block; { @@ -294,14 +305,22 @@ private static SAMFileHeader readSAMFileHeader(final Version version, InputStrea final ByteBuffer buffer = ByteBuffer.allocate(4); buffer.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < 4; i++) - buffer.put((byte) inputStream.read()); + try { + for (int i = 0; i < 4; i++) + buffer.put((byte) inputStream.read()); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } buffer.flip(); final int size = buffer.asIntBuffer().get(); final DataInputStream dataInputStream = new DataInputStream(inputStream); final byte[] bytes = new byte[size]; - dataInputStream.readFully(bytes); + try { + dataInputStream.readFully(bytes); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } final BufferedLineReader bufferedLineReader = new BufferedLineReader(new ByteArrayInputStream(bytes)); final SAMTextHeaderCodec codec = new SAMTextHeaderCodec(); @@ -316,28 +335,29 @@ private static SAMFileHeader readSAMFileHeader(final Version version, InputStrea * @param file the CRAM file * @param newHeader the new CramHeader container a new SAM file header * @return true if successfully replaced the header, false otherwise - * @throws IOException as per java IO contract */ - public static boolean replaceCramHeader(final File file, final CramHeader newHeader) throws IOException { - - final CountingInputStream countingInputStream = new CountingInputStream(new FileInputStream(file)); - - final CramHeader header = readFormatDefinition(countingInputStream); - final Container c = ContainerIO.readContainerHeader(header.getVersion().major, countingInputStream); - final long pos = countingInputStream.getCount(); - countingInputStream.close(); + public static boolean replaceCramHeader(final File file, final CramHeader newHeader) { + try (final CountingInputStream countingInputStream = new CountingInputStream(new FileInputStream(file)); + final RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw")) { + final CramHeader header = readFormatDefinition(countingInputStream); + final Container c = ContainerIO.readContainerHeader(header.getVersion().major, countingInputStream); + final long pos = countingInputStream.getCount(); + countingInputStream.close(); + + final Block block = Block.createRawFileHeaderBlock(toByteArray(newHeader.getSamFileHeader())); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + block.write(newHeader.getVersion().major, byteArrayOutputStream); + if (byteArrayOutputStream.size() > c.containerByteSize) { + log.error("Failed to replace CRAM header because the new header does not fit."); + return false; + } - final Block block = Block.createRawFileHeaderBlock(toByteArray(newHeader.getSamFileHeader())); - final ExposedByteArrayOutputStream byteArrayOutputStream = new ExposedByteArrayOutputStream(); - block.write(newHeader.getVersion().major, byteArrayOutputStream); - if (byteArrayOutputStream.size() > c.containerByteSize) { - log.error("Failed to replace CRAM header because the new header does not fit."); - return false; + randomAccessFile.seek(pos); + randomAccessFile.write(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size()); + randomAccessFile.close(); + return true; + } catch (final IOException e) { + throw new RuntimeIOException(e); } - final RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); - randomAccessFile.seek(pos); - randomAccessFile.write(byteArrayOutputStream.getBuffer(), 0, byteArrayOutputStream.size()); - randomAccessFile.close(); - return true; } } diff --git a/src/main/java/htsjdk/samtools/cram/build/CramSpanContainerIterator.java b/src/main/java/htsjdk/samtools/cram/build/CramSpanContainerIterator.java index 2956cda629..240449155d 100644 --- a/src/main/java/htsjdk/samtools/cram/build/CramSpanContainerIterator.java +++ b/src/main/java/htsjdk/samtools/cram/build/CramSpanContainerIterator.java @@ -4,6 +4,7 @@ import htsjdk.samtools.cram.structure.ContainerIO; import htsjdk.samtools.cram.structure.CramHeader; import htsjdk.samtools.seekablestream.SeekableStream; +import htsjdk.samtools.util.RuntimeIOException; import java.io.IOException; import java.util.ArrayList; @@ -36,29 +37,25 @@ private CramSpanContainerIterator(final SeekableStream seekableStream, final lon currentBoundary = containerBoundaries.next(); } - public static CramSpanContainerIterator fromFileSpan(final SeekableStream seekableStream, final long[] coordinates) throws IOException { - return new CramSpanContainerIterator(seekableStream, coordinates); + public static CramSpanContainerIterator fromFileSpan(final SeekableStream seekableStream, final long[] coordinates) { + try { + return new CramSpanContainerIterator(seekableStream, coordinates); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override public boolean hasNext() { - try { - if (currentBoundary.hasNext()) return true; - if (!containerBoundaries.hasNext()) return false; - currentBoundary = containerBoundaries.next(); - return currentBoundary.hasNext(); - } catch (final IOException e) { - throw new RuntimeException(e); - } + if (currentBoundary.hasNext()) return true; + if (!containerBoundaries.hasNext()) return false; + currentBoundary = containerBoundaries.next(); + return currentBoundary.hasNext(); } @Override public Container next() { - try { - return currentBoundary.next(); - } catch (final IOException e) { - throw new RuntimeException(e); - } + return currentBoundary.next(); } @Override @@ -70,27 +67,45 @@ public CramHeader getCramHeader() { return cramHeader; } - private class Boundary { + private class Boundary implements Iterator { final long start; final long end; public Boundary(final long start, final long end) { this.start = start; this.end = end; - if (start >= end) throw new RuntimeException("Boundary start is greater than end."); + if (start >= end) { + throw new RuntimeException("Boundary start is greater than end."); + } } - boolean hasNext() throws IOException { - return seekableStream.position() <= (end >> 16); + @Override + public boolean hasNext() { + try { + return seekableStream.position() <= (end >> 16); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } - Container next() throws IOException { - if (seekableStream.position() < (start >> 16)) seekableStream.seek(start >> 16); - if (seekableStream.position() > (end >> 16)) throw new RuntimeException("No more containers in this boundary."); - final long offset = seekableStream.position(); - final Container c = ContainerIO.readContainer(cramHeader.getVersion(), seekableStream); - c.offset = offset; - return c; + @Override + public Container next() { + try { + if (seekableStream.position() < (start >> 16)) { + seekableStream.seek(start >> 16); + } + + if (!hasNext()) { + throw new RuntimeException("No more containers in this boundary."); + } + + final long offset = seekableStream.position(); + final Container c = ContainerIO.readContainer(cramHeader.getVersion(), seekableStream); + c.offset = offset; + return c; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } } diff --git a/src/main/java/htsjdk/samtools/cram/compression/ExternalCompression.java b/src/main/java/htsjdk/samtools/cram/compression/ExternalCompression.java index 3f8b511583..44a8dcb4de 100644 --- a/src/main/java/htsjdk/samtools/cram/compression/ExternalCompression.java +++ b/src/main/java/htsjdk/samtools/cram/compression/ExternalCompression.java @@ -4,6 +4,7 @@ import htsjdk.samtools.cram.io.InputStreamUtils; import htsjdk.samtools.cram.structure.block.BlockCompressionMethod; import htsjdk.samtools.util.IOUtil; +import htsjdk.samtools.util.RuntimeIOException; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; @@ -28,15 +29,17 @@ public class ExternalCompression { * @param data byte array to compress * @return compressed blob */ - public static byte[] gzip(final byte[] data) throws IOException { + public static byte[] gzip(final byte[] data) { final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - final GZIPOutputStream gos = new GZIPOutputStream(byteArrayOutputStream) { + try (final GZIPOutputStream gos = new GZIPOutputStream(byteArrayOutputStream) { { def.setLevel(GZIP_COMPRESSION_LEVEL); } - }; - IOUtil.copyStream(new ByteArrayInputStream(data), gos); - gos.close(); + }) { + IOUtil.copyStream(new ByteArrayInputStream(data), gos); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } return byteArrayOutputStream.toByteArray(); } @@ -46,24 +49,29 @@ public static byte[] gzip(final byte[] data) throws IOException { * * @param data compressed data blob * @return uncompressed data - * @throws IOException as per java IO contract */ - public static byte[] gunzip(final byte[] data) throws IOException { - final GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(data)); - return InputStreamUtils.readFully(gzipInputStream); + public static byte[] gunzip(final byte[] data) { + try (final GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(data))) { + return InputStreamUtils.readFully(gzipInputStream); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } + /** * Compress a byte array into BZIP2 blob. * * @param data byte array to compress * @return compressed blob */ - public static byte[] bzip2(final byte[] data) throws IOException { + public static byte[] bzip2(final byte[] data) { final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - final BZip2CompressorOutputStream bos = new BZip2CompressorOutputStream(byteArrayOutputStream); - IOUtil.copyStream(new ByteArrayInputStream(data), bos); - bos.close(); + try (final BZip2CompressorOutputStream bos = new BZip2CompressorOutputStream(byteArrayOutputStream)) { + IOUtil.copyStream(new ByteArrayInputStream(data), bos); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } return byteArrayOutputStream.toByteArray(); } @@ -72,12 +80,14 @@ public static byte[] bzip2(final byte[] data) throws IOException { * * @param data compressed data blob * @return uncompressed data - * @throws IOException as per java IO contract */ @SuppressWarnings("ResultOfMethodCallIgnored") - public static byte[] unbzip2(final byte[] data) throws IOException { - final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data); - return InputStreamUtils.readFully(new BZip2CompressorInputStream(byteArrayInputStream)); + public static byte[] unbzip2(final byte[] data) { + try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data)) { + return InputStreamUtils.readFully(new BZip2CompressorInputStream(byteArrayInputStream)); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } /** @@ -122,11 +132,13 @@ public static byte[] unrans(final byte[] data) { * @param data byte array to compress * @return compressed blob */ - public static byte[] xz(final byte[] data) throws IOException { + public static byte[] xz(final byte[] data) { final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(data.length * 2); - final XZCompressorOutputStream xzCompressorOutputStream = new XZCompressorOutputStream(byteArrayOutputStream); - xzCompressorOutputStream.write(data); - xzCompressorOutputStream.close(); + try (final XZCompressorOutputStream xzCompressorOutputStream = new XZCompressorOutputStream(byteArrayOutputStream)) { + xzCompressorOutputStream.write(data); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } return byteArrayOutputStream.toByteArray(); } @@ -136,11 +148,13 @@ public static byte[] xz(final byte[] data) throws IOException { * * @param data compressed data blob * @return uncompressed data - * @throws IOException as per java IO contract */ - public static byte[] unxz(final byte[] data) throws IOException { - final XZCompressorInputStream xzCompressorInputStream = new XZCompressorInputStream(new ByteArrayInputStream(data)); - return InputStreamUtils.readFully(xzCompressorInputStream); + public static byte[] unxz(final byte[] data) { + try (final XZCompressorInputStream xzCompressorInputStream = new XZCompressorInputStream(new ByteArrayInputStream(data))) { + return InputStreamUtils.readFully(xzCompressorInputStream); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @@ -153,23 +167,19 @@ private static byte[] toByteArray(final ByteBuffer buffer) { } public static byte[] uncompress(final BlockCompressionMethod method, final byte[] compressedContent) { - try { - switch (method) { - case RAW: - return compressedContent; - case GZIP: - return gunzip(compressedContent); - case BZIP2: - return unbzip2(compressedContent); - case LZMA: - return unxz(compressedContent); - case RANS: - return unrans(compressedContent); - default: - throw new RuntimeException("Unknown block compression method: " + method.name()); - } - } catch (final IOException e) { - throw new RuntimeException(e); + switch (method) { + case RAW: + return compressedContent; + case GZIP: + return gunzip(compressedContent); + case BZIP2: + return unbzip2(compressedContent); + case LZMA: + return unxz(compressedContent); + case RANS: + return unrans(compressedContent); + default: + throw new RuntimeException("Unknown block compression method: " + method.name()); } } } diff --git a/src/main/java/htsjdk/samtools/cram/compression/ExternalCompressor.java b/src/main/java/htsjdk/samtools/cram/compression/ExternalCompressor.java index ca45dffea4..e9aa359a40 100644 --- a/src/main/java/htsjdk/samtools/cram/compression/ExternalCompressor.java +++ b/src/main/java/htsjdk/samtools/cram/compression/ExternalCompressor.java @@ -3,8 +3,6 @@ import htsjdk.samtools.cram.structure.block.BlockCompressionMethod; import htsjdk.samtools.cram.compression.rans.RANS.ORDER; -import java.io.IOException; - public abstract class ExternalCompressor { private final BlockCompressionMethod method; @@ -33,11 +31,7 @@ public static ExternalCompressor createGZIP() { @Override public byte[] compress(final byte[] data) { - try { - return ExternalCompression.gzip(data); - } catch (final IOException e) { - throw new RuntimeException(e); - } + return ExternalCompression.gzip(data); } }; } @@ -47,11 +41,7 @@ public static ExternalCompressor createLZMA() { @Override public byte[] compress(final byte[] data) { - try { - return ExternalCompression.xz(data); - } catch (final IOException e) { - throw new RuntimeException(e); - } + return ExternalCompression.xz(data); } }; } @@ -61,11 +51,7 @@ public static ExternalCompressor createBZIP2() { @Override public byte[] compress(final byte[] data) { - try { - return ExternalCompression.bzip2(data); - } catch (final IOException e) { - throw new RuntimeException(e); - } + return ExternalCompression.bzip2(data); } }; diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/BetaIntegerCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/BetaIntegerCodec.java index 06f00e2f47..0476ed1ad9 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/BetaIntegerCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/BetaIntegerCodec.java @@ -19,9 +19,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; /** * Encodes integers by adding a constant offset value to a range of values in order to reduce @@ -57,11 +54,7 @@ public BetaIntegerCodec(final BitInputStream coreBlockInputStream, @Override public final Integer read() { - try { - return coreBlockInputStream.readBits(bitsPerValue) - offset; - } catch (IOException e) { - throw new RuntimeIOException(e); - } + return coreBlockInputStream.readBits(bitsPerValue) - offset; } @Override @@ -87,10 +80,6 @@ private int getAndCheckOffsetValue(int value) { @Override public final void write(final Integer value) { - try { - coreBlockOutputStream.write(getAndCheckOffsetValue(value), bitsPerValue); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + coreBlockOutputStream.write(getAndCheckOffsetValue(value), bitsPerValue); } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanByteCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanByteCodec.java index e8f919a089..97c811f83e 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanByteCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanByteCodec.java @@ -20,9 +20,6 @@ import htsjdk.samtools.cram.encoding.core.huffmanUtils.HuffmanByteHelper; import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; /** * Encode Bytes using the Canonical Huffman Codec. @@ -48,20 +45,12 @@ public CanonicalHuffmanByteCodec(final BitInputStream coreBlockInputStream, @Override public Byte read() { - try { - return helper.read(coreBlockInputStream); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + return helper.read(coreBlockInputStream); } @Override public void write(final Byte value) { - try { - helper.write(coreBlockOutputStream, value); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + helper.write(coreBlockOutputStream, value); } @Override diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanIntegerCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanIntegerCodec.java index 4d40e907f3..cbd1da14e1 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanIntegerCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/CanonicalHuffmanIntegerCodec.java @@ -20,9 +20,6 @@ import htsjdk.samtools.cram.encoding.core.huffmanUtils.HuffmanIntHelper; import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; /** * Encode Integers using the Canonical Huffman Codec. @@ -48,20 +45,12 @@ public CanonicalHuffmanIntegerCodec(final BitInputStream coreBlockInputStream, @Override public Integer read() { - try { - return helper.read(coreBlockInputStream); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + return helper.read(coreBlockInputStream); } @Override public void write(final Integer value) { - try { - helper.write(coreBlockOutputStream, value); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + helper.write(coreBlockOutputStream, value); } @Override diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/GammaIntegerCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/GammaIntegerCodec.java index 245ccefe0c..35acab913d 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/GammaIntegerCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/GammaIntegerCodec.java @@ -19,9 +19,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; /** * Encode Integers using Elias Gamma Encoding. @@ -51,17 +48,13 @@ public final Integer read() { int length = 1; final boolean lenCodingBit = false; - try { - while (coreBlockInputStream.readBit() == lenCodingBit) { - length++; - } - - final int readBits = coreBlockInputStream.readBits(length - 1); - final int value = readBits | 1 << (length - 1); - return value - offset; - } catch (IOException e) { - throw new RuntimeIOException(e); + while (coreBlockInputStream.readBit() == lenCodingBit) { + length++; } + + final int readBits = coreBlockInputStream.readBits(length - 1); + final int value = readBits | 1 << (length - 1); + return value - offset; } @Override @@ -75,15 +68,12 @@ public final void write(final Integer value) { final long newValue = value + offset; final int betaCodeLength = 1 + (int) (Math.log(newValue) / Math.log(2)); - try { - if (betaCodeLength > 1) { - coreBlockOutputStream.write(0L, betaCodeLength - 1); - } - coreBlockOutputStream.write(newValue, betaCodeLength); - } catch (IOException e) { - throw new RuntimeIOException(e); + if (betaCodeLength > 1) { + coreBlockOutputStream.write(0L, betaCodeLength - 1); } + + coreBlockOutputStream.write(newValue, betaCodeLength); } @Override diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/SubexponentialIntegerCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/SubexponentialIntegerCodec.java index b3efd70ecc..528c58440c 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/SubexponentialIntegerCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/SubexponentialIntegerCodec.java @@ -19,9 +19,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; /** * Use the Subexponential Codec @@ -51,26 +48,22 @@ public SubexponentialIntegerCodec(final BitInputStream coreBlockInputStream, @Override public final Integer read() { int u = 0; - try { - while (coreBlockInputStream.readBit()) { - u++; - } - - final int b; - final int n; + while (coreBlockInputStream.readBit()) { + u++; + } - if (u == 0) { - b = k; - n = coreBlockInputStream.readBits(b); - } else { - b = u + k - 1; - n = (1 << b) | coreBlockInputStream.readBits(b); - } + final int b; + final int n; - return n - offset; - } catch (IOException e) { - throw new RuntimeIOException(e); + if (u == 0) { + b = k; + n = coreBlockInputStream.readBits(b); + } else { + b = u + k - 1; + n = (1 << b) | coreBlockInputStream.readBits(b); } + + return n - offset; } @Override @@ -90,16 +83,12 @@ public final void write(final Integer value) { u = b - k + 1; } - try { - // write 'u' 1 bits followed by a 0 bit - coreBlockOutputStream.write(true, u); - coreBlockOutputStream.write(false); + // write 'u' 1 bits followed by a 0 bit + coreBlockOutputStream.write(true, u); + coreBlockOutputStream.write(false); - // write only the 'b' lowest bits of newValue - coreBlockOutputStream.write(newValue, b); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + // write only the 'b' lowest bits of newValue + coreBlockOutputStream.write(newValue, b); } @Override diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombIntegerCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombIntegerCodec.java index bc50ed98f0..b704866e44 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombIntegerCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombIntegerCodec.java @@ -19,9 +19,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; class GolombIntegerCodec extends ExperimentalCodec { private final int m; @@ -43,23 +40,20 @@ public GolombIntegerCodec(final BitInputStream coreBlockInputStream, @Override public final Integer read() { int quotient = 0; - try { - while (coreBlockInputStream.readBit() == quotientBit) { - quotient++; - } - final int ceiling = (int) (Math.log(m) / Math.log(2) + 1); - int reminder = coreBlockInputStream.readBits(ceiling - 1); - if (reminder >= Math.pow(2, ceiling) - m) { - reminder <<= 1; - reminder |= coreBlockInputStream.readBits(1); - reminder -= Math.pow(2, ceiling) - m; - } + while (coreBlockInputStream.readBit() == quotientBit) { + quotient++; + } - return (quotient * m + reminder) - offset; - } catch (IOException e) { - throw new RuntimeIOException(e); + final int ceiling = (int) (Math.log(m) / Math.log(2) + 1); + int reminder = coreBlockInputStream.readBits(ceiling - 1); + if (reminder >= Math.pow(2, ceiling) - m) { + reminder <<= 1; + reminder |= coreBlockInputStream.readBits(1); + reminder -= Math.pow(2, ceiling) - m; } + + return (quotient * m + reminder) - offset; } @Override @@ -69,18 +63,14 @@ public final void write(final Integer value) { final int reminder = newValue % m; final int ceiling = (int) (Math.log(m) / Math.log(2) + 1); - try { - coreBlockOutputStream.write(quotientBit, quotient); - coreBlockOutputStream.write(!quotientBit); + coreBlockOutputStream.write(quotientBit, quotient); + coreBlockOutputStream.write(!quotientBit); - if (reminder < Math.pow(2, ceiling) - m) { - coreBlockOutputStream.write(reminder, ceiling - 1); - } else { - coreBlockOutputStream.write((int) (reminder + Math.pow(2, ceiling) - m), - ceiling); - } - } catch (IOException e) { - throw new RuntimeIOException(e); + if (reminder < Math.pow(2, ceiling) - m) { + coreBlockOutputStream.write(reminder, ceiling - 1); + } else { + coreBlockOutputStream.write((int) (reminder + Math.pow(2, ceiling) - m), + ceiling); } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombLongCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombLongCodec.java index a95cafdf02..5fbb3553f3 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombLongCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombLongCodec.java @@ -19,9 +19,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; class GolombLongCodec extends ExperimentalCodec { private final int m; @@ -45,23 +42,20 @@ public GolombLongCodec(final BitInputStream coreBlockInputStream, @Override public final Long read() { long quotient = 0L; - try { - while (coreBlockInputStream.readBit() == quotientBit) { - quotient++; - } - final long ceiling = (long) (Math.log(m) / Math.log(2) + 1); - long reminder = coreBlockInputStream.readBits((int) (ceiling - 1)); - if (reminder >= Math.pow(2, ceiling) - m) { - reminder <<= 1; - reminder |= coreBlockInputStream.readBits(1); - reminder -= Math.pow(2, ceiling) - m; - } + while (coreBlockInputStream.readBit() == quotientBit) { + quotient++; + } - return (quotient * m + reminder) - offset; - } catch (IOException e) { - throw new RuntimeIOException(e); + final long ceiling = (long) (Math.log(m) / Math.log(2) + 1); + long reminder = coreBlockInputStream.readBits((int) (ceiling - 1)); + if (reminder >= Math.pow(2, ceiling) - m) { + reminder <<= 1; + reminder |= coreBlockInputStream.readBits(1); + reminder -= Math.pow(2, ceiling) - m; } + + return (quotient * m + reminder) - offset; } @Override @@ -71,19 +65,15 @@ public final void write(final Long value) { final long reminder = newValue % m; final long ceiling = (long) (Math.log(m) / Math.log(2) + 1); - try { - coreBlockOutputStream.write(quotientBit, quotient); - coreBlockOutputStream.write(!quotientBit); + coreBlockOutputStream.write(quotientBit, quotient); + coreBlockOutputStream.write(!quotientBit); - if (reminder < Math.pow(2, ceiling) - m) { - coreBlockOutputStream.write(reminder, (int) ceiling - 1); - } else { - coreBlockOutputStream.write((int) (reminder + Math.pow(2, ceiling) - m), - (int) ceiling); - } - } catch (IOException e) { - throw new RuntimeIOException(e); + if (reminder < Math.pow(2, ceiling) - m) { + coreBlockOutputStream.write(reminder, (int) ceiling - 1); + } else { + coreBlockOutputStream.write((int) (reminder + Math.pow(2, ceiling) - m), (int) ceiling); } + } @Override diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombRiceIntegerCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombRiceIntegerCodec.java index debb794b52..75774b873b 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombRiceIntegerCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/experimental/GolombRiceIntegerCodec.java @@ -19,9 +19,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import htsjdk.samtools.util.RuntimeIOException; - -import java.io.IOException; class GolombRiceIntegerCodec extends ExperimentalCodec { private final int m; @@ -46,46 +43,39 @@ public GolombRiceIntegerCodec(final BitInputStream coreBlockInputStream, public final Integer read() { int unary = 0; - try { - while (coreBlockInputStream.readBit() == quotientBit) { - unary++; - } - final int remainder = coreBlockInputStream.readBits(log2m); - - final int result = unary * m + remainder; - return result - offset; - } catch (IOException e) { - throw new RuntimeIOException(e); + while (coreBlockInputStream.readBit() == quotientBit) { + unary++; } + + final int remainder = coreBlockInputStream.readBits(log2m); + + final int result = unary * m + remainder; + return result - offset; } @Override public final void write(final Integer value) { final long newValue = value + offset; final long quotient = newValue >>> log2m; - try { - if (quotient > 0x7fffffffL) { - for (long i = 0; i < quotient; i++) { - coreBlockOutputStream.write(quotientBit); - } - } - else if (quotient > 0) { - final int qi = (int) quotient; - for (int i = 0; i < qi; i++) { - coreBlockOutputStream.write(quotientBit); - } + + if (quotient > 0x7fffffffL) { + for (long i = 0; i < quotient; i++) { + coreBlockOutputStream.write(quotientBit); } - coreBlockOutputStream.write(!quotientBit); - final long remainder = newValue & mask; - long reminderMask = 1 << (log2m - 1); - for (int i = log2m - 1; i >= 0; i--) { - final long b = remainder & reminderMask; - coreBlockOutputStream.write(b != 0L); - reminderMask >>>= 1; + } else if (quotient > 0) { + final int qi = (int) quotient; + for (int i = 0; i < qi; i++) { + coreBlockOutputStream.write(quotientBit); } - } catch (IOException e) { - throw new RuntimeIOException(e); + } + coreBlockOutputStream.write(!quotientBit); + final long remainder = newValue & mask; + long reminderMask = 1 << (log2m - 1); + for (int i = log2m - 1; i >= 0; i--) { + final long b = remainder & reminderMask; + coreBlockOutputStream.write(b != 0L); + reminderMask >>>= 1; } } diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanByteHelper.java b/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanByteHelper.java index 6bbfa808ba..865364a7df 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanByteHelper.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanByteHelper.java @@ -20,7 +20,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -52,12 +51,10 @@ public HuffmanByteHelper(final byte[] values, final int[] bitLengths) { buildCodeBook(); buildCodes(); - final ArrayList list = new ArrayList( - codes.size()); + final ArrayList list = new ArrayList<>(codes.size()); list.addAll(codes.values()); Collections.sort(list, bitCodeComparator); - sortedCodes = list.toArray(new HuffmanBitCode[list - .size()]); + sortedCodes = list.toArray(new HuffmanBitCode[list.size()]); final byte[] sortedValues = Arrays.copyOf(values, values.length); Arrays.sort(sortedValues); @@ -86,12 +83,12 @@ public HuffmanByteHelper(final byte[] values, final int[] bitLengths) { } private void buildCodeBook() { - codeBook = new TreeMap>(); + codeBook = new TreeMap<>(); for (int i = 0; i < values.length; i++) { if (codeBook.containsKey(bitLengths[i])) codeBook.get(bitLengths[i]).add(values[i]); else { - final TreeSet entry = new TreeSet(); + final TreeSet entry = new TreeSet<>(); entry.add(values[i]); codeBook.put(bitLengths[i], entry); } @@ -99,7 +96,7 @@ private void buildCodeBook() { } private void buildCodes() { - codes = new TreeMap(); + codes = new TreeMap<>(); int codeLength = 0, codeValue = -1; for (final Object key : codeBook.keySet()) { // Iterate over code lengths @@ -126,8 +123,7 @@ private void buildCodes() { } } - final public long write(final BitOutputStream bitOutputStream, final byte value) - throws IOException { + final public long write(final BitOutputStream bitOutputStream, final byte value) { final HuffmanBitCode code = valueToCode[value]; if (code.value != value) throw new RuntimeException(String.format( @@ -137,7 +133,7 @@ final public long write(final BitOutputStream bitOutputStream, final byte value) return code.bitLength; } - final public byte read(final BitInputStream bitInputStream) throws IOException { + final public byte read(final BitInputStream bitInputStream) { int prevLen = 0; int bits = 0; for (int i = 0; i < sortedCodes.length; i++) { diff --git a/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanIntHelper.java b/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanIntHelper.java index db080cfe6c..e2ede30d97 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanIntHelper.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/core/huffmanUtils/HuffmanIntHelper.java @@ -20,7 +20,6 @@ import htsjdk.samtools.cram.io.BitInputStream; import htsjdk.samtools.cram.io.BitOutputStream; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -126,7 +125,7 @@ private void buildCodes() { } } - public final long write(final BitOutputStream bitOutputStream, final int value) throws IOException { + public final long write(final BitOutputStream bitOutputStream, final int value) { final int index = Arrays.binarySearch(sortedValues, value); final HuffmanBitCode code = sortedByValue[index]; if (code.value != value) @@ -136,7 +135,7 @@ public final long write(final BitOutputStream bitOutputStream, final int value) return code.bitLength; } - public final int read(final BitInputStream bitInputStream) throws IOException { + public final int read(final BitInputStream bitInputStream) { int prevLen = 0; int bits = 0; for (int i = 0; i < sortedCodes.length; i++) { diff --git a/src/main/java/htsjdk/samtools/cram/encoding/external/ByteArrayStopCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/external/ByteArrayStopCodec.java index af9b86f385..4daf1a21d2 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/external/ByteArrayStopCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/external/ByteArrayStopCodec.java @@ -1,9 +1,10 @@ package htsjdk.samtools.cram.encoding.external; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import htsjdk.samtools.util.RuntimeIOException; /** * Encode byte arrays by specifying a stop byte to separate the arrays. diff --git a/src/main/java/htsjdk/samtools/cram/encoding/external/ExternalByteArrayCodec.java b/src/main/java/htsjdk/samtools/cram/encoding/external/ExternalByteArrayCodec.java index 063a18e976..e2f22407f6 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/external/ExternalByteArrayCodec.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/external/ExternalByteArrayCodec.java @@ -21,8 +21,8 @@ import htsjdk.samtools.util.RuntimeIOException; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.ByteArrayInputStream; +import java.io.IOException; /** * Encode Byte Arrays using an External Data Block @@ -41,11 +41,7 @@ public ExternalByteArrayCodec(final ByteArrayInputStream inputStream, @Override public byte[] read(final int length) { - try { - return InputStreamUtils.readFully(inputStream, length); - } catch (IOException e) { - throw new RuntimeIOException(e); - } + return InputStreamUtils.readFully(inputStream, length); } @Override diff --git a/src/main/java/htsjdk/samtools/cram/encoding/writer/CramRecordWriter.java b/src/main/java/htsjdk/samtools/cram/encoding/writer/CramRecordWriter.java index cf698516b1..ae5e8e468a 100644 --- a/src/main/java/htsjdk/samtools/cram/encoding/writer/CramRecordWriter.java +++ b/src/main/java/htsjdk/samtools/cram/encoding/writer/CramRecordWriter.java @@ -21,7 +21,6 @@ import htsjdk.samtools.cram.io.BitOutputStream; import htsjdk.samtools.cram.structure.*; -import java.io.IOException; import java.io.ByteArrayOutputStream; import java.nio.charset.Charset; import java.util.List; diff --git a/src/main/java/htsjdk/samtools/cram/io/BitInputStream.java b/src/main/java/htsjdk/samtools/cram/io/BitInputStream.java index e5f89ad2dc..8d42db67fa 100644 --- a/src/main/java/htsjdk/samtools/cram/io/BitInputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/BitInputStream.java @@ -29,24 +29,20 @@ public interface BitInputStream extends Closeable { /** * Reads a single bit from the stream. - * - * @throws IOException as per streaming contract in java. */ - boolean readBit() throws IOException; + boolean readBit(); /** * Read specified number of bits from the stream. The bits are return in an integer value. * * @param length number of bits to read - * @throws IOException as per streaming contract in java. */ - int readBits(int length) throws IOException; + int readBits(int length); /** * Read specified number of bits from the stream. The bits are return in a long value. * * @param length number of bits to read - * @throws IOException as per streaming contract in java. */ - long readLongBits(int length) throws IOException; + long readLongBits(int length); } diff --git a/src/main/java/htsjdk/samtools/cram/io/BitOutputStream.java b/src/main/java/htsjdk/samtools/cram/io/BitOutputStream.java index b2a081f516..c10e759039 100644 --- a/src/main/java/htsjdk/samtools/cram/io/BitOutputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/BitOutputStream.java @@ -33,41 +33,36 @@ public interface BitOutputStream extends Closeable, Flushable { * Write specified number of bits supplied in the integer value. The method is naturally limited to 32 bits max. * @param bitContainer an integer containing the bits to be written out * @param nofBits the number of bits to written out, minimum 0, maximum 32. - * @throws IOException as per streaming contract in java. */ - void write(int bitContainer, int nofBits) throws IOException; + void write(int bitContainer, int nofBits); /** * Write specified number of bits supplied in the long value. The method is naturally limited to 64 bits max. * @param bitContainer an integer containing the bits to be written out * @param nofBits the number of bits to written out, minimum 0, maximum 64. - * @throws IOException as per streaming contract in java. */ - void write(long bitContainer, int nofBits) throws IOException; + void write(long bitContainer, int nofBits); /** * Write specified number of bits supplied in the byte value. The method is naturally limited to 8 bits max. * @param bitContainer an integer containing the bits to be written out * @param nofBits the number of bits to written out, minimum 0, maximum 8. - * @throws IOException as per streaming contract in java. */ - void write(byte bitContainer, int nofBits) throws IOException; + void write(byte bitContainer, int nofBits); /** * Write a single bit specified in the boolean argument. * @param bit emit 1 if true, 0 otherwise. - * @throws IOException as per streaming contract in java. */ - void write(boolean bit) throws IOException; + void write(boolean bit); /** * Write a single bit specified in the boolean argument repeatedly. * @param bit emit 1 if true, 0 otherwise. * @param repeat the number of bits to emit. - * @throws IOException as per streaming contract in java. */ - void write(boolean bit, long repeat) throws IOException; + void write(boolean bit, long repeat); } diff --git a/src/main/java/htsjdk/samtools/cram/io/CRC32InputStream.java b/src/main/java/htsjdk/samtools/cram/io/CRC32InputStream.java index 31e957e9c4..11e44a02b4 100644 --- a/src/main/java/htsjdk/samtools/cram/io/CRC32InputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/CRC32InputStream.java @@ -1,5 +1,7 @@ package htsjdk.samtools.cram.io; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.IOException; import java.io.InputStream; import java.util.zip.CRC32; @@ -22,41 +24,65 @@ public int getCRC32() { } @Override - public int read() throws IOException { - final int value = delegate.read(); - if (value != -1) - crc32.update(value); - return value; + public int read() { + try { + final int value = delegate.read(); + if (value != -1) + crc32.update(value); + return value; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public int read(@SuppressWarnings("NullableProblems") final byte[] b) throws IOException { - final int result = delegate.read(b); - if (result != -1) - crc32.update(b, 0, result); - return result; + public int read(@SuppressWarnings("NullableProblems") final byte[] b) { + try { + final int result = delegate.read(b); + if (result != -1) + crc32.update(b, 0, result); + return result; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public int read(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) throws IOException { - final int result = delegate.read(b, off, length); - crc32.update(b, off, result); - return result; + public int read(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) { + try { + final int result = delegate.read(b, off, length); + crc32.update(b, off, result); + return result; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public long skip(final long n) throws IOException { - return delegate.skip(n); + public long skip(final long n) { + try { + return delegate.skip(n); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public int available() throws IOException { - return delegate.available(); + public int available() { + try { + return delegate.available(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void close() throws IOException { - delegate.close(); + public void close() { + try { + delegate.close(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override @@ -65,8 +91,12 @@ public void mark(final int readLimit) { } @Override - public void reset() throws IOException { - delegate.reset(); + public void reset() { + try { + delegate.reset(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override diff --git a/src/main/java/htsjdk/samtools/cram/io/CRC32OutputStream.java b/src/main/java/htsjdk/samtools/cram/io/CRC32OutputStream.java index dff2137de6..e8e135c6bc 100644 --- a/src/main/java/htsjdk/samtools/cram/io/CRC32OutputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/CRC32OutputStream.java @@ -1,5 +1,7 @@ package htsjdk.samtools.cram.io; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -18,21 +20,33 @@ public CRC32OutputStream(final OutputStream out) { } @Override - public void write(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) throws IOException { + public void write(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) { crc32.update(b, off, length); - out.write(b, off, length); + try { + out.write(b, off, length); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void write(final int b) throws IOException { + public void write(final int b) { crc32.update(b); - out.write(b); + try { + out.write(b); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void write(@SuppressWarnings("NullableProblems") final byte[] b) throws IOException { + public void write(@SuppressWarnings("NullableProblems") final byte[] b) { crc32.update(b); - out.write(b); + try { + out.write(b); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } public long getLongCrc32() { diff --git a/src/main/java/htsjdk/samtools/cram/io/CountingInputStream.java b/src/main/java/htsjdk/samtools/cram/io/CountingInputStream.java index 41cb22aefa..27e00ab94a 100644 --- a/src/main/java/htsjdk/samtools/cram/io/CountingInputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/CountingInputStream.java @@ -17,6 +17,8 @@ */ package htsjdk.samtools.cram.io; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.IOException; import java.io.InputStream; @@ -32,41 +34,67 @@ public CountingInputStream(final InputStream inputStream) { } @Override - public int read() throws IOException { + public int read() { count++; - return delegate.read(); + try { + return delegate.read(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public int read(@SuppressWarnings("NullableProblems") final byte[] b) throws IOException { - final int read = delegate.read(b); - count += read; - return read; + public int read(@SuppressWarnings("NullableProblems") final byte[] b) { + try { + final int read = delegate.read(b); + + count += read; + return read; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public int read(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) throws IOException { - final int read = delegate.read(b, off, length); - count += read; - return read; + public int read(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) { + try { + final int read = delegate.read(b, off, length); + count += read; + return read; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public long skip(final long n) throws IOException { - final long skipped = delegate.skip(n); - count += skipped; - return skipped; + public long skip(final long n) { + try { + final long skipped = delegate.skip(n); + count += skipped; + return skipped; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public int available() throws IOException { - return delegate.available(); + public int available() { + try { + return delegate.available(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void close() throws IOException { - if (delegate != null) - delegate.close(); + public void close() { + try { + if (delegate != null) { + delegate.close(); + } + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override @@ -75,8 +103,12 @@ public void mark(final int readLimit) { } @Override - public void reset() throws IOException { - delegate.reset(); + public void reset() { + try { + delegate.reset(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } count = 0; } diff --git a/src/main/java/htsjdk/samtools/cram/io/CramInt.java b/src/main/java/htsjdk/samtools/cram/io/CramInt.java index 58a14d15db..25b81f6172 100644 --- a/src/main/java/htsjdk/samtools/cram/io/CramInt.java +++ b/src/main/java/htsjdk/samtools/cram/io/CramInt.java @@ -1,5 +1,7 @@ package htsjdk.samtools.cram.io; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -15,10 +17,13 @@ public class CramInt { * * @param inputStream input stream to read from * @return an integer value read - * @throws IOException as per java IO contract */ - public static int readInt32(final InputStream inputStream) throws IOException { - return inputStream.read() | inputStream.read() << 8 | inputStream.read() << 16 | inputStream.read() << 24; + public static int readInt32(final InputStream inputStream) { + try { + return inputStream.read() | inputStream.read() << 8 | inputStream.read() << 16 | inputStream.read() << 24; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } /** @@ -52,14 +57,17 @@ public static int readInt32(final ByteBuffer buffer) { * @param value value to be written out * @param outputStream the output stream * @return the number of bits written out - * @throws IOException as per java IO contract */ @SuppressWarnings("SameReturnValue") - public static int writeInt32(final int value, final OutputStream outputStream) throws IOException { - outputStream.write((byte) value); - outputStream.write((byte) (value >> 8)); - outputStream.write((byte) (value >> 16)); - outputStream.write((byte) (value >> 24)); + public static int writeInt32(final int value, final OutputStream outputStream) { + try { + outputStream.write((byte) value); + outputStream.write((byte) (value >> 8)); + outputStream.write((byte) (value >> 16)); + outputStream.write((byte) (value >> 24)); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } return 4 * 8; } diff --git a/src/main/java/htsjdk/samtools/cram/io/DefaultBitInputStream.java b/src/main/java/htsjdk/samtools/cram/io/DefaultBitInputStream.java index fef9e2b086..661c68c512 100644 --- a/src/main/java/htsjdk/samtools/cram/io/DefaultBitInputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/DefaultBitInputStream.java @@ -17,8 +17,10 @@ */ package htsjdk.samtools.cram.io; +import htsjdk.samtools.util.RuntimeEOFException; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.DataInputStream; -import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -42,31 +44,39 @@ public DefaultBitInputStream(final InputStream in) { } @Override - public final boolean readBit() throws IOException { + public final boolean readBit() { if (--nofBufferedBits >= 0) return ((byteBuffer >>> nofBufferedBits) & 1) == 1; nofBufferedBits = 7; - byteBuffer = in.read(); + try { + byteBuffer = in.read(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } if (byteBuffer == -1) { if (throwEOF) - throw new EOFException("End of stream."); + throw new RuntimeEOFException("End of stream."); } return ((byteBuffer >>> 7) & 1) == 1; } @Override - public final int readBits(int n) throws IOException { + public final int readBits(int n) { if (n == 0) return 0; int x = 0; while (n > nofBufferedBits) { n -= nofBufferedBits; x |= rightBits(nofBufferedBits, byteBuffer) << n; - byteBuffer = in.read(); + try { + byteBuffer = in.read(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } if (byteBuffer == -1) { - throw new EOFException("End of stream."); + throw new RuntimeEOFException("End of stream."); } nofBufferedBits = 8; @@ -80,7 +90,7 @@ private static int rightBits(final int n, final int x) { } @Override - public final long readLongBits(int n) throws IOException { + public final long readLongBits(int n) { if (n > 64) throw new RuntimeException("More then 64 bits are requested in one read from bit stream."); @@ -90,9 +100,13 @@ public final long readLongBits(int n) throws IOException { long x = 0; long byteBuffer = this.byteBuffer; if (nofBufferedBits == 0) { - byteBuffer = in.read(); + try { + byteBuffer = in.read(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } if (byteBuffer == -1) { - throw new EOFException("End of stream."); + throw new RuntimeEOFException("End of stream."); } nofBufferedBits = 8; } @@ -100,9 +114,13 @@ public final long readLongBits(int n) throws IOException { while (n > nofBufferedBits) { n -= nofBufferedBits; x |= byteBuffer << n; - byteBuffer = in.read(); + try { + byteBuffer = in.read(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } if (byteBuffer == -1) { - throw new EOFException("End of stream."); + throw new RuntimeEOFException("End of stream."); } nofBufferedBits = 8; } diff --git a/src/main/java/htsjdk/samtools/cram/io/DefaultBitOutputStream.java b/src/main/java/htsjdk/samtools/cram/io/DefaultBitOutputStream.java index 95d6789a81..4a35885222 100644 --- a/src/main/java/htsjdk/samtools/cram/io/DefaultBitOutputStream.java +++ b/src/main/java/htsjdk/samtools/cram/io/DefaultBitOutputStream.java @@ -17,6 +17,8 @@ */ package htsjdk.samtools.cram.io; +import htsjdk.samtools.util.RuntimeIOException; + import java.io.IOException; import java.io.OutputStream; @@ -38,13 +40,21 @@ public DefaultBitOutputStream(final OutputStream delegate) { this.out = delegate; } - public void write(final byte b) throws IOException { - out.write((int) b); + public void write(final byte b) { + try { + out.write((int) b); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void write(final int value) throws IOException { - out.write(value); + public void write(final int value) { + try { + out.write(value); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override @@ -54,12 +64,12 @@ public String toString() { } @Override - public void write(final long bitContainer, final int nofBits) throws IOException { + public void write(final long bitContainer, final int nofBits) { if (nofBits == 0) return; if (nofBits < 1 || nofBits > 64) - throw new IOException("Expecting 1 to 64 bits, got: value=" + bitContainer + ", nofBits=" + nofBits); + throw new RuntimeIOException("Expecting 1 to 64 bits, got: value=" + bitContainer + ", nofBits=" + nofBits); if (nofBits <= 8) write((byte) bitContainer, nofBits); @@ -75,12 +85,12 @@ public void write(final long bitContainer, final int nofBits) throws IOException } } - void write_int_LSB_0(final int value, final int nofBitsToWrite) throws IOException { + void write_int_LSB_0(final int value, final int nofBitsToWrite) { if (nofBitsToWrite == 0) return; if (nofBitsToWrite < 1 || nofBitsToWrite > 32) - throw new IOException("Expecting 1 to 32 bits."); + throw new RuntimeIOException("Expecting 1 to 32 bits."); if (nofBitsToWrite <= 8) write((byte) value, nofBitsToWrite); @@ -97,24 +107,28 @@ void write_int_LSB_0(final int value, final int nofBitsToWrite) throws IOExcepti } @Override - public void write(final int bitContainer, final int nofBits) throws IOException { + public void write(final int bitContainer, final int nofBits) { write_int_LSB_0(bitContainer, nofBits); } - private void writeByte(final int value) throws IOException { - if (bufferedNumberOfBits == 0) - out.write(value); - else { - bufferByte = ((value & 0xFF) >>> bufferedNumberOfBits) | bufferByte; - out.write(bufferByte); - bufferByte = (value << (8 - bufferedNumberOfBits)) & 0xFF; + private void writeByte(final int value) { + try { + if (bufferedNumberOfBits == 0) + out.write(value); + else { + bufferByte = ((value & 0xFF) >>> bufferedNumberOfBits) | bufferByte; + out.write(bufferByte); + bufferByte = (value << (8 - bufferedNumberOfBits)) & 0xFF; + } + } catch (final IOException e) { + throw new RuntimeIOException(e); } } @Override - public void write(byte bitContainer, final int nofBits) throws IOException { + public void write(byte bitContainer, final int nofBits) { if (nofBits < 0 || nofBits > 8) - throw new IOException("Expecting 0 to 8 bits."); + throw new RuntimeIOException("Expecting 0 to 8 bits."); if (nofBits == 8) writeByte(bitContainer); @@ -125,58 +139,78 @@ public void write(byte bitContainer, final int nofBits) throws IOException { } else { bitContainer = (byte) (bitContainer & ~bitMasks[8 - nofBits]); int bits = 8 - bufferedNumberOfBits - nofBits; - if (bits < 0) { - bits = -bits; - bufferByte |= (bitContainer >>> bits); - out.write(bufferByte); - bufferByte = (bitContainer << (8 - bits)) & 0xFF; - bufferedNumberOfBits = bits; - } else if (bits == 0) { - bufferByte = bufferByte | bitContainer; - out.write(bufferByte); - bufferedNumberOfBits = 0; - } else { - bufferByte = bufferByte | (bitContainer << bits); - bufferedNumberOfBits = 8 - bits; + try { + if (bits < 0) { + bits = -bits; + bufferByte |= (bitContainer >>> bits); + out.write(bufferByte); + bufferByte = (bitContainer << (8 - bits)) & 0xFF; + bufferedNumberOfBits = bits; + } else if (bits == 0) { + bufferByte = bufferByte | bitContainer; + out.write(bufferByte); + bufferedNumberOfBits = 0; + } else { + bufferByte = bufferByte | (bitContainer << bits); + bufferedNumberOfBits = 8 - bits; + } + } catch (final IOException e) { + throw new RuntimeException(e); } } } } @Override - public void write(final boolean bit) throws IOException { + public void write(final boolean bit) { write(bit ? (byte) 1 : (byte) 0, 1); } @Override - public void write(final boolean bit, final long repeat) throws IOException { + public void write(final boolean bit, final long repeat) { for (long i = 0; i < repeat; i++) write(bit); } @Override - public void close() throws IOException { + public void close() { flush(); - out.close(); + try { + out.close(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void flush() throws IOException { - if (bufferedNumberOfBits > 0) - out.write(bufferByte); - - bufferedNumberOfBits = 0; - out.flush(); + public void flush() { + try { + if (bufferedNumberOfBits > 0) + out.write(bufferByte); + + bufferedNumberOfBits = 0; + out.flush(); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void write(@SuppressWarnings("NullableProblems") final byte[] b) throws IOException { - out.write(b); + public void write(@SuppressWarnings("NullableProblems") final byte[] b) { + try { + out.write(b); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } @Override - public void write(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) throws IOException { - out.write(b, off, length); + public void write(@SuppressWarnings("NullableProblems") final byte[] b, final int off, final int length) { + try { + out.write(b, off, length); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } } diff --git a/src/main/java/htsjdk/samtools/cram/io/ExposedByteArrayOutputStream.java b/src/main/java/htsjdk/samtools/cram/io/ExposedByteArrayOutputStream.java deleted file mode 100644 index 0bac0dddbc..0000000000 --- a/src/main/java/htsjdk/samtools/cram/io/ExposedByteArrayOutputStream.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * **************************************************************************** - * 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.io; - -import java.io.ByteArrayOutputStream; - -public class ExposedByteArrayOutputStream extends ByteArrayOutputStream { - public byte[] getBuffer() { - return buf; - } -} diff --git a/src/main/java/htsjdk/samtools/cram/io/InputStreamUtils.java b/src/main/java/htsjdk/samtools/cram/io/InputStreamUtils.java index 7a62752dc9..b88d12b9a2 100644 --- a/src/main/java/htsjdk/samtools/cram/io/InputStreamUtils.java +++ b/src/main/java/htsjdk/samtools/cram/io/InputStreamUtils.java @@ -18,9 +18,10 @@ package htsjdk.samtools.cram.io; import htsjdk.samtools.util.IOUtil; +import htsjdk.samtools.util.RuntimeEOFException; +import htsjdk.samtools.util.RuntimeIOException; import java.io.ByteArrayOutputStream; -import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -48,10 +49,9 @@ public static byte[] readFully(final InputStream input) { * @param inputStream the input stream to read from * @param length the number of bytes to read * @return a new byte array containing data from the input stream - * @throws IOException as per java IO contract - * @throws EOFException if there is less than length bytes in the stream + * @throws RuntimeEOFException if there is less than length bytes in the stream */ - public static byte[] readFully(final InputStream inputStream, final int length) throws IOException { + public static byte[] readFully(final InputStream inputStream, final int length) { final byte[] b = new byte[length]; readFully(inputStream, b, 0, length); return b; @@ -65,16 +65,19 @@ public static byte[] readFully(final InputStream inputStream, final int length) * @param b the byte array to read into * @param off offset in the byte array * @param length the number of bytes to read - * @throws IOException as per java IO contract - * @throws EOFException if there is less than length bytes in the stream + * @throws RuntimeEOFException if there is less than length bytes in the stream */ - public static void readFully(final InputStream inputStream, final byte[] b, final int off, final int length) throws IOException { + public static void readFully(final InputStream inputStream, final byte[] b, final int off, final int length) { if (length < 0) throw new IndexOutOfBoundsException(); int n = 0; while (n < length) { - final int count = inputStream.read(b, off + n, length - n); - if (count < 0) throw new EOFException(); - n += count; + try { + final int count = inputStream.read(b, off + n, length - n); + if (count < 0) throw new RuntimeEOFException(); + n += count; + } catch (final IOException e) { + throw new RuntimeIOException(e); + } } } @@ -82,24 +85,27 @@ public static void readFully(final InputStream inputStream, final byte[] b, fina * Skip the specified number of bytes from the {@link InputStream}. * @param in the input stream to skip bytes from * @param length the number of bytes to skip - * @throws IOException as per java IO contract - * @throws EOFException if there is less than length bytes in the stream + * @throws RuntimeEOFException if there is less than length bytes in the stream */ - public static void skipFully(final InputStream in, final long length) throws IOException { + public static void skipFully(final InputStream in, final long length) { long amt = length; while (amt > 0) { - long ret = in.skip(amt); - if (ret == 0) { - // skip may return 0 even if we're not at EOF. Luckily, we can - // use the read() method to figure out if we're at the end. - int b = in.read(); - if (b == -1) { - throw new EOFException( "Premature EOF from inputStream after " + - "skipping " + (length - amt) + " byte(s)."); + try { + long ret = in.skip(amt); + if (ret == 0) { + // skip may return 0 even if we're not at EOF. Luckily, we can + // use the read() method to figure out if we're at the end. + int b = in.read(); + if (b == -1) { + throw new RuntimeEOFException("Premature EOF from inputStream after " + + "skipping " + (length - amt) + " byte(s)."); + } + ret = 1; } - ret = 1; + amt -= ret; + } catch (final IOException e) { + throw new RuntimeIOException(e); } - amt -= ret; } } } diff --git a/src/main/java/htsjdk/samtools/cram/ref/EnaRefService.java b/src/main/java/htsjdk/samtools/cram/ref/EnaRefService.java index 0e121a4181..593900d24d 100644 --- a/src/main/java/htsjdk/samtools/cram/ref/EnaRefService.java +++ b/src/main/java/htsjdk/samtools/cram/ref/EnaRefService.java @@ -19,7 +19,7 @@ public class EnaRefService { private static final int HTTP_CONNECTION_TIMEOUT = 522; private static final int HTTP_MOVED_PERMANENTLY = HttpURLConnection.HTTP_MOVED_PERM; - byte[] getSequence(final String md5) throws GaveUpException { + byte[] getSequence(final String md5) { final int restBetweenTries_ms = 0; final int maxTries = 1; final int timeout_ms = 0; @@ -31,15 +31,14 @@ byte[] getSequence(final String md5) throws GaveUpException { * try downloading the sequence many times before giving up. * * @param md5 MD5 checksum string of the sequence to download - * @param timeoutMs timeout in milliseconds before failing with the {@link EnaRefService.GaveUpException} - * @param maxTries maximum number of tries before failing with the {@link EnaRefService.GaveUpException} + * @param timeoutMs timeout in milliseconds before failing with the {@link GaveUpException} + * @param maxTries maximum number of tries before failing with the {@link GaveUpException} * @param restBetweenTriesMs wait this number of milliseconds before repeating attempt * @return sequence bases or null if there is no sequence with such md5 * @throws GaveUpException if the sequence could not be downloaded within the time/try * limit. */ - byte[] getSequence(final String md5, final long timeoutMs, int maxTries, final long restBetweenTriesMs) throws - GaveUpException { + byte[] getSequence(final String md5, final long timeoutMs, int maxTries, final long restBetweenTriesMs) { if (md5 == null) throw new NullPointerException("Expecting sequence md5 but got null."); if (!md5.matches("[a-z0-9]{32}")) @@ -112,20 +111,4 @@ byte[] getSequence(final String md5, final long timeoutMs, int maxTries, final l throw new GaveUpException(md5); } - public static class GaveUpException extends Exception { - private static final long serialVersionUID = -8997576068346912410L; - private String md5; - - public GaveUpException(final String md5) { - this.setMd5(md5); - } - - public String getMd5() { - return md5; - } - - public void setMd5(final String md5) { - this.md5 = md5; - } - } } diff --git a/src/main/java/htsjdk/samtools/cram/ref/GaveUpException.java b/src/main/java/htsjdk/samtools/cram/ref/GaveUpException.java new file mode 100644 index 0000000000..27cc522b2a --- /dev/null +++ b/src/main/java/htsjdk/samtools/cram/ref/GaveUpException.java @@ -0,0 +1,14 @@ +package htsjdk.samtools.cram.ref; + +public class GaveUpException extends RuntimeException { + private static final long serialVersionUID = -8997576068346912410L; + private final String md5; + + GaveUpException(final String md5) { + this.md5 = md5; + } + + public String getMd5() { + return md5; + } +} diff --git a/src/main/java/htsjdk/samtools/cram/ref/InMemoryReferenceSequenceFile.java b/src/main/java/htsjdk/samtools/cram/ref/InMemoryReferenceSequenceFile.java index 34bfc198b8..0872c6d44e 100644 --- a/src/main/java/htsjdk/samtools/cram/ref/InMemoryReferenceSequenceFile.java +++ b/src/main/java/htsjdk/samtools/cram/ref/InMemoryReferenceSequenceFile.java @@ -59,7 +59,7 @@ public ReferenceSequence getSubsequenceAt(final String name, final long start, f } @Override - public void close() throws IOException { + public void close() { sequences = null; dictionary = null; } diff --git a/src/main/java/htsjdk/samtools/cram/ref/ReferenceSource.java b/src/main/java/htsjdk/samtools/cram/ref/ReferenceSource.java index 1264fee09b..ac6f8ba2dd 100644 --- a/src/main/java/htsjdk/samtools/cram/ref/ReferenceSource.java +++ b/src/main/java/htsjdk/samtools/cram/ref/ReferenceSource.java @@ -24,10 +24,7 @@ import htsjdk.samtools.reference.ReferenceSequence; import htsjdk.samtools.reference.ReferenceSequenceFile; import htsjdk.samtools.reference.ReferenceSequenceFileFactory; -import htsjdk.samtools.util.IOUtil; -import htsjdk.samtools.util.Log; -import htsjdk.samtools.util.SequenceUtil; -import htsjdk.samtools.util.StringUtil; +import htsjdk.samtools.util.*; import java.io.File; import java.io.IOException; @@ -171,11 +168,7 @@ public synchronized byte[] getReferenceBases(final SAMSequenceRecord record, { if (Defaults.USE_CRAM_REF_DOWNLOAD) { // try to fetch sequence by md5: if (md5 != null) { - try { - bases = findBasesByMD5(md5.toLowerCase()); - } catch (final Exception e) { - throw new RuntimeException(e); - } + bases = findBasesByMD5(md5.toLowerCase()); } if (bases != null) { return addToCache(md5, bases); @@ -214,21 +207,18 @@ byte[] findBasesByName(final String name, final boolean tryVariants) { return null; } - byte[] findBasesByMD5(final String md5) throws - IOException { + private byte[] findBasesByMD5(final String md5) { final String url = String.format(Defaults.EBI_REFERENCE_SERVICE_URL_MASK, md5); for (int i = 0; i < downloadTriesBeforeFailing; i++) { - final InputStream is = new URL(url).openStream(); - if (is == null) - return null; + try (final InputStream is = new URL(url).openStream()) { + if (is == null) + return null; - log.debug("Downloading reference sequence: " + url); - final byte[] data = InputStreamUtils.readFully(is); - log.debug("Downloaded " + data.length + " bytes for md5 " + md5); - is.close(); + log.info("Downloading reference sequence: " + url); + final byte[] data = InputStreamUtils.readFully(is); + log.info("Downloaded " + data.length + " bytes for md5 " + md5); - try { final String downloadedMD5 = SequenceUtil.calculateMD5String(data); if (md5.equals(downloadedMD5)) { return data; @@ -238,11 +228,12 @@ byte[] findBasesByMD5(final String md5) throws md5, downloadedMD5); log.error(message); } - } catch (final NoSuchAlgorithmException e) { + } + catch (final NoSuchAlgorithmException | IOException e) { throw new RuntimeException(e); } } - throw new RuntimeException("Giving up on downloading sequence for md5 " + throw new GaveUpException("Giving up on downloading sequence for md5 " + md5); } diff --git a/src/main/java/htsjdk/samtools/cram/structure/CompressionHeader.java b/src/main/java/htsjdk/samtools/cram/structure/CompressionHeader.java index 4607026176..5e9a335aba 100644 --- a/src/main/java/htsjdk/samtools/cram/structure/CompressionHeader.java +++ b/src/main/java/htsjdk/samtools/cram/structure/CompressionHeader.java @@ -114,7 +114,7 @@ public byte[][] getTagIds(final int id) { return dictionary[id]; } - private void internalRead(final InputStream is) throws IOException { + private void internalRead(final InputStream is) { { // preservation map: final int byteSize = ITF8.readUnsignedITF8(is); final byte[] bytes = new byte[byteSize]; diff --git a/src/main/java/htsjdk/samtools/cram/structure/ContainerHeaderIO.java b/src/main/java/htsjdk/samtools/cram/structure/ContainerHeaderIO.java index 7e6e203f13..f74ed330ef 100644 --- a/src/main/java/htsjdk/samtools/cram/structure/ContainerHeaderIO.java +++ b/src/main/java/htsjdk/samtools/cram/structure/ContainerHeaderIO.java @@ -22,6 +22,7 @@ import htsjdk.samtools.cram.io.CramInt; import htsjdk.samtools.cram.io.ITF8; import htsjdk.samtools.cram.io.LTF8; +import htsjdk.samtools.util.RuntimeIOException; import java.io.IOException; import java.io.InputStream; @@ -29,24 +30,26 @@ class ContainerHeaderIO { - public boolean readContainerHeader(final Container container, final InputStream inputStream) - throws IOException { + public boolean readContainerHeader(final Container container, final InputStream inputStream) { return readContainerHeader(2, container, inputStream); } - public boolean readContainerHeader(final int major, final Container container, final InputStream inputStream) - throws IOException { + public boolean readContainerHeader(final int major, final Container container, final InputStream inputStream) { final byte[] peek = new byte[4]; - int character = inputStream.read(); - if (character == -1) - return false; - - peek[0] = (byte) character; - for (int i = 1; i < peek.length; i++) { - character = inputStream.read(); + try { + int character = inputStream.read(); if (character == -1) - throw new RuntimeException("Incomplete or broken stream."); - peek[i] = (byte) character; + return false; + + peek[0] = (byte) character; + for (int i = 1; i < peek.length; i++) { + character = inputStream.read(); + if (character == -1) + throw new RuntimeException("Incomplete or broken stream."); + peek[i] = (byte) character; + } + } catch (final IOException e) { + throw new RuntimeIOException(e); } container.containerByteSize = CramInt.readInt32(peek); @@ -70,10 +73,8 @@ public boolean readContainerHeader(final int major, final Container container, f * @param container container to be written * @param outputStream the output stream to write the container to * @return number of bytes written out to the output stream - * @throws IOException as per java IO contract */ - public int writeContainerHeader(final int major, final Container container, final OutputStream outputStream) - throws IOException { + public int writeContainerHeader(final int major, final Container container, final OutputStream outputStream) { final CRC32OutputStream crc32OutputStream = new CRC32OutputStream(outputStream); int length = (CramInt.writeInt32(container.containerByteSize, crc32OutputStream) + 7) / 8; @@ -87,7 +88,11 @@ public int writeContainerHeader(final int major, final Container container, fina length += (CramIntArray.write(container.landmarks, crc32OutputStream) + 7) / 8; if (major >= 3) { - outputStream.write(crc32OutputStream.getCrc32_LittleEndian()); + try { + outputStream.write(crc32OutputStream.getCrc32_LittleEndian()); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } length += 4 ; } diff --git a/src/main/java/htsjdk/samtools/cram/structure/ContainerIO.java b/src/main/java/htsjdk/samtools/cram/structure/ContainerIO.java index b897e8dd26..6ba8a88ca9 100644 --- a/src/main/java/htsjdk/samtools/cram/structure/ContainerIO.java +++ b/src/main/java/htsjdk/samtools/cram/structure/ContainerIO.java @@ -3,15 +3,12 @@ import htsjdk.samtools.cram.build.CramIO; import htsjdk.samtools.cram.common.CramVersionPolicies; import htsjdk.samtools.cram.common.Version; -import htsjdk.samtools.cram.io.ExposedByteArrayOutputStream; +import htsjdk.samtools.util.Log; import htsjdk.samtools.cram.structure.block.Block; import htsjdk.samtools.cram.structure.block.BlockContentType; -import htsjdk.samtools.util.Log; +import htsjdk.samtools.util.RuntimeIOException; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.util.ArrayList; import java.util.List; @@ -27,9 +24,8 @@ public class ContainerIO { * @param version CRAM version to expect * @param inputStream the stream to read from * @return a new container object read from the stream - * @throws IOException as per java IO contract */ - public static Container readContainer(final Version version, final InputStream inputStream) throws IOException { + public static Container readContainer(final Version version, final InputStream inputStream) { final Container container = readContainer(version.major, inputStream); if (container == null) { // this will cause System.exit(1): @@ -47,9 +43,8 @@ public static Container readContainer(final Version version, final InputStream i * * @param inputStream the stream to read from * @return CRAM container or null if no more data - * @throws IOException */ - private static Container readContainer(final int major, final InputStream inputStream) throws IOException { + private static Container readContainer(final int major, final InputStream inputStream) { return readContainer(major, inputStream, 0, Integer.MAX_VALUE); } @@ -59,9 +54,8 @@ private static Container readContainer(final int major, final InputStream inputS * @param major the CRAM version to assume * @param inputStream the input stream to read from * @return a new {@link Container} object with container header values filled out but empty body (no slices and blocks). - * @throws IOException as per java IO contract */ - public static Container readContainerHeader(final int major, final InputStream inputStream) throws IOException { + public static Container readContainerHeader(final int major, final InputStream inputStream) { final Container container = new Container(); final ContainerHeaderIO containerHeaderIO = new ContainerHeaderIO(); if (!containerHeaderIO.readContainerHeader(major, container, inputStream)) { @@ -72,7 +66,7 @@ public static Container readContainerHeader(final int major, final InputStream i } @SuppressWarnings("SameParameterValue") - private static Container readContainer(final int major, final InputStream inputStream, final int fromSlice, int howManySlices) throws IOException { + private static Container readContainer(final int major, final InputStream inputStream, final int fromSlice, int howManySlices) { final Container container = readContainerHeader(major, inputStream); if (container.isEOF()) { @@ -83,8 +77,12 @@ private static Container readContainer(final int major, final InputStream inputS howManySlices = Math.min(container.landmarks.length, howManySlices); - if (fromSlice > 0) //noinspection ResultOfMethodCallIgnored - inputStream.skip(container.landmarks[fromSlice]); + try { + if (fromSlice > 0) //noinspection ResultOfMethodCallIgnored + inputStream.skip(container.landmarks[fromSlice]); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } final List slices = new ArrayList(); for (int sliceCount = fromSlice; sliceCount < howManySlices - fromSlice; sliceCount++) { @@ -126,9 +124,8 @@ private static void calculateSliceOffsetsAndSizes(final Container container) { * @param container the container holding the header to write * @param outputStream the stream to write to * @return the number of bytes written - * @throws IOException as per java IO contract */ - public static int writeContainerHeader(final int major, final Container container, final OutputStream outputStream) throws IOException { + public static int writeContainerHeader(final int major, final Container container, final OutputStream outputStream) { return new ContainerHeaderIO().writeContainerHeader(major, container, outputStream); } @@ -140,27 +137,30 @@ public static int writeContainerHeader(final int major, final Container containe * @param container the container to write * @param outputStream the stream to write to * @return the number of bytes written out - * @throws IOException as per java IO contract */ - public static int writeContainer(final Version version, final Container container, final OutputStream outputStream) throws IOException { + public static int writeContainer(final Version version, final Container container, final OutputStream outputStream) { { if (container.blocks != null && container.blocks.length > 0) { final Block firstBlock = container.blocks[0]; final boolean isFileHeaderContainer = firstBlock.getContentType() == BlockContentType.FILE_HEADER; if (isFileHeaderContainer) { - final ExposedByteArrayOutputStream byteArrayOutputStream = new ExposedByteArrayOutputStream(); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); firstBlock.write(version.major, byteArrayOutputStream); container.containerByteSize = byteArrayOutputStream.size(); final int containerHeaderByteSize = new ContainerHeaderIO().writeContainerHeader(version.major, container, outputStream); - outputStream.write(byteArrayOutputStream.getBuffer(), 0, byteArrayOutputStream.size()); + try { + outputStream.write(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size()); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } return containerHeaderByteSize + byteArrayOutputStream.size(); } } } - final ExposedByteArrayOutputStream byteArrayOutputStream = new ExposedByteArrayOutputStream(); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); container.header.write(version, byteArrayOutputStream); container.blockCount = 1; @@ -183,7 +183,11 @@ public static int writeContainer(final Version version, final Container containe calculateSliceOffsetsAndSizes(container); int length = new ContainerHeaderIO().writeContainerHeader(version.major, container, outputStream); - outputStream.write(byteArrayOutputStream.getBuffer(), 0, byteArrayOutputStream.size()); + try { + outputStream.write(byteArrayOutputStream.toByteArray(), 0, byteArrayOutputStream.size()); + } catch (final IOException e) { + throw new RuntimeIOException(e); + } length += byteArrayOutputStream.size(); log.debug("CONTAINER WRITTEN: " + container.toString()); diff --git a/src/main/java/htsjdk/samtools/cram/structure/SliceIO.java b/src/main/java/htsjdk/samtools/cram/structure/SliceIO.java index bba4c91aad..d289443691 100644 --- a/src/main/java/htsjdk/samtools/cram/structure/SliceIO.java +++ b/src/main/java/htsjdk/samtools/cram/structure/SliceIO.java @@ -26,6 +26,7 @@ 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; @@ -37,7 +38,7 @@ class SliceIO { private static final Log log = Log.getInstance(SliceIO.class); - private static void readSliceHeader(final int major, final Slice slice, final InputStream readInputStream) throws IOException { + private static void readSliceHeader(final int major, final Slice slice, final InputStream readInputStream) { slice.headerBlock = Block.read(major, readInputStream); if (slice.headerBlock.getContentType() != BlockContentType.MAPPED_SLICE) throw new RuntimeException("Slice Header Block expected, found: " + slice.headerBlock.getContentType().name()); @@ -69,7 +70,7 @@ private static void readSliceHeader(final int major, final Slice slice, final In } } - private static byte[] createSliceHeaderBlockContent(final int major, final Slice slice) throws IOException { + private static byte[] createSliceHeaderBlockContent(final int major, final Slice slice) { final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ITF8.writeUnsignedITF8(slice.sequenceId, byteArrayOutputStream); ITF8.writeUnsignedITF8(slice.alignmentStart, byteArrayOutputStream); @@ -84,7 +85,11 @@ private static byte[] createSliceHeaderBlockContent(final int major, final Slice slice.contentIDs[i++] = id; CramIntArray.write(slice.contentIDs, byteArrayOutputStream); ITF8.writeUnsignedITF8(slice.embeddedRefBlockContentID, byteArrayOutputStream); - byteArrayOutputStream.write(slice.refMD5 == null ? new byte[16] : slice.refMD5); + 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) { @@ -104,7 +109,7 @@ private static byte[] createSliceHeaderBlockContent(final int major, final Slice return byteArrayOutputStream.toByteArray(); } - private static void readSliceBlocks(final int major, final Slice slice, final InputStream inputStream) throws IOException { + 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); @@ -126,7 +131,7 @@ private static void readSliceBlocks(final int major, final Slice slice, final In } } - public static void write(final int major, final Slice slice, final OutputStream outputStream) throws IOException { + public static void write(final int major, final Slice slice, final OutputStream outputStream) { slice.nofBlocks = 1 + slice.external.size() + (slice.embeddedRefBlock == null ? 0 : 1); @@ -145,7 +150,7 @@ public static void write(final int major, final Slice slice, final OutputStream block.write(major, outputStream); } - public static void read(final int major, final Slice slice, final InputStream inputStream) throws IOException { + public static void read(final int major, final Slice slice, final InputStream inputStream) { readSliceHeader(major, slice, inputStream); readSliceBlocks(major, slice, inputStream); } diff --git a/src/test/java/htsjdk/samtools/cram/build/ContainerFactoryTest.java b/src/test/java/htsjdk/samtools/cram/build/ContainerFactoryTest.java index cf4f91e518..c50f056665 100644 --- a/src/test/java/htsjdk/samtools/cram/build/ContainerFactoryTest.java +++ b/src/test/java/htsjdk/samtools/cram/build/ContainerFactoryTest.java @@ -12,7 +12,6 @@ import org.testng.Assert; import org.testng.annotations.Test; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -23,7 +22,7 @@ public class ContainerFactoryTest extends HtsjdkTest { @Test - public void testUnmapped() throws IOException, IllegalAccessException { + public void testUnmapped() { SAMFileHeader header = new SAMFileHeader(); int recordsPerContainer = 10; @@ -49,7 +48,7 @@ public void testUnmapped() throws IOException, IllegalAccessException { } @Test - public void testMapped() throws IOException, IllegalAccessException { + public void testMapped() { InMemoryReferenceSequenceFile refFile = new InMemoryReferenceSequenceFile(); String refName = "1"; String refString = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; @@ -89,7 +88,7 @@ public void testMapped() throws IOException, IllegalAccessException { } @Test - public void testMultiref() throws IOException, IllegalAccessException { + public void testMultiref() { SAMFileHeader header = new SAMFileHeader(); header.addSequence(new SAMSequenceRecord("1", 100)); header.addSequence(new SAMSequenceRecord("2", 200)); diff --git a/src/test/java/htsjdk/samtools/cram/build/ContainerParserTest.java b/src/test/java/htsjdk/samtools/cram/build/ContainerParserTest.java index b16dc0f15e..91e087cac0 100644 --- a/src/test/java/htsjdk/samtools/cram/build/ContainerParserTest.java +++ b/src/test/java/htsjdk/samtools/cram/build/ContainerParserTest.java @@ -28,7 +28,7 @@ public class ContainerParserTest extends HtsjdkTest { @Test - public void testEOF() throws IOException, IllegalAccessException { + public void testEOF() throws IOException { ContainerParser parser = new ContainerParser(new SAMFileHeader()); ByteArrayOutputStream v2_baos = new ByteArrayOutputStream(); Version version = CramVersions.CRAM_v2_1; @@ -46,7 +46,7 @@ public void testEOF() throws IOException, IllegalAccessException { } @Test - public void testSingleRefContainer() throws IOException, IllegalAccessException { + public void testSingleRefContainer() throws IOException { SAMFileHeader samFileHeader = new SAMFileHeader(); ContainerFactory factory = new ContainerFactory(samFileHeader, 10); List records = new ArrayList<>(); @@ -75,7 +75,7 @@ public void testSingleRefContainer() throws IOException, IllegalAccessException } @Test - public void testUnmappedContainer() throws IOException, IllegalAccessException { + public void testUnmappedContainer() throws IOException { SAMFileHeader samFileHeader = new SAMFileHeader(); ContainerFactory factory = new ContainerFactory(samFileHeader, 10); List records = new ArrayList<>(); @@ -104,7 +104,7 @@ public void testUnmappedContainer() throws IOException, IllegalAccessException { } @Test - public void testMappedAndUnmappedContainer() throws IOException, IllegalAccessException { + public void testMappedAndUnmappedContainer() throws IOException { SAMFileHeader samFileHeader = new SAMFileHeader(); ContainerFactory factory = new ContainerFactory(samFileHeader, 10); List records = new ArrayList<>(); @@ -142,7 +142,7 @@ public void testMappedAndUnmappedContainer() throws IOException, IllegalAccessEx } @Test - public void testMultirefContainer() throws IOException, IllegalAccessException { + public void testMultirefContainer() throws IOException { SAMFileHeader samFileHeader = new SAMFileHeader(); ContainerFactory factory = new ContainerFactory(samFileHeader, 10); List records = new ArrayList<>(); diff --git a/src/test/java/htsjdk/samtools/cram/io/InputStreamUtilsTest.java b/src/test/java/htsjdk/samtools/cram/io/InputStreamUtilsTest.java index 8f96bc6e15..7c8e8b8c5a 100644 --- a/src/test/java/htsjdk/samtools/cram/io/InputStreamUtilsTest.java +++ b/src/test/java/htsjdk/samtools/cram/io/InputStreamUtilsTest.java @@ -1,12 +1,12 @@ package htsjdk.samtools.cram.io; import htsjdk.HtsjdkTest; +import htsjdk.samtools.util.RuntimeEOFException; import org.testng.Assert; import org.testng.annotations.Test; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; -import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -23,8 +23,8 @@ public void testSkipFully() throws IOException { Assert.assertEquals(in.read(), -1); // EOF } - @Test(expectedExceptions = EOFException.class) - public void testSkipFullyPastEOF() throws IOException { + @Test(expectedExceptions = RuntimeEOFException.class) + public void testSkipFullyPastEOF() { byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; InputStream in = new BufferedInputStream(new ByteArrayInputStream(data), 4); InputStreamUtils.skipFully(in, 10); diff --git a/src/test/java/htsjdk/samtools/cram/ref/EnaRefServiceTest.java b/src/test/java/htsjdk/samtools/cram/ref/EnaRefServiceTest.java index 945aa0850c..ce505f485b 100644 --- a/src/test/java/htsjdk/samtools/cram/ref/EnaRefServiceTest.java +++ b/src/test/java/htsjdk/samtools/cram/ref/EnaRefServiceTest.java @@ -16,7 +16,7 @@ public Object[][] testEnaRefServiceData(){ } @Test(dataProvider = "testEnaRefServiceData") - public void testEnaRefServiceData(final String md5) throws IOException, EnaRefService.GaveUpException { + public void testEnaRefServiceData(final String md5) throws IOException, GaveUpException { Assert.assertNotNull(new EnaRefService().getSequence(md5)); } }