From d615dcb30a361b31f07c1a1ad6c0f7b5f221064b Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 21 Mar 2014 13:41:33 -0700 Subject: [PATCH] Replace all uses of strstream and stringstream with bufferstream istringstream makes a copy of its input, which is not very nice for performance. strstream doesn't do bounds checking, which is not very nice for safety (and is deprecated). --- libaegisub/common/cajun/reader.cpp | 4 ++-- libaegisub/common/json.cpp | 23 ++++++++++--------- libaegisub/common/log.cpp | 3 +-- libaegisub/common/option.cpp | 4 ++-- libaegisub/common/vfr.cpp | 16 ++++++------- libaegisub/include/libaegisub/json.h | 2 +- libaegisub/include/libaegisub/line_iterator.h | 4 ++-- libaegisub/include/libaegisub/log.h | 11 ++------- libaegisub/lagi_pre.h | 10 +------- src/main.cpp | 4 ++-- src/toolbar.cpp | 8 ++++--- 11 files changed, 38 insertions(+), 51 deletions(-) diff --git a/libaegisub/common/cajun/reader.cpp b/libaegisub/common/cajun/reader.cpp index 5db3c1060..f03566904 100644 --- a/libaegisub/common/cajun/reader.cpp +++ b/libaegisub/common/cajun/reader.cpp @@ -8,9 +8,9 @@ Author: Terry Caton #include "libaegisub/cajun/reader.h" +#include #include #include -#include /* @@ -320,7 +320,7 @@ UnknownElement Reader::ParseNumber(Reader::TokenStream& tokenStream) { std::string const& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream); // First try to parse it as an int - std::istringstream iStr(sValue); + boost::interprocess::ibufferstream iStr(sValue.data(), sValue.size()); int64_t iValue; iStr >> iValue; diff --git a/libaegisub/common/json.cpp b/libaegisub/common/json.cpp index 5834faad8..00343b27c 100644 --- a/libaegisub/common/json.cpp +++ b/libaegisub/common/json.cpp @@ -20,22 +20,20 @@ #include "libaegisub/json.h" -#include -#include -#include - #include "libaegisub/fs.h" #include "libaegisub/io.h" #include "libaegisub/log.h" #include "libaegisub/util.h" +#include + namespace agi { namespace json_util { -json::UnknownElement parse(std::unique_ptr stream) { +json::UnknownElement parse(std::istream &stream) { try { json::UnknownElement root; - json::Reader::Read(root, *stream); + json::Reader::Read(root, stream); return root; } catch (json::Reader::ParseException& e) { LOG_E("json/parse") << "json::ParseException: " << e.what() << ", Line/offset: " << e.m_locTokenBegin.m_nLine + 1 << '/' << e.m_locTokenBegin.m_nLineOffset + 1; @@ -47,24 +45,27 @@ json::UnknownElement parse(std::unique_ptr stream) { } json::UnknownElement file(agi::fs::path const& file) { - return parse(io::Open(file)); + return parse(*io::Open(file)); } json::UnknownElement file(agi::fs::path const& file, const std::string &default_config) { try { - return parse(io::Open(file)); + return parse(*io::Open(file)); } catch (fs::FileNotFound const&) { // Not an error - return parse(util::make_unique(default_config)); + boost::interprocess::ibufferstream stream(default_config.data(), default_config.size()); + return parse(stream); } catch (json::Exception&) { // Already logged in parse - return parse(util::make_unique(default_config)); + boost::interprocess::ibufferstream stream(default_config.data(), default_config.size()); + return parse(stream); } catch (agi::Exception& e) { LOG_E("json/file") << "Unexpected error when reading config file " << file << ": " << e.GetMessage(); - return parse(util::make_unique(default_config)); + boost::interprocess::ibufferstream stream(default_config.data(), default_config.size()); + return parse(stream); } } diff --git a/libaegisub/common/log.cpp b/libaegisub/common/log.cpp index 46b981f12..f78b32fd3 100644 --- a/libaegisub/common/log.cpp +++ b/libaegisub/common/log.cpp @@ -93,9 +93,8 @@ Message::Message(const char *section, Severity severity, const char *file, const } Message::~Message() { - sm.message = std::string(msg.str(), (std::string::size_type)msg.pcount()); + sm.message = std::string(buffer, (std::string::size_type)msg.tellp()); agi::log::log->Log(sm); - msg.freeze(false); } JsonEmitter::JsonEmitter(fs::path const& directory) diff --git a/libaegisub/common/option.cpp b/libaegisub/common/option.cpp index 3d3a3c811..87693a665 100644 --- a/libaegisub/common/option.cpp +++ b/libaegisub/common/option.cpp @@ -31,11 +31,11 @@ #include "option_visit.h" +#include #include #include #include #include -#include namespace { /// @brief Write an option to a json object @@ -72,7 +72,7 @@ Options::Options(agi::fs::path const& file, const std::string& default_config, c , setting(setting) { LOG_D("agi/options") << "New Options object"; - std::istringstream stream(default_config); + boost::interprocess::ibufferstream stream(default_config.data(), default_config.size()); LoadConfig(stream); } diff --git a/libaegisub/common/vfr.cpp b/libaegisub/common/vfr.cpp index 15dadf99a..4ee0be669 100644 --- a/libaegisub/common/vfr.cpp +++ b/libaegisub/common/vfr.cpp @@ -20,7 +20,14 @@ #include "libaegisub/vfr.h" +#include "libaegisub/charset.h" +#include "libaegisub/io.h" +#include "libaegisub/line_iterator.h" +#include "libaegisub/scoped_ptr.h" + #include +#include +#include #include #include #include @@ -28,13 +35,6 @@ #include #include -#include "libaegisub/charset.h" -#include "libaegisub/io.h" -#include "libaegisub/line_iterator.h" -#include "libaegisub/scoped_ptr.h" - -#include - namespace { static const int64_t default_denominator = 1000000000; @@ -73,7 +73,7 @@ struct TimecodeRange { TimecodeRange v1_parse_line(std::string const& str) { if (str.empty() || str[0] == '#') return TimecodeRange(); - std::istringstream ss(str); + boost::interprocess::ibufferstream ss(str.data(), str.size()); TimecodeRange range; char comma1 = 0, comma2 = 0; ss >> range.start >> comma1 >> range.end >> comma2 >> range.fps; diff --git a/libaegisub/include/libaegisub/json.h b/libaegisub/include/libaegisub/json.h index 0fb67ecfe..9b799780c 100644 --- a/libaegisub/include/libaegisub/json.h +++ b/libaegisub/include/libaegisub/json.h @@ -28,7 +28,7 @@ namespace agi { /// Parse a JSON stream. /// @param stream JSON stream to parse /// @return json::UnknownElement -json::UnknownElement parse(std::unique_ptr stream); +json::UnknownElement parse(std::istream &stream); /// Parse a JSON file. /// @param file Path JSON to file diff --git a/libaegisub/include/libaegisub/line_iterator.h b/libaegisub/include/libaegisub/line_iterator.h index e34f4b8bd..27e91c570 100644 --- a/libaegisub/include/libaegisub/line_iterator.h +++ b/libaegisub/include/libaegisub/line_iterator.h @@ -20,9 +20,9 @@ #include #include -#include #include +#include #include #include @@ -205,7 +205,7 @@ inline void line_iterator::next() { template inline bool line_iterator::convert(std::string &str) { - std::istringstream ss(str); + boost::interprocess::ibufferstream ss(str.data(), str.size()); ss >> value; return !ss.fail(); } diff --git a/libaegisub/include/libaegisub/log.h b/libaegisub/include/libaegisub/log.h index da965f458..f2c6b75f7 100644 --- a/libaegisub/include/libaegisub/log.h +++ b/libaegisub/include/libaegisub/log.h @@ -21,18 +21,11 @@ #include #include +#include #include #include #include -#ifdef __DEPRECATED // Dodge GCC warnings -# undef __DEPRECATED -# include -# define __DEPRECATED -#else -# include -#endif - // These macros below aren't a perm solution, it will depend on how annoying they are through // actual usage, and also depends on msvc support. #define LOG_SINK(section, severity) agi::log::Message(section, severity, __FILE__, __FUNCTION__, __LINE__).stream() @@ -137,7 +130,7 @@ public: /// Generates a message and submits it to the log sink. class Message { - std::ostrstream msg; + boost::interprocess::obufferstream msg; SinkMessage sm; char buffer[2048]; diff --git a/libaegisub/lagi_pre.h b/libaegisub/lagi_pre.h index 044eedac1..a206b3b8d 100644 --- a/libaegisub/lagi_pre.h +++ b/libaegisub/lagi_pre.h @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -64,11 +63,4 @@ #define BOOST_NO_SCOPED_ENUMS #include #undef BOOST_NO_SCOPED_ENUMS - -#ifdef __DEPRECATED // Dodge GCC warnings -# undef __DEPRECATED -# include -# define __DEPRECATED -#else -# include -#endif +#include diff --git a/src/main.cpp b/src/main.cpp index 3437f1d7b..5e7e924e2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,8 +67,8 @@ #include #include +#include #include -#include #include #include @@ -181,7 +181,7 @@ bool AegisubApp::OnInit() { try { if (!config::opt) config::opt = new agi::Options(config::path->Decode("?user/config.json"), GET_DEFAULT_CONFIG(default_config)); - std::istringstream stream(GET_DEFAULT_CONFIG(default_config_platform)); + boost::interprocess::ibufferstream stream((const char *)default_config, sizeof(default_config)); config::opt->ConfigNext(stream); } catch (agi::Exception& e) { LOG_E("config/init") << "Caught exception: " << e.GetName() << " -> " << e.GetMessage(); diff --git a/src/toolbar.cpp b/src/toolbar.cpp index b57ceebd7..208f8b14a 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include @@ -45,8 +45,10 @@ namespace { json::Object const& get_root() { static json::Object root; - if (root.empty()) - root = agi::json_util::parse(agi::util::make_unique(GET_DEFAULT_CONFIG(default_toolbar))); + if (root.empty()) { + boost::interprocess::ibufferstream stream((const char *)default_toolbar, sizeof(default_toolbar)); + root = agi::json_util::parse(stream); + } return root; }