Package net.sf.cram.structure

Source Code of net.sf.cram.structure.CompressionHeader

package net.sf.cram.structure;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import net.sf.cram.EncodingID;
import net.sf.cram.EncodingKey;
import net.sf.cram.EncodingParams;
import net.sf.cram.encoding.NullEncoding;
import net.sf.cram.io.ByteBufferUtils;
import net.sf.picard.util.Log;

public class CompressionHeader {
  private static Log log = Log.getInstance(CompressionHeader.class);

  public boolean readNamesIncluded;
  public boolean AP_seriesDelta=true;

  public Map<EncodingKey, EncodingParams> eMap;
  public Map<Integer, EncodingParams> tMap;

  public SubstitutionMatrix substitutionMatrix ;

  public List<Integer> externalIds;

  public byte[][][] dictionary;

  public CompressionHeader() {
  }

  public CompressionHeader(InputStream is) throws IOException {
    read(is);
  }

  private byte[][][] parseDictionary(byte[] bytes) {
    List<List<byte[]>> dictionary = new ArrayList<List<byte[]>>();
    {
      int i = 0;
      while (i < bytes.length) {
        List<byte[]> list = new ArrayList<byte[]>();
        while (bytes[i] != 0) {
          list.add(Arrays.copyOfRange(bytes, i, i + 3));
          i += 3;
        }
        i++;
        dictionary.add(list);
      }
    }

    int maxWidth = 0;
    for (List<byte[]> list : dictionary)
      maxWidth = Math.max(maxWidth, list.size());

    byte[][][] array = new byte[dictionary.size()][][];
    for (int i = 0; i < dictionary.size(); i++) {
      List<byte[]> list = dictionary.get(i);
      array[i] = (byte[][]) list.toArray(new byte[list.size()][]);
    }

    return array;
  }

  private byte[] dictionaryToByteArray() {
    int size = 0;
    for (int i = 0; i < dictionary.length; i++) {
      for (int j = 0; j < dictionary[i].length; j++)
        size += dictionary[i][j].length;
      size++;
    }

    byte[] bytes = new byte[size];
    ByteBuffer buf = ByteBuffer.wrap(bytes);
    for (int i = 0; i < dictionary.length; i++) {
      for (int j = 0; j < dictionary[i].length; j++)
        buf.put(dictionary[i][j]);
      buf.put((byte) 0);
    }

    return bytes;
  }

  public byte[][] getTagIds(int id) {
    return dictionary[id];
  }

  public void read(byte[] data) {
    ByteArrayInputStream bais = new ByteArrayInputStream(data);
    try {
      read(bais);
    } catch (IOException e) {
      throw new RuntimeException("This should have never happened.");
    }
  }

  public void read(InputStream is) throws IOException {
    { // preservation map:
      int byteSize = ByteBufferUtils.readUnsignedITF8(is);
      byte[] bytes = new byte[byteSize];
      ByteBufferUtils.readFully(bytes, is);
      ByteBuffer buf = ByteBuffer.wrap(bytes);

      int mapSize = ByteBufferUtils.readUnsignedITF8(buf);
      for (int i = 0; i < mapSize; i++) {
        String key = new String(new byte[] { buf.get(), buf.get() });
        if ("RN".equals(key))
          readNamesIncluded = buf.get() == 1 ? true : false;
        else if ("AP".equals(key))
          AP_seriesDelta = buf.get() == 1 ? true : false;
        else if ("TD".equals(key)) {
          int size = ByteBufferUtils.readUnsignedITF8(buf);
          byte[] dictionaryBytes = new byte[size];
          buf.get(dictionaryBytes);
          dictionary = parseDictionary(dictionaryBytes);
        } else if ("SM".equals(key)) {
          // parse subs matrix here:
          byte[] matrixBytes = new byte[5] ;
          buf.get(matrixBytes);
          substitutionMatrix = new SubstitutionMatrix(matrixBytes) ;
        } else
          throw new RuntimeException("Unknown preservation map key: "
              + key);
      }
    }

    { // encoding map:
      int byteSize = ByteBufferUtils.readUnsignedITF8(is);
      byte[] bytes = new byte[byteSize];
      ByteBufferUtils.readFully(bytes, is);
      ByteBuffer buf = ByteBuffer.wrap(bytes);

      int mapSize = ByteBufferUtils.readUnsignedITF8(buf);
      eMap = new TreeMap<EncodingKey, EncodingParams>();
      for (EncodingKey key : EncodingKey.values())
        eMap.put(key, NullEncoding.toParam());

      for (int i = 0; i < mapSize; i++) {
        String key = new String(new byte[] { buf.get(), buf.get() });
        EncodingKey eKey = EncodingKey.byFirstTwoChars(key);
        if (eKey == null)
          throw new RuntimeException("Unknown encoding key: " + key);

        EncodingID id = EncodingID.values()[buf.get()];
        int paramLen = ByteBufferUtils.readUnsignedITF8(buf);
        byte[] paramBytes = new byte[paramLen];
        buf.get(paramBytes);

        eMap.put(eKey, new EncodingParams(id, paramBytes));

        log.debug(String.format("FOUND ENCODING: %s, %s, %s.",
            eKey.name(), id.name(),
            Arrays.toString(Arrays.copyOf(paramBytes, 20))));
      }
    }

    { // tag encoding map:
      int byteSize = ByteBufferUtils.readUnsignedITF8(is);
      byte[] bytes = new byte[byteSize];
      ByteBufferUtils.readFully(bytes, is);
      ByteBuffer buf = ByteBuffer.wrap(bytes);

      int mapSize = ByteBufferUtils.readUnsignedITF8(buf);
      tMap = new TreeMap<Integer, EncodingParams>();
      for (int i = 0; i < mapSize; i++) {
        int key = ByteBufferUtils.readUnsignedITF8(buf);

        EncodingID id = EncodingID.values()[buf.get()];
        int paramLen = ByteBufferUtils.readUnsignedITF8(buf);
        byte[] paramBytes = new byte[paramLen];
        buf.get(paramBytes);

        tMap.put(key, new EncodingParams(id, paramBytes));
      }
    }
  }

  public byte[] toByteArray() throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    write(baos);
    return baos.toByteArray();
  }

  public void write(OutputStream os) throws IOException {

    { // preservation map:
      ByteBuffer mapBuf = ByteBuffer.allocate(1024 * 100);
      ByteBufferUtils.writeUnsignedITF8(4, mapBuf);

      mapBuf.put("RN".getBytes());
      mapBuf.put((byte) (readNamesIncluded ? 1 : 0));

      mapBuf.put("AP".getBytes());
      mapBuf.put((byte) (AP_seriesDelta ? 1 : 0));

      mapBuf.put("SM".getBytes());
      mapBuf.put(substitutionMatrix.getEncodedMatrix());

      mapBuf.put("TD".getBytes());
      {

        byte[] dBytes = dictionaryToByteArray();
        ByteBufferUtils.writeUnsignedITF8(dBytes.length, mapBuf);
        mapBuf.put(dBytes);
      }

      mapBuf.flip();
      byte[] mapBytes = new byte[mapBuf.limit()];
      mapBuf.get(mapBytes);

      ByteBufferUtils.writeUnsignedITF8(mapBytes.length, os);
      os.write(mapBytes);
    }

    { // encoding map:
      int size = 0;
      for (EncodingKey eKey : eMap.keySet()) {
        if (eMap.get(eKey).id != EncodingID.NULL)
          size++;
      }

      ByteBuffer mapBuf = ByteBuffer.allocate(1024 * 100);
      ByteBufferUtils.writeUnsignedITF8(size, mapBuf);
      for (EncodingKey eKey : eMap.keySet()) {
        if (eMap.get(eKey).id == EncodingID.NULL)
          continue;

        mapBuf.put((byte) eKey.name().charAt(0));
        mapBuf.put((byte) eKey.name().charAt(1));

        EncodingParams params = eMap.get(eKey);
        mapBuf.put((byte) (0xFF & params.id.ordinal()));
        ByteBufferUtils.writeUnsignedITF8(params.params.length, mapBuf);
        mapBuf.put(params.params);
      }
      mapBuf.flip();
      byte[] mapBytes = new byte[mapBuf.limit()];
      mapBuf.get(mapBytes);

      ByteBufferUtils.writeUnsignedITF8(mapBytes.length, os);
      os.write(mapBytes);
    }

    { // tag encoding map:
      ByteBuffer mapBuf = ByteBuffer.allocate(1024 * 100);
      ByteBufferUtils.writeUnsignedITF8(tMap.size(), mapBuf);
      for (Integer eKey : tMap.keySet()) {
        ByteBufferUtils.writeUnsignedITF8(eKey, mapBuf);

        EncodingParams params = tMap.get(eKey);
        mapBuf.put((byte) (0xFF & params.id.ordinal()));
        ByteBufferUtils.writeUnsignedITF8(params.params.length, mapBuf);
        mapBuf.put(params.params);
      }
      mapBuf.flip();
      byte[] mapBytes = new byte[mapBuf.limit()];
      mapBuf.get(mapBytes);

      ByteBufferUtils.writeUnsignedITF8(mapBytes.length, os);
      os.write(mapBytes);
    }
  }

}
TOP

Related Classes of net.sf.cram.structure.CompressionHeader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.