Unified · Split
| @@ -118,3 +118,41 @@ pub fn bytes_of_file( · 117 unmodified lines | |||
| 118 | progress.show_throughput(start); | 118 | progress.show_throughput(start); |
| 119 | Ok(id) | 119 | Ok(id) |
| 120 | } | 120 | } |
| 121 | |||
| 122 | /// A utility to automatically generate a hash while writing into an inner writer. | ||
| 123 | pub struct Write<T> { | ||
| 124 | /// The hash implementation. | ||
| 125 | pub hash: Sha1, | ||
| 126 | /// The inner writer. | ||
| 127 | pub inner: T, | ||
| 128 | } | ||
| 129 | |||
| 130 | impl<T> std::io::Write for Write<T> | ||
| 131 | where | ||
| 132 | T: std::io::Write, | ||
| 133 | { | ||
| 134 | fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { | ||
| 135 | let written = self.inner.write(buf)?; | ||
| 136 | self.hash.update(&buf[..written]); | ||
| 137 | Ok(written) | ||
| 138 | } | ||
| 139 | |||
| 140 | fn flush(&mut self) -> std::io::Result<()> { | ||
| 141 | self.inner.flush() | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | impl<T> Write<T> | ||
| 146 | where | ||
| 147 | T: std::io::Write, | ||
| 148 | { | ||
| 149 | /// Create a new hash writer which hashes all bytes written to `inner` with a hash of `kind`. | ||
| 150 | pub fn new(inner: T, kind: git_hash::Kind) -> Self { | ||
| 151 | match kind { | ||
| 152 | git_hash::Kind::Sha1 => Write { | ||
| 153 | inner, | ||
| 154 | hash: Sha1::default(), | ||
| 155 | }, | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
| @@ -67,7 +67,8 @@ impl<'a> Object<'a> { · 66 unmodified lines | |||
| 67 | 67 | ||
| 68 | /// Types supporting object hash verification | 68 | /// Types supporting object hash verification |
| 69 | pub mod verify { | 69 | pub mod verify { |
| 70 | use crate::{hash, loose}; | 70 | use crate::loose; |
| 71 | use git_features::hash; | ||
| 71 | use std::io; | 72 | use std::io; |
| 72 | 73 | ||
| 73 | /// Returned by [`crate::data::Object::verify_checksum()`] | 74 | /// Returned by [`crate::data::Object::verify_checksum()`] |
| @@ -1,36 +0,0 @@ | |||
| 1 | use git_features::hash; | ||
| 2 | use std::io; | ||
| 3 | |||
| 4 | pub(crate) struct Write<T> { | ||
| 5 | pub hash: hash::Sha1, | ||
| 6 | pub inner: T, | ||
| 7 | } | ||
| 8 | |||
| 9 | impl<T> io::Write for Write<T> | ||
| 10 | where | ||
| 11 | T: io::Write, | ||
| 12 | { | ||
| 13 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | ||
| 14 | let written = self.inner.write(buf)?; | ||
| 15 | self.hash.update(&buf[..written]); | ||
| 16 | Ok(written) | ||
| 17 | } | ||
| 18 | |||
| 19 | fn flush(&mut self) -> io::Result<()> { | ||
| 20 | self.inner.flush() | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | impl<T> Write<T> | ||
| 25 | where | ||
| 26 | T: io::Write, | ||
| 27 | { | ||
| 28 | pub fn new(inner: T, kind: git_hash::Kind) -> Self { | ||
| 29 | match kind { | ||
| 30 | git_hash::Kind::Sha1 => Write { | ||
| 31 | inner, | ||
| 32 | hash: hash::Sha1::default(), | ||
| 33 | }, | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| @@ -19,11 +19,8 @@ · 18 unmodified lines | |||
| 19 | //! * [`store::linked::Db`] | 19 | //! * [`store::linked::Db`] |
| 20 | //! * A database containing various [`compound::Backends`][store::compound::Backend] as gathered from `alternates` files. | 20 | //! * A database containing various [`compound::Backends`][store::compound::Backend] as gathered from `alternates` files. |
| 21 | 21 | ||
| 22 | pub mod pack; | ||
| 23 | |||
| 24 | pub(crate) mod hash; | ||
| 25 | |||
| 26 | pub mod data; | 22 | pub mod data; |
| 23 | pub mod pack; | ||
| 27 | 24 | ||
| 28 | /// | 25 | /// |
| 29 | pub mod find; | 26 | pub mod find; |
| @@ -1,6 +1,9 @@ | |||
| 1 | use crate::{hash, pack, pack::data::input}; | 1 | use crate::{pack, pack::data::input}; |
| 2 | use git_features::hash::Sha1; | 2 | use git_features::{ |
| 3 | use git_features::zlib::{stream::inflate::ReadBoxed, Decompress}; | 3 | hash, |
| 4 | hash::Sha1, | ||
| 5 | zlib::{stream::inflate::ReadBoxed, Decompress}, | ||
| 6 | }; | ||
| 4 | use std::{fs, io}; | 7 | use std::{fs, io}; |
| 5 | 8 | ||
| 6 | /// An iterator over [`Entries`][input::Entry] in a byte stream. | 9 | /// An iterator over [`Entries`][input::Entry] in a byte stream. |
| @@ -1,4 +1,5 @@ | |||
| 1 | use crate::{hash, pack, pack::data::output}; | 1 | use crate::{pack, pack::data::output}; |
| 2 | use git_features::hash; | ||
| 2 | use std::io::Write; | 3 | use std::io::Write; |
| 3 | 4 | ||
| 4 | /// The error returned by `next()` in the [`EntriesToBytesIter`] iterator. | 5 | /// The error returned by `next()` in the [`EntriesToBytesIter`] iterator. |
| @@ -1,9 +1,12 @@ | |||
| 1 | use crate::{ | 1 | use crate::{ |
| 2 | hash, pack, | 2 | pack, |
| 3 | pack::index::{util::Count, V2_SIGNATURE}, | 3 | pack::index::{util::Count, V2_SIGNATURE}, |
| 4 | }; | 4 | }; |
| 5 | use byteorder::{BigEndian, WriteBytesExt}; | 5 | use byteorder::{BigEndian, WriteBytesExt}; |
| 6 | use git_features::progress::{self, Progress}; | 6 | use git_features::{ |
| 7 | hash, | ||
| 8 | progress::{self, Progress}, | ||
| 9 | }; | ||
| 7 | use std::{cmp::Ordering, collections::VecDeque, io}; | 10 | use std::{cmp::Ordering, collections::VecDeque, io}; |
| 8 | 11 | ||
| 9 | pub(crate) fn write_to( | 12 | pub(crate) fn write_to( |
| @@ -221,7 +221,7 @@ fn modify_base( · 220 unmodified lines | |||
| 221 | hash: git_hash::Kind, | 221 | hash: git_hash::Kind, |
| 222 | ) { | 222 | ) { |
| 223 | fn compute_hash(kind: git_object::Kind, bytes: &[u8], hash_kind: git_hash::Kind) -> git_hash::ObjectId { | 223 | fn compute_hash(kind: git_object::Kind, bytes: &[u8], hash_kind: git_hash::Kind) -> git_hash::ObjectId { |
| 224 | let mut write = crate::hash::Write::new(io::sink(), hash_kind); | 224 | let mut write = git_features::hash::Write::new(io::sink(), hash_kind); |
| 225 | loose::object::header::encode(kind, bytes.len() as u64, &mut write) | 225 | loose::object::header::encode(kind, bytes.len() as u64, &mut write) |
| 226 | .expect("write to sink and hash cannot fail"); | 226 | .expect("write to sink and hash cannot fail"); |
| 227 | write.hash.update(bytes); | 227 | write.hash.update(bytes); |