Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Commit

Permalink
Split Entry into two different enums to remove unnecessary expects
Browse files Browse the repository at this point in the history
  • Loading branch information
c410-f3r committed Jul 31, 2020
1 parent cb002eb commit 8668c68
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 166 deletions.
84 changes: 36 additions & 48 deletions http/src/v0/root_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use async_stream::try_stream;
use bytes::Bytes;
use cid::{Cid, Codec};
use futures::stream::TryStream;
use ipfs::unixfs::ll::walk::{self, ContinuedWalk, Walker};
use ipfs::unixfs::ll::walk::{self, ContinuedWalk, Entry, MetadataEntry, Walker};
use ipfs::unixfs::{ll::file::FileReadFailed, TraversalFailed};
use ipfs::Block;
use ipfs::{Ipfs, IpfsTypes};
Expand Down Expand Up @@ -159,75 +159,63 @@ fn walk<Types: IpfsTypes>(

visit = match walker.continue_walk(&data, &mut cache)? {
ContinuedWalk::File(segment, item) => {
let total_size = item.as_entry()
.total_file_size()
.expect("files do have total_size");

if segment.is_first() {
let path = item.as_entry().path();
let metadata = item
.as_entry()
.metadata()
.expect("files must have metadata");

for mut bytes in tar_helper.apply_file(path, metadata, total_size)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
if let Entry::Metadata(MetadataEntry::File(.., p, md, size)) = item.as_entry() {
if segment.is_first() {
for mut bytes in tar_helper.apply_file(p, md, size)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
}
}
}
}

// even if the largest of files can have 256 kB blocks and about the same
// amount of content, try to consume it in small parts not to grow the buffers
// too much.
// even if the largest of files can have 256 kB blocks and about the same
// amount of content, try to consume it in small parts not to grow the buffers
// too much.

let mut n = 0usize;
let slice = segment.as_ref();
let total = slice.len();
let mut n = 0usize;
let slice = segment.as_ref();
let total = slice.len();

while n < total {
let next = tar_helper.buffer_file_contents(&slice[n..]);
n += next.len();
yield next;
}
while n < total {
let next = tar_helper.buffer_file_contents(&slice[n..]);
n += next.len();
yield next;
}

if segment.is_last() {
if let Some(zeroes) = tar_helper.pad(total_size) {
yield zeroes;
if segment.is_last() {
if let Some(zeroes) = tar_helper.pad(size) {
yield zeroes;
}
}
}

item.into_inner()
},
ContinuedWalk::Directory(item) => {

// only first instances of directories will have the metadata
if let Some(metadata) = item.as_entry().metadata() {
let path = item.as_entry().path();

if let Entry::Metadata(metadata_entry) = item.as_entry() {
let metadata = metadata_entry.metadata();
let path = metadata_entry.path();
for mut bytes in tar_helper.apply_directory(path, metadata)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
}
}
}

item.into_inner()
},
ContinuedWalk::Symlink(bytes, item) => {

// converting a symlink is the most tricky part
let path = item.as_entry().path();
let target = std::str::from_utf8(bytes).map_err(|_| GetError::NonUtf8Symlink)?;
let target = Path::new(target);
let metadata = item.as_entry().metadata().expect("symlink must have metadata");

for mut bytes in tar_helper.apply_symlink(path, target, metadata)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
if let Entry::Metadata(metadata_entry) = item.as_entry() {
// converting a symlink is the most tricky part
let path = metadata_entry.path();
let target = std::str::from_utf8(bytes).map_err(|_| GetError::NonUtf8Symlink)?;
let target = Path::new(target);
let metadata = metadata_entry.metadata();

for mut bytes in tar_helper.apply_symlink(path, target, metadata)?.iter_mut() {
if let Some(bytes) = bytes.take() {
yield bytes;
}
}
}

item.into_inner()
},
};
Expand Down
61 changes: 25 additions & 36 deletions unixfs/examples/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn main() {
}

fn walk(blocks: ShardedBlockStore, start: &Cid) -> Result<(), Error> {
use ipfs_unixfs::walk::{ContinuedWalk, Walker};
use ipfs_unixfs::walk::{ContinuedWalk, Entry, MetadataEntry, Walker};

let mut buf = Vec::new();
let mut cache = None;
Expand All @@ -72,56 +72,45 @@ fn walk(blocks: ShardedBlockStore, start: &Cid) -> Result<(), Error> {
// items.
visit = match walker.continue_walk(&buf, &mut cache)? {
ContinuedWalk::File(segment, item) => {
let entry = item.as_entry();
let total_size = entry.total_file_size().expect("all files have total size");
// metadata is picked up from the root file and carried until the last block
let metadata = entry.metadata().expect("all files have metadata");

if segment.is_first() {
// this is set on the root block, no actual bytes are present for multiblock
// files
if let Entry::Metadata(MetadataEntry::File(.., path, md, size)) = item.as_entry() {
if segment.is_first() {
// this is set on the root block, no actual bytes are present for multiblock
// files
}

if segment.is_last() {
let mode = md.mode().unwrap_or(0o0644) & 0o7777;
let (seconds, _) = md.mtime().unwrap_or((0, 0));
println!("f {:o} {:>12} {:>16} {:?}", mode, seconds, size, path);
}
}

if segment.is_last() {
let path = entry.path();
let mode = metadata.mode().unwrap_or(0o0644) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));

println!("f {:o} {:>12} {:>16} {:?}", mode, seconds, total_size, path);
}

// continue the walk
item.into_inner()
}
ContinuedWalk::Directory(item) => {
// presense of metadata can be used to determine if this is the first apperiance of
// a directory by looking at the metadata: sibling hamt shard buckets do not have
// metadata.
if let Some(metadata) = item.as_entry().metadata() {
if let Entry::Metadata(metadata_entry) = item.as_entry() {
let metadata = metadata_entry.metadata();
let path = item.as_entry().path();

let mode = metadata.mode().unwrap_or(0o0755) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));

println!("d {:o} {:>12} {:>16} {:?}", mode, seconds, "-", path);
}

item.into_inner()
}
ContinuedWalk::Symlink(bytes, item) => {
let entry = item.as_entry();
let metadata = entry.metadata().expect("symlink must have metadata");

let path = entry.path();
let target = Path::new(std::str::from_utf8(bytes).unwrap());
let mode = metadata.mode().unwrap_or(0o0755) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));

println!(
"s {:o} {:>12} {:>16} {:?} -> {:?}",
mode, seconds, "-", path, target
);

if let Entry::Metadata(metadata_entry) = item.as_entry() {
let metadata = metadata_entry.metadata();
let path = metadata_entry.path();
let target = Path::new(std::str::from_utf8(bytes).unwrap());
let mode = metadata.mode().unwrap_or(0o0755) & 0o7777;
let (seconds, _) = metadata.mtime().unwrap_or((0, 0));
println!(
"s {:o} {:>12} {:>16} {:?} -> {:?}",
mode, seconds, "-", path, target
);
}
item.into_inner()
}
};
Expand Down
Loading

0 comments on commit 8668c68

Please sign in to comment.