diff --git a/src/pieces.rs b/src/pieces.rs
index d5c9797..75b3ddf 100644
--- a/src/pieces.rs
+++ b/src/pieces.rs
@@ -28,19 +28,31 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+//! Tools for implementing a `resource::Resource` body composed from many "slices".
+
use error::{Error, Result};
use std::fmt;
use std::io;
use std::marker::PhantomData;
use std::ops::Range;
+/// Information needed by `Slices` about a single slice.
#[derive(Debug)]
struct SliceInfo {
+ /// The byte position (relative to the start of the `Slices`) beyond the end of this slice.
+ /// Note the starting position (and thus length) are inferred from the previous slice.
end: u64,
+
+ /// Should be an implementation of `ContextWriter` for some `Ctx`.
writer: W,
}
+/// Writes a byte range to the given `io::Write` given a context argument; meant for use with
+/// `Slices`.
pub trait ContextWriter {
+ /// Writes `r` to `out`, as in `resource::Resource::write_to`.
+ /// The additional argument `ctx` is as supplied to the `Slices`.
+ /// The additional argument `l` is the length of this slice, as determined by the `Slices`.
fn write_to(&self, ctx: &Ctx, r: Range, l: u64, out: &mut io::Write) -> Result<()>;
}
@@ -59,13 +71,22 @@ where F: FnMut(&mut Vec) -> Result<()> {
Ok(())
}
-pub struct Slices {
+/// Helper to serve byte ranges from a body which is broken down into many "slices".
+/// This is used to implement `.mp4` serving in `mp4::Mp4File` from `mp4::Mp4FileSlice` enums.
+pub struct Slices where W: ContextWriter {
+ /// The total byte length of the `Slices`.
+ /// Equivalent to `self.slices.back().map(|s| s.end).unwrap_or(0)`; kept for convenience and to
+ /// avoid a branch.
len: u64,
+
+ /// 0 or more slices of this file.
slices: Vec>,
+
+ /// Marker so that `C` is part of the type.
phantom: PhantomData,
}
-impl fmt::Debug for Slices where W: fmt::Debug {
+impl fmt::Debug for Slices where W: fmt::Debug + ContextWriter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} slices with overall length {}:", self.slices.len(), self.len)?;
let mut start = 0;
@@ -83,10 +104,12 @@ impl Slices where W: ContextWriter {
Slices{len: 0, slices: Vec::new(), phantom: PhantomData}
}
+ /// Reserves space for at least `additional` more slices to be appended.
pub fn reserve(&mut self, additional: usize) {
self.slices.reserve(additional)
}
+ /// Appends the given slice.
pub fn append(&mut self, len: u64, writer: W) {
self.len += len;
self.slices.push(SliceInfo{end: self.len, writer: writer});
@@ -98,8 +121,9 @@ impl Slices where W: ContextWriter {
/// Returns the number of slices.
pub fn num(&self) -> usize { self.slices.len() }
- pub fn write_to(&self, ctx: &C, range: Range, out: &mut io::Write)
- -> Result<()> {
+ /// Writes `range` to `out`.
+ /// This interface mirrors `resource::Resource::write_to`, with the additional `ctx` argument.
+ pub fn write_to(&self, ctx: &C, range: Range, out: &mut io::Write) -> Result<()> {
if range.start > range.end || range.end > self.len {
return Err(Error{
description: format!("Bad range {:?} for slice of length {}", range, self.len),
@@ -116,6 +140,7 @@ impl Slices where W: ContextWriter {
Err(i) => (i, self.slices[i-1].end), // desired start < slice i's end; first is i.
};
+ // There is at least one slice to write.
// Iterate through and write each slice until the end.
let mut start_pos = range.start - slice_start;
loop {
@@ -126,7 +151,7 @@ impl Slices where W: ContextWriter {
}
s.writer.write_to(ctx, start_pos .. s.end - slice_start, l, out)?;
- // setup next iteration.
+ // Setup next iteration.
start_pos = 0;
slice_start = s.end;
i += 1;