package htsjdk.samtools.cram.encoding.reader;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
public class FastqView {
private int NAME = -1;
private int BASES = -1;
private int SCORES = -1;
private byte[] buf;
private ByteBuffer bb;
public int start, length;
public int readLen;
public int[] index;
public int[] nameLength;
public int readCount;
public FastqView(byte[] buf, int from, int to) {
this.buf = buf;
start = from;
bb = ByteBuffer.wrap(buf);
bb.position(start);
bb.limit(to);
}
public void setReadName(byte[] name, int from, int len) {
System.arraycopy(name, from, buf, start + NAME, len);
buf[start + NAME + len] = '\n';
BASES = NAME + len + 1;
}
public void setBases(byte[] bases, int from, int len) {
if (BASES < 1)
throw new RuntimeException("BASES not set.");
readLen = len;
System.arraycopy(bases, from, buf, start + BASES, len);
buf[start + BASES + len] = '\n';
buf[start + BASES + len + 1] = '+';
buf[start + BASES + len + 2] = '\n';
SCORES = BASES + len + 3;
}
public void setScores(byte[] scores, int from, int len) {
if (readLen != len || SCORES < 1)
throw new RuntimeException("BASES not set.");
System.arraycopy(scores, from, buf, start + BASES, len);
buf[start + BASES + len] = '\n';
}
public void finish() {
start += SCORES + readLen + 1;
NAME = -1;
BASES = -1;
SCORES = -1;
}
public static int estimateNumberOfReads(int maxReadsToAnalyze, byte[] buf, int start, int length) {
int readCount = 0;
int newLineCounter = 0;
int line = 0;
float nameLength = 0;
float readLength = 0;
for (int i = start; i < start + length || readCount < maxReadsToAnalyze; i++) {
if (buf[start] == '\n') {
switch (newLineCounter % 4) {
case 0:
nameLength += line;
break;
case 1:
readLength += line;
readCount++;
i += 2 * line + 3;
newLineCounter += 3;
break;
default:
throw new RuntimeException("Bad implementation, should have never happened.");
}
line = 0;
} else
line++;
}
float avgReadBytes = nameLength / readCount + 2 * readLength + 4;
return (int) (0.5 + length / avgReadBytes);
}
public static int detectNumberOfReads(byte[] buf, int start, int length) {
int readCount = 0;
int newLineCounter = 0;
for (int i = start; i < start + length; i++) {
if (buf[start] == '\n') {
switch (newLineCounter) {
case 4:
newLineCounter = 0;
readCount++;
break;
default:
newLineCounter++;
break;
}
}
}
return readCount;
}
public static int buildIndex(int[] index, int[] nameLength, byte[] buf, int start, int length) {
int readCount = 0;
index[readCount++] = start;
int newLineCounter = 0;
int line = 0;
for (int i = start; i < start + length; i++) {
if (buf[start] == '\n') {
switch (newLineCounter) {
case 0:
nameLength[readCount] = line;
break;
case 4:
index[readCount] = i;
newLineCounter = 0;
readCount++;
break;
default:
newLineCounter++;
break;
}
line = 0;
} else
line++;
}
return readCount;
}
public static int readOffset(int read, LongBuffer buf) {
long entry = buf.get(read);
return (int) (0xFFFFFFFF & (entry >>> (8 * 5)));
}
public static int readNameLength(int read, LongBuffer buf) {
long entry = buf.get(read);
return (int) (0x0000FFFF & (entry >> (8 * 3)));
}
public static int readLength(int read, LongBuffer buf) {
long entry = buf.get(read);
return (int) (0x00FFFFFF & entry);
}
// private static class IndexComparator implements Comparator<T>
public static void main(String[] args) {
ByteBuffer buf = ByteBuffer.allocate(8);
buf.put(new byte[] { 0, 0, 1, 0, 2, 0, 0, 3 });
buf.rewind();
System.out.println(readOffset(0, buf.asLongBuffer()));
buf.rewind();
System.out.println(readNameLength(0, buf.asLongBuffer()));
buf.rewind();
System.out.println(readLength(0, buf.asLongBuffer()));
}
}