From af7a2135b7117b5ee407d625e3538219963b7fdd Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 22 Oct 2023 23:46:25 +0300 Subject: [PATCH] strings: add Bulder.write_decimal/1 method (write a decimal number, without additional allocations) (#19625) --- vlib/strings/builder.c.v | 29 ++++++++++++++++++++++++++++- vlib/strings/builder_test.v | 22 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/vlib/strings/builder.c.v b/vlib/strings/builder.c.v index 52b69e03217e1a..e0b8b3c23dc559 100644 --- a/vlib/strings/builder.c.v +++ b/vlib/strings/builder.c.v @@ -74,7 +74,34 @@ pub fn (mut b Builder) write_byte(data byte) { b << data } -// write implements the Writer interface +// write_decimal appends a decimal representation of the number `n` into the builder `b`, +// without dynamic allocation. The higher order digits come first, i.e. 6123 will be written +// with the digit `6` first, then `1`, then `2` and `3` last. +[direct_array_access] +pub fn (mut b Builder) write_decimal(n i64) { + if n == 0 { + b.write_u8(0x30) + return + } + mut buf := [25]u8{} + mut x := if n < 0 { -n } else { n } + mut i := 24 + for x != 0 { + nextx := x / 10 + r := x % 10 + buf[i] = u8(r) + 0x30 + x = nextx + i-- + } + if n < 0 { + buf[i] = `-` + i-- + } + unsafe { b.write_ptr(&buf[i + 1], 24 - i) } +} + +// write implements the io.Writer interface, that is why it +// it returns how many bytes were written to the string builder. pub fn (mut b Builder) write(data []u8) !int { if data.len == 0 { return 0 diff --git a/vlib/strings/builder_test.v b/vlib/strings/builder_test.v index 25c3d53ad93476..16b01cff132a03 100644 --- a/vlib/strings/builder_test.v +++ b/vlib/strings/builder_test.v @@ -144,3 +144,25 @@ fn test_drain_builder() { assert target_sb.len == 3 assert target_sb.str() == 'abc' } + +[manualfree] +fn sb_i64_str(n i64) string { + mut sb := strings.new_builder(24) + defer { + unsafe { sb.free() } + } + sb.write_decimal(n) + return sb.str() +} + +fn test_write_decimal() { + assert sb_i64_str(0) == '0' + assert sb_i64_str(1) == '1' + assert sb_i64_str(-1) == '-1' + assert sb_i64_str(1001) == '1001' + assert sb_i64_str(-1001) == '-1001' + assert sb_i64_str(1234567890) == '1234567890' + assert sb_i64_str(-1234567890) == '-1234567890' + assert sb_i64_str(9223372036854775807) == '9223372036854775807' + assert sb_i64_str(-9223372036854775807) == '-9223372036854775807' +}