private final ArrayList<String> parseDictionary(final VCFHeader header) { final ArrayList<String> dict = BCF2Utils.makeDictionary(header); // if we got here we never found a dictionary, or there are no elements in the dictionary if ( dict.isEmpty() ) error("Dictionary header element was absent or empty"); return dict; }
/** * Recode the incoming object to a String, compacting it into a * BCF2 string if the value is a list. * * @param value a String or List<String> to encode, or null * @return a non-null string to encode */ private String javaStringToBCF2String(final Object value) { if ( value == null ) return ""; else if (value instanceof List) { final List<String> l = (List<String>)value; return BCF2Utils.collapseStringList(l); } else if ( value.getClass().isArray() ) { final List<String> l = new ArrayList<String>(); Collections.addAll(l, (String[])value); return BCF2Utils.collapseStringList(l); } else return (String)value; } }
@Override public BCF2Type getDynamicType(final Object value) { return value == null ? BCF2Type.INT8 : BCF2Utils.determineIntegerType((int[])value); }
@Override public BCF2Type getDynamicType(final Object value) { return value == null ? BCF2Type.INT8 : BCF2Utils.determineIntegerType(BCF2Utils.toList(Integer.class, value)); }
private final Object decodeLiteralString(final int size) { assert size > 0; // TODO -- assumes size > 0 final byte[] bytes = new byte[size]; // TODO -- in principle should just grab bytes from underlying array try { recordStream.read(bytes); int goodLength = 0; for ( ; goodLength < bytes.length ; goodLength++ ) if ( bytes[goodLength] == 0 ) break; if ( goodLength == 0 ) return null; else { final String s = new String(bytes, 0, goodLength); return BCF2Utils.isCollapsedString(s) ? BCF2Utils.explodeStringList(s) : s; } } catch ( IOException e ) { throw new TribbleException("readByte failure", e); } }
public final int decodeNumberOfElements(final byte typeDescriptor) throws IOException { if ( BCF2Utils.sizeIsOverflow(typeDescriptor) ) // -1 ensures we explode immediately with a bad size if the result is missing return decodeInt(readTypeDescriptor(), -1); else // the size is inline, so just decode it return BCF2Utils.decodeSize(typeDescriptor); }
@Test(dataProvider = "CollapseExpandTest") public void testCollapseExpandTest(final List<String> in, final String expectedCollapsed, final boolean isCollapsed) { final String actualCollapsed = BCF2Utils.collapseStringList(in); Assert.assertEquals(actualCollapsed, expectedCollapsed); Assert.assertEquals(BCF2Utils.isCollapsedString(actualCollapsed), isCollapsed); if ( isCollapsed ) Assert.assertEquals(BCF2Utils.explodeStringList(actualCollapsed), in); }
public final int[] decodeIntArray(final byte typeDescriptor, final int size) throws IOException { final BCF2Type type = BCF2Utils.decodeType(typeDescriptor); return decodeIntArray(size, type, null); }
@Test(dataProvider = "ListOfStrings") public void testEncodingListOfString(List<String> strings, String expected) throws IOException { final String collapsed = BCF2Utils.collapseStringList(strings); Assert.assertEquals(collapsed, expected); Assert.assertEquals(BCF2Utils.explodeStringList(collapsed), strings); }
@Override public void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type, final int minValues) throws IOException { int count = 0; for ( final Integer i : BCF2Utils.toList(Integer.class, value) ) { if ( i != null ) { // necessary because .,. => [null, null] in VC encoder.encodeRawInt(i, type); count++; } } for ( ; count < minValues; count++ ) encoder.encodeRawMissingValue(type); } }
public final void encodeType(final int size, final BCF2Type type) throws IOException { if ( size <= BCF2Utils.MAX_INLINE_ELEMENTS ) { final int typeByte = BCF2Utils.encodeTypeDescriptor(size, type); encodeStream.write(typeByte); } else { final int typeByte = BCF2Utils.encodeTypeDescriptor(BCF2Utils.OVERFLOW_ELEMENT_MARKER, type); encodeStream.write(typeByte); // write in the overflow size encodeTypedInt(size); } }
/** * Can we safely write on the raw (undecoded) genotypes of an input VC? * * The cache depends on the undecoded lazy data header == lastVCFHeaderOfUnparsedGenotypes, in * which case we return the previous result. If it's not cached, we use the BCF2Util to * compare the VC header with our header (expensive) and cache it. * * @param lazyData * @return */ private boolean canSafelyWriteRawGenotypesBytes(final BCF2Codec.LazyData lazyData) { if ( lazyData.header != lastVCFHeaderOfUnparsedGenotypes ) { // result is already cached canPassOnUnparsedGenotypeDataForLastVCFHeader = BCF2Utils.headerLinesAreOrderedConsistently(this.header,lazyData.header); lastVCFHeaderOfUnparsedGenotypes = lazyData.header; } return canPassOnUnparsedGenotypeDataForLastVCFHeader; }
/** * Inverse operation of collapseStringList. * * ",s1,s2,s3" => ["s1", "s2", "s3"] * * * @param collapsed * @return */ public static List<String> explodeStringList(final String collapsed) { assert isCollapsedString(collapsed); final String[] exploded = collapsed.substring(1).split(","); return Arrays.asList(exploded); }
public static boolean sizeIsOverflow(final byte typeDescriptor) { return decodeSize(typeDescriptor) == OVERFLOW_ELEMENT_MARKER; }
@Override public BCF2Type getDynamicType(final Object value) { return value == null ? BCF2Type.INT8 : BCF2Utils.determineIntegerType(BCF2Utils.toList(Integer.class, value)); }
private final Object decodeLiteralString(final int size) { assert size > 0; // TODO -- assumes size > 0 final byte[] bytes = new byte[size]; // TODO -- in principle should just grab bytes from underlying array try { recordStream.read(bytes); int goodLength = 0; for ( ; goodLength < bytes.length ; goodLength++ ) if ( bytes[goodLength] == 0 ) break; if ( goodLength == 0 ) return null; else { final String s = new String(bytes, 0, goodLength); return BCF2Utils.isCollapsedString(s) ? BCF2Utils.explodeStringList(s) : s; } } catch ( IOException e ) { throw new TribbleException("readByte failure", e); } }
public final int[] decodeIntArray(final byte typeDescriptor, final int size) throws IOException { final BCF2Type type = BCF2Utils.decodeType(typeDescriptor); return decodeIntArray(size, type, null); }
public final int decodeNumberOfElements(final byte typeDescriptor) throws IOException { if ( BCF2Utils.sizeIsOverflow(typeDescriptor) ) // -1 ensures we explode immediately with a bad size if the result is missing return decodeInt(readTypeDescriptor(), -1); else // the size is inline, so just decode it return BCF2Utils.decodeSize(typeDescriptor); }
@Override public void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type, final int minValues) throws IOException { int count = 0; for ( final Integer i : BCF2Utils.toList(Integer.class, value) ) { if ( i != null ) { // necessary because .,. => [null, null] in VC encoder.encodeRawInt(i, type); count++; } } for ( ; count < minValues; count++ ) encoder.encodeRawMissingValue(type); } }
public final void encodeType(final int size, final BCF2Type type) throws IOException { if ( size <= BCF2Utils.MAX_INLINE_ELEMENTS ) { final int typeByte = BCF2Utils.encodeTypeDescriptor(size, type); encodeStream.write(typeByte); } else { final int typeByte = BCF2Utils.encodeTypeDescriptor(BCF2Utils.OVERFLOW_ELEMENT_MARKER, type); encodeStream.write(typeByte); // write in the overflow size encodeTypedInt(size); } }