rust-base64 icon indicating copy to clipboard operation
rust-base64 copied to clipboard

[RFE] add support for Reader/Writer for chaining

Open igor-raits opened this issue 8 years ago • 13 comments

My use-case is pretty simple, I have file which contains base64-encoded, zlib-compressed JSON ;)

igor-raits avatar Mar 31 '17 16:03 igor-raits

I hope internally this could do something partially decoding base64 (since you can decode it by chunks), you don't need full string to be available.

igor-raits avatar Mar 31 '17 16:03 igor-raits

Are you picturing something like a Base64BufReader that wraps an underlying BufRead?

marshallpierce avatar Mar 31 '17 16:03 marshallpierce

yes, something like that. Unfortunately, I'm still in the middle of understanding how to chain FlateReader from flate2, so I can't come up with syntax how I would like to see it.

P.S. it's my first experience with chaining readers in Rust

igor-raits avatar Mar 31 '17 16:03 igor-raits

Also I'm not sure whether it should be BufRead or just Read

igor-raits avatar Mar 31 '17 17:03 igor-raits

impl EntitlementCertificate {
    pub fn from_file(file: &str) -> Self {
        let path = Path::new(file);

        let rdr = BufReader::new(File::open(path).unwrap());
        let b64iter = rdr.lines()
            .skip_while(|l| l.as_ref().unwrap() != ENTITLEMENT_DATA_HEADER)
            .skip(1)
            .take_while(|l| l.as_ref().unwrap() != ENTITLEMENT_DATA_FOOTER);
        let mut b64rdr = IterRead::new(b64iter);

        let mut data = String::new();
        b64rdr.read_to_string(&mut data).unwrap();
        let zlib_encoded = base64::decode(&data).unwrap();

        let decompressor = flate2::read::ZlibDecoder::new(&*zlib_encoded);

        serde_json::from_reader(decompressor).unwrap()
    }
}

that's what I've got so far in my project, as you can see, I have reading file, decompressing and deserializing working on top of Read.

igor-raits avatar Apr 02 '17 10:04 igor-raits

I have 80% of an implementation of this internally at work. Basically is a Read and Write implementation loosely based on the golang implementation of the streaming encoder and decoder.

I'd be happy to extract the code and contribute it if there is interest.

(80% == it is not allocation free on read(..) right now, and doesn't handle the case of unpadded base64 because config.pad is not exposed (which would not be a problem if the code moved here)).

brianm avatar Mar 19 '18 19:03 brianm

Sure, I'd be happy to take a look at that, if you feel like making a PR (even a rough one). I haven't forgotten about this feature; just got several things ahead of it on the to-do list. :)

BTW, thanks for JDBI!

marshallpierce avatar Mar 19 '18 20:03 marshallpierce

Okay, got rid of the allocation at the expense of having to do extra reads sometimes (return less than full buffer), and I think need for access to config.pad.

PR incoming.

brianm avatar Mar 19 '18 23:03 brianm

@brianm well, finally shipped encoding... decoding next? If you think your decoder is a good starting point I'm happy to run with it, or I can start from scratch.

marshallpierce avatar Oct 28 '18 22:10 marshallpierce

@marshallpierce I have a working version of a streaming decoder here: https://github.com/dignifiedquire/pgp/blob/master/src/base64_decoder.rs if you want something as a starting point. It is modeled after the go implementation, but has some additional logic I needed, to be able to handle input ending for my use case.

It also is not very well tuned yet, in terms of how the buffers are used.

dignifiedquire avatar Nov 13 '18 17:11 dignifiedquire

Thanks; I'll look at it when I have some time!

marshallpierce avatar Nov 13 '18 17:11 marshallpierce

I've implemented a streaming decoder. Please see this MR: https://github.com/alicemaz/rust-base64/pull/106

nwalfield avatar Jun 23 '19 07:06 nwalfield

In case anyone else stumbles here waiting for this feature. It's been implemented in the radix64 crate. radix64::io has both an EncodeWriter and DecodeReader. https://docs.rs/radix64

ggriffiniii avatar Jul 28 '19 15:07 ggriffiniii