package com.ripple.core.serialized;
import java.io.*;
import java.util.zip.GZIPInputStream;
public class StreamBinaryParser extends BinaryParser {
final BufferedInputStream stream;
public StreamBinaryParser(InputStream stream, long size) {
super((int) size);
this.stream = new BufferedInputStream(stream);
}
private static boolean isGZip(File fio) {
return fio.getName().endsWith("gz");
}
private static int getUncompressedSize(File fio) {
if (isGZip(fio)) {
int val;
try {
RandomAccessFile raf = new RandomAccessFile(fio, "r");
raf.seek(raf.length() - 4);
int b4 = raf.read();
int b3 = raf.read();
int b2 = raf.read();
int b1 = raf.read();
val = (b1 << 24) | (b2 << 16) + (b3 << 8) + b4;
raf.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return val;
} else {
return (int) fio.length();
}
}
public void skip(int n) {
try {
long skipped = stream.skip(n);
if (skipped != n) {
throw new RuntimeException("Expected to skip more bytes");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public byte readOne() {
return read(1)[0];
}
public byte[] read(int n) {
byte[] ret = new byte[n];
try {
int read = stream.read(ret);
if (read != n) {
throw new RuntimeException("Expected to read more bytes");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
cursor += n;
return ret;
}
public static StreamBinaryParser fromFile(String path) {
try {
File f = new File(path);
FileInputStream fstream = new FileInputStream(path);
InputStream stream = fstream;
long s = fstream.getChannel().size();
if (isGZip(f)) {
s = getUncompressedSize(f);
stream = new GZIPInputStream(fstream);
}
return new StreamBinaryParser(stream, s);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}