Add write_string_to_file().
[libdcp.git] / src / util.cc
index 5133a43bac8dc83fcc76ac46313cb50a0c8b0e97..a920ce0eae0cb717ff78298a45df79284f34cbd6 100644 (file)
  */
 
 
-#include "util.h"
-#include "language_tag.h"
-#include "exceptions.h"
-#include "types.h"
 #include "certificate.h"
-#include "openjpeg_image.h"
-#include "dcp_assert.h"
 #include "compose.hpp"
+#include "dcp_assert.h"
+#include "exceptions.h"
+#include "file.h"
+#include "filesystem.h"
+#include "language_tag.h"
+#include "openjpeg_image.h"
+#include "rating.h"
+#include "types.h"
+#include "util.h"
 #include <openjpeg.h>
 #include <asdcp/KM_util.h>
 #include <asdcp/KM_fileio.h>
@@ -114,10 +117,10 @@ dcp::make_digest (ArrayData data)
 
 
 string
-dcp::make_digest (boost::filesystem::path filename, function<void (float)> progress)
+dcp::make_digest(boost::filesystem::path filename, function<void (int64_t, int64_t)> progress)
 {
        Kumu::FileReader reader;
-       auto r = reader.OpenRead (filename.string().c_str ());
+       auto r = reader.OpenRead(dcp::filesystem::fix_long_path(filename).string().c_str());
        if (ASDCP_FAILURE(r)) {
                boost::throw_exception (FileError("could not open file to compute digest", filename, r));
        }
@@ -143,7 +146,7 @@ dcp::make_digest (boost::filesystem::path filename, function<void (float)> progr
                SHA1_Update (&sha, read_buffer.Data(), read);
 
                if (progress) {
-                       progress (float (done) / size);
+                       progress(done, size);
                        done += read;
                }
        }
@@ -156,21 +159,8 @@ dcp::make_digest (boost::filesystem::path filename, function<void (float)> progr
 }
 
 
-bool
-dcp::empty_or_white_space (string s)
-{
-       for (size_t i = 0; i < s.length(); ++i) {
-               if (s[i] != ' ' && s[i] != '\n' && s[i] != '\t') {
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-
 void
-dcp::init (optional<boost::filesystem::path> tags_directory)
+dcp::init (optional<boost::filesystem::path> given_resources_directory)
 {
        if (xmlSecInit() < 0) {
                throw MiscError ("could not initialise xmlsec");
@@ -194,11 +184,10 @@ dcp::init (optional<boost::filesystem::path> tags_directory)
 
        asdcp_smpte_dict = &ASDCP::DefaultSMPTEDict();
 
-       if (!tags_directory) {
-               tags_directory = resources_directory() / "tags";
-       }
+       auto res = given_resources_directory.get_value_or(resources_directory());
 
-       load_language_tag_lists (*tags_directory);
+       load_language_tag_lists (res / "tags");
+       load_rating_list (res / "ratings");
 }
 
 
@@ -228,19 +217,6 @@ dcp::base64_decode (string const & in, unsigned char* out, int out_length)
 }
 
 
-FILE *
-dcp::fopen_boost (boost::filesystem::path p, string t)
-{
-#ifdef LIBDCP_WINDOWS
-        wstring w (t.begin(), t.end());
-       /* c_str() here should give a UTF-16 string */
-        return _wfopen (p.c_str(), w.c_str ());
-#else
-        return fopen (p.c_str(), t.c_str ());
-#endif
-}
-
-
 optional<boost::filesystem::path>
 dcp::relative_to_root (boost::filesystem::path root, boost::filesystem::path file)
 {
@@ -279,25 +255,32 @@ dcp::ids_equal (string a, string b)
 string
 dcp::file_to_string (boost::filesystem::path p, uintmax_t max_length)
 {
-       auto len = boost::filesystem::file_size (p);
+       auto len = filesystem::file_size(p);
        if (len > max_length) {
                throw MiscError (String::compose("Unexpectedly long file (%1)", p.string()));
        }
 
-       auto f = fopen_boost (p, "r");
+       File f(p, "r");
        if (!f) {
                throw FileError ("could not open file", p, errno);
        }
 
-       char* c = new char[len];
+       std::vector<char> buffer(len);
        /* This may read less than `len' if we are on Windows and we have CRLF in the file */
-       int const N = fread (c, 1, len, f);
-       fclose (f);
+       int const N = f.read(buffer.data(), 1, len);
+       return string(buffer.data(), N);
+}
 
-       string s (c, N);
-       delete[] c;
 
-       return s;
+void
+dcp::write_string_to_file(string const& string, boost::filesystem::path const& path)
+{
+       File file(path, "w");
+       if (!file) {
+               throw FileError("could not open file", path, errno);
+       }
+
+       file.write(string.c_str(), string.length(), 1);
 }
 
 
@@ -306,6 +289,8 @@ dcp::private_key_fingerprint (string key)
 {
        boost::replace_all (key, "-----BEGIN RSA PRIVATE KEY-----\n", "");
        boost::replace_all (key, "\n-----END RSA PRIVATE KEY-----\n", "");
+       boost::replace_all (key, "-----BEGIN PRIVATE KEY-----\n", "");
+       boost::replace_all (key, "\n-----END PRIVATE KEY-----\n", "");
 
        unsigned char buffer[4096];
        int const N = base64_decode (key, buffer, sizeof (buffer));
@@ -338,7 +323,10 @@ dcp::find_child (xmlpp::Node const * node, string name)
 string
 dcp::remove_urn_uuid (string raw)
 {
-       DCP_ASSERT (raw.substr(0, 9) == "urn:uuid:");
+       if (raw.substr(0, 9) != "urn:uuid:") {
+               throw BadURNUUIDError(raw);
+       }
+
        return raw.substr (9);
 }
 
@@ -442,7 +430,7 @@ ASDCPErrorSuspender::~ASDCPErrorSuspender ()
 boost::filesystem::path dcp::directory_containing_executable ()
 {
 #if BOOST_VERSION >= 106100
-       return boost::filesystem::canonical(boost::dll::program_location().parent_path());
+       return filesystem::canonical(boost::dll::program_location().parent_path());
 #else
        char buffer[PATH_MAX];
        ssize_t N = readlink ("/proc/self/exe", buffer, PATH_MAX);