diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 981068a..23883b6 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -16,5 +16,5 @@ name = "data-encoding" path = "src/main.rs" [dependencies] -data-encoding = { version = "2.11.2-git", path = "../lib" } +data-encoding = { version = "2.12.0-git", path = "../lib" } getopts = "0.2" diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index 087a505..55cbfdf 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## 2.11.2-git +## 2.12.0-git + +### Minor + +- Add `Encoding::decode_align()` to decide where to split long inputs ### Patch diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 1288e60..ff6d396 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "data-encoding" -version = "2.11.2-git" +version = "2.12.0-git" license = "MIT" edition = "2018" rust-version = "1.48" diff --git a/lib/macro/Cargo.toml b/lib/macro/Cargo.toml index f89fa0a..83c69b7 100644 --- a/lib/macro/Cargo.toml +++ b/lib/macro/Cargo.toml @@ -13,5 +13,5 @@ description = "Macros for data-encoding" include = ["Cargo.toml", "LICENSE", "README.md", "src/lib.rs"] [dependencies] -data-encoding = { version = "2.11.2-git", path = "..", default-features = false } +data-encoding = { version = "2.12.0-git", path = "..", default-features = false } data-encoding-macro-internal = { version = "0.1.20-git", path = "internal" } diff --git a/lib/macro/internal/Cargo.toml b/lib/macro/internal/Cargo.toml index 8c3e517..eab1d2a 100644 --- a/lib/macro/internal/Cargo.toml +++ b/lib/macro/internal/Cargo.toml @@ -13,7 +13,7 @@ include = ["Cargo.toml", "LICENSE", "README.md", "src/lib.rs"] proc-macro = true [dependencies.data-encoding] -version = "2.11.2-git" +version = "2.12.0-git" path = "../.." default-features = false features = ["alloc"] diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 225d6dc..009d00f 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1521,14 +1521,9 @@ impl Encoding { /// - `len <= 2_305843_009213_693951` when `target_pointer_width = "64"` /// /// If you need to decode an input of length greater than this limit (possibly of infinite - /// length), then you must decode your input chunk by chunk with [`decode_mut`], making sure - /// that you take into account how many bytes have been read from the input and how many bytes - /// have been written to the output: - /// - `Ok(written)` means all bytes have been read and `written` bytes have been written - /// - `Err(DecodePartial { error, .. })` means an error occurred if `error.kind != - /// DecodeKind::Length` or this was the last input chunk - /// - `Err(DecodePartial { read, written, .. })` means that `read` bytes have been read and - /// `written` bytes written (the error can be ignored) + /// length), then you must chunk your input, decode each chunk, and concatenate to obtain the + /// output. The number of non-ignored characters of each input chunk (except the last) must be a + /// multiple of [`decode_align`]. /// /// Note that this function only _may_ panic in those cases. The function may also return the /// correct value in some cases depending on the implementation. In other words, those limits @@ -1540,6 +1535,7 @@ impl Encoding { /// Returns an error if `len` is invalid. The error kind is [`Length`] and the [position] is the /// greatest valid input length. /// + /// [`decode_align`]: struct.Encoding.html#method.decode_align /// [`decode_mut`]: struct.Encoding.html#method.decode_mut /// [`Length`]: enum.DecodeKind.html#variant.Length /// [position]: struct.DecodeError.html#structfield.position @@ -1557,6 +1553,16 @@ impl Encoding { Ok(olen) } + /// Returns the minimum alignment when chunking a long input + /// + /// See [`decode_len`] for context. + /// + /// [`decode_len`]: struct.Encoding.html#method.decode_len + #[must_use] + pub fn decode_align(&self) -> usize { + dec(self.bit()) + } + /// Decodes `input` in `output` /// /// Returns the length of the decoded output. This length may be smaller than the output length diff --git a/lib/tests/lib.rs b/lib/tests/lib.rs index 22aca36..b917254 100644 --- a/lib/tests/lib.rs +++ b/lib/tests/lib.rs @@ -701,3 +701,25 @@ fn encoder() { test(&[b"foob", b"a"], "Zm9vYmE="); test(&[b"foob", b"ar"], "Zm9vYmFy"); } + +#[test] +fn decode_align() { + #[track_caller] + fn test(chunks: &[&[u8]], expected: &[u8]) { + let mut output = Vec::new(); + for chunk in chunks { + let mut buffer = vec![0; data_encoding::BASE64_MIME.decode_len(chunk.len()).unwrap()]; + let written = data_encoding::BASE64_MIME.decode_mut(chunk, &mut buffer).unwrap(); + output.extend_from_slice(&buffer[.. written]); + } + assert_eq!(output, expected); + } + assert_eq!(data_encoding::BASE64_MIME.decode_align(), 4); + test(&[], b""); + test(&[b""], b""); + test(&[b"Zm9vYmFy"], b"foobar"); + test(&[b"Zm9v", b"YmFy"], b"foobar"); + test(&[b"Zm9v", b"Yg=="], b"foob"); + test(&[b"Zm9v\r\n", b"YmE=\r\n"], b"fooba"); + test(&[b"Zm9v\r\nYmFy", b"\r\nZm9v"], b"foobarfoo"); +}