diff --git a/include/zim/error.h b/include/zim/error.h index 25f2b74b3..673a52028 100644 --- a/include/zim/error.h +++ b/include/zim/error.h @@ -21,9 +21,9 @@ #define ZIM_ERROR_H #include "zim.h" +#include "tools.h" #include -#include #include namespace zim @@ -135,11 +135,9 @@ namespace zim try { std::rethrow_exception(exception); } catch (const std::exception& e) { - std::stringstream ss; - ss << "Asynchronous error: "; - ss << typeid(e).name() << std::endl; - ss << e.what(); - return ss.str(); + return Formatter() + << "Asynchronous error: " << typeid(e).name() << std::endl + << e.what(); } catch (...) { return "Unknown asynchronous exception"; } diff --git a/include/zim/tools.h b/include/zim/tools.h index e5341fdec..afbaed40b 100644 --- a/include/zim/tools.h +++ b/include/zim/tools.h @@ -21,7 +21,7 @@ #define ZIM_TOOLS_H #include "zim.h" - +#include namespace zim { #if defined(LIBZIM_WITH_XAPIAN) @@ -34,6 +34,50 @@ namespace zim { LIBZIM_API void setICUDataDirectory(const std::string& path); #endif + + /** + * @brief Stringstream Class to use itself as the stream object + * returned by << operator. (std::stringstream returns an std::ostream). + * Allows a one-line stringstream to str conversion, e.g. use_str(Formatter() + * << "foo" << variable); + * + */ + class Formatter + { + public: + Formatter() {} + ~Formatter() {} + + template Formatter &operator<<(const Type &value) + { + stream_ << value; + return *this; + } + + /* Operator for function templates like std::endl */ + Formatter &operator<<(std::ostream& (* __pf)(std::ostream&)) + { + stream_ << __pf; + return *this; + } + + /* Operator for working with other ostream like std::cerr */ + friend std::ostream &operator<<(std::ostream &os, const Formatter &obj) + { + os << obj.stream_.str(); + return os; + } + + operator std::string() const { return stream_.str(); } + + private: + /* Disable copy and assignment constructors */ + Formatter(const Formatter &) = delete; + Formatter &operator=(Formatter &) = delete; + + /* Simple composition with std::stringstream */ + std::stringstream stream_; + }; } #endif // ZIM_TOOLS_H diff --git a/src/archive.cpp b/src/archive.cpp index cb467a91b..b10f1bb91 100644 --- a/src/archive.cpp +++ b/src/archive.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "fileimpl.h" #include "tools.h" #include "log.h" @@ -154,9 +155,8 @@ namespace zim } Item Archive::getIllustrationItem(unsigned int size) const { - std::ostringstream ss; - ss << "Illustration_" << size << "x" << size << "@" << 1; - auto r = m_impl->findx('M', ss.str()); + auto r = m_impl->findx('M', Formatter() << "Illustration_" << size << "x" + << size << "@" << 1); if (r.first) { return getEntryByPath(entry_index_type(r.second)).getItem(); } diff --git a/src/compression.cpp b/src/compression.cpp index f14504052..a931ee8ab 100644 --- a/src/compression.cpp +++ b/src/compression.cpp @@ -23,6 +23,7 @@ #include "envvalue.h" +#include #include const std::string LZMA_INFO::name = "lzma"; @@ -51,9 +52,8 @@ CompStatus LZMA_INFO::stream_run(stream_t* stream, CompStep step) case LZMA_OK: return CompStatus::OK; default: { - std::ostringstream ss; - ss << "Unexpected lzma status : " << errcode; - throw std::runtime_error(ss.str()); + throw std::runtime_error(zim::Formatter() + << "Unexpected lzma status : " << errcode); } } } diff --git a/src/debug.h b/src/debug.h index 5bb96b809..4ec9ffb8a 100644 --- a/src/debug.h +++ b/src/debug.h @@ -20,8 +20,8 @@ #ifndef DEBUG_H_ #define DEBUG_H_ +#include #include -#include #include #include @@ -36,10 +36,11 @@ template void _on_assert_fail(const char* vara, const char* op, const char* varb, T a, U b, const char* file, int line) { - std::ostringstream ss; - ss << "\nAssertion failed at "<< file << ":" << line << "\n " << - vara << "[" << a << "] " << op << " " << varb << "[" << b << "]"; - std::cerr << ss.str() << std::endl; + zim::Formatter fmt; + std::cerr << (fmt << "\nAssertion failed at " << file << ":" << line << "\n " + << vara << "[" << a << "] " << op << " " << varb << "[" << b + << "]") + << std::endl; #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && defined(__GNU_LIBRARY__) void *callstack[64]; @@ -51,7 +52,7 @@ void _on_assert_fail(const char* vara, const char* op, const char* varb, } free(strings); #endif - throw std::runtime_error(ss.str()); + throw std::runtime_error(fmt); } # define ASSERT(left, operator, right) do { auto _left = left; auto _right = right; if (!((_left) operator (_right))) _on_assert_fail(#left, #operator, #right, _left, _right, __FILE__, __LINE__); } while(0) diff --git a/src/entry.cpp b/src/entry.cpp index 4d3e14a34..dbe60ea4c 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -21,11 +21,10 @@ #include #include #include +#include #include "fileimpl.h" #include "log.h" -#include - log_define("zim.entry") using namespace zim; @@ -57,14 +56,13 @@ bool Entry::isRedirect() const Item Entry::getItem(bool follow) const { - if (isRedirect()) { - if (! follow) { - std::ostringstream sstream; - sstream << "Entry " << getPath() << " is a redirect entry."; - throw InvalidType(sstream.str()); - } + if (isRedirect()) + { + if (!follow) + throw InvalidType(Formatter() + << "Entry " << getPath() << " is a redirect entry."); return getRedirect(); - } + } return Item(*this); } @@ -79,11 +77,10 @@ Item Entry::getRedirect() const { } entry_index_type Entry::getRedirectEntryIndex() const { - if (!isRedirect()) { - std::ostringstream sstream; - sstream << "Entry " << getPath() << " is not a redirect entry."; - throw InvalidType(sstream.str()); - } + if (!isRedirect()) + throw InvalidType(Formatter() + << "Entry " << getPath() << " is not a redirect entry."); + return m_dirent->getRedirectIndex().v; } diff --git a/src/file_compound.cpp b/src/file_compound.cpp index c3fcd8262..4653d19a8 100644 --- a/src/file_compound.cpp +++ b/src/file_compound.cpp @@ -22,8 +22,8 @@ #include #include -#include #include +#include #ifdef _WIN32 # include @@ -61,11 +61,9 @@ FileCompound::FileCompound(const std::string& filename): } catch (...) { } if (empty()) - { - std::ostringstream msg; - msg << "error " << errnoSave << " opening file \"" << filename; - throw std::runtime_error(msg.str()); - } + throw std::runtime_error(Formatter() + << "error " << errnoSave << " opening file \"" + << filename << "\""); } } @@ -115,11 +113,9 @@ time_t FileCompound::getMTime() const { int ret = ::stat(fname, &st); #endif if (ret != 0) - { - std::ostringstream msg; - msg << "stat failed with errno " << errno << " : " << strerror(errno); - throw std::runtime_error(msg.str()); - } + throw std::runtime_error(Formatter() << "stat failed with errno " << errno + << " : " << strerror(errno)); + mtime = st.st_mtime; return mtime; diff --git a/src/file_reader.cpp b/src/file_reader.cpp index 2fcf09661..d32895b50 100644 --- a/src/file_reader.cpp +++ b/src/file_reader.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "file_reader.h" #include "file_compound.h" #include "buffer.h" @@ -27,7 +28,6 @@ #include #include #include -#include #include #include @@ -74,17 +74,17 @@ char MultiPartFileReader::read(offset_t offset) const { fhandle.readAt(&ret, zsize_t(1), physical_local_offset); } catch (std::runtime_error& e) { //Error while reading. - std::ostringstream s; - s << "Cannot read a char.\n"; - s << " - File part is " << part_pair->second->filename() << "\n"; - s << " - File part size is " << part_pair->second->size().v << "\n"; - s << " - File part range is " << part_pair->first.min << "-" << part_pair->first.max << "\n"; - s << " - Reading offset at " << offset.v << "\n"; - s << " - logical local offset is " << logical_local_offset.v << "\n"; - s << " - physical local offset is " << physical_local_offset.v << "\n"; - s << " - error is " << strerror(errno) << "\n"; + Formatter fmt; + fmt << "Cannot read a char.\n"; + fmt << " - File part is " << part_pair->second->filename() << "\n"; + fmt << " - File part size is " << part_pair->second->size().v << "\n"; + fmt << " - File part range is " << part_pair->first.min << "-" << part_pair->first.max << "\n"; + fmt << " - Reading offset at " << offset.v << "\n"; + fmt << " - logical local offset is " << logical_local_offset.v << "\n"; + fmt << " - physical local offset is " << physical_local_offset.v << "\n"; + fmt << " - error is " << strerror(errno) << "\n"; std::error_code ec(errno, std::generic_category()); - throw std::system_error(ec, s.str()); + throw std::system_error(ec, fmt); }; return ret; } @@ -107,19 +107,19 @@ void MultiPartFileReader::read(char* dest, offset_t offset, zsize_t size) const try { part->fhandle().readAt(dest, size_to_get, physical_local_offset); } catch (std::runtime_error& e) { - std::ostringstream s; - s << "Cannot read chars.\n"; - s << " - File part is " << part->filename() << "\n"; - s << " - File part size is " << part->size().v << "\n"; - s << " - File part range is " << partRange.min << "-" << partRange.max << "\n"; - s << " - size_to_get is " << size_to_get.v << "\n"; - s << " - total size is " << size.v << "\n"; - s << " - Reading offset at " << offset.v << "\n"; - s << " - logical local offset is " << logical_local_offset.v << "\n"; - s << " - physical local offset is " << physical_local_offset.v << "\n"; - s << " - error is " << strerror(errno) << "\n"; + Formatter fmt; + fmt << "Cannot read chars.\n"; + fmt << " - File part is " << part->filename() << "\n"; + fmt << " - File part size is " << part->size().v << "\n"; + fmt << " - File part range is " << partRange.min << "-" << partRange.max << "\n"; + fmt << " - size_to_get is " << size_to_get.v << "\n"; + fmt << " - total size is " << size.v << "\n"; + fmt << " - Reading offset at " << offset.v << "\n"; + fmt << " - logical local offset is " << logical_local_offset.v << "\n"; + fmt << " - physical local offset is " << physical_local_offset.v << "\n"; + fmt << " - error is " << strerror(errno) << "\n"; std::error_code ec(errno, std::generic_category()); - throw std::system_error(ec, s.str()); + throw std::system_error(ec, fmt); }; ASSERT(size_to_get, <=, size); dest += size_to_get.v; @@ -147,13 +147,11 @@ mmapReadOnly(int fd, offset_type offset, size_type size) #endif const auto p = (char*)mmap(NULL, size, PROT_READ, MAP_FLAGS, fd, offset); - if (p == MAP_FAILED ) - { - std::ostringstream s; - s << "Cannot mmap size " << size << " at off " << offset - << " : " << strerror(errno); - throw std::runtime_error(s.str()); - } + if (p == MAP_FAILED) + throw std::runtime_error(Formatter() + << "Cannot mmap size " << size << " at off " + << offset << " : " << strerror(errno)); + return p; } @@ -243,12 +241,12 @@ char FileReader::read(offset_t offset) const _fhandle->readAt(&ret, zsize_t(1), offset); } catch (std::runtime_error& e) { //Error while reading. - std::ostringstream s; - s << "Cannot read a char.\n"; - s << " - Reading offset at " << offset.v << "\n"; - s << " - error is " << strerror(errno) << "\n"; + Formatter fmt; + fmt << "Cannot read a char.\n"; + fmt << " - Reading offset at " << offset.v << "\n"; + fmt << " - error is " << strerror(errno) << "\n"; std::error_code ec(errno, std::generic_category()); - throw std::system_error(ec, s.str()); + throw std::system_error(ec, fmt); }; return ret; } @@ -264,13 +262,13 @@ void FileReader::read(char* dest, offset_t offset, zsize_t size) const try { _fhandle->readAt(dest, size, offset); } catch (std::runtime_error& e) { - std::ostringstream s; - s << "Cannot read chars.\n"; - s << " - Reading offset at " << offset.v << "\n"; - s << " - size is " << size.v << "\n"; - s << " - error is " << strerror(errno) << "\n"; + Formatter fmt; + fmt << "Cannot read chars.\n"; + fmt << " - Reading offset at " << offset.v << "\n"; + fmt << " - size is " << size.v << "\n"; + fmt << " - error is " << strerror(errno) << "\n"; std::error_code ec(errno, std::generic_category()); - throw std::system_error(ec, s.str()); + throw std::system_error(ec, fmt); }; } diff --git a/src/fileimpl.cpp b/src/fileimpl.cpp index 7882d381b..61d43c7e9 100644 --- a/src/fileimpl.cpp +++ b/src/fileimpl.cpp @@ -21,6 +21,7 @@ #include "fileimpl.h" #include +#include #include "_dirent.h" #include "file_compound.h" #include "buffer_reader.h" @@ -507,11 +508,7 @@ class Grouping const std::string& FileImpl::getMimeType(uint16_t idx) const { if (idx >= mimeTypes.size()) - { - std::ostringstream msg; - msg << "unknown mime type code " << idx; - throw ZimFileFormatError(msg.str()); - } + throw ZimFileFormatError(Formatter() << "unknown mime type code " << idx); return mimeTypes[idx]; } diff --git a/src/fs_unix.cpp b/src/fs_unix.cpp index 872393d3e..758c53341 100644 --- a/src/fs_unix.cpp +++ b/src/fs_unix.cpp @@ -19,10 +19,10 @@ #include "fs_unix.h" #include -#include #include #include +#include #include #include #include @@ -138,10 +138,7 @@ bool FS::removeFile(path_t path) { std::string getFilePathFromFD(int fd) { - std::ostringstream oss; - oss << "/dev/fd/" << fd; - - return oss.str(); + return Formatter() << "/dev/fd/" << fd; } }; // zim namespace diff --git a/src/fs_windows.cpp b/src/fs_windows.cpp index 4fe568491..e6f6cfe00 100644 --- a/src/fs_windows.cpp +++ b/src/fs_windows.cpp @@ -25,9 +25,9 @@ #include #include #include +#include #include -#include namespace zim { @@ -135,11 +135,10 @@ std::unique_ptr FS::toWideChar(path_t path) auto wdata = std::unique_ptr(new wchar_t[size]); auto ret = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, wdata.get(), size); - if (0 == ret) { - std::ostringstream oss; - oss << "Cannot convert path to wchar : " << GetLastError(); - throw std::runtime_error(oss.str()); - } + if (0 == ret) + throw std::runtime_error(Formatter() << "Cannot convert path to wchar : " + << GetLastError()); + return wdata; } @@ -154,11 +153,10 @@ FD FS::openFile(path_t filepath) OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_RANDOM_ACCESS, NULL); - if (handle == INVALID_HANDLE_VALUE) { - std::ostringstream oss; - oss << "Cannot open file : " << GetLastError(); - throw std::runtime_error(oss.str()); - } + if (handle == INVALID_HANDLE_VALUE) + throw std::runtime_error(Formatter() + << "Cannot open file : " << GetLastError()); + return FD(handle); } @@ -173,11 +171,9 @@ bool FS::makeDirectory(path_t path) void FS::rename(path_t old_path, path_t new_path) { auto ret = MoveFileExW(toWideChar(old_path).get(), toWideChar(new_path).get(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH); - if (!ret) { - std::ostringstream oss; - oss << "Cannot move file " << old_path << " to " << new_path; - throw std::runtime_error(oss.str()); - } + if (!ret) + throw std::runtime_error(Formatter() << "Cannot move file " << old_path + << " to " << new_path); } std::string FS::join(path_t base, path_t name) diff --git a/src/narrowdown.h b/src/narrowdown.h index 6ce4caf73..7486cd1cb 100644 --- a/src/narrowdown.h +++ b/src/narrowdown.h @@ -27,6 +27,7 @@ #include #include +#include namespace zim { @@ -107,11 +108,11 @@ class NarrowDown // It is somehow a bug and have been fixed then, but we still have to be tolerent here and accept that // two concecutive keys can be equal. if (key > nextKey) { - std::stringstream ss; - ss << "Dirent table is not properly sorted:\n"; - ss << " #" << i << ": " << key[0] << "/" << key.substr(1) << "\n"; - ss << " #" << i+1 << ": " << nextKey[0] << "/" << nextKey.substr(1); - throw ZimFileFormatError(ss.str()); + Formatter fmt; + fmt << "Dirent table is not properly sorted:\n"; + fmt << " #" << i << ": " << key[0] << "/" << key.substr(1) << "\n"; + fmt << " #" << i+1 << ": " << nextKey[0] << "/" << nextKey.substr(1); + throw ZimFileFormatError(fmt); } if ( entries.empty() ) { addEntry(key, i); @@ -120,10 +121,10 @@ class NarrowDown { const std::string pseudoKey = shortestStringInBetween(key, nextKey); if (pred(pseudoKey, entries.back())) { - std::stringstream ss; - ss << "Dirent table is not properly sorted:\n"; - ss << "PseudoKey " << pseudoKey << " should be after (or equal) previously generated " << pred.getKeyContent(entries.back()) << "\n"; - throw ZimFileFormatError(ss.str()); + Formatter fmt; + fmt << "Dirent table is not properly sorted:\n"; + fmt << "PseudoKey " << pseudoKey << " should be after (or equal) previously generated " << pred.getKeyContent(entries.back()) << "\n"; + throw ZimFileFormatError(fmt); } ASSERT(entries.back().lindex, <, i); addEntry(pseudoKey, i); diff --git a/src/version.cpp b/src/version.cpp index 5f6b077bf..3f192fc30 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -18,10 +18,10 @@ */ #include -#include #include #include +#include #include #include #include @@ -45,9 +45,9 @@ namespace zim versions.push_back({ "libxapian", XAPIAN_VERSION }); // U_ICU_VERSION does not include the patch level if 0 - std::ostringstream libicu_version; - libicu_version << U_ICU_VERSION_MAJOR_NUM << "." << U_ICU_VERSION_MINOR_NUM << "." << U_ICU_VERSION_PATCHLEVEL_NUM; - versions.push_back({ "libicu", libicu_version.str() }); + versions.push_back({"libicu", Formatter() << U_ICU_VERSION_MAJOR_NUM << "." + << U_ICU_VERSION_MINOR_NUM << "." + << U_ICU_VERSION_PATCHLEVEL_NUM}); #endif return versions; diff --git a/src/writer/cluster.cpp b/src/writer/cluster.cpp index a70d5367e..1ef6de228 100644 --- a/src/writer/cluster.cpp +++ b/src/writer/cluster.cpp @@ -26,8 +26,7 @@ #include "../compression.h" #include - -#include +#include #include #include @@ -202,10 +201,10 @@ void Cluster::write(int out_fd) const } default: - std::ostringstream msg; - msg << "invalid compression flag " << static_cast(getCompression()); - log_error(msg.str()); - throw std::runtime_error(msg.str()); + Formatter fmt_msg; + fmt_msg << "invalid compression flag " << static_cast(getCompression()); + log_error(fmt_msg); + throw std::runtime_error(fmt_msg); } } @@ -243,12 +242,12 @@ void Cluster::write_data(writer_t writer) const size += blob.size(); writer(blob); } - if (size != provider->getSize()) { - std::stringstream ss; - ss << "Declared provider's size (" << provider->getSize() << ")"; - ss << " is not equal to total size returned by feed() calls (" << size << ")."; - throw IncoherentImplementationError(ss.str()); - } + if (size != provider->getSize()) + throw IncoherentImplementationError( + Formatter() + << "Declared provider's size (" << provider->getSize() << ")" + << " is not equal to total size returned by feed() calls (" << size + << ")."); } } diff --git a/src/writer/counterHandler.cpp b/src/writer/counterHandler.cpp index b29df05a6..7f07893ef 100644 --- a/src/writer/counterHandler.cpp +++ b/src/writer/counterHandler.cpp @@ -22,6 +22,7 @@ #include #include +#include using namespace zim::writer; @@ -45,16 +46,16 @@ DirentHandler::Dirents CounterHandler::createDirents() const { DirentHandler::ContentProviders CounterHandler::getContentProviders() const { ContentProviders ret; - std::stringstream ss; + Formatter fmt; bool first = true; for(auto pair: m_mimetypeCounter) { if (! first) { - ss << ";"; + fmt << ";"; } - ss << pair.first << "=" << pair.second; + fmt << pair.first << "=" << pair.second; first = false; } - ret.push_back(std::unique_ptr(new StringProvider(ss.str()))); + ret.push_back(std::unique_ptr(new StringProvider(fmt))); return ret; } diff --git a/src/writer/creator.cpp b/src/writer/creator.cpp index 127661e6d..e28d60b2c 100644 --- a/src/writer/creator.cpp +++ b/src/writer/creator.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include "../endian_tools.h" #include #include @@ -190,9 +191,8 @@ namespace zim void Creator::addIllustration(unsigned int size, std::unique_ptr provider) { checkError(); - std::stringstream ss; - ss << "Illustration_" << size << "x" << size << "@1"; - addMetadata(ss.str(), std::move(provider), "image/png"); + addMetadata(Formatter() << "Illustration_" << size << "x" << size << "@1", + std::move(provider), "image/png"); } void Creator::addRedirection(const std::string& path, const std::string& title, const std::string& targetPath, const Hints& hints) @@ -213,10 +213,10 @@ namespace zim auto existing_dirent_it = data->dirents.find(&tmpDirent); if (existing_dirent_it == data->dirents.end()) { - std::ostringstream ss; - ss << "Impossible to alias C/" << targetPath << " as C/" << path << std::endl; - ss << "C/" << targetPath << " doesn't exist." << std::endl; - throw InvalidEntry(ss.str()); + Formatter fmt; + fmt << "Impossible to alias C/" << targetPath << " as C/" << path << std::endl; + fmt << "C/" << targetPath << " doesn't exist." << std::endl; + throw InvalidEntry(fmt); } auto dirent = data->createAliasDirent(path, title, **existing_dirent_it); @@ -543,11 +543,11 @@ namespace zim existing->markRemoved(); dirents.insert(dirent); } else { - std::ostringstream ss; - ss << "Impossible to add " << NsAsChar(dirent->getNamespace()) << "/" << dirent->getPath() << std::endl; - ss << " dirent's title to add is : " << dirent->getTitle() << std::endl; - ss << " existing dirent's title is : " << existing->getTitle() << std::endl; - throw InvalidEntry(ss.str()); + Formatter fmt; + fmt << "Impossible to add " << NsAsChar(dirent->getNamespace()) << "/" << dirent->getPath() << std::endl; + fmt << " dirent's title to add is : " << dirent->getTitle() << std::endl; + fmt << " existing dirent's title is : " << existing->getTitle() << std::endl; + throw InvalidEntry(fmt); } }; diff --git a/src/writer/defaultIndexData.h b/src/writer/defaultIndexData.h index 9924c320a..f9397353a 100644 --- a/src/writer/defaultIndexData.h +++ b/src/writer/defaultIndexData.h @@ -21,6 +21,7 @@ #define ZIM_WRITER_DEFAULTINDEXDATA_H #include +#include #include "xapian/myhtmlparse.h" #include "../tools.h" @@ -60,17 +61,17 @@ namespace zim return; } #if defined(ENABLE_XAPIAN) - std::ostringstream ss; + Formatter fmt; while (true) { auto blob = mp_contentProvider->feed(); if(blob.size() == 0) { break; } - ss << blob; + fmt << blob; } MyHtmlParser htmlParser; try { - htmlParser.parse_html(ss.str(), "UTF-8", true); + htmlParser.parse_html(fmt, "UTF-8", true); } catch(...) {} m_hasIndexData = !htmlParser.dump.empty() && htmlParser.indexing_allowed && (htmlParser.dump.find("NOINDEX") == std::string::npos); m_content = zim::removeAccents(htmlParser.dump); diff --git a/src/writer/xapianWorker.cpp b/src/writer/xapianWorker.cpp index eb2b5b5d1..f2039f6fc 100644 --- a/src/writer/xapianWorker.cpp +++ b/src/writer/xapianWorker.cpp @@ -24,8 +24,8 @@ #include "xapianIndexer.h" #include -#include #include +#include static std::mutex s_dbaccessLock; @@ -63,10 +63,7 @@ namespace zim std::string fullPath = "C/" + m_path; document.set_data(fullPath); document.add_value(0, mp_indexData->getTitle()); - - std::stringstream countWordStringStream; - countWordStringStream << mp_indexData->getWordCount(); - document.add_value(1, countWordStringStream.str()); + document.add_value(1, Formatter() << mp_indexData->getWordCount()); auto geoInfo = mp_indexData->getGeoPosition(); if (std::get<0>(geoInfo)) { diff --git a/test/creator.cpp b/test/creator.cpp index b884dce83..dba1a6150 100644 --- a/test/creator.cpp +++ b/test/creator.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "tools.h" #include "../src/file_compound.h" @@ -358,11 +359,11 @@ TEST(ZimCreator, interruptedZimCreation) writer::Creator creator; creator.configClusterSize(16*1024); creator.startZimCreation(tmpFile.path()); - std::ostringstream oss; + zim::Formatter fmt; for ( size_t i = 0; i < 12345; ++i ) { - oss << i; + fmt << i; } - const std::string content(oss.str()); + const std::string content(fmt); for ( char c = 'a'; c <= 'z'; ++c ) { const std::string path(1, c); creator.addItem(std::make_shared(path, path, content)); diff --git a/test/tools.h b/test/tools.h index e65a1afed..f228d284d 100644 --- a/test/tools.h +++ b/test/tools.h @@ -44,6 +44,7 @@ typedef SSIZE_T ssize_t; #include #include #include +#include namespace zim { @@ -100,9 +101,7 @@ class TempFile template std::string to_string(const T& value) { - std::ostringstream ss; - ss << value; - return ss.str(); + return Formatter() << value; } std::unique_ptr diff --git a/test/uuid.cpp b/test/uuid.cpp index abfdd822d..c59478de8 100644 --- a/test/uuid.cpp +++ b/test/uuid.cpp @@ -22,6 +22,7 @@ #include #include "gtest/gtest.h" +#include "tools.h" #ifdef _WIN32 # include # include @@ -110,9 +111,7 @@ TEST(UuidTest, output) { zim::Uuid uuid( "\x55\x0e\x84\x00\xe2\x9b\x41\xd4\xa7\x16\x44\x66\x55\x44\x00\x00"); - std::ostringstream out; - out << uuid; - std::string s = out.str(); + std::string s = zim::unittests::to_string(uuid); ASSERT_EQ(s, "550e8400-e29b-41d4-a716-446655440000"); ASSERT_EQ((std::string)uuid, "550e8400-e29b-41d4-a716-446655440000"); }