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).
This commit is contained in:
Thomas Goyne 2014-03-21 13:41:33 -07:00
parent d454872c00
commit d615dcb30a
11 changed files with 38 additions and 51 deletions

View file

@ -8,9 +8,9 @@ Author: Terry Caton
#include "libaegisub/cajun/reader.h" #include "libaegisub/cajun/reader.h"
#include <boost/interprocess/streams/bufferstream.hpp>
#include <cassert> #include <cassert>
#include <set> #include <set>
#include <sstream>
/* /*
@ -320,7 +320,7 @@ UnknownElement Reader::ParseNumber(Reader::TokenStream& tokenStream) {
std::string const& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream); std::string const& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream);
// First try to parse it as an int // First try to parse it as an int
std::istringstream iStr(sValue); boost::interprocess::ibufferstream iStr(sValue.data(), sValue.size());
int64_t iValue; int64_t iValue;
iStr >> iValue; iStr >> iValue;

View file

@ -20,22 +20,20 @@
#include "libaegisub/json.h" #include "libaegisub/json.h"
#include <fstream>
#include <memory>
#include <sstream>
#include "libaegisub/fs.h" #include "libaegisub/fs.h"
#include "libaegisub/io.h" #include "libaegisub/io.h"
#include "libaegisub/log.h" #include "libaegisub/log.h"
#include "libaegisub/util.h" #include "libaegisub/util.h"
#include <boost/interprocess/streams/bufferstream.hpp>
namespace agi { namespace agi {
namespace json_util { namespace json_util {
json::UnknownElement parse(std::unique_ptr<std::istream> stream) { json::UnknownElement parse(std::istream &stream) {
try { try {
json::UnknownElement root; json::UnknownElement root;
json::Reader::Read(root, *stream); json::Reader::Read(root, stream);
return root; return root;
} catch (json::Reader::ParseException& e) { } 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; 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<std::istream> stream) {
} }
json::UnknownElement file(agi::fs::path const& file) { 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) { json::UnknownElement file(agi::fs::path const& file, const std::string &default_config) {
try { try {
return parse(io::Open(file)); return parse(*io::Open(file));
} }
catch (fs::FileNotFound const&) { catch (fs::FileNotFound const&) {
// Not an error // Not an error
return parse(util::make_unique<std::istringstream>(default_config)); boost::interprocess::ibufferstream stream(default_config.data(), default_config.size());
return parse(stream);
} }
catch (json::Exception&) { catch (json::Exception&) {
// Already logged in parse // Already logged in parse
return parse(util::make_unique<std::istringstream>(default_config)); boost::interprocess::ibufferstream stream(default_config.data(), default_config.size());
return parse(stream);
} }
catch (agi::Exception& e) { catch (agi::Exception& e) {
LOG_E("json/file") << "Unexpected error when reading config file " << file << ": " << e.GetMessage(); LOG_E("json/file") << "Unexpected error when reading config file " << file << ": " << e.GetMessage();
return parse(util::make_unique<std::istringstream>(default_config)); boost::interprocess::ibufferstream stream(default_config.data(), default_config.size());
return parse(stream);
} }
} }

View file

@ -93,9 +93,8 @@ Message::Message(const char *section, Severity severity, const char *file, const
} }
Message::~Message() { 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); agi::log::log->Log(sm);
msg.freeze(false);
} }
JsonEmitter::JsonEmitter(fs::path const& directory) JsonEmitter::JsonEmitter(fs::path const& directory)

View file

@ -31,11 +31,11 @@
#include "option_visit.h" #include "option_visit.h"
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/range/adaptor/map.hpp> #include <boost/range/adaptor/map.hpp>
#include <cassert> #include <cassert>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <sstream>
namespace { namespace {
/// @brief Write an option to a json object /// @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) , setting(setting)
{ {
LOG_D("agi/options") << "New Options object"; LOG_D("agi/options") << "New Options object";
std::istringstream stream(default_config); boost::interprocess::ibufferstream stream(default_config.data(), default_config.size());
LoadConfig(stream); LoadConfig(stream);
} }

View file

@ -20,7 +20,14 @@
#include "libaegisub/vfr.h" #include "libaegisub/vfr.h"
#include "libaegisub/charset.h"
#include "libaegisub/io.h"
#include "libaegisub/line_iterator.h"
#include "libaegisub/scoped_ptr.h"
#include <algorithm> #include <algorithm>
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/range/algorithm.hpp>
#include <cmath> #include <cmath>
#include <fstream> #include <fstream>
#include <functional> #include <functional>
@ -28,13 +35,6 @@
#include <list> #include <list>
#include <numeric> #include <numeric>
#include "libaegisub/charset.h"
#include "libaegisub/io.h"
#include "libaegisub/line_iterator.h"
#include "libaegisub/scoped_ptr.h"
#include <boost/range/algorithm.hpp>
namespace { namespace {
static const int64_t default_denominator = 1000000000; static const int64_t default_denominator = 1000000000;
@ -73,7 +73,7 @@ struct TimecodeRange {
TimecodeRange v1_parse_line(std::string const& str) { TimecodeRange v1_parse_line(std::string const& str) {
if (str.empty() || str[0] == '#') return TimecodeRange(); if (str.empty() || str[0] == '#') return TimecodeRange();
std::istringstream ss(str); boost::interprocess::ibufferstream ss(str.data(), str.size());
TimecodeRange range; TimecodeRange range;
char comma1 = 0, comma2 = 0; char comma1 = 0, comma2 = 0;
ss >> range.start >> comma1 >> range.end >> comma2 >> range.fps; ss >> range.start >> comma1 >> range.end >> comma2 >> range.fps;

View file

@ -28,7 +28,7 @@ namespace agi {
/// Parse a JSON stream. /// Parse a JSON stream.
/// @param stream JSON stream to parse /// @param stream JSON stream to parse
/// @return json::UnknownElement /// @return json::UnknownElement
json::UnknownElement parse(std::unique_ptr<std::istream> stream); json::UnknownElement parse(std::istream &stream);
/// Parse a JSON file. /// Parse a JSON file.
/// @param file Path JSON to file /// @param file Path JSON to file

View file

@ -20,9 +20,9 @@
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <sstream>
#include <cstdint> #include <cstdint>
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <libaegisub/charset_conv.h> #include <libaegisub/charset_conv.h>
@ -205,7 +205,7 @@ inline void line_iterator<std::string>::next() {
template<class OutputType> template<class OutputType>
inline bool line_iterator<OutputType>::convert(std::string &str) { inline bool line_iterator<OutputType>::convert(std::string &str) {
std::istringstream ss(str); boost::interprocess::ibufferstream ss(str.data(), str.size());
ss >> value; ss >> value;
return !ss.fail(); return !ss.fail();
} }

View file

@ -21,18 +21,11 @@
#include <ctime> #include <ctime>
#include <boost/circular_buffer.hpp> #include <boost/circular_buffer.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
#include <iosfwd> #include <iosfwd>
#include <memory> #include <memory>
#include <vector> #include <vector>
#ifdef __DEPRECATED // Dodge GCC warnings
# undef __DEPRECATED
# include <strstream>
# define __DEPRECATED
#else
# include <strstream>
#endif
// These macros below aren't a perm solution, it will depend on how annoying they are through // 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. // actual usage, and also depends on msvc support.
#define LOG_SINK(section, severity) agi::log::Message(section, severity, __FILE__, __FUNCTION__, __LINE__).stream() #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. /// Generates a message and submits it to the log sink.
class Message { class Message {
std::ostrstream msg; boost::interprocess::obufferstream msg;
SinkMessage sm; SinkMessage sm;
char buffer[2048]; char buffer[2048];

View file

@ -48,7 +48,6 @@
#include <memory> #include <memory>
#include <numeric> #include <numeric>
#include <set> #include <set>
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <tuple> #include <tuple>
@ -64,11 +63,4 @@
#define BOOST_NO_SCOPED_ENUMS #define BOOST_NO_SCOPED_ENUMS
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#undef BOOST_NO_SCOPED_ENUMS #undef BOOST_NO_SCOPED_ENUMS
#include <boost/interprocess/streams/bufferstream.hpp>
#ifdef __DEPRECATED // Dodge GCC warnings
# undef __DEPRECATED
# include <strstream>
# define __DEPRECATED
#else
# include <strstream>
#endif

View file

@ -67,8 +67,8 @@
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/interprocess/streams/bufferstream.hpp>
#include <boost/locale.hpp> #include <boost/locale.hpp>
#include <sstream>
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <wx/config.h> #include <wx/config.h>
@ -181,7 +181,7 @@ bool AegisubApp::OnInit() {
try { try {
if (!config::opt) if (!config::opt)
config::opt = new agi::Options(config::path->Decode("?user/config.json"), GET_DEFAULT_CONFIG(default_config)); 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); config::opt->ConfigNext(stream);
} catch (agi::Exception& e) { } catch (agi::Exception& e) {
LOG_E("config/init") << "Caught exception: " << e.GetName() << " -> " << e.GetMessage(); LOG_E("config/init") << "Caught exception: " << e.GetName() << " -> " << e.GetMessage();

View file

@ -36,7 +36,7 @@
#include <libaegisub/util.h> #include <libaegisub/util.h>
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <sstream> #include <boost/interprocess/streams/bufferstream.hpp>
#include <vector> #include <vector>
#include <wx/frame.h> #include <wx/frame.h>
@ -45,8 +45,10 @@
namespace { namespace {
json::Object const& get_root() { json::Object const& get_root() {
static json::Object root; static json::Object root;
if (root.empty()) if (root.empty()) {
root = agi::json_util::parse(agi::util::make_unique<std::istringstream>(GET_DEFAULT_CONFIG(default_toolbar))); boost::interprocess::ibufferstream stream((const char *)default_toolbar, sizeof(default_toolbar));
root = agi::json_util::parse(stream);
}
return root; return root;
} }