Skip to content

Commit

Permalink
fix for unsigned int in CRAM tags, issue #322
Browse files Browse the repository at this point in the history
  • Loading branch information
vadimzalunin committed Oct 23, 2015
1 parent 7ae8940 commit 0b259ff
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/java/htsjdk/samtools/SAMRecord.java
Expand Up @@ -1203,7 +1203,7 @@ protected void setAttribute(final short tag, final Object value) {

protected void setAttribute(final short tag, final Object value, final boolean isUnsignedArray) {
if (value != null &&
!(value instanceof Byte || value instanceof Short || value instanceof Integer ||
!(value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long ||
value instanceof String || value instanceof Character || value instanceof Float ||
value instanceof byte[] || value instanceof short[] || value instanceof int[] ||
value instanceof float[])) {
Expand Down
9 changes: 3 additions & 6 deletions src/java/htsjdk/samtools/cram/structure/ReadTag.java
Expand Up @@ -21,6 +21,8 @@
import htsjdk.samtools.SAMFormatException;
import htsjdk.samtools.SAMRecord.SAMTagAndValue;
import htsjdk.samtools.SAMTagUtil;
import htsjdk.samtools.SAMUtils;
import htsjdk.samtools.SAMValidationError;
import htsjdk.samtools.TagValueAndUnsignedArrayFlag;
import htsjdk.samtools.util.StringUtil;

Expand Down Expand Up @@ -372,12 +374,7 @@ public static Object readSingleValue(final byte tagType,
case 'A':
return (char) byteBuffer.get();
case 'I':
final long val = byteBuffer.getInt() & 0xffffffffL;
if (val <= Integer.MAX_VALUE) {
return (int) val;
}
throw new RuntimeException(
"Tag value is too large to store as signed integer.");
return byteBuffer.getInt() & 0xffffffffL;
case 'i':
return byteBuffer.getInt();
case 's':
Expand Down
16 changes: 4 additions & 12 deletions src/tests/java/htsjdk/samtools/SAMIntegerTagTest.java
Expand Up @@ -68,22 +68,14 @@ public void testSAM() throws Exception {
Assert.assertEquals(((Number) rec.getAttribute(INTEGER_TAG)).intValue(), 1);
}

@Test(expectedExceptions = SAMException.class)
@Test
public void testUnsignedIntegerBAM() throws Exception {
SAMRecord rec = createSamRecord();
final long val = 1l + Integer.MAX_VALUE;
rec.setAttribute(UNSIGNED_INTEGER_TAG, val);
Assert.fail("Exception should have been thrown.");
}

/**
* Cannot store unsigned int in SAM text format.
*/
@Test(expectedExceptions = SAMException.class)
public void testUnsignedIntegerSAM() throws Exception {
final SAMRecord rec = createSamRecord();
final long val = 1l + Integer.MAX_VALUE;
rec.setAttribute(UNSIGNED_INTEGER_TAG, val);
Object roundTripValue = rec.getAttribute(UNSIGNED_INTEGER_TAG);
Assert.assertTrue(roundTripValue instanceof Long);
Assert.assertEquals(roundTripValue, val);
}

@Test
Expand Down
12 changes: 12 additions & 0 deletions src/tests/java/htsjdk/samtools/cram/structure/ReadTagTest.java
Expand Up @@ -71,6 +71,18 @@ public void test () {
Assert.assertEquals((byte[]) value, baValue);
}

@Test
public void testUnsignedInt() {
long intValue = Integer.MAX_VALUE+1L;
byte[] data = ReadTag.writeSingleValue((byte) 'I', intValue, false);
ByteBuffer byteBuffer = ByteBuffer.wrap(data);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
Object value = ReadTag.readSingleValue((byte) 'I', byteBuffer);
Assert.assertTrue(value instanceof Long);
long lValue = (Long)value;
Assert.assertEquals (lValue & 0xFFFFFFFF, intValue);
}

@Test
public void testParallelReadTag() throws Exception {
// NOTE: testng 5.5 (circa 2007) doesn't support parallel data providers, but modern versions do.
Expand Down

0 comments on commit 0b259ff

Please sign in to comment.