From 61860563a6f321248a3fcb4965ceb619a475fff9 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 21 Dec 2018 12:43:04 +0100 Subject: [PATCH] Make string builder reusable --- lib/base/CMakeLists.txt | 1 + lib/base/object-packer.cpp | 26 +++++++++---------- lib/base/stringbuilder.cpp | 53 ++++++++++++++++++++++++++++++++++++++ lib/base/stringbuilder.hpp | 53 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 lib/base/stringbuilder.cpp create mode 100644 lib/base/stringbuilder.hpp diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 5dda17939..e1cbd6669 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -81,6 +81,7 @@ set(base_SOURCES stream.cpp stream.hpp streamlogger.cpp streamlogger.hpp streamlogger-ti.hpp string.cpp string.hpp string-script.cpp + stringbuilder.cpp stringbuilder.hpp sysloglogger.cpp sysloglogger.hpp sysloglogger-ti.hpp tcpsocket.cpp tcpsocket.hpp threadpool.cpp threadpool.hpp diff --git a/lib/base/object-packer.cpp b/lib/base/object-packer.cpp index 03e61b971..4100ba52e 100644 --- a/lib/base/object-packer.cpp +++ b/lib/base/object-packer.cpp @@ -22,6 +22,7 @@ #include "base/dictionary.hpp" #include "base/array.hpp" #include "base/objectlock.hpp" +#include "base/stringbuilder.hpp" #include #include #include @@ -30,9 +31,6 @@ using namespace icinga; -// Just for the sake of code readability -typedef std::vector StringBuilder; - union EndiannessDetector { EndiannessDetector() @@ -105,7 +103,7 @@ static inline void PackUInt64BE(uint_least64_t i, StringBuilder& builder) UIntToByte(i & 255u) }; - builder.insert(builder.end(), (char*)buf, (char*)buf + 8); + builder.Append((char*)buf, (char*)buf + 8); } union Double2BytesConverter @@ -142,7 +140,7 @@ static inline void PackFloat64BE(double f, StringBuilder& builder) SwapBytes(converter.buf[3], converter.buf[4]); } - builder.insert(builder.end(), (char*)converter.buf, (char*)converter.buf + 8); + builder.Append((char*)converter.buf, (char*)converter.buf + 8); } /** @@ -151,7 +149,7 @@ static inline void PackFloat64BE(double f, StringBuilder& builder) static inline void PackString(const String& string, StringBuilder& builder) { PackUInt64BE(string.GetLength(), builder); - builder.insert(builder.end(), string.Begin(), string.End()); + builder.Append(string); } /** @@ -161,7 +159,7 @@ static inline void PackArray(const Array::Ptr& arr, StringBuilder& builder) { ObjectLock olock(arr); - builder.emplace_back(5); + builder.Append('\5'); PackUInt64BE(arr->GetLength(), builder); for (const Value& value : arr) { @@ -176,7 +174,7 @@ static inline void PackDictionary(const Dictionary::Ptr& dict, StringBuilder& bu { ObjectLock olock(dict); - builder.emplace_back(6); + builder.Append('\6'); PackUInt64BE(dict->GetLength(), builder); for (const Dictionary::Pair& kv : dict) { @@ -192,21 +190,21 @@ static void PackAny(const Value& value, StringBuilder& builder) { switch (value.GetType()) { case ValueString: - builder.emplace_back(4); + builder.Append('\4'); PackString(value.Get(), builder); break; case ValueNumber: - builder.emplace_back(3); + builder.Append('\3'); PackFloat64BE(value.Get(), builder); break; case ValueBoolean: - builder.emplace_back(value.ToBool() ? 2 : 1); + builder.Append(value.ToBool() ? '\2' : '\1'); break; case ValueEmpty: - builder.emplace_back(0); + builder.Append('\0'); break; case ValueObject: @@ -226,7 +224,7 @@ static void PackAny(const Value& value, StringBuilder& builder) } } - builder.emplace_back(0); + builder.Append('\0'); break; default: @@ -262,5 +260,5 @@ String icinga::PackObject(const Value& value) StringBuilder builder; PackAny(value, builder); - return String(builder.begin(), builder.end()); + return builder.ToString(); } diff --git a/lib/base/stringbuilder.cpp b/lib/base/stringbuilder.cpp new file mode 100644 index 000000000..f0c44c8c4 --- /dev/null +++ b/lib/base/stringbuilder.cpp @@ -0,0 +1,53 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/) * + * * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "base/stringbuilder.hpp" +#include + +using namespace icinga; + +void StringBuilder::Append(const String& str) +{ + m_Buffer.insert(m_Buffer.end(), str.Begin(), str.End()); +} + +void StringBuilder::Append(const std::string& str) +{ + m_Buffer.insert(m_Buffer.end(), str.begin(), str.end()); +} + +void StringBuilder::Append(const char *begin, const char *end) +{ + m_Buffer.insert(m_Buffer.end(), begin, end); +} + +void StringBuilder::Append(const char *cstr) +{ + m_Buffer.insert(m_Buffer.end(), cstr, cstr + std::strlen(cstr)); +} + +void StringBuilder::Append(char chr) +{ + m_Buffer.emplace_back(chr); +} + +String StringBuilder::ToString() const +{ + return String(m_Buffer.data(), m_Buffer.data() + m_Buffer.size()); +} diff --git a/lib/base/stringbuilder.hpp b/lib/base/stringbuilder.hpp new file mode 100644 index 000000000..841ce19bf --- /dev/null +++ b/lib/base/stringbuilder.hpp @@ -0,0 +1,53 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/) * + * * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef STRINGBUILDER_H +#define STRINGBUILDER_H + +#include "base/i2-base.hpp" +#include "base/string.hpp" +#include +#include + +namespace icinga +{ + +/** + * A string builder. + * + * @ingroup base + */ +class StringBuilder final +{ +public: + void Append(const String&); + void Append(const std::string&); + void Append(const char *, const char *); + void Append(const char *); + void Append(char); + + String ToString() const; + +private: + std::vector m_Buffer; +}; + +} + +#endif /* STRINGBUILDER_H */ -- 2.40.0