Use SafeStringStream instead of std::stringstream to try to fix random crashes on...
authorCarl Hetherington <cth@carlh.net>
Tue, 19 Aug 2014 20:01:28 +0000 (21:01 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 19 Aug 2014 20:01:28 +0000 (21:01 +0100)
36 files changed:
ChangeLog
src/lib/analyse_audio_job.cc
src/lib/compose.hpp
src/lib/config.cc
src/lib/content.cc
src/lib/dcp_video_frame.cc
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_decoder.cc
src/lib/ffmpeg_examiner.cc
src/lib/film.cc
src/lib/filter_graph.cc
src/lib/image_content.cc
src/lib/internet.cc
src/lib/job.cc
src/lib/kdm.cc
src/lib/log.cc
src/lib/md5_digester.cc
src/lib/safe_stringstream.cc [new file with mode: 0644]
src/lib/safe_stringstream.h [new file with mode: 0644]
src/lib/server.cc
src/lib/server_finder.cc
src/lib/sndfile_content.cc
src/lib/stack.cpp
src/lib/transcode_job.cc
src/lib/update.cc
src/lib/util.cc
src/lib/video_content.cc
src/lib/wscript
src/tools/dcpomatic.cc
src/tools/dcpomatic_kdm.cc
src/tools/dcpomatic_server_cli.cc
src/wx/colour_conversion_editor.cc
src/wx/film_editor.cc
src/wx/job_wrapper.cc
src/wx/properties_dialog.cc
test/film_metadata_test.cc

index 04778b35f72b1a98fb7118b4c5538be69e591920..1f93e2f984435807c8facfd3d8f75d30fa3c4717 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-08-19  Carl Hetherington  <cth@carlh.net>
+
+       * Attempt to fix random crashes on OS X (especially during encodes)
+       thought to be caused by multiple threads using (different) stringstreams
+       at the same time; see src/lib/safe_stringstream.h
+
 2014-08-09  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.72.10 released.
index 8186f9de49b9d89baa81c04d7f454f876b8de963..ab985bdf75468ee557a81f0307d09a919df390e0 100644 (file)
@@ -87,7 +87,7 @@ AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time)
                for (int j = 0; j < b->channels(); ++j) {
                        float s = b->data(j)[i];
                        if (fabsf (s) < 10e-7) {
-                               /* stringstream can't serialise and recover inf or -inf, so prevent such
+                               /* SafeStringStream can't serialise and recover inf or -inf, so prevent such
                                   values by replacing with this (140dB down) */
                                s = 10e-7;
                        }
index b3f410c8ea52345112dc911671fe6756cbde9554..aa67b5a1fd8bc9f1027ab272b20c93ff744d8732 100644 (file)
 #ifndef STRING_COMPOSE_H
 #define STRING_COMPOSE_H
 
-#include <sstream>
 #include <string>
 #include <list>
 #include <map>                 // for multimap
+#include "safe_stringstream.h"
 
 namespace StringPrivate
 {
@@ -56,7 +56,7 @@ namespace StringPrivate
     std::string str() const;
 
   private:
-    std::ostringstream os;
+    SafeStringStream os;
     int arg_no;
 
     // we store the output as a list - when the output string is requested, the
index ee1b01386e4d6561154ebc084d39fa536cd92db7..d11bcf983f5365a872027570d840b1c5ff92dc36 100644 (file)
@@ -17,7 +17,6 @@
 
 */
 
-#include <sstream>
 #include <cstdlib>
 #include <fstream>
 #include <glib.h>
index 7966219ff60a4bf186a3af6ce58a6b52aa0a97e5..11a4b21cca3026706911cb0c51ea9230eabc8797 100644 (file)
 #include "ui_signaller.h"
 #include "exceptions.h"
 #include "film.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::set;
 using std::list;
 using std::cout;
@@ -230,7 +230,7 @@ Content::trimmed (Time t) const
 string
 Content::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
        
        s << Content::digest()
          << "_" << position()
index 09b909696f2fcbb89a028d295b66d843d37cff9e..bb7eaa064194e238ec66656b75e8caa7abc65088 100644 (file)
@@ -34,7 +34,6 @@
 #include <stdexcept>
 #include <cstdio>
 #include <iomanip>
-#include <sstream>
 #include <iostream>
 #include <fstream>
 #include <unistd.h>
@@ -67,7 +66,6 @@
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::cout;
 using boost::shared_ptr;
 using libdcp::Size;
@@ -282,10 +280,9 @@ DCPVideoFrame::encode_remotely (ServerDescription serv)
        LOG_GENERAL (N_("Sending frame %1 to remote"), _index);
        
        /* Send XML metadata */
-       stringstream xml;
-       doc.write_to_stream (xml, "UTF-8");
-       socket->write (xml.str().length() + 1);
-       socket->write ((uint8_t *) xml.str().c_str(), xml.str().length() + 1);
+       string xml = doc.write_to_string ("UTF-8");
+       socket->write (xml.length() + 1);
+       socket->write ((uint8_t *) xml.c_str(), xml.length() + 1);
 
        /* Send binary data */
        _frame->send_binary (socket);
index 4d886a6ddf224ceabc38d15369d9da1bb4261806..a4209f5b648306e734861c56ea96329b79a25a4a 100644 (file)
@@ -32,13 +32,13 @@ extern "C" {
 #include "log.h"
 #include "exceptions.h"
 #include "frame_rate_change.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 #define LOG_GENERAL(...) film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL);
 
 using std::string;
-using std::stringstream;
 using std::vector;
 using std::list;
 using std::cout;
@@ -241,7 +241,7 @@ FFmpegContent::information () const
                return "";
        }
        
-       stringstream s;
+       SafeStringStream s;
        
        s << String::compose (_("%1 frames; %2 frames per second"), video_length_after_3d_combine(), video_frame_rate()) << "\n";
        s << VideoContent::information ();
@@ -445,7 +445,7 @@ FFmpegContent::set_audio_mapping (AudioMapping m)
 string
 FFmpegContent::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
 
        s << VideoContent::identifier();
 
index 9ecc503dc6fb6d305375ff6729a1667b49ecdaf5..d40b798baafb77058f019e2bc6cf71817b5bd2f8 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <stdexcept>
 #include <vector>
-#include <sstream>
 #include <iomanip>
 #include <iostream>
 #include <stdint.h>
index bc82a9700f8c3b254ea287c43483919299a37de7..5fb20ef2c5dc9a4ed21822d500bedbc10e030398 100644 (file)
@@ -23,13 +23,13 @@ extern "C" {
 }
 #include "ffmpeg_examiner.h"
 #include "ffmpeg_content.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
 using std::cout;
 using std::max;
-using std::stringstream;
 using boost::shared_ptr;
 using boost::optional;
 
@@ -144,7 +144,7 @@ FFmpegExaminer::video_length () const
 string
 FFmpegExaminer::audio_stream_name (AVStream* s) const
 {
-       stringstream n;
+       SafeStringStream n;
 
        n << stream_name (s);
 
@@ -160,7 +160,7 @@ FFmpegExaminer::audio_stream_name (AVStream* s) const
 string
 FFmpegExaminer::subtitle_stream_name (AVStream* s) const
 {
-       stringstream n;
+       SafeStringStream n;
 
        n << stream_name (s);
 
@@ -174,7 +174,7 @@ FFmpegExaminer::subtitle_stream_name (AVStream* s) const
 string
 FFmpegExaminer::stream_name (AVStream* s) const
 {
-       stringstream n;
+       SafeStringStream n;
 
        if (s->metadata) {
                AVDictionaryEntry const * lang = av_dict_get (s->metadata, "language", 0, 0);
index 0a77caf502cc4405695a84c6db8aec6fa9f23387..2701d81b8374f619c205aa63589933da63717f39 100644 (file)
@@ -22,7 +22,6 @@
 #include <algorithm>
 #include <fstream>
 #include <cstdlib>
-#include <sstream>
 #include <iomanip>
 #include <unistd.h>
 #include <boost/filesystem.hpp>
 #include "ratio.h"
 #include "cross.h"
 #include "cinema.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::multimap;
 using std::pair;
 using std::map;
@@ -159,7 +158,7 @@ Film::video_identifier () const
 {
        assert (container ());
 
-       stringstream s;
+       SafeStringStream s;
        s.imbue (std::locale::classic ());
        
        s << container()->id()
@@ -493,7 +492,7 @@ Film::file (boost::filesystem::path f) const
 string
 Film::isdcf_name (bool if_created_now) const
 {
-       stringstream d;
+       SafeStringStream d;
 
        string raw_name = name ();
 
@@ -817,7 +816,7 @@ Film::info_path (int f, Eyes e) const
        boost::filesystem::path p;
        p /= info_dir ();
 
-       stringstream s;
+       SafeStringStream s;
        s.width (8);
        s << setfill('0') << f;
 
@@ -844,7 +843,7 @@ Film::j2c_path (int f, Eyes e, bool t) const
        p /= "j2c";
        p /= video_identifier ();
 
-       stringstream s;
+       SafeStringStream s;
        s.width (8);
        s << setfill('0') << f;
 
index c11ee633185aabac54837744b99604fa1f3b359a..0d72eacdfd2311c2a793065078bf178ff4e86a15 100644 (file)
@@ -34,10 +34,10 @@ extern "C" {
 #include "exceptions.h"
 #include "image.h"
 #include "ffmpeg_content.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
-using std::stringstream;
 using std::string;
 using std::list;
 using std::pair;
@@ -80,7 +80,7 @@ FilterGraph::FilterGraph (shared_ptr<const FFmpegContent> content, libdcp::Size
                throw DecodeError (N_("Could not create buffer sink filter"));
        }
 
-       stringstream a;
+       SafeStringStream a;
        a << "video_size=" << _size.width << "x" << _size.height << ":"
          << "pix_fmt=" << _pixel_format << ":"
          << "time_base=1/1:"
index 6acf0bab924001eaa5b51e1d1349ce134e5e719c..915da7beba33b70687e0536d751d4e8e6e96a65f 100644 (file)
 #include "film.h"
 #include "job.h"
 #include "frame_rate_change.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
 using std::cout;
-using std::stringstream;
 using boost::shared_ptr;
 
 ImageContent::ImageContent (shared_ptr<const Film> f, boost::filesystem::path p)
@@ -138,7 +138,7 @@ ImageContent::full_length () const
 string
 ImageContent::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
        s << VideoContent::identifier ();
        s << "_" << video_length();
        return s.str ();
index 99ae5c2142ed255d3731e1a667591e811bc63bb9..c28e650fdd92f4514bb850dacd13c7869b040ad4 100644 (file)
 #include <curl/curl.h>
 #include <zip.h>
 #include "util.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::list;
 using boost::optional;
 using boost::function;
@@ -130,11 +130,10 @@ ftp_ls (string url)
                return list<string> ();
        }
 
-       stringstream s (ls_raw);
-       string line;
+       SafeStringStream s (ls_raw);
        list<string> ls;
        while (s.good ()) {
-               getline (s, line);
+               string const line = s.getline ();
                if (line.length() > 55) {
                        string const file = line.substr (55);
                        if (file != "." && file != "..") {
index 530ad979830495cbe9a43ecbb90c3bc6082457f7..52ec1426c0bd0300a6658293471ef795e2e995ae 100644 (file)
 #include "cross.h"
 #include "ui_signaller.h"
 #include "exceptions.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
 using std::list;
 using std::cout;
-using std::stringstream;
 using boost::shared_ptr;
 
 Job::Job (shared_ptr<const Film> f)
@@ -306,7 +306,7 @@ Job::status () const
                pc = 99;
        }
 
-       stringstream s;
+       SafeStringStream s;
        if (!finished ()) {
                s << pc << N_("%");
                if (p >= 0 && t > 10 && r > 0) {
index 177dec078a8bc0770f6478b762b06014e6cf651d..f5054b8ed0c11d4d0522b14ba420348da90284a0 100644 (file)
 #include "util.h"
 #include "film.h"
 #include "config.h"
+#include "safe_stringstream.h"
 
 using std::list;
 using std::string;
-using std::stringstream;
 using std::cout;
 using boost::shared_ptr;
 
@@ -233,9 +233,9 @@ email_kdms (
                
                quickmail_initialize ();
 
-               stringstream start;
+               SafeStringStream start;
                start << from.date() << " " << from.time_of_day();
-               stringstream end;
+               SafeStringStream end;
                end << to.date() << " " << to.time_of_day();
                
                string subject = Config::instance()->kdm_subject();
@@ -259,7 +259,7 @@ email_kdms (
                boost::algorithm::replace_all (body, "$END_TIME", end.str ());
                boost::algorithm::replace_all (body, "$CINEMA_NAME", i->cinema->name);
                
-               stringstream screens;
+               SafeStringStream screens;
                for (list<ScreenKDM>::const_iterator j = i->screen_kdms.begin(); j != i->screen_kdms.end(); ++j) {
                        screens << j->screen->name << ", ";
                }
index 4de6bd874e94c4c97feed165a210de7b10169936..5e8277a23c5da6a023212defe579f9c5270212a7 100644 (file)
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "cross.h"
 #include "config.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -63,7 +64,7 @@ Log::log (string message, int type)
        time (&t);
        string a = ctime (&t);
 
-       stringstream s;
+       SafeStringStream s;
        s << a.substr (0, a.length() - 1) << N_(": ");
 
        if (type & TYPE_ERROR) {
@@ -90,7 +91,7 @@ Log::microsecond_log (string m, int t)
        struct timeval tv;
        gettimeofday (&tv, 0);
 
-       stringstream s;
+       SafeStringStream s;
        s << tv.tv_sec << N_(":") << tv.tv_usec << N_(" ") << m;
        do_log (s.str ());
 }      
index 1244209bd62fc149aea62d4f1f41025ce400d916..1d4d1974ad88fc1295307948d443a5dd5373e3ba 100644 (file)
 */
 
 #include <iomanip>
-#include <sstream>
 #include <openssl/md5.h>
 #include "md5_digester.h"
+#include "safe_stringstream.h"
 
 using std::string;
-using std::stringstream;
 using std::hex;
 using std::setfill;
 using std::setw;
@@ -51,7 +50,7 @@ MD5Digester::get () const
                unsigned char digest[MD5_DIGEST_LENGTH];
                MD5_Final (digest, &_context);
                
-               stringstream s;
+               SafeStringStream s;
                for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
                        s << hex << setfill('0') << setw(2) << ((int) digest[i]);
                }
diff --git a/src/lib/safe_stringstream.cc b/src/lib/safe_stringstream.cc
new file mode 100644 (file)
index 0000000..01d5450
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/thread/mutex.hpp>
+#include "safe_stringstream.h"
+
+boost::mutex SafeStringStream::_mutex;
diff --git a/src/lib/safe_stringstream.h b/src/lib/safe_stringstream.h
new file mode 100644 (file)
index 0000000..e455de9
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+    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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef DCPOMATIC_SAFE_STRINGSTREAM_H
+#define DCPOMATIC_SAFE_STRINGSTREAM_H
+
+#include <boost/thread/mutex.hpp>
+
+/* I've not been able to reproduce it, but there have been reports that DCP-o-matic crashes
+ * on OS X with two simultaneous backtraces that look like this:
+ *
+ * 0 libSystem.B.dylib  0x00007fff84ebe264 __numeric_load_locale + 125
+ * 1 libSystem.B.dylib  0x00007fff84e2aac4 loadlocale + 323
+ * 2 libstdc++.6.dylib  0x00007fff8976ba69 std::__convert_from_v(int* const&, char*, int, char const*, ...) + 199
+ * 3 libstdc++.6.dylib  0x00007fff8974e99b std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char,
+std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const + 199
+ * 4 libstdc++.6.dylib  0x00007fff8974ebc0 std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> >
+>::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const + 28
+ * 5 libstdc++.6.dylib  0x00007fff897566a2 std::ostream& std::ostream::_M_insert<double>(double) + 178
+ * 6 libdcpomatic.dylib 0x0000000100331e21 StringPrivate::Composition& StringPrivate::Composition::arg<float>(float const&) + 33
+ *
+ * in two different threads.  I'm assuming that for some bizarre reason it is unsafe to use two separate stringstream
+ * objects in different threads on OS X.  This is a hack to work around it.
+ */
+
+class SafeStringStream
+{
+public:
+       SafeStringStream ()
+       {}
+       
+       SafeStringStream (std::string s)
+               : _stream (s)
+       {}
+       
+       template <class T>
+       std::ostream& operator<< (T val)
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stream << val;
+               return _stream;
+       }
+
+       template <class T>
+       std::istream& operator>> (T& val)
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stream >> val;
+               return _stream;
+       }
+
+       std::string str () const {
+               return _stream.str ();
+       }
+
+       void str (std::string const & s) {
+               _stream.str (s);
+       }
+
+       void imbue (std::locale const & loc)
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stream.imbue (loc);
+       }
+
+       void width (int w)
+       {
+               _stream.width (w);
+       }
+
+       void precision (int p)
+       {
+               _stream.precision (p);
+       }
+
+       bool good () const
+       {
+               return _stream.good ();
+       }
+
+       std::string getline ()
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               std::string s;
+               std::getline (_stream, s);
+               return s;
+       }
+
+       void setf (std::ios_base::fmtflags flags, std::ios_base::fmtflags mask)
+       {
+               _stream.setf (flags, mask);
+       }
+
+private:
+       static boost::mutex _mutex;
+       std::stringstream _stream;
+};
+
+#endif
index f1c6d6c44afd0e34d6eb3436a1a493042a6a52c8..9591be1886414dc77f6f335dbb976c0c857bad93 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <string>
 #include <vector>
-#include <sstream>
 #include <iostream>
 #include <boost/algorithm/string.hpp>
 #include <boost/scoped_array.hpp>
@@ -38,6 +37,7 @@
 #include "config.h"
 #include "cross.h"
 #include "player_video_frame.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -47,7 +47,6 @@
 #define LOG_ERROR_NC(...)   _log->log (__VA_ARGS__, Log::TYPE_ERROR);
 
 using std::string;
-using std::stringstream;
 using std::multimap;
 using std::vector;
 using std::list;
@@ -82,9 +81,9 @@ Server::process (shared_ptr<Socket> socket, struct timeval& after_read, struct t
        scoped_array<char> buffer (new char[length]);
        socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
 
-       stringstream s (buffer.get());
+       string s (buffer.get());
        shared_ptr<cxml::Document> xml (new cxml::Document ("EncodingRequest"));
-       xml->read_stream (s);
+       xml->read_string (s);
        if (xml->number_child<int> ("Version") != SERVER_LINK_VERSION) {
                cerr << "Mismatched server/client versions\n";
                LOG_ERROR_NC ("Mismatched server/client versions");
@@ -154,7 +153,7 @@ Server::worker_thread ()
                        struct timeval end;
                        gettimeofday (&end, 0);
 
-                       stringstream message;
+                       SafeStringStream message;
                        message.precision (2);
                        message << fixed
                                << "Encoded frame " << frame << " from " << ip << ": "
@@ -246,14 +245,13 @@ Server::broadcast_received ()
                xmlpp::Document doc;
                xmlpp::Element* root = doc.create_root_node ("ServerAvailable");
                root->add_child("Threads")->add_child_text (raw_convert<string> (_worker_threads.size ()));
-               stringstream xml;
-               doc.write_to_stream (xml, "UTF-8");
+               string xml = doc.write_to_string ("UTF-8");
 
                shared_ptr<Socket> socket (new Socket);
                try {
                        socket->connect (boost::asio::ip::tcp::endpoint (_broadcast.send_endpoint.address(), Config::instance()->server_port_base() + 1));
-                       socket->write (xml.str().length() + 1);
-                       socket->write ((uint8_t *) xml.str().c_str(), xml.str().length() + 1);
+                       socket->write (xml.length() + 1);
+                       socket->write ((uint8_t *) xml.c_str(), xml.length() + 1);
                } catch (...) {
 
                }
index 65e0940a0a11aab9469f32247a0a58ba36e11ba3..744a65f597300fcc809b6daab70e32f8ccd0f0a0 100644 (file)
@@ -27,7 +27,6 @@
 #include "ui_signaller.h"
 
 using std::string;
-using std::stringstream;
 using std::list;
 using std::vector;
 using std::cout;
@@ -116,9 +115,9 @@ try
                scoped_array<char> buffer (new char[length]);
                sock->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
                
-               stringstream s (buffer.get());
+               string s (buffer.get());
                shared_ptr<cxml::Document> xml (new cxml::Document ("ServerAvailable"));
-               xml->read_stream (s);
+               xml->read_string (s);
 
                string const ip = sock->socket().remote_endpoint().address().to_string ();
                if (!server_found (ip)) {
index 3efba6fd5db219c38e6f93249d28155786020934..ba3bd0a772d489714a01bebd7c90d56ab1b063e6 100644 (file)
 #include "compose.hpp"
 #include "job.h"
 #include "util.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::cout;
 using boost::shared_ptr;
 using libdcp::raw_convert;
@@ -76,7 +76,7 @@ SndfileContent::information () const
                return "";
        }
        
-       stringstream s;
+       SafeStringStream s;
 
        s << String::compose (
                _("%1 channels, %2kHz, %3 samples"),
index a8183d3444c7c426f47fcbcc3d60b70548039f47..167524017a0a2232eca56ff880d0b943e9091dde 100644 (file)
@@ -9,7 +9,6 @@
 #include <iomanip>
 #include <ostream>
 #include <stdexcept>
-#include <sstream>
 
 #include "stack.hpp"
 
index 675a951160cd31f2027da12d6f2c3ac89d146c03..831c74b3b244d9a78b4369eb3d089852c74c9174 100644 (file)
@@ -27,6 +27,7 @@
 #include "film.h"
 #include "transcoder.h"
 #include "log.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -34,7 +35,6 @@
 #define LOG_ERROR_NC(...)   _film->log()->log (__VA_ARGS__, Log::TYPE_ERROR);
 
 using std::string;
-using std::stringstream;
 using std::fixed;
 using std::setprecision;
 using boost::shared_ptr;
@@ -89,7 +89,7 @@ TranscodeJob::status () const
                return Job::status ();
        }
 
-       stringstream s;
+       SafeStringStream s;
 
        s << Job::status ();
 
index af3e46f0e7d14ea1abb8d64c4c4e467143588547..7bec061e9292e15d044c360e8c13d60dc6a0faab 100644 (file)
@@ -18,7 +18,6 @@
 */
 
 #include <string>
-#include <sstream>
 #include <boost/algorithm/string.hpp>
 #include <curl/curl.h>
 #include <libcxml/cxml.h>
 #include "update.h"
 #include "version.h"
 #include "ui_signaller.h"
+#include "safe_stringstream.h"
 
 #define BUFFER_SIZE 1024
 
 using std::cout;
 using std::min;
 using std::string;
-using std::stringstream;
 using libdcp::raw_convert;
 
 UpdateChecker* UpdateChecker::_instance = 0;
@@ -103,10 +102,9 @@ UpdateChecker::thread ()
                        }
                        
                        _buffer[_offset] = '\0';
-                       stringstream s;
-                       s << _buffer;
+                       string s (_buffer);
                        cxml::Document doc ("Update");
-                       doc.read_stream (s);
+                       doc.read_string (s);
                        
                        {
                                boost::mutex::scoped_lock lm (_data_mutex);
index 6f39073910e8ee055c3197535ee3cc98dd35cee0..d96001d13916fcf3eda519c625ce0d68f15b512a 100644 (file)
@@ -22,7 +22,6 @@
  *  @brief Some utility functions and classes.
  */
 
-#include <sstream>
 #include <iomanip>
 #include <iostream>
 #include <fstream>
@@ -70,6 +69,7 @@ extern "C" {
 #include "cross.h"
 #include "video_content.h"
 #include "md5_digester.h"
+#include "safe_stringstream.h"
 #ifdef DCPOMATIC_WINDOWS
 #include "stack.hpp"
 #endif
@@ -77,7 +77,6 @@ extern "C" {
 #include "i18n.h"
 
 using std::string;
-using std::stringstream;
 using std::setfill;
 using std::ostream;
 using std::endl;
@@ -121,7 +120,7 @@ seconds_to_hms (int s)
        int h = m / 60;
        m -= (h * 60);
 
-       stringstream hms;
+       SafeStringStream hms;
        hms << h << N_(":");
        hms.width (2);
        hms << std::setfill ('0') << m << N_(":");
@@ -142,7 +141,7 @@ seconds_to_approximate_hms (int s)
        int h = m / 60;
        m -= (h * 60);
 
-       stringstream ap;
+       SafeStringStream ap;
 
        bool const hours = h > 0;
        bool const minutes = h < 10 && m > 0;
@@ -261,7 +260,7 @@ stacktrace (ostream& out, int levels)
 static string
 ffmpeg_version_to_string (int v)
 {
-       stringstream s;
+       SafeStringStream s;
        s << ((v & 0xff0000) >> 16) << N_(".") << ((v & 0xff00) >> 8) << N_(".") << (v & 0xff);
        return s.str ();
 }
@@ -270,7 +269,7 @@ ffmpeg_version_to_string (int v)
 string
 dependency_version_summary ()
 {
-       stringstream s;
+       SafeStringStream s;
        s << N_("libopenjpeg ") << opj_version () << N_(", ")
          << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ")
          << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ")
index 15e1ca7911982b9dc811de4481f7f386e9035688..b0d4c2de506cb2b4abd828639365b8d786342354 100644 (file)
@@ -31,6 +31,7 @@
 #include "film.h"
 #include "exceptions.h"
 #include "frame_rate_change.h"
+#include "safe_stringstream.h"
 
 #include "i18n.h"
 
@@ -42,7 +43,6 @@ int const VideoContentProperty::VIDEO_SCALE     = 4;
 int const VideoContentProperty::COLOUR_CONVERSION = 5;
 
 using std::string;
-using std::stringstream;
 using std::setprecision;
 using std::cout;
 using std::vector;
@@ -207,7 +207,7 @@ VideoContent::information () const
                return "";
        }
        
-       stringstream s;
+       SafeStringStream s;
 
        s << String::compose (
                _("%1x%2 pixels (%3:1)"),
@@ -299,7 +299,7 @@ VideoContent::set_scale (VideoContentScale s)
 string
 VideoContent::identifier () const
 {
-       stringstream s;
+       SafeStringStream s;
        s << Content::identifier()
          << "_" << crop().left
          << "_" << crop().right
@@ -473,7 +473,7 @@ VideoContentScale::as_xml (xmlpp::Node* node) const
 string
 VideoContentScale::id () const
 {
-       stringstream s;
+       SafeStringStream s;
        
        if (_ratio) {
                s << _ratio->id () << "_";
index f53ae7b74db8dbb4923b97ca13ea4228e3a1bd0a..1e4efddc4fbb2e49986265a2a877f44344ecd930 100644 (file)
@@ -48,6 +48,7 @@ sources = """
           playlist.cc
           ratio.cc
           resampler.cc
+          safe_stringstream.cc
           scp_dcp_job.cc
           scaler.cc
           send_kdm_email_job.cc
index cd2978052add1f55409eda32784413bd5f0e84f2..c92f5b6cf8b182004a9879076dd5b2305db8fd20 100644 (file)
@@ -64,7 +64,6 @@
 using std::cout;
 using std::string;
 using std::wstring;
-using std::stringstream;
 using std::map;
 using std::make_pair;
 using std::list;
index 092a1ca1b0725027a5026491ea1efb54b93a7866..758060a08e7aea7e49ce27594c03ece111926d64 100644 (file)
@@ -24,9 +24,9 @@
 #include "lib/kdm.h"
 #include "lib/config.h"
 #include "lib/exceptions.h"
+#include "lib/safe_stringstream.h"
 
 using std::string;
-using std::stringstream;
 using std::cout;
 using std::cerr;
 using std::list;
@@ -76,7 +76,7 @@ time_from_string (string t)
 static boost::posix_time::time_duration
 duration_from_string (string d)
 {
-       stringstream s (d);
+       SafeStringStream s (d);
        int N;
        string unit;
        s >> N >> unit;
index e4ac85f4cb6d48f47f19786238ec1a5c221fddc6..f35797954ae907ff237146c2480ecc3289574bff 100644 (file)
@@ -20,7 +20,6 @@
 #include "lib/server.h"
 #include <iostream>
 #include <stdexcept>
-#include <sstream>
 #include <cstring>
 #include <vector>
 #include <unistd.h>
index 6617b66d6ca44dbae258041628898663dda3c979..4a1e5074fa625073be95def3dcbc5b34fb39b5a6 100644 (file)
 #include <wx/spinctrl.h>
 #include <wx/gbsizer.h>
 #include "lib/colour_conversion.h"
+#include "lib/safe_stringstream.h"
 #include "wx_util.h"
 #include "colour_conversion_editor.h"
 
 using std::string;
 using std::cout;
-using std::stringstream;
 using boost::shared_ptr;
 using boost::lexical_cast;
 
@@ -110,7 +110,7 @@ ColourConversionEditor::set (ColourConversion conversion)
        _input_gamma_linearised->SetValue (conversion.input_gamma_linearised);
        for (int i = 0; i < 3; ++i) {
                for (int j = 0; j < 3; ++j) {
-                       stringstream s;
+                       SafeStringStream s;
                        s.setf (std::ios::fixed, std::ios::floatfield);
                        s.precision (7);
                        s << conversion.matrix (i, j);
index b341cb0fee6775f5092e4b99d57b0588ec576393..87310d21ae598ac93d1b67a8e40d3b2e8c61082c 100644 (file)
@@ -45,6 +45,7 @@
 #include "lib/playlist.h"
 #include "lib/content.h"
 #include "lib/content_factory.h"
+#include "lib/safe_stringstream.h"
 #include "timecode.h"
 #include "wx_util.h"
 #include "film_editor.h"
@@ -57,7 +58,6 @@
 
 using std::string;
 using std::cout;
-using std::stringstream;
 using std::pair;
 using std::fixed;
 using std::setprecision;
@@ -420,7 +420,7 @@ FilmEditor::film_changed (Film::Property p)
                return;
        }
 
-       stringstream s;
+       SafeStringStream s;
 
        for (list<FilmEditorPanel*>::iterator i = _panels.begin(); i != _panels.end(); ++i) {
                (*i)->film_changed (p);
index df4aa7d2e78a740c786caffb1250a798c065a864..4c4ef049b8156ceda036ce3600235a0dc2ac2b5b 100644 (file)
@@ -17,7 +17,6 @@
 
 */
 
-#include <sstream>
 #include "lib/film.h"
 #include "lib/exceptions.h"
 #include "job_wrapper.h"
index 28247bc33eb3c62b9ef85a7dea83785be7b4fa54..53ca237555af31672f2dd2517038dc829ce270bf 100644 (file)
 #include <boost/bind.hpp>
 #include "lib/film.h"
 #include "lib/config.h"
+#include "lib/safe_stringstream.h"
 #include "properties_dialog.h"
 #include "wx_util.h"
 
 using std::string;
-using std::stringstream;
 using std::fixed;
 using std::setprecision;
 using boost::shared_ptr;
@@ -48,7 +48,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr<Film> film)
        
        _frames->SetLabel (std_to_wx (lexical_cast<string> (_film->time_to_video_frames (_film->length()))));
        double const disk = double (_film->required_disk_space()) / 1073741824.0f;
-       stringstream s;
+       SafeStringStream s;
        s << fixed << setprecision (1) << disk << wx_to_std (_("Gb"));
        _disk->SetLabel (std_to_wx (s.str ()));
 
@@ -58,7 +58,7 @@ PropertiesDialog::PropertiesDialog (wxWindow* parent, shared_ptr<Film> film)
 string
 PropertiesDialog::frames_already_encoded () const
 {
-       stringstream u;
+       SafeStringStream u;
        try {
                u << _film->encoded_frames ();
        } catch (boost::thread_interrupted &) {
index c41e8618900af948c77cd85e1f8e4fabb7bd410b..c9f4a2c38faaab5b4d82bbb0ece8a550b0fc3537 100644 (file)
@@ -17,7 +17,6 @@
 
 */
 
-#include <sstream>
 #include <boost/test/unit_test.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/date_time.hpp>