{"action":"created","comment":{"url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/comments/150409140","pull_request_review_id":75957824,"id":150409140,"diff_hunk":"@@ -180,3 +182,177 @@ impl<W: Write> Drop for GzEncoder<W> {\n         }\n     }\n }\n+\n+/// A gzip streaming decoder\n+///\n+/// This structure exposes a [`Write`] interface that will emit compressed data\n+/// to the underlying writer `W`.\n+///\n+/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html\n+///\n+/// # Examples\n+///\n+/// ```\n+/// use std::io::prelude::*;\n+/// use std::io;\n+/// use flate2::Compression;\n+/// use flate2::write::{GzEncoder, GzDecoder};\n+///\n+/// # fn main() {\n+/// #    let mut e = GzEncoder::new(Vec::new(), Compression::default());\n+/// #    e.write(b\"Hello World\").unwrap();\n+/// #    let bytes = e.finish().unwrap();\n+/// #    assert_eq!(\"Hello World\", decode_writer(bytes).unwrap());\n+/// # }\n+/// // Uncompresses a gzip encoded vector of bytes and returns a string or error\n+/// // Here Vec<u8> implements Write\n+/// fn decode_writer(bytes: Vec<u8>) -> io::Result<String> {\n+///    let mut writer = Vec::new();\n+///    let mut decoder = GzDecoder::new(writer);\n+///    decoder.write(&bytes[..])?;\n+///    writer = decoder.finish()?;\n+///    let return_string = String::from_utf8(writer).expect(\"String parsing error\");\n+///    Ok(return_string)\n+/// }\n+/// ```\n+#[derive(Debug)]\n+pub struct GzDecoder<W: Write> {\n+    inner: zio::Writer<CrcWriter<W>, Decompress>,\n+    crc_bytes: Vec<u8>,\n+    header: Option<GzHeader>,\n+}\n+\n+impl<W: Write> GzDecoder<W> {\n+    /// Creates a new decoder which will write uncompressed data to the stream.\n+    ///\n+    /// When this encoder is dropped or unwrapped the final pieces of data will\n+    /// be flushed.\n+    pub fn new(w: W) -> GzDecoder<W> {\n+        GzDecoder {\n+            inner: zio::Writer::new(CrcWriter::new(w), Decompress::new(false)),\n+            crc_bytes: Vec::with_capacity(8),\n+            header: None,\n+        }\n+    }\n+\n+    /// Returns the header associated with this stream.\n+    pub fn header(&self) -> Option<&GzHeader> {\n+        self.header.as_ref()\n+    }\n+\n+    /// Acquires a reference to the underlying writer.\n+    pub fn get_ref(&self) -> &W {\n+        self.inner.get_ref().get_ref()\n+    }\n+\n+    /// Acquires a mutable reference to the underlying writer.\n+    ///\n+    /// Note that mutating the output/input state of the stream may corrupt this\n+    /// object, so care must be taken when using this method.\n+    pub fn get_mut(&mut self) -> &mut W {\n+        self.inner.get_mut().get_mut()\n+    }\n+\n+    /// Attempt to finish this output stream, writing out final chunks of data.\n+    ///\n+    /// Note that this function can only be used once data has finished being\n+    /// written to the output stream. After this function is called then further\n+    /// calls to `write` may result in a panic.\n+    ///\n+    /// # Panics\n+    ///\n+    /// Attempts to write data to this stream may result in a panic after this\n+    /// function is called.\n+    ///\n+    /// # Errors\n+    ///\n+    /// This function will perform I/O to finish the stream, returning any\n+    /// errors which happen.\n+    pub fn try_finish(&mut self) -> io::Result<()> {\n+        try!(self.inner.finish());\n+\n+        if self.crc_bytes.len() != 8 {\n+            return Err(corrupt())\n+        }\n+\n+        let crc = ((self.crc_bytes[0] as u32) << 0)\n+            | ((self.crc_bytes[1] as u32) << 8)\n+            | ((self.crc_bytes[2] as u32) << 16)\n+            | ((self.crc_bytes[3] as u32) << 24);\n+        let amt = ((self.crc_bytes[4] as u32) << 0)\n+            | ((self.crc_bytes[5] as u32) << 8)\n+            | ((self.crc_bytes[6] as u32) << 16)\n+            | ((self.crc_bytes[7] as u32) << 24);\n+        if crc != self.inner.get_ref().crc().sum() as u32 {\n+            return Err(corrupt());\n+        }\n+        if amt != self.inner.get_ref().crc().amount() {\n+            return Err(corrupt());\n+        }\n+        Ok(())\n+    }\n+\n+    /// Consumes this decoder, flushing the output stream.\n+    ///\n+    /// This will flush the underlying data stream and then return the contained\n+    /// writer if the flush succeeded.\n+    ///\n+    /// Note that this function may not be suitable to call in a situation where\n+    /// the underlying stream is an asynchronous I/O stream. To finish a stream\n+    /// the `try_finish` (or `shutdown`) method should be used instead. To\n+    /// re-acquire ownership of a stream it is safe to call this method after\n+    /// `try_finish` or `shutdown` has returned `Ok`.\n+    ///\n+    /// # Errors\n+    ///\n+    /// This function will perform I/O to complete this stream, and any I/O\n+    /// errors which occur will be returned from this function.\n+    pub fn finish(mut self) -> io::Result<W> {\n+        try!(self.inner.finish());\n+        Ok(self.inner.take_inner().into_inner())\n+    }\n+\n+    fn write_buf(&mut self, buf: &[u8]) -> io::Result<usize> {\n+        let n = if let Some(Status::StreamEnd) = self.inner.op_status() {\n+            0\n+        } else {\n+            try!(self.inner.write(buf))\n+        };\n+        if let Some(Status::StreamEnd) = self.inner.op_status() {\n+            if n < buf.len() && self.crc_bytes.len() < 8 {\n+                let d = cmp::min(buf.len(), n + 8 - self.crc_bytes.len());","path":"src/gz/write.rs","position":161,"original_position":161,"commit_id":"35277946211e05d4b16271141dc75c7cd030f286","original_commit_id":"35277946211e05d4b16271141dc75c7cd030f286","user":{"login":"alexcrichton","id":64996,"avatar_url":"https://avatars1.githubusercontent.com/u/64996?v=4","gravatar_id":"","url":"https://api.github.com/users/alexcrichton","html_url":"https://github.com/alexcrichton","followers_url":"https://api.github.com/users/alexcrichton/followers","following_url":"https://api.github.com/users/alexcrichton/following{/other_user}","gists_url":"https://api.github.com/users/alexcrichton/gists{/gist_id}","starred_url":"https://api.github.com/users/alexcrichton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexcrichton/subscriptions","organizations_url":"https://api.github.com/users/alexcrichton/orgs","repos_url":"https://api.github.com/users/alexcrichton/repos","events_url":"https://api.github.com/users/alexcrichton/events{/privacy}","received_events_url":"https://api.github.com/users/alexcrichton/received_events","type":"User","site_admin":false},"body":"Could this instead be:\r\n\r\n```rust\r\nlet d = cmp::min(buf.len() - n, 8 - self.crc_bytes.len());\r\n```\r\n\r\nI found the current expression to take a moment to get my head around...","created_at":"2017-11-12T12:38:35Z","updated_at":"2017-11-12T12:39:11Z","html_url":"https://github.com/alexcrichton/flate2-rs/pull/132#discussion_r150409140","pull_request_url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/comments/150409140"},"html":{"href":"https://github.com/alexcrichton/flate2-rs/pull/132#discussion_r150409140"},"pull_request":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132"}}},"pull_request":{"url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132","id":151255596,"html_url":"https://github.com/alexcrichton/flate2-rs/pull/132","diff_url":"https://github.com/alexcrichton/flate2-rs/pull/132.diff","patch_url":"https://github.com/alexcrichton/flate2-rs/pull/132.patch","issue_url":"https://api.github.com/repos/alexcrichton/flate2-rs/issues/132","number":132,"state":"open","locked":false,"title":"add write::GzDecoder","user":{"login":"fafhrd91","id":598990,"avatar_url":"https://avatars2.githubusercontent.com/u/598990?v=4","gravatar_id":"","url":"https://api.github.com/users/fafhrd91","html_url":"https://github.com/fafhrd91","followers_url":"https://api.github.com/users/fafhrd91/followers","following_url":"https://api.github.com/users/fafhrd91/following{/other_user}","gists_url":"https://api.github.com/users/fafhrd91/gists{/gist_id}","starred_url":"https://api.github.com/users/fafhrd91/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fafhrd91/subscriptions","organizations_url":"https://api.github.com/users/fafhrd91/orgs","repos_url":"https://api.github.com/users/fafhrd91/repos","events_url":"https://api.github.com/users/fafhrd91/events{/privacy}","received_events_url":"https://api.github.com/users/fafhrd91/received_events","type":"User","site_admin":false},"body":"","created_at":"2017-11-07T23:26:38Z","updated_at":"2017-11-12T12:39:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e4705c6457bd7a46c17669f88c8865a4b0a4b969","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132/commits","review_comments_url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132/comments","review_comment_url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/alexcrichton/flate2-rs/issues/132/comments","statuses_url":"https://api.github.com/repos/alexcrichton/flate2-rs/statuses/35277946211e05d4b16271141dc75c7cd030f286","head":{"label":"fafhrd91:master","ref":"master","sha":"35277946211e05d4b16271141dc75c7cd030f286","user":{"login":"fafhrd91","id":598990,"avatar_url":"https://avatars2.githubusercontent.com/u/598990?v=4","gravatar_id":"","url":"https://api.github.com/users/fafhrd91","html_url":"https://github.com/fafhrd91","followers_url":"https://api.github.com/users/fafhrd91/followers","following_url":"https://api.github.com/users/fafhrd91/following{/other_user}","gists_url":"https://api.github.com/users/fafhrd91/gists{/gist_id}","starred_url":"https://api.github.com/users/fafhrd91/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fafhrd91/subscriptions","organizations_url":"https://api.github.com/users/fafhrd91/orgs","repos_url":"https://api.github.com/users/fafhrd91/repos","events_url":"https://api.github.com/users/fafhrd91/events{/privacy}","received_events_url":"https://api.github.com/users/fafhrd91/received_events","type":"User","site_admin":false},"repo":{"id":109887315,"name":"flate2-rs","full_name":"fafhrd91/flate2-rs","owner":{"login":"fafhrd91","id":598990,"avatar_url":"https://avatars2.githubusercontent.com/u/598990?v=4","gravatar_id":"","url":"https://api.github.com/users/fafhrd91","html_url":"https://github.com/fafhrd91","followers_url":"https://api.github.com/users/fafhrd91/followers","following_url":"https://api.github.com/users/fafhrd91/following{/other_user}","gists_url":"https://api.github.com/users/fafhrd91/gists{/gist_id}","starred_url":"https://api.github.com/users/fafhrd91/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fafhrd91/subscriptions","organizations_url":"https://api.github.com/users/fafhrd91/orgs","repos_url":"https://api.github.com/users/fafhrd91/repos","events_url":"https://api.github.com/users/fafhrd91/events{/privacy}","received_events_url":"https://api.github.com/users/fafhrd91/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fafhrd91/flate2-rs","description":"FLATE, Gzip, and Zlib bindings for Rust","fork":true,"url":"https://api.github.com/repos/fafhrd91/flate2-rs","forks_url":"https://api.github.com/repos/fafhrd91/flate2-rs/forks","keys_url":"https://api.github.com/repos/fafhrd91/flate2-rs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fafhrd91/flate2-rs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fafhrd91/flate2-rs/teams","hooks_url":"https://api.github.com/repos/fafhrd91/flate2-rs/hooks","issue_events_url":"https://api.github.com/repos/fafhrd91/flate2-rs/issues/events{/number}","events_url":"https://api.github.com/repos/fafhrd91/flate2-rs/events","assignees_url":"https://api.github.com/repos/fafhrd91/flate2-rs/assignees{/user}","branches_url":"https://api.github.com/repos/fafhrd91/flate2-rs/branches{/branch}","tags_url":"https://api.github.com/repos/fafhrd91/flate2-rs/tags","blobs_url":"https://api.github.com/repos/fafhrd91/flate2-rs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fafhrd91/flate2-rs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fafhrd91/flate2-rs/git/refs{/sha}","trees_url":"https://api.github.com/repos/fafhrd91/flate2-rs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fafhrd91/flate2-rs/statuses/{sha}","languages_url":"https://api.github.com/repos/fafhrd91/flate2-rs/languages","stargazers_url":"https://api.github.com/repos/fafhrd91/flate2-rs/stargazers","contributors_url":"https://api.github.com/repos/fafhrd91/flate2-rs/contributors","subscribers_url":"https://api.github.com/repos/fafhrd91/flate2-rs/subscribers","subscription_url":"https://api.github.com/repos/fafhrd91/flate2-rs/subscription","commits_url":"https://api.github.com/repos/fafhrd91/flate2-rs/commits{/sha}","git_commits_url":"https://api.github.com/repos/fafhrd91/flate2-rs/git/commits{/sha}","comments_url":"https://api.github.com/repos/fafhrd91/flate2-rs/comments{/number}","issue_comment_url":"https://api.github.com/repos/fafhrd91/flate2-rs/issues/comments{/number}","contents_url":"https://api.github.com/repos/fafhrd91/flate2-rs/contents/{+path}","compare_url":"https://api.github.com/repos/fafhrd91/flate2-rs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fafhrd91/flate2-rs/merges","archive_url":"https://api.github.com/repos/fafhrd91/flate2-rs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fafhrd91/flate2-rs/downloads","issues_url":"https://api.github.com/repos/fafhrd91/flate2-rs/issues{/number}","pulls_url":"https://api.github.com/repos/fafhrd91/flate2-rs/pulls{/number}","milestones_url":"https://api.github.com/repos/fafhrd91/flate2-rs/milestones{/number}","notifications_url":"https://api.github.com/repos/fafhrd91/flate2-rs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fafhrd91/flate2-rs/labels{/name}","releases_url":"https://api.github.com/repos/fafhrd91/flate2-rs/releases{/id}","deployments_url":"https://api.github.com/repos/fafhrd91/flate2-rs/deployments","created_at":"2017-11-07T20:29:21Z","updated_at":"2017-11-07T20:29:23Z","pushed_at":"2017-11-08T19:24:17Z","git_url":"git://github.com/fafhrd91/flate2-rs.git","ssh_url":"git@github.com:fafhrd91/flate2-rs.git","clone_url":"https://github.com/fafhrd91/flate2-rs.git","svn_url":"https://github.com/fafhrd91/flate2-rs","homepage":"http://alexcrichton.com/flate2-rs","size":1216,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"alexcrichton:master","ref":"master","sha":"739079431f2184b9c29c60bee3376fea7ec347cc","user":{"login":"alexcrichton","id":64996,"avatar_url":"https://avatars1.githubusercontent.com/u/64996?v=4","gravatar_id":"","url":"https://api.github.com/users/alexcrichton","html_url":"https://github.com/alexcrichton","followers_url":"https://api.github.com/users/alexcrichton/followers","following_url":"https://api.github.com/users/alexcrichton/following{/other_user}","gists_url":"https://api.github.com/users/alexcrichton/gists{/gist_id}","starred_url":"https://api.github.com/users/alexcrichton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexcrichton/subscriptions","organizations_url":"https://api.github.com/users/alexcrichton/orgs","repos_url":"https://api.github.com/users/alexcrichton/repos","events_url":"https://api.github.com/users/alexcrichton/events{/privacy}","received_events_url":"https://api.github.com/users/alexcrichton/received_events","type":"User","site_admin":false},"repo":{"id":21954009,"name":"flate2-rs","full_name":"alexcrichton/flate2-rs","owner":{"login":"alexcrichton","id":64996,"avatar_url":"https://avatars1.githubusercontent.com/u/64996?v=4","gravatar_id":"","url":"https://api.github.com/users/alexcrichton","html_url":"https://github.com/alexcrichton","followers_url":"https://api.github.com/users/alexcrichton/followers","following_url":"https://api.github.com/users/alexcrichton/following{/other_user}","gists_url":"https://api.github.com/users/alexcrichton/gists{/gist_id}","starred_url":"https://api.github.com/users/alexcrichton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexcrichton/subscriptions","organizations_url":"https://api.github.com/users/alexcrichton/orgs","repos_url":"https://api.github.com/users/alexcrichton/repos","events_url":"https://api.github.com/users/alexcrichton/events{/privacy}","received_events_url":"https://api.github.com/users/alexcrichton/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/alexcrichton/flate2-rs","description":"FLATE, Gzip, and Zlib bindings for Rust","fork":false,"url":"https://api.github.com/repos/alexcrichton/flate2-rs","forks_url":"https://api.github.com/repos/alexcrichton/flate2-rs/forks","keys_url":"https://api.github.com/repos/alexcrichton/flate2-rs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/alexcrichton/flate2-rs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/alexcrichton/flate2-rs/teams","hooks_url":"https://api.github.com/repos/alexcrichton/flate2-rs/hooks","issue_events_url":"https://api.github.com/repos/alexcrichton/flate2-rs/issues/events{/number}","events_url":"https://api.github.com/repos/alexcrichton/flate2-rs/events","assignees_url":"https://api.github.com/repos/alexcrichton/flate2-rs/assignees{/user}","branches_url":"https://api.github.com/repos/alexcrichton/flate2-rs/branches{/branch}","tags_url":"https://api.github.com/repos/alexcrichton/flate2-rs/tags","blobs_url":"https://api.github.com/repos/alexcrichton/flate2-rs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/alexcrichton/flate2-rs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/alexcrichton/flate2-rs/git/refs{/sha}","trees_url":"https://api.github.com/repos/alexcrichton/flate2-rs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/alexcrichton/flate2-rs/statuses/{sha}","languages_url":"https://api.github.com/repos/alexcrichton/flate2-rs/languages","stargazers_url":"https://api.github.com/repos/alexcrichton/flate2-rs/stargazers","contributors_url":"https://api.github.com/repos/alexcrichton/flate2-rs/contributors","subscribers_url":"https://api.github.com/repos/alexcrichton/flate2-rs/subscribers","subscription_url":"https://api.github.com/repos/alexcrichton/flate2-rs/subscription","commits_url":"https://api.github.com/repos/alexcrichton/flate2-rs/commits{/sha}","git_commits_url":"https://api.github.com/repos/alexcrichton/flate2-rs/git/commits{/sha}","comments_url":"https://api.github.com/repos/alexcrichton/flate2-rs/comments{/number}","issue_comment_url":"https://api.github.com/repos/alexcrichton/flate2-rs/issues/comments{/number}","contents_url":"https://api.github.com/repos/alexcrichton/flate2-rs/contents/{+path}","compare_url":"https://api.github.com/repos/alexcrichton/flate2-rs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/alexcrichton/flate2-rs/merges","archive_url":"https://api.github.com/repos/alexcrichton/flate2-rs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/alexcrichton/flate2-rs/downloads","issues_url":"https://api.github.com/repos/alexcrichton/flate2-rs/issues{/number}","pulls_url":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls{/number}","milestones_url":"https://api.github.com/repos/alexcrichton/flate2-rs/milestones{/number}","notifications_url":"https://api.github.com/repos/alexcrichton/flate2-rs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/alexcrichton/flate2-rs/labels{/name}","releases_url":"https://api.github.com/repos/alexcrichton/flate2-rs/releases{/id}","deployments_url":"https://api.github.com/repos/alexcrichton/flate2-rs/deployments","created_at":"2014-07-17T19:03:20Z","updated_at":"2017-11-10T23:57:03Z","pushed_at":"2017-11-10T17:30:21Z","git_url":"git://github.com/alexcrichton/flate2-rs.git","ssh_url":"git@github.com:alexcrichton/flate2-rs.git","clone_url":"https://github.com/alexcrichton/flate2-rs.git","svn_url":"https://github.com/alexcrichton/flate2-rs","homepage":"http://alexcrichton.com/flate2-rs","size":1163,"stargazers_count":115,"watchers_count":115,"language":"C","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":53,"mirror_url":null,"archived":false,"open_issues_count":7,"forks":53,"open_issues":7,"watchers":115,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132"},"html":{"href":"https://github.com/alexcrichton/flate2-rs/pull/132"},"issue":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/issues/132"},"comments":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/issues/132/comments"},"review_comments":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132/comments"},"review_comment":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/pulls/132/commits"},"statuses":{"href":"https://api.github.com/repos/alexcrichton/flate2-rs/statuses/35277946211e05d4b16271141dc75c7cd030f286"}},"author_association":"NONE"}}
{"actor":{"display_login":"alexcrichton"}}