package org.smoothbuild.db.hashed;
import java.io.IOException;
import java.io.InputStream;
import com.google.common.hash.HashCode;
import com.google.common.primitives.Ints;
public class Unmarshaller extends InputStream {
private final HashCode hash;
private final InputStream inputStream;
public Unmarshaller(HashCode hash, InputStream inputStream) {
this.hash = hash;
this.inputStream = inputStream;
}
public HashCode readHash() {
return readHash(false);
}
public HashCode tryReadHash() {
return readHash(true);
}
public int read() throws IOException {
return inputStream.read();
}
public int read(byte b[], int off, int len) throws IOException {
return inputStream.read(b, off, len);
}
public int read(byte b[]) throws IOException {
return inputStream.read(b);
}
private HashCode readHash(boolean allowNull) {
byte[] bytes = readBytes(Hash.size(), "hash", allowNull);
if (bytes == null && allowNull) {
return null;
}
return HashCode.fromBytes(bytes);
}
public int readInt() {
byte[] bytes = readBytes(4, "int", false);
return Ints.fromByteArray(bytes);
}
private byte[] readBytes(int size, String valueName, boolean allowNull) {
try {
byte[] bytes = new byte[size];
int read = inputStream.read(bytes);
if (read < size) {
if (read == -1 && allowNull) {
return null;
} else {
read = Math.max(0, read);
throw new HashedDbException("Corrupted " + hash + " object. Value " + valueName
+ " has expected size = " + size + " but only " + read + " is available.");
}
}
return bytes;
} catch (IOException e) {
throw new HashedDbException("IO error occurred while reading " + hash + " object.");
}
}
public void close() {
try {
inputStream.close();
} catch (IOException e) {
throw new HashedDbException("IO error occurred while reading " + hash + " object.");
}
}
}