Small fixes and tidy-ups spotted by cppcheck.
[dcpomatic.git] / src / lib / util.cc
index 3ab864c2ff5db919c31b5224dc5731dd52379444..807883ca0906ffc787ff8da0f54533c50566df9e 100644 (file)
@@ -1,6 +1,5 @@
 /*
     Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
-    Copyright (C) 2000-2007 Paul Davis
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -288,9 +287,8 @@ set_backtrace_file (boost::filesystem::path p)
 void
 terminate ()
 {
-       static bool tried_throw = false;
-
        try {
+               static bool tried_throw = false;
                // try once to re-throw currently active exception
                if (!tried_throw) {
                        tried_throw = true;
@@ -418,69 +416,53 @@ dcpomatic_setup_gettext_i18n (string lang)
 #endif
 }
 
-/** @param s A string.
- *  @return Parts of the string split at spaces, except when a space is within quotation marks.
- */
-vector<string>
-split_at_spaces_considering_quotes (string s)
-{
-       vector<string> out;
-       bool in_quotes = false;
-       string c;
-       for (string::size_type i = 0; i < s.length(); ++i) {
-               if (s[i] == ' ' && !in_quotes) {
-                       out.push_back (c);
-                       c = N_("");
-               } else if (s[i] == '"') {
-                       in_quotes = !in_quotes;
-               } else {
-                       c += s[i];
-               }
-       }
-
-       out.push_back (c);
-       return out;
-}
-
-/** @param job Optional job for which to report progress */
+/** Compute a digest of the first and last `size' bytes of a set of files. */
 string
-md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
+md5_digest_head_tail (vector<boost::filesystem::path> files, boost::uintmax_t size)
 {
-       boost::uintmax_t const buffer_size = 64 * 1024;
-       char buffer[buffer_size];
-
+       boost::scoped_array<char> buffer (new char[size]);
        MD5Digester digester;
 
-       vector<int64_t> sizes;
-       for (size_t i = 0; i < files.size(); ++i) {
-               sizes.push_back (boost::filesystem::file_size (files[i]));
-       }
-
-       for (size_t i = 0; i < files.size(); ++i) {
+       /* Head */
+       boost::uintmax_t to_do = size;
+       char* p = buffer.get ();
+       int i = 0;
+       while (i < int64_t (files.size()) && to_do > 0) {
                FILE* f = fopen_boost (files[i], "rb");
                if (!f) {
                        throw OpenFileError (files[i].string());
                }
 
-               boost::uintmax_t const bytes = boost::filesystem::file_size (files[i]);
-               boost::uintmax_t remaining = bytes;
-
-               while (remaining > 0) {
-                       int const t = min (remaining, buffer_size);
-                       int const r = fread (buffer, 1, t, f);
-                       if (r != t) {
-                               throw ReadFileError (files[i], errno);
-                       }
-                       digester.add (buffer, t);
-                       remaining -= t;
-
-                       if (job) {
-                               job->set_progress ((float (i) + 1 - float(remaining) / bytes) / files.size ());
-                       }
+               boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i]));
+               fread (p, 1, this_time, f);
+               p += this_time;
+               to_do -= this_time;
+               fclose (f);
+
+               ++i;
+       }
+       digester.add (buffer.get(), size - to_do);
+
+       /* Tail */
+       to_do = size;
+       p = buffer.get ();
+       i = files.size() - 1;
+       while (i >= 0 && to_do > 0) {
+               FILE* f = fopen_boost (files[i], "rb");
+               if (!f) {
+                       throw OpenFileError (files[i].string());
                }
 
+               boost::uintmax_t this_time = min (to_do, boost::filesystem::file_size (files[i]));
+               fseek (f, -this_time, SEEK_END);
+               fread (p, 1, this_time, f);
+               p += this_time;
+               to_do -= this_time;
                fclose (f);
-       }
+
+               --i;
+       }               
+       digester.add (buffer.get(), size - to_do);
 
        return digester.get ();
 }
@@ -651,103 +633,6 @@ round_to (float n, int r)
        return int (n + float(r) / 2) &~ (r - 1);
 }
 
-/** Read a sequence of key / value pairs from a text stream;
- *  the keys are the first words on the line, and the values are
- *  the remainder of the line following the key.  Lines beginning
- *  with # are ignored.
- *  @param s Stream to read.
- *  @return key/value pairs.
- */
-multimap<string, string>
-read_key_value (istream &s) 
-{
-       multimap<string, string> kv;
-       
-       string line;
-       while (getline (s, line)) {
-               if (line.empty ()) {
-                       continue;
-               }
-
-               if (line[0] == '#') {
-                       continue;
-               }
-
-               if (line[line.size() - 1] == '\r') {
-                       line = line.substr (0, line.size() - 1);
-               }
-
-               size_t const s = line.find (' ');
-               if (s == string::npos) {
-                       continue;
-               }
-
-               kv.insert (make_pair (line.substr (0, s), line.substr (s + 1)));
-       }
-
-       return kv;
-}
-
-string
-get_required_string (multimap<string, string> const & kv, string k)
-{
-       if (kv.count (k) > 1) {
-               throw StringError (N_("unexpected multiple keys in key-value set"));
-       }
-
-       multimap<string, string>::const_iterator i = kv.find (k);
-       
-       if (i == kv.end ()) {
-               throw StringError (String::compose (_("missing key %1 in key-value set"), k));
-       }
-
-       return i->second;
-}
-
-int
-get_required_int (multimap<string, string> const & kv, string k)
-{
-       string const v = get_required_string (kv, k);
-       return raw_convert<int> (v);
-}
-
-float
-get_required_float (multimap<string, string> const & kv, string k)
-{
-       string const v = get_required_string (kv, k);
-       return raw_convert<float> (v);
-}
-
-string
-get_optional_string (multimap<string, string> const & kv, string k)
-{
-       if (kv.count (k) > 1) {
-               throw StringError (N_("unexpected multiple keys in key-value set"));
-       }
-
-       multimap<string, string>::const_iterator i = kv.find (k);
-       if (i == kv.end ()) {
-               return N_("");
-       }
-
-       return i->second;
-}
-
-int
-get_optional_int (multimap<string, string> const & kv, string k)
-{
-       if (kv.count (k) > 1) {
-               throw StringError (N_("unexpected multiple keys in key-value set"));
-       }
-
-       multimap<string, string>::const_iterator i = kv.find (k);
-       if (i == kv.end ()) {
-               return 0;
-       }
-
-       return raw_convert<int> (i->second);
-}
-
 /** Trip an assert if the caller is not in the UI thread */
 void
 ensure_ui_thread ()
@@ -836,24 +721,6 @@ wrapped_av_malloc (size_t s)
        return p;
 }
                
-string
-entities_to_text (string e)
-{
-       boost::algorithm::replace_all (e, "%3A", ":");
-       boost::algorithm::replace_all (e, "%2F", "/");
-       return e;
-}
-
-int64_t
-divide_with_round (int64_t a, int64_t b)
-{
-       if (a % b >= (b / 2)) {
-               return (a + b - 1) / b;
-       } else {
-               return a / b;
-       }
-}
-
 /** Return a user-readable string summarising the versions of our dependencies */
 string
 dependency_version_summary ()