mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
@@ -80,46 +80,44 @@ namespace beast {
|
|||||||
class SimpleJsonWriter
|
class SimpleJsonWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SimpleJsonWriter(std::ostringstream& stream) : stream_(stream)
|
explicit SimpleJsonWriter(std::string& stream) : stream_(stream)
|
||||||
{
|
{
|
||||||
stream_.imbue(std::locale::classic());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
startObject() const
|
startObject() const
|
||||||
{
|
{
|
||||||
stream_.put('{');
|
stream_.append("{", 1);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
endObject() const
|
endObject() const
|
||||||
{
|
{
|
||||||
stream_.seekp(-1, std::ios_base::end);
|
stream_.pop_back();
|
||||||
stream_.write("},", 2);
|
stream_.append("},", 2);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeKey(std::string_view key) const
|
writeKey(std::string_view key) const
|
||||||
{
|
{
|
||||||
writeString(key);
|
writeString(key);
|
||||||
stream_.seekp(-1, std::ios_base::end);
|
*stream_.rbegin() = ':';
|
||||||
stream_.put(':');
|
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
startArray() const
|
startArray() const
|
||||||
{
|
{
|
||||||
stream_.put('[');
|
stream_.append("[", 1);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
endArray() const
|
endArray() const
|
||||||
{
|
{
|
||||||
stream_.seekp(-1, std::ios_base::end);
|
stream_.pop_back();
|
||||||
stream_.write("],", 2);
|
stream_.append("],", 2);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeString(std::string_view str) const
|
writeString(std::string_view str) const
|
||||||
{
|
{
|
||||||
stream_.put('"');
|
stream_.push_back('"');
|
||||||
escape(str, stream_);
|
escape(str, stream_);
|
||||||
stream_.write("\",", 2);
|
stream_.append("\",", 2);
|
||||||
}
|
}
|
||||||
std::string_view
|
std::string_view
|
||||||
writeInt(std::int64_t val) const
|
writeInt(std::int64_t val) const
|
||||||
@@ -140,44 +138,43 @@ public:
|
|||||||
writeBool(bool val) const
|
writeBool(bool val) const
|
||||||
{
|
{
|
||||||
auto str = val ? "true," : "false,";
|
auto str = val ? "true," : "false,";
|
||||||
stream_.write(str, std::strlen(str));
|
stream_.append(str, std::strlen(str));
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeNull() const
|
writeNull() const
|
||||||
{
|
{
|
||||||
stream_.write("null", std::strlen("null"));
|
stream_.append("null", std::strlen("null"));
|
||||||
stream_.put(',');
|
stream_.push_back(',');
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
writeRaw(std::string_view str) const
|
writeRaw(std::string_view str) const
|
||||||
{
|
{
|
||||||
stream_.write(str.data(), str.length());
|
stream_.append(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string
|
[[nodiscard]] std::string
|
||||||
str() const
|
finish()
|
||||||
{
|
{
|
||||||
auto result = stream_.str();
|
stream_.pop_back();
|
||||||
result.pop_back();
|
return stream_;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::string_view
|
static std::string_view
|
||||||
pushNumber(T val, std::ostringstream& stream)
|
pushNumber(T val, std::string& stream)
|
||||||
{
|
{
|
||||||
static char buffer[128];
|
static char buffer[128];
|
||||||
auto result = std::to_chars(std::begin(buffer), std::end(buffer), val);
|
auto result = std::to_chars(std::begin(buffer), std::end(buffer), val);
|
||||||
*result.ptr = ',';
|
*result.ptr = ',';
|
||||||
auto len = result.ptr - std::begin(buffer);
|
auto len = result.ptr - std::begin(buffer);
|
||||||
stream.write(buffer, len + 1);
|
stream.append(buffer, len + 1);
|
||||||
return {buffer, static_cast<size_t>(len)};
|
return {buffer, static_cast<size_t>(len)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
escape(std::string_view str, std::ostringstream& os)
|
escape(std::string_view str, std::string& os)
|
||||||
{
|
{
|
||||||
static constexpr char HEX[] = "0123456789ABCDEF";
|
static constexpr char HEX[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
@@ -198,16 +195,16 @@ private:
|
|||||||
|
|
||||||
// Flush the preceding safe run in one go.
|
// Flush the preceding safe run in one go.
|
||||||
if (chunk != p)
|
if (chunk != p)
|
||||||
os.write(chunk, p - chunk);
|
os.append(chunk, p - chunk);
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '"': os.write("\\\"", 2); break;
|
case '"': os.append("\\\"", 2); break;
|
||||||
case '\\': os.write("\\\\", 2); break;
|
case '\\': os.append("\\\\", 2); break;
|
||||||
case '\b': os.write("\\b", 2); break;
|
case '\b': os.append("\\b", 2); break;
|
||||||
case '\f': os.write("\\f", 2); break;
|
case '\f': os.append("\\f", 2); break;
|
||||||
case '\n': os.write("\\n", 2); break;
|
case '\n': os.append("\\n", 2); break;
|
||||||
case '\r': os.write("\\r", 2); break;
|
case '\r': os.append("\\r", 2); break;
|
||||||
case '\t': os.write("\\t", 2); break;
|
case '\t': os.append("\\t", 2); break;
|
||||||
default: {
|
default: {
|
||||||
// Other C0 controls -> \u00XX (JSON compliant)
|
// Other C0 controls -> \u00XX (JSON compliant)
|
||||||
char buf[6]{
|
char buf[6]{
|
||||||
@@ -215,7 +212,7 @@ private:
|
|||||||
HEX[(c >> 4) & 0xF],
|
HEX[(c >> 4) & 0xF],
|
||||||
HEX[c & 0xF]
|
HEX[c & 0xF]
|
||||||
};
|
};
|
||||||
os.write(buf, 6);
|
os.append(buf, 6);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,10 +223,10 @@ private:
|
|||||||
|
|
||||||
// Flush trailing safe run
|
// Flush trailing safe run
|
||||||
if (chunk != p)
|
if (chunk != p)
|
||||||
os.write(chunk, p - chunk);
|
os.append(chunk, p - chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream& stream_;
|
std::string& stream_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A namespace for easy access to logging severity values. */
|
/** A namespace for easy access to logging severity values. */
|
||||||
@@ -284,7 +281,7 @@ public:
|
|||||||
|
|
||||||
class JsonLogContext
|
class JsonLogContext
|
||||||
{
|
{
|
||||||
std::ostringstream buffer_;
|
std::string buffer_;
|
||||||
SimpleJsonWriter messageParamsWriter_;
|
SimpleJsonWriter messageParamsWriter_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -567,14 +564,14 @@ public:
|
|||||||
Journal(Journal const& other, TAttributesFactory&& attributesFactory)
|
Journal(Journal const& other, TAttributesFactory&& attributesFactory)
|
||||||
: m_name(other.m_name), m_sink(other.m_sink)
|
: m_name(other.m_name), m_sink(other.m_sink)
|
||||||
{
|
{
|
||||||
std::ostringstream stream{other.m_attributesJson, std::ios_base::app};
|
std::string stream{other.m_attributesJson};
|
||||||
SimpleJsonWriter writer{stream};
|
SimpleJsonWriter writer{stream};
|
||||||
if (other.m_attributesJson.empty())
|
if (other.m_attributesJson.empty())
|
||||||
{
|
{
|
||||||
writer.startObject();
|
writer.startObject();
|
||||||
}
|
}
|
||||||
attributesFactory(writer);
|
attributesFactory(writer);
|
||||||
m_attributesJson = stream.str();
|
m_attributesJson = std::move(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a journal that writes to the specified sink. */
|
/** Create a journal that writes to the specified sink. */
|
||||||
@@ -591,11 +588,11 @@ public:
|
|||||||
TAttributesFactory&& attributesFactory)
|
TAttributesFactory&& attributesFactory)
|
||||||
: m_name(name), m_sink(&sink)
|
: m_name(name), m_sink(&sink)
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::string stream;
|
||||||
SimpleJsonWriter writer{stream};
|
SimpleJsonWriter writer{stream};
|
||||||
writer.startObject();
|
writer.startObject();
|
||||||
attributesFactory(writer);
|
attributesFactory(writer);
|
||||||
m_attributesJson = stream.str();
|
m_attributesJson = std::move(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
Journal&
|
Journal&
|
||||||
@@ -712,15 +709,14 @@ public:
|
|||||||
std::lock_guard lock(globalLogAttributesMutex_);
|
std::lock_guard lock(globalLogAttributesMutex_);
|
||||||
|
|
||||||
auto isEmpty = globalLogAttributesJson_.empty();
|
auto isEmpty = globalLogAttributesJson_.empty();
|
||||||
std::ostringstream stream{
|
std::string stream{std::move(globalLogAttributesJson_)};
|
||||||
std::move(globalLogAttributesJson_), std::ios_base::app};
|
|
||||||
SimpleJsonWriter writer{stream};
|
SimpleJsonWriter writer{stream};
|
||||||
if (isEmpty)
|
if (isEmpty)
|
||||||
{
|
{
|
||||||
writer.startObject();
|
writer.startObject();
|
||||||
}
|
}
|
||||||
factory(writer);
|
factory(writer);
|
||||||
globalLogAttributesJson_ = stream.str();
|
globalLogAttributesJson_ = std::move(stream);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ Journal::JsonLogContext::reset(
|
|||||||
};
|
};
|
||||||
thread_local ThreadIdStringInitializer const threadId;
|
thread_local ThreadIdStringInitializer const threadId;
|
||||||
|
|
||||||
buffer_.str("");
|
buffer_.clear();
|
||||||
|
|
||||||
writer().startObject();
|
writer().startObject();
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ Journal::formatLog(std::string&& message)
|
|||||||
|
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
|
|
||||||
return writer.str();
|
return writer.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -212,35 +212,35 @@ TEST_CASE("Global attributes inheritable")
|
|||||||
TEST_CASE("Test JsonWriter")
|
TEST_CASE("Test JsonWriter")
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::string stream;
|
||||||
beast::SimpleJsonWriter writer{stream};
|
beast::SimpleJsonWriter writer{stream};
|
||||||
|
|
||||||
writer.writeString("\n");
|
writer.writeString("\n");
|
||||||
CHECK(writer.str() == "\"\\n\"");
|
CHECK(writer.finish() == "\"\\n\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::string stream;
|
||||||
beast::SimpleJsonWriter writer{stream};
|
beast::SimpleJsonWriter writer{stream};
|
||||||
|
|
||||||
writer.writeString("\t");
|
writer.writeString("\t");
|
||||||
CHECK(writer.str() == "\"\\t\"");
|
CHECK(writer.finish() == "\"\\t\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::string stream;
|
||||||
beast::SimpleJsonWriter writer{stream};
|
beast::SimpleJsonWriter writer{stream};
|
||||||
|
|
||||||
writer.writeString(std::string_view{"\0", 1});
|
writer.writeString(std::string_view{"\0", 1});
|
||||||
CHECK(writer.str() == "\"\\u0000\"");
|
CHECK(writer.finish() == "\"\\u0000\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream stream;
|
std::string stream;
|
||||||
beast::SimpleJsonWriter writer{stream};
|
beast::SimpleJsonWriter writer{stream};
|
||||||
|
|
||||||
writer.writeString("\"\\");
|
writer.writeString("\"\\");
|
||||||
CHECK(writer.str() == "\"\\\"\\\\\"");
|
CHECK(writer.finish() == "\"\\\"\\\\\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user