aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-07-10 09:20:25 +0200
committerKaren Arutyunov <karen@codesynthesis.com>2018-07-10 14:58:50 +0300
commit16b63f8cdf5b488ab2f4b0e029478b01a2d6b8a8 (patch)
tree78509ede9ae2652e8c82f01ec91b35eba3c3c7e4
parent681ca375fd5af01501a91a78214ab7a26ad67ac7 (diff)
Add support for hashing ifdstream
-rw-r--r--libbutl/sha1.cxx20
-rw-r--r--libbutl/sha1.mxx10
-rw-r--r--libbutl/sha256.cxx18
-rw-r--r--libbutl/sha256.mxx10
-rw-r--r--tests/sha1/driver.cxx38
-rw-r--r--tests/sha256/driver.cxx32
6 files changed, 122 insertions, 6 deletions
diff --git a/libbutl/sha1.cxx b/libbutl/sha1.cxx
index 8fdb833..af1f260 100644
--- a/libbutl/sha1.cxx
+++ b/libbutl/sha1.cxx
@@ -42,6 +42,8 @@ extern "C"
#define SHA1_Update(x, y, z) sha1_loop((x), (const uint8_t *)(y), (z))
#define SHA1_Final(x, y) sha1_result((y), (char(&)[20])(x))
+#include <cassert>
+
#ifndef __cpp_lib_modules
#include <string>
#include <cstddef>
@@ -53,12 +55,16 @@ extern "C"
#ifdef __cpp_modules
module butl.sha1;
+// Only imports additional to interface.
#ifdef __clang__
#ifdef __cpp_lib_modules
import std.core;
#endif
#endif
+import butl.fdstream;
+#else
+#include <libbutl/fdstream.mxx>
#endif
using namespace std;
@@ -78,6 +84,20 @@ namespace butl
SHA1_Update (reinterpret_cast<SHA1_CTX*> (buf_), b, n);
}
+ void sha1::
+ append (ifdstream& is)
+ {
+ fdbuf* buf (dynamic_cast<fdbuf*> (is.rdbuf ()));
+ assert (buf != nullptr);
+
+ while (is.peek () != ifdstream::traits_type::eof () && is.good ())
+ {
+ size_t n (buf->egptr () - buf->gptr ());
+ append (buf->gptr (), n);
+ buf->gbump (static_cast<int> (n));
+ }
+ }
+
const sha1::digest_type& sha1::
binary () const
{
diff --git a/libbutl/sha1.mxx b/libbutl/sha1.mxx
index a3b75d7..ea4d240 100644
--- a/libbutl/sha1.mxx
+++ b/libbutl/sha1.mxx
@@ -28,6 +28,8 @@ import std.core;
LIBBUTL_MODEXPORT namespace butl
{
+ class ifdstream;
+
// SHA1 checksum calculator.
//
// For a single chunk of data a sum can be obtained in one line, for
@@ -64,6 +66,14 @@ LIBBUTL_MODEXPORT namespace butl
explicit
sha1 (const char* s): sha1 () {append (s);}
+ // Append stream.
+ //
+ void
+ append (ifdstream&);
+
+ explicit
+ sha1 (ifdstream& i): sha1 () {append (i);}
+
// Extract result.
//
// It can be obtained as either a 20-byte binary digest or as a 40-
diff --git a/libbutl/sha256.cxx b/libbutl/sha256.cxx
index a688a15..c4556e7 100644
--- a/libbutl/sha256.cxx
+++ b/libbutl/sha256.cxx
@@ -27,6 +27,8 @@ extern "C"
#include "sha256c.c"
}
+#include <cassert>
+
#ifndef __cpp_lib_modules
#include <string>
#include <cstddef>
@@ -53,8 +55,10 @@ import std.core;
#endif
import butl.utility; // *case()
+import butl.fdstream;
#else
#include <libbutl/utility.mxx>
+#include <libbutl/fdstream.mxx>
#endif
using namespace std;
@@ -74,6 +78,20 @@ namespace butl
SHA256_Update (reinterpret_cast<SHA256_CTX*> (buf_), b, n);
}
+ void sha256::
+ append (ifdstream& is)
+ {
+ fdbuf* buf (dynamic_cast<fdbuf*> (is.rdbuf ()));
+ assert (buf != nullptr);
+
+ while (is.peek () != ifdstream::traits_type::eof () && is.good ())
+ {
+ size_t n (buf->egptr () - buf->gptr ());
+ append (buf->gptr (), n);
+ buf->gbump (static_cast<int> (n));
+ }
+ }
+
const sha256::digest_type& sha256::
binary () const
{
diff --git a/libbutl/sha256.mxx b/libbutl/sha256.mxx
index ba8eeea..c0c8a84 100644
--- a/libbutl/sha256.mxx
+++ b/libbutl/sha256.mxx
@@ -29,6 +29,8 @@ import std.core;
LIBBUTL_MODEXPORT namespace butl
{
+ class ifdstream;
+
// SHA256 checksum calculator.
//
// For a single chunk of data a sum can be obtained in one line, for
@@ -98,6 +100,14 @@ LIBBUTL_MODEXPORT namespace butl
append (&x, len);
}
+ // Append stream.
+ //
+ void
+ append (ifdstream&);
+
+ explicit
+ sha256 (ifdstream& i): sha256 () {append (i);}
+
// Extract result.
//
// It can be obtained as either a 32-byte binary digest or as a 64-
diff --git a/tests/sha1/driver.cxx b/tests/sha1/driver.cxx
index 5d53faa..92a8443 100644
--- a/tests/sha1/driver.cxx
+++ b/tests/sha1/driver.cxx
@@ -6,7 +6,7 @@
#ifndef __cpp_lib_modules
#include <string>
-#include <iostream>
+#include <cstddef> // size_t
#endif
// Other includes.
@@ -14,11 +14,16 @@
#ifdef __cpp_modules
#ifdef __cpp_lib_modules
import std.core;
-import std.io;
#endif
import butl.sha1;
+import butl.path;
+import butl.fdstream;
+import butl.filesystem;
#else
#include <libbutl/sha1.mxx>
+#include <libbutl/path.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/filesystem.mxx> // auto_rmfile
#endif
using namespace std;
@@ -37,8 +42,32 @@ main ()
"40bd001563085fc35165329ea1ff5c5ecbdbbeef");
{
+ string s;
+ for (size_t i (0); i < 1024; ++i)
+ s += "0123456789";
+
+ path p (path::temp_path ("butl-sha1"));
+
+ auto_rmfile pr; // Always remove the file after the stream is closed.
+ ofdstream os (p);
+ pr = auto_rmfile (p);
+
+ os << s;
+ os.close ();
+
+ ifdstream is (p);
+
+ assert (string (sha1 (is).string ()) ==
+ sha1 (s.c_str (), s.size ()).string ());
+
+ assert (is.eof ());
+ is.close ();
+ }
+
+ {
sha1 h ("123");
- assert (string (h.string ()) == "cc320164df1a2130045a28f08d3b88bc5bbcc43a");
+ assert (string (h.string ()) ==
+ "cc320164df1a2130045a28f08d3b88bc5bbcc43a");
assert (h.abbreviated_string (10) == "cc320164df");
assert (h.abbreviated_string (41) == h.string ());
@@ -53,6 +82,7 @@ main ()
auto& b (h.binary ());
assert (b[0] == 0x58 && b[19] == 0xfd);
- assert (string (h.string ()) == "58c596bafad8d007952934af1db9abc5401d4dfd");
+ assert (string (h.string ()) ==
+ "58c596bafad8d007952934af1db9abc5401d4dfd");
}
}
diff --git a/tests/sha256/driver.cxx b/tests/sha256/driver.cxx
index 5653e05..908b6ec 100644
--- a/tests/sha256/driver.cxx
+++ b/tests/sha256/driver.cxx
@@ -6,7 +6,7 @@
#ifndef __cpp_lib_modules
#include <string>
-#include <iostream>
+#include <cstddef> // size_t
#endif
// Other includes.
@@ -14,11 +14,16 @@
#ifdef __cpp_modules
#ifdef __cpp_lib_modules
import std.core;
-import std.io;
#endif
+import butl.path;
import butl.sha256;
+import butl.fdstream;
+import butl.filesystem;
#else
+#include <libbutl/path.mxx>
#include <libbutl/sha256.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/filesystem.mxx> // auto_rmfile
#endif
using namespace std;
@@ -37,6 +42,29 @@ main ()
"a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3");
{
+ string s;
+ for (size_t i (0); i < 1024; ++i)
+ s += "0123456789";
+
+ path p (path::temp_path ("butl-sha256"));
+
+ auto_rmfile pr; // Always remove the file after the stream is closed.
+ ofdstream os (p);
+ pr = auto_rmfile (p);
+
+ os << s;
+ os.close ();
+
+ ifdstream is (p);
+
+ assert (string (sha256 (is).string ()) ==
+ sha256 (s.c_str (), s.size ()).string ());
+
+ assert (is.eof ());
+ is.close ();
+ }
+
+ {
sha256 h ("123");
assert (string (h.string ()) ==