diff options
author | asynts <asynts@gmail.com> | 2020-10-02 15:21:30 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-10-02 20:48:19 +0200 |
commit | 6351a56d275714205be721ec192c0b98b4f917f3 (patch) | |
tree | ce2ed22f91ad7a0302029989c89a5994544ccf16 /AK/PrintfImplementation.h | |
parent | ac5e08a541409bc47766be5196f5bec3140339dd (diff) | |
download | serenity-6351a56d275714205be721ec192c0b98b4f917f3.zip |
AK+Format: Do some housekeeping in the format implementation.
Diffstat (limited to 'AK/PrintfImplementation.h')
-rw-r--r-- | AK/PrintfImplementation.h | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/AK/PrintfImplementation.h b/AK/PrintfImplementation.h index f7926968c2..fc4179feef 100644 --- a/AK/PrintfImplementation.h +++ b/AK/PrintfImplementation.h @@ -38,172 +38,6 @@ namespace PrintfImplementation { static constexpr const char* printf_hex_digits_lower = "0123456789abcdef"; static constexpr const char* printf_hex_digits_upper = "0123456789ABCDEF"; -enum class Align { - Left, - Center, - Right, -}; - -enum class SignMode { - OnlyIfNeeded, - Always, - Reserved -}; - -// The worst case is that we have the largest 64-bit value formatted as binary number, this would take -// 65 bytes. Choosing a larger power of two won't hurt and is a bit of mitigation against out-of-bounds accesses. -inline size_t convert_unsigned_to_string(u64 value, Array<u8, 128>& buffer, u8 base, bool upper_case) -{ - ASSERT(base >= 2 && base <= 16); - - static constexpr const char* lowercase_lookup = "0123456789abcdef"; - static constexpr const char* uppercase_lookup = "0123456789ABCDEF"; - - if (value == 0) { - buffer[0] = '0'; - return 1; - } - - size_t used = 0; - while (value > 0) { - if (upper_case) - buffer[used++] = uppercase_lookup[value % base]; - else - buffer[used++] = lowercase_lookup[value % base]; - - value /= base; - } - - // Reverse the list; I came up with this logic in like three seconds so it's probably wrong in some edge case. - for (size_t i = 0; i < used / 2; ++i) - swap(buffer[i], buffer[used - i - 1]); - - return used; -} - -inline size_t convert_unsigned_to_string( - u64 value, - StringBuilder& builder, - u8 base = 10, - bool prefix = false, - bool upper_case = false, - bool zero_pad = false, - Align align = Align::Right, - size_t width = 0, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded, - bool is_negative = false) -{ - Array<u8, 128> buffer; - - const auto used_by_significant_digits = convert_unsigned_to_string(value, buffer, base, upper_case); - size_t used_by_prefix = sign_mode == SignMode::OnlyIfNeeded ? static_cast<size_t>(is_negative) : 1; - - if (prefix) { - if (base == 8) - used_by_prefix += 1; - else if (base == 16) - used_by_prefix += 2; - else if (base == 2) - used_by_prefix += 2; - } - - const auto put_prefix = [&]() { - if (is_negative) - builder.append('-'); - else if (sign_mode == SignMode::Always) - builder.append('+'); - else if (sign_mode == SignMode::Reserved) - builder.append(' '); - - if (prefix) { - if (base == 2) { - if (upper_case) - builder.append("0B"); - else - builder.append("0b"); - } else if (base == 8) { - builder.append("0"); - } else if (base == 16) { - if (upper_case) - builder.append("0X"); - else - builder.append("0x"); - } - } - }; - const auto put_padding = [&](size_t amount, char fill) { - for (size_t i = 0; i < amount; ++i) - builder.append(fill); - }; - const auto put_digits = [&]() { - builder.append(StringView { buffer.span().trim(used_by_significant_digits) }); - }; - - const auto used_by_field = used_by_significant_digits + used_by_prefix; - const auto used_by_padding = width < used_by_field ? 0 : width - used_by_field; - - if (align == Align::Left) { - const auto used_by_right_padding = used_by_padding; - - put_prefix(); - put_digits(); - put_padding(used_by_right_padding, fill); - - return used_by_field + used_by_right_padding; - } - - if (align == Align::Center) { - const auto used_by_left_padding = used_by_padding / 2; - const auto used_by_right_padding = ceil_div<size_t, size_t>(used_by_padding, 2); - - put_padding(used_by_left_padding, fill); - put_prefix(); - put_digits(); - put_padding(used_by_right_padding, fill); - - return used_by_left_padding + used_by_field + used_by_right_padding; - } - - if (align == Align::Right) { - const auto used_by_left_padding = used_by_padding; - - if (zero_pad) { - put_prefix(); - put_padding(used_by_left_padding, '0'); - put_digits(); - } else { - put_padding(used_by_left_padding, fill); - put_prefix(); - put_digits(); - } - - return used_by_field + used_by_left_padding; - } - - ASSERT_NOT_REACHED(); -} - -inline size_t convert_signed_to_string( - i64 value, - StringBuilder& builder, - u8 base = 10, - bool common_prefix = false, - bool upper_case = false, - bool zero_pad = false, - Align align = Align::Right, - size_t width = 0, - char fill = ' ', - SignMode sign_mode = SignMode::OnlyIfNeeded) -{ - bool is_negative = value < 0; - - if (value < 0) - value = -value; - - return convert_unsigned_to_string(static_cast<size_t>(value), builder, base, common_prefix, upper_case, zero_pad, align, width, fill, sign_mode, is_negative); -} - #ifdef __serenity__ extern "C" size_t strlen(const char*); #else |