From: Carl Hetherington Date: Tue, 19 Aug 2014 20:01:28 +0000 (+0100) Subject: Use SafeStringStream instead of std::stringstream to try to fix random crashes on... X-Git-Tag: v2.0.48~561^2~76 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=9a2b45caa81d8fb056802dfe3c25f214e808ffdf Use SafeStringStream instead of std::stringstream to try to fix random crashes on OS X. --- diff --git a/ChangeLog b/ChangeLog index 04778b35f..1f93e2f98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-08-19 Carl Hetherington + + * 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 * Version 1.72.10 released. diff --git a/src/lib/analyse_audio_job.cc b/src/lib/analyse_audio_job.cc index 8186f9de4..ab985bdf7 100644 --- a/src/lib/analyse_audio_job.cc +++ b/src/lib/analyse_audio_job.cc @@ -87,7 +87,7 @@ AnalyseAudioJob::audio (shared_ptr 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; } diff --git a/src/lib/compose.hpp b/src/lib/compose.hpp index b3f410c8e..aa67b5a1f 100644 --- a/src/lib/compose.hpp +++ b/src/lib/compose.hpp @@ -33,10 +33,10 @@ #ifndef STRING_COMPOSE_H #define STRING_COMPOSE_H -#include #include #include #include // 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 diff --git a/src/lib/config.cc b/src/lib/config.cc index ee1b01386..d11bcf983 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -17,7 +17,6 @@ */ -#include #include #include #include diff --git a/src/lib/content.cc b/src/lib/content.cc index 7966219ff..11a4b21cc 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -27,11 +27,11 @@ #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() diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc index 09b909696..bb7eaa064 100644 --- a/src/lib/dcp_video_frame.cc +++ b/src/lib/dcp_video_frame.cc @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -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); diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 4d886a6dd..a4209f5b6 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -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(); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 9ecc503dc..d40b798ba 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc index bc82a9700..5fb20ef2c 100644 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@ -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); diff --git a/src/lib/film.cc b/src/lib/film.cc index 0a77caf50..2701d81b8 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -55,11 +54,11 @@ #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; diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index c11ee6331..0d72eacdf 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -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 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:" diff --git a/src/lib/image_content.cc b/src/lib/image_content.cc index 6acf0bab9..915da7beb 100644 --- a/src/lib/image_content.cc +++ b/src/lib/image_content.cc @@ -25,12 +25,12 @@ #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 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 (); diff --git a/src/lib/internet.cc b/src/lib/internet.cc index 99ae5c214..c28e650fd 100644 --- a/src/lib/internet.cc +++ b/src/lib/internet.cc @@ -24,11 +24,11 @@ #include #include #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 (); } - stringstream s (ls_raw); - string line; + SafeStringStream s (ls_raw); list 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 != "..") { diff --git a/src/lib/job.cc b/src/lib/job.cc index 530ad9798..52ec1426c 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -29,13 +29,13 @@ #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 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) { diff --git a/src/lib/kdm.cc b/src/lib/kdm.cc index 177dec078..f5054b8ed 100644 --- a/src/lib/kdm.cc +++ b/src/lib/kdm.cc @@ -28,10 +28,10 @@ #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::const_iterator j = i->screen_kdms.begin(); j != i->screen_kdms.end(); ++j) { screens << j->screen->name << ", "; } diff --git a/src/lib/log.cc b/src/lib/log.cc index 4de6bd874..5e8277a23 100644 --- a/src/lib/log.cc +++ b/src/lib/log.cc @@ -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 ()); } diff --git a/src/lib/md5_digester.cc b/src/lib/md5_digester.cc index 1244209bd..1d4d1974a 100644 --- a/src/lib/md5_digester.cc +++ b/src/lib/md5_digester.cc @@ -18,12 +18,11 @@ */ #include -#include #include #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 index 000000000..01d545045 --- /dev/null +++ b/src/lib/safe_stringstream.cc @@ -0,0 +1,23 @@ +/* + Copyright (C) 2014 Carl Hetherington + + 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 +#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 index 000000000..e455de964 --- /dev/null +++ b/src/lib/safe_stringstream.h @@ -0,0 +1,115 @@ +/* + Copyright (C) 2014 Carl Hetherington + + 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 + +/* 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 > std::num_put > >::_M_insert_float(std::ostreambuf_iterator >, std::ios_base&, char, char, double) const + 199 + * 4 libstdc++.6.dylib 0x00007fff8974ebc0 std::num_put > +>::do_put(std::ostreambuf_iterator >, std::ios_base&, char, double) const + 28 + * 5 libstdc++.6.dylib 0x00007fff897566a2 std::ostream& std::ostream::_M_insert(double) + 178 + * 6 libdcpomatic.dylib 0x0000000100331e21 StringPrivate::Composition& StringPrivate::Composition::arg(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 + std::ostream& operator<< (T val) + { + boost::mutex::scoped_lock lm (_mutex); + _stream << val; + return _stream; + } + + template + 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 diff --git a/src/lib/server.cc b/src/lib/server.cc index f1c6d6c44..9591be188 100644 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -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, struct timeval& after_read, struct t scoped_array buffer (new char[length]); socket->read (reinterpret_cast (buffer.get()), length); - stringstream s (buffer.get()); + string s (buffer.get()); shared_ptr xml (new cxml::Document ("EncodingRequest")); - xml->read_stream (s); + xml->read_string (s); if (xml->number_child ("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 (_worker_threads.size ())); - stringstream xml; - doc.write_to_stream (xml, "UTF-8"); + string xml = doc.write_to_string ("UTF-8"); shared_ptr 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 (...) { } diff --git a/src/lib/server_finder.cc b/src/lib/server_finder.cc index 65e0940a0..744a65f59 100644 --- a/src/lib/server_finder.cc +++ b/src/lib/server_finder.cc @@ -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 buffer (new char[length]); sock->read (reinterpret_cast (buffer.get()), length); - stringstream s (buffer.get()); + string s (buffer.get()); shared_ptr 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)) { diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 3efba6fd5..ba3bd0a77 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -25,11 +25,11 @@ #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"), diff --git a/src/lib/stack.cpp b/src/lib/stack.cpp index a8183d344..167524017 100644 --- a/src/lib/stack.cpp +++ b/src/lib/stack.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include "stack.hpp" diff --git a/src/lib/transcode_job.cc b/src/lib/transcode_job.cc index 675a95116..831c74b3b 100644 --- a/src/lib/transcode_job.cc +++ b/src/lib/transcode_job.cc @@ -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 (); diff --git a/src/lib/update.cc b/src/lib/update.cc index af3e46f0e..7bec061e9 100644 --- a/src/lib/update.cc +++ b/src/lib/update.cc @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -26,13 +25,13 @@ #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); diff --git a/src/lib/util.cc b/src/lib/util.cc index 6f3907391..d96001d13 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -22,7 +22,6 @@ * @brief Some utility functions and classes. */ -#include #include #include #include @@ -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_(", ") diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 15e1ca791..b0d4c2de5 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -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 () << "_"; diff --git a/src/lib/wscript b/src/lib/wscript index f53ae7b74..1e4efddc4 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -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 diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index cd2978052..c92f5b6cf 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -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; diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 092a1ca1b..758060a08 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -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; diff --git a/src/tools/dcpomatic_server_cli.cc b/src/tools/dcpomatic_server_cli.cc index e4ac85f4c..f35797954 100644 --- a/src/tools/dcpomatic_server_cli.cc +++ b/src/tools/dcpomatic_server_cli.cc @@ -20,7 +20,6 @@ #include "lib/server.h" #include #include -#include #include #include #include diff --git a/src/wx/colour_conversion_editor.cc b/src/wx/colour_conversion_editor.cc index 6617b66d6..4a1e5074f 100644 --- a/src/wx/colour_conversion_editor.cc +++ b/src/wx/colour_conversion_editor.cc @@ -21,12 +21,12 @@ #include #include #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); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index b341cb0fe..87310d21a 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -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::iterator i = _panels.begin(); i != _panels.end(); ++i) { (*i)->film_changed (p); diff --git a/src/wx/job_wrapper.cc b/src/wx/job_wrapper.cc index df4aa7d2e..4c4ef049b 100644 --- a/src/wx/job_wrapper.cc +++ b/src/wx/job_wrapper.cc @@ -17,7 +17,6 @@ */ -#include #include "lib/film.h" #include "lib/exceptions.h" #include "job_wrapper.h" diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc index 28247bc33..53ca23755 100644 --- a/src/wx/properties_dialog.cc +++ b/src/wx/properties_dialog.cc @@ -22,11 +22,11 @@ #include #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) _frames->SetLabel (std_to_wx (lexical_cast (_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) string PropertiesDialog::frames_already_encoded () const { - stringstream u; + SafeStringStream u; try { u << _film->encoded_frames (); } catch (boost::thread_interrupted &) { diff --git a/test/film_metadata_test.cc b/test/film_metadata_test.cc index c41e86189..c9f4a2c38 100644 --- a/test/film_metadata_test.cc +++ b/test/film_metadata_test.cc @@ -17,7 +17,6 @@ */ -#include #include #include #include