aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/string/format-inl.h
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.com>2022-08-26 10:04:55 +0300
committerbabenko <babenko@yandex-team.com>2022-08-26 10:04:55 +0300
commitaf6b0b93037268a9ca1343dd09629cf910c944d9 (patch)
tree609b08bbb2cd7498d55b6f7a92aaf1a4d51d003c /library/cpp/yt/string/format-inl.h
parentd40e0a72d30643f29b6fe0dee30d6d686f563e3f (diff)
downloadydb-af6b0b93037268a9ca1343dd09629cf910c944d9.tar.gz
Natively support %x and %X in Format
Diffstat (limited to 'library/cpp/yt/string/format-inl.h')
-rw-r--r--library/cpp/yt/string/format-inl.h115
1 files changed, 45 insertions, 70 deletions
diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h
index 5484d4a216..c437d7ab34 100644
--- a/library/cpp/yt/string/format-inl.h
+++ b/library/cpp/yt/string/format-inl.h
@@ -13,6 +13,8 @@
#include <library/cpp/yt/misc/enum.h>
+#include <util/system/platform.h>
+
#include <cctype>
#include <optional>
@@ -20,7 +22,7 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
-static const char GenericSpecSymbol = 'v';
+static constexpr char GenericSpecSymbol = 'v';
inline bool IsQuotationSpecSymbol(char symbol)
{
@@ -91,8 +93,8 @@ inline void FormatValue(TStringBuilderBase* builder, TStringBuf value, TStringBu
builder->AppendString("\\t");
} else if (ch < PrintableASCIILow || ch > PrintableASCIIHigh) {
builder->AppendString("\\x");
- builder->AppendChar(Int2Hex[static_cast<ui8>(ch) >> 4]);
- builder->AppendChar(Int2Hex[static_cast<ui8>(ch) & 0xf]);
+ builder->AppendChar(IntToHexLowercase[static_cast<ui8>(ch) >> 4]);
+ builder->AppendChar(IntToHexLowercase[static_cast<ui8>(ch) & 0xf]);
} else if ((singleQuotes && ch == '\'') || (doubleQuotes && ch == '\"')) {
builder->AppendChar('\\');
builder->AppendChar(ch);
@@ -121,6 +123,12 @@ inline void FormatValue(TStringBuilderBase* builder, const char* value, TStringB
FormatValue(builder, TStringBuf(value), format);
}
+// char*
+inline void FormatValue(TStringBuilderBase* builder, char* value, TStringBuf format)
+{
+ FormatValue(builder, TStringBuf(value), format);
+}
+
// char
inline void FormatValue(TStringBuilderBase* builder, char value, TStringBuf format)
{
@@ -438,91 +446,54 @@ auto FormatValue(TStringBuilderBase* builder, const TValue& value, TStringBuf fo
return TValueFormatter<TValue>::Do(builder, value, format);
}
+namespace NDetail {
+
template <class TValue>
void FormatValueViaSprintf(
TStringBuilderBase* builder,
TValue value,
TStringBuf format,
- TStringBuf genericSpec)
-{
- constexpr int MaxFormatSize = 64;
- constexpr int SmallResultSize = 64;
-
- auto copyFormat = [] (char* destination, const char* source, int length) {
- int position = 0;
- for (int index = 0; index < length; ++index) {
- if (IsQuotationSpecSymbol(source[index])) {
- continue;
- }
- destination[position] = source[index];
- ++position;
- }
- return destination + position;
- };
-
- char formatBuf[MaxFormatSize];
- YT_VERIFY(format.length() >= 1 && format.length() <= MaxFormatSize - 2); // one for %, one for \0
- formatBuf[0] = '%';
- if (format[format.length() - 1] == GenericSpecSymbol) {
- char* formatEnd = copyFormat(formatBuf + 1, format.begin(), format.length() - 1);
- ::memcpy(formatEnd, genericSpec.begin(), genericSpec.length());
- formatEnd[genericSpec.length()] = '\0';
- } else {
- char* formatEnd = copyFormat(formatBuf + 1, format.begin(), format.length());
- *formatEnd = '\0';
- }
-
- char* result = builder->Preallocate(SmallResultSize);
- size_t resultSize = ::snprintf(result, SmallResultSize, formatBuf, value);
- if (resultSize >= SmallResultSize) {
- result = builder->Preallocate(resultSize + 1);
- YT_VERIFY(::snprintf(result, resultSize + 1, formatBuf, value) == static_cast<int>(resultSize));
- }
- builder->Advance(resultSize);
-}
+ TStringBuf genericSpec);
template <class TValue>
-char* WriteIntToBufferBackwards(char* buffer, TValue value);
+void FormatIntValue(
+ TStringBuilderBase* builder,
+ TValue value,
+ TStringBuf format,
+ TStringBuf genericSpec);
-template <class TValue>
-void FormatValueViaHelper(TStringBuilderBase* builder, TValue value, TStringBuf format, TStringBuf genericSpec)
-{
- if (format == TStringBuf("v")) {
- const int MaxResultSize = 64;
- char buffer[MaxResultSize];
- char* end = buffer + MaxResultSize;
- char* start = WriteIntToBufferBackwards(end, value);
- builder->AppendString(TStringBuf(start, end));
- } else {
- FormatValueViaSprintf(builder, value, format, genericSpec);
- }
-}
+} // namespace NDetail
#define XX(valueType, castType, genericSpec) \
inline void FormatValue(TStringBuilderBase* builder, valueType value, TStringBuf format) \
{ \
- FormatValueViaHelper(builder, static_cast<castType>(value), format, genericSpec); \
- }
-
-XX(i8, int, TStringBuf("d"))
-XX(ui8, unsigned int, TStringBuf("u"))
-XX(i16, int, TStringBuf("d"))
-XX(ui16, unsigned int, TStringBuf("u"))
-XX(i32, int, TStringBuf("d"))
-XX(ui32, unsigned int, TStringBuf("u"))
-XX(long, long, TStringBuf("ld"))
-XX(unsigned long, unsigned long, TStringBuf("lu"))
+ NYT::NDetail::FormatIntValue(builder, static_cast<castType>(value), format, genericSpec); \
+ }
+
+XX(i8, i32, TStringBuf("d"))
+XX(ui8, ui32, TStringBuf("u"))
+XX(i16, i32, TStringBuf("d"))
+XX(ui16, ui32, TStringBuf("u"))
+XX(i32, i32, TStringBuf("d"))
+XX(ui32, ui32, TStringBuf("u"))
+#ifdef _win_
+XX(long long, i64, TStringBuf("lld"))
+XX(unsigned long long, ui64, TStringBuf("llu"))
+#else
+XX(long, i64, TStringBuf("ld"))
+XX(unsigned long, ui64, TStringBuf("lu"))
+#endif
#undef XX
#define XX(valueType, castType, genericSpec) \
inline void FormatValue(TStringBuilderBase* builder, valueType value, TStringBuf format) \
{ \
- FormatValueViaSprintf(builder, static_cast<castType>(value), format, genericSpec); \
+ NYT::NDetail::FormatValueViaSprintf(builder, static_cast<castType>(value), format, genericSpec); \
}
-XX(double, double, TStringBuf("lf"))
-XX(float, float, TStringBuf("f"))
+XX(double, double, TStringBuf("lf"))
+XX(float, float, TStringBuf("f"))
#undef XX
@@ -530,7 +501,7 @@ XX(float, float, TStringBuf("f"))
template <class T>
void FormatValue(TStringBuilderBase* builder, T* value, TStringBuf format)
{
- FormatValueViaSprintf(builder, value, format, TStringBuf("p"));
+ NYT::NDetail::FormatValueViaSprintf(builder, static_cast<const void*>(value), format, TStringBuf("p"));
}
// TDuration (specialize for performance reasons)
@@ -548,6 +519,8 @@ inline void FormatValue(TStringBuilderBase* builder, TInstant value, TStringBuf
////////////////////////////////////////////////////////////////////////////////
+namespace NDetail {
+
template <class TArgFormatter>
void FormatImpl(
TStringBuilderBase* builder,
@@ -649,6 +622,8 @@ void FormatImpl(
}
}
+} // namespace NDetail
+
////////////////////////////////////////////////////////////////////////////////
template <class T>
@@ -716,7 +691,7 @@ void Format(
TArgs&&... args)
{
TArgFormatterImpl<0, TArgs...> argFormatter(args...);
- FormatImpl(builder, format, argFormatter);
+ NYT::NDetail::FormatImpl(builder, format, argFormatter);
}
template <size_t Length, class... TArgs>