Merge pull request #6858 from Icinga/feature/string-builder

Make string builder reusable
This commit is contained in:
Michael Friedrich 2019-02-04 16:05:20 +01:00 committed by GitHub
commit 4339240b46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 119 additions and 14 deletions

View File

@ -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

View File

@ -22,6 +22,7 @@
#include "base/dictionary.hpp"
#include "base/array.hpp"
#include "base/objectlock.hpp"
#include "base/stringbuilder.hpp"
#include <algorithm>
#include <climits>
#include <cstdint>
@ -30,9 +31,6 @@
using namespace icinga;
// Just for the sake of code readability
typedef std::vector<char> 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<String>(), builder);
break;
case ValueNumber:
builder.emplace_back(3);
builder.Append('\3');
PackFloat64BE(value.Get<double>(), 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();
}

View File

@ -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 <cstring>
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());
}

View File

@ -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 <string>
#include <vector>
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<char> m_Buffer;
};
}
#endif /* STRINGBUILDER_H */