From 615f2147028688b5e36f159ccd2958552488215c Mon Sep 17 00:00:00 2001 From: Andy Getzendanner Date: Mon, 7 Nov 2022 14:12:00 -0800 Subject: Factor out the internal helper AppendTruncated, which is used and redefined in a couple places, plus several more that have yet to be released. PiperOrigin-RevId: 486759835 Change-Id: Ib1b24f287f856ca38b691fbce7e747f0f5a34626 --- absl/log/internal/append_truncated.h | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 absl/log/internal/append_truncated.h (limited to 'absl/log/internal/append_truncated.h') diff --git a/absl/log/internal/append_truncated.h b/absl/log/internal/append_truncated.h new file mode 100644 index 00000000..096b7517 --- /dev/null +++ b/absl/log/internal/append_truncated.h @@ -0,0 +1,40 @@ +// Copyright 2022 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_LOG_INTERNAL_APPEND_TRUNCATED_H_ +#define ABSL_LOG_INTERNAL_APPEND_TRUNCATED_H_ + +#include +#include + +#include "absl/base/config.h" +#include "absl/strings/string_view.h" +#include "absl/types/span.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace log_internal { +// Copies into `dst` as many bytes of `src` as will fit, then truncates the +// copied bytes from the front of `dst` and returns the number of bytes written. +inline size_t AppendTruncated(absl::string_view src, absl::Span &dst) { + if (src.size() > dst.size()) src = src.substr(0, dst.size()); + memcpy(dst.data(), src.data(), src.size()); + dst.remove_prefix(src.size()); + return src.size(); +} +} // namespace log_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_LOG_INTERNAL_APPEND_TRUNCATED_H_ -- cgit v1.2.3 From 13708db87b1ab69f4f2b3214f3f51e986546f282 Mon Sep 17 00:00:00 2001 From: Andy Getzendanner Date: Mon, 28 Nov 2022 15:14:27 -0800 Subject: Write (more) directly into the structured buffer from StringifySink, including for (size_t, char) overload. PiperOrigin-RevId: 491456410 Change-Id: I76dec24b0bd02204fa38419af9247cee38b1cf50 --- absl/log/check_test.cc | 2 +- absl/log/internal/append_truncated.h | 7 +++++++ absl/log/internal/log_message.cc | 21 +++++++++++++++++++++ absl/log/internal/log_message.h | 14 ++++++++++---- 4 files changed, 39 insertions(+), 5 deletions(-) (limited to 'absl/log/internal/append_truncated.h') diff --git a/absl/log/check_test.cc b/absl/log/check_test.cc index 4ce9d872..755adb3a 100644 --- a/absl/log/check_test.cc +++ b/absl/log/check_test.cc @@ -93,7 +93,7 @@ TEST(CHECKTest, TestBoolConvertible) { #if GTEST_HAS_DEATH_TEST -TEST(CHECKDeathTest, TestChecksWithSideeffects) { +TEST(CHECKDeathTest, TestChecksWithSideEffects) { int var = 0; CHECK([&var]() { ++var; diff --git a/absl/log/internal/append_truncated.h b/absl/log/internal/append_truncated.h index 096b7517..f0e7912c 100644 --- a/absl/log/internal/append_truncated.h +++ b/absl/log/internal/append_truncated.h @@ -33,6 +33,13 @@ inline size_t AppendTruncated(absl::string_view src, absl::Span &dst) { dst.remove_prefix(src.size()); return src.size(); } +// Likewise, but `n` copies of `c`. +inline size_t AppendTruncated(char c, size_t n, absl::Span &dst) { + if (n > dst.size()) n = dst.size(); + memset(dst.data(), c, n); + dst.remove_prefix(n); + return n; +} } // namespace log_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/log/internal/log_message.cc b/absl/log/internal/log_message.cc index 6b4804f1..a8080610 100644 --- a/absl/log/internal/log_message.cc +++ b/absl/log/internal/log_message.cc @@ -540,6 +540,27 @@ void LogMessage::CopyToEncodedBuffer(absl::string_view str, data_->encoded_remaining.remove_suffix(data_->encoded_remaining.size()); } } +void LogMessage::CopyToEncodedBuffer(char ch, size_t num, StringType str_type) { + auto encoded_remaining_copy = data_->encoded_remaining; + auto value_start = EncodeMessageStart( + EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + num, + &encoded_remaining_copy); + auto str_start = EncodeMessageStart(str_type == StringType::kLiteral + ? ValueTag::kStringLiteral + : ValueTag::kString, + num, &encoded_remaining_copy); + if (str_start.data()) { + // The field headers fit. + log_internal::AppendTruncated(ch, num, encoded_remaining_copy); + EncodeMessageLength(str_start, &encoded_remaining_copy); + EncodeMessageLength(value_start, &encoded_remaining_copy); + data_->encoded_remaining = encoded_remaining_copy; + } else { + // The field header(s) did not fit; zero `encoded_remaining` so we don't + // write anything else later. + data_->encoded_remaining.remove_suffix(data_->encoded_remaining.size()); + } +} LogMessageFatal::LogMessageFatal(const char* file, int line) : LogMessage(file, line, absl::LogSeverity::kFatal) {} diff --git a/absl/log/internal/log_message.h b/absl/log/internal/log_message.h index 7302dde0..3744276b 100644 --- a/absl/log/internal/log_message.h +++ b/absl/log/internal/log_message.h @@ -47,8 +47,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace log_internal { -class AsLiteralImpl; - constexpr int kLogMessageBufferSize = 15000; class LogMessage { @@ -195,6 +193,7 @@ class LogMessage { private: struct LogMessageData; // Opaque type containing message state friend class AsLiteralImpl; + friend class StringifySink; // This streambuf writes directly into the structured logging buffer so that // arbitrary types can be encoded as string data (using @@ -222,6 +221,8 @@ class LogMessage { }; void CopyToEncodedBuffer(absl::string_view str, StringType str_type) ABSL_ATTRIBUTE_NOINLINE; + void CopyToEncodedBuffer(char ch, size_t num, + StringType str_type) ABSL_ATTRIBUTE_NOINLINE; // Returns `true` if the message is fatal or enabled debug-fatal. bool IsFatal() const; @@ -250,9 +251,14 @@ class StringifySink final { public: explicit StringifySink(LogMessage& message) : message_(message) {} - void Append(size_t count, char ch) { message_ << std::string(count, ch); } + void Append(size_t count, char ch) { + message_.CopyToEncodedBuffer(ch, count, + LogMessage::StringType::kNotLiteral); + } - void Append(absl::string_view v) { message_ << v; } + void Append(absl::string_view v) { + message_.CopyToEncodedBuffer(v, LogMessage::StringType::kNotLiteral); + } // For types that implement `AbslStringify` using `absl::Format()`. friend void AbslFormatFlush(StringifySink* sink, absl::string_view v) { -- cgit v1.2.3