aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nix-rust/src/lib.rs19
-rw-r--r--src/nix/test.cc34
2 files changed, 45 insertions, 8 deletions
diff --git a/nix-rust/src/lib.rs b/nix-rust/src/lib.rs
index abcb89055..799d52e31 100644
--- a/nix-rust/src/lib.rs
+++ b/nix-rust/src/lib.rs
@@ -7,13 +7,28 @@ use std::os::unix::fs::OpenOptionsExt;
use std::path::Path;
use tar::Archive;
+/// A wrapper around Nix's Source class that provides the Read trait.
+#[repr(C)]
+pub struct Source {
+ fun: extern "C" fn(this: *mut libc::c_void, data: &mut [u8]) -> usize,
+ this: *mut libc::c_void,
+}
+
+impl std::io::Read for Source {
+ fn read(&mut self, buf: &mut [u8]) -> std::result::Result<usize, std::io::Error> {
+ let n = (self.fun)(self.this, buf);
+ assert!(n <= buf.len());
+ Ok(n)
+ }
+}
+
#[no_mangle]
-pub extern "C" fn unpack_tarfile(data: &[u8], dest_dir: &str) -> bool {
+pub extern "C" fn unpack_tarfile(source: Source, dest_dir: &str) -> bool {
// FIXME: handle errors.
let dest_dir = Path::new(dest_dir);
- let mut tar = Archive::new(data);
+ let mut tar = Archive::new(source);
for file in tar.entries().unwrap() {
let mut file = file.unwrap();
diff --git a/src/nix/test.cc b/src/nix/test.cc
index 70e0a903d..7f1f0d47a 100644
--- a/src/nix/test.cc
+++ b/src/nix/test.cc
@@ -1,6 +1,7 @@
#include "command.hh"
#include "store-api.hh"
#include "common-args.hh"
+#include "compression.hh"
using namespace nix;
@@ -10,10 +11,10 @@ namespace rust {
// evil...
template<typename T> struct Slice
{
- const T * ptr;
+ T * ptr;
size_t size;
- Slice(const T * ptr, size_t size) : ptr(ptr), size(size)
+ Slice(T * ptr, size_t size) : ptr(ptr), size(size)
{
assert(ptr);
}
@@ -21,13 +22,30 @@ template<typename T> struct Slice
struct StringSlice : Slice<char>
{
- StringSlice(const std::string & s): Slice(s.data(), s.size()) { }
+ StringSlice(const std::string & s): Slice((char *) s.data(), s.size()) {}
+};
+
+struct Source
+{
+ size_t (*fun)(void * source_this, rust::Slice<uint8_t> data);
+ nix::Source * _this;
+
+ Source(nix::Source & _this)
+ : fun(sourceWrapper), _this(&_this)
+ {}
+
+ // FIXME: how to propagate exceptions?
+ static size_t sourceWrapper(void * _this, rust::Slice<uint8_t> data)
+ {
+ auto n = ((nix::Source *) _this)->read(data.ptr, data.size);
+ return n;
+ }
};
}
extern "C" {
- bool unpack_tarfile(rust::Slice<uint8_t> data, rust::StringSlice dest_dir);
+ bool unpack_tarfile(rust::Source source, rust::StringSlice dest_dir);
}
struct CmdTest : StoreCommand
@@ -48,13 +66,17 @@ struct CmdTest : StoreCommand
void run(ref<Store> store) override
{
- auto data = readFile("./nix-2.2.tar");
+ auto source = sinkToSource([&](Sink & sink) {
+ auto decompressor = makeDecompressionSink("bzip2", sink);
+ readFile("./nix-2.2.tar.bz2", *decompressor);
+ decompressor->finish();
+ });
std::string destDir = "./dest";
deletePath(destDir);
- unpack_tarfile({(uint8_t*) data.data(), data.size()}, destDir);
+ unpack_tarfile(*source, destDir);
}
};