author | Michael Krelin <hacker@klever.net> | 2011-08-30 20:04:30 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2011-08-30 20:04:30 (UTC) |
commit | 111044b60ba5f40e003d1ba1d4082794985aa3ad (patch) (side-by-side diff) | |
tree | ce7949dad0cded81f47f7f067b43d2c29a795067 | |
parent | 09b6e86aaad70bc7488604b2e291d098a7de0eac (diff) | |
download | iii-111044b60ba5f40e003d1ba1d4082794985aa3ad.zip iii-111044b60ba5f40e003d1ba1d4082794985aa3ad.tar.gz iii-111044b60ba5f40e003d1ba1d4082794985aa3ad.tar.bz2 |
introduce incremental md5 digester
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | src/eyetil.cc | 14 | ||||
-rw-r--r-- | src/eyetil.h | 37 |
2 files changed, 51 insertions, 0 deletions
diff --git a/src/eyetil.cc b/src/eyetil.cc index 7669cb6..57ae607 100644 --- a/src/eyetil.cc +++ b/src/eyetil.cc @@ -57,32 +57,46 @@ std::string binary_t::hex() const { int rc = snprintf(t,sizeof(t),"%02x",*i); assert(rc<sizeof(t)); rv += t; } return rv; } binary_t binary_t::md5() const { binary_t rv(MD5_DIGEST_LENGTH); if(!MD5( (const unsigned char*)&(front()),size(), (unsigned char*)&(rv.front()) )) throw std::runtime_error("failed to md5()"); return rv; } +void md5_digester::init() { + if(!MD5_Init(&ctx)) throw std::runtime_error("failed to MD5_Init()"); +} +void md5_digester::update(const void *d,size_t l) { + if(!MD5_Update(&ctx,d,l)) throw std::runtime_error("failed to MD5_Update()"); +} +binary_t md5_digester::final() { + binary_t rv(MD5_DIGEST_LENGTH); + if(!MD5_Final((unsigned char*)&(rv.front()), &ctx)) + throw std::runtime_error("failed to MD5_Final()"); + return rv; +} + + static void make_path_for_template(const std::string& p,mode_t m) { struct stat st; std::string pp; for(std::string::size_type sl=p.find('/',1); sl!=std::string::npos; sl=p.find('/',sl+1)) { if(stat( (pp=p.substr(0,sl)).c_str() ,&st) || !S_ISDIR(st.st_mode)) { if(mkdir(pp.c_str(),m)) throw std::runtime_error("failed to mkdir()"); } } } tmpdir_t::tmpdir_t(const std::string& dt) : dir(dt) { make_path_for_template(dt,0777); diff --git a/src/eyetil.h b/src/eyetil.h index d946e71..eff2c43 100644 --- a/src/eyetil.h +++ b/src/eyetil.h @@ -1,39 +1,76 @@ #ifndef __EYETIL_H #define __EYETIL_H #include <vector> #include <string> #include <archive.h> #include <archive_entry.h> +#include "openssl/md5.h" class binary_t : public std::vector<unsigned char> { public: binary_t() { } binary_t(size_type n) : std::vector<unsigned char>(n) { } binary_t(const std::string& h) { from_hex(h); } binary_t(const void *d,size_t s) { from_data(d,s); } binary_t& from_hex(const std::string& h); binary_t& from_data(const void *d,size_t s); binary_t& make_nonce(); std::string hex() const; binary_t md5() const; }; +struct md5_digester { + MD5_CTX ctx; + md5_digester() { init(); } + + void init(); + void update(const void *d,size_t l); + binary_t final(); + + template<typename T> + void update(const T& x) { update(&x,sizeof(x)); } + + template<typename T> + struct update_iterator : public std::iterator<std::output_iterator_tag,T,void,T*,T&> { + md5_digester *d; + update_iterator(md5_digester *d_) : d(d_) { } + update_iterator(const update_iterator& x) : d(x.d) { } + + update_iterator& operator*() { return *this; } + update_iterator& operator++() { return *this; } + update_iterator& operator++(int) { return *this; } + + update_iterator& operator=(const T& x) { + d->update(x); return *this; + } + }; + + template<typename T> + update_iterator<T> updater() { + return update_iterator<T>(this); + } + +}; +template<> inline void md5_digester::update<binary_t>(const binary_t& x) { + update((const unsigned char*)&(x.front()),x.size()); +} + class tmpdir_t { public: std::string dir; tmpdir_t(const std::string& dt); ~tmpdir_t(); std::string get_file(const std::string& f); }; class tarchive_t { public: struct archive *a; struct archive_entry *e; tarchive_t(void *p,size_t s); |