gitg/libgitg/gitg-diff-view-file-info.vala

104 lines
2.2 KiB
Vala

class Gitg.DiffViewFileInfo : Object
{
public Ggit.DiffDelta delta { get; construct set; }
public bool from_workdir { get; construct set; }
public Repository repository { get; construct set; }
public InputStream? new_file_input_stream { get; set; }
public string? new_file_content_type { get; private set; }
public DiffViewFileInfo(Repository repository, Ggit.DiffDelta delta, bool from_workdir)
{
Object(repository: repository, delta: delta, from_workdir: from_workdir);
}
public async void query(Cancellable? cancellable)
{
yield query_content(cancellable);
}
private async void query_content(Cancellable? cancellable)
{
var file = delta.get_new_file();
var id = file.get_oid();
var path = file.get_path();
if ((id.is_zero() && !from_workdir) || (path == null && from_workdir))
{
return;
}
var location = repository.get_workdir().get_child(path);
if (!from_workdir)
{
Ggit.Blob blob;
try
{
blob = repository.lookup<Ggit.Blob>(id);
}
catch (Error e)
{
return;
}
var bytes = new Bytes(blob.get_raw_content());
new_file_input_stream = new GLib.MemoryInputStream.from_bytes(bytes);
}
else
{
// Try to read from disk
try
{
new_file_input_stream = yield location.read_async(Priority.DEFAULT, cancellable);
}
catch
{
return;
}
}
var seekable = new_file_input_stream as Seekable;
if (seekable != null && seekable.can_seek())
{
// Read a little bit of content to guess the type
yield guess_content_type(new_file_input_stream, location.get_basename(), cancellable);
try
{
seekable.seek(0, SeekType.SET, cancellable);
}
catch (Error e)
{
stderr.printf("Failed to seek back to beginning of stream...\n");
new_file_input_stream = null;
}
}
}
private async void guess_content_type(InputStream stream, string basename, Cancellable? cancellable)
{
var buffer = new uint8[4096];
size_t bytes_read = 0;
try
{
yield stream.read_all_async(buffer, Priority.DEFAULT, cancellable, out bytes_read);
}
catch (Error e)
{
if (bytes_read <= 0)
{
return;
}
}
buffer.length = (int)bytes_read;
bool uncertain;
new_file_content_type = GLib.ContentType.guess(basename, buffer, out uncertain);
}
}