package com.beijunyi.parallelgit.utils.io;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.eclipse.jgit.lib.*;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
public class BlobSnapshot extends ObjectSnapshot<byte[]> {
private final ObjectReader reader;
private BlobSnapshot(ObjectReader reader, @Nullable ObjectId id) {
super(null, id);
this.reader = reader;
}
private BlobSnapshot(ObjectReader reader) {
this(null, null);
}
private BlobSnapshot(byte[] data) {
super(data, null);
reader = null;
}
@Nonnull
@Override
public byte[] getData() throws IOException {
if (data == null) {
loadData();
}
return data;
}
private void loadData() throws IOException {
synchronized (reader) {
ObjectLoader loader = reader.open(id);
if (loader.getSize() > Integer.MAX_VALUE - 8) {
throw new IOException("Can't load object" + id + ": size is greater than can fit in a Java array");
}
int len = (int) loader.getSize();
data = new byte[len];
int offset = 0;
while (offset < len) {
int bytesRead = loader.openStream().read(data, offset, len - offset);
if (bytesRead <= 0) {
throw new IOException("Unexpected EOF reading " + id);
}
offset += bytesRead;
}
}
}
@Nonnull
public static BlobSnapshot load(ObjectId id, ObjectReader reader) throws IOException {
return new BlobSnapshot(reader, id);
}
@Nonnull
public static BlobSnapshot load(ObjectId id, Repository repo) throws IOException {
try(ObjectReader reader = repo.newObjectReader()) {
return load(id, reader);
}
}
@Nonnull
public static BlobSnapshot capture(byte[] bytes) {
return new BlobSnapshot(bytes);
}
@Nonnull
@Override
public ObjectId save(ObjectInserter inserter) throws IOException {
return inserter.insert(OBJ_BLOB, getData());
}
@Override
protected int getType() {
return OBJ_BLOB;
}
@Nonnull
@Override
protected byte[] toByteArray(byte[] bytes) {
return bytes;
}
public InputStream getInputStream() throws IOException {
synchronized (reader) {
return reader.open(id).openStream();
}
}
}