1 // Copyright 2019 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
15 // This size report uses pw::StringBuilder and std::snprintf to write several
16 // strings to a buffer. Ten strings are written using pw::StringBuilder and
17 // std::snprintf, tracking the number of bytes written and whether an error
20 // This compares the incremental cost of using StringBuilder instead of
21 // std::snprintf when both are already in use in a binary.
25 #include "pw_bloat/bloat_this_binary.h"
26 #include "pw_string/string_builder.h"
28 #if !defined(USE_STRING_BUILDER)
29 #error "USE_STRING_BUILDER must be defined"
30 #endif // !defined(USE_STRING_BUILDER)
32 #if USE_STRING_BUILDER
34 #define FORMAT_STRING(string_builder_out, ...) sb << string_builder_out
36 #else // std::snprintf
38 #define FORMAT_STRING(unused_string_builder_out, ...) \
39 ProcessResult(buffer, \
41 sizeof(buffer) - bytes, \
42 std::snprintf(buffer, sizeof(buffer) - bytes, __VA_ARGS__))
44 #endif // USE_STRING_BUILDER
46 bool ProcessResult(char* buffer, unsigned* total, unsigned size, int result) {
48 // Null-terminate since snprintf doesn't report the written count.
53 if (static_cast<unsigned>(result) >= size) {
64 volatile bool get_boolean;
65 volatile int get_integer;
66 char* volatile get_buffer;
67 char* volatile get_string;
70 int integer = get_integer;
71 bool boolean = get_boolean;
72 auto string = get_string;
74 char* buffer = get_buffer;
75 unsigned size = get_integer;
79 // Use std::snprintf and pw::StringBuilder so they're both accounted for in
81 int result = std::snprintf(buffer,
83 "Hello, %s. The answer to 3 == %d is %s.",
86 boolean ? "true" : "false");
88 ProcessResult(buffer, &bytes, size, result);
90 pw::StringBuilder sb(std::span(buffer, size));
91 sb << "This is part of the base " << 123 << false << '\n';
95 // Add five strings with either StringBuilder or std::snprintf.
96 FORMAT_STRING("Three", "Three");
97 FORMAT_STRING("point " << 1, "Three point %d", 1);
99 << "one" << ' ' << 5u,
103 FORMAT_STRING(string, "%s", string);
104 FORMAT_STRING("-->" << string << string << string << ' ' << integer << ' '
113 // Add five more strings with either StringBuilder or std::snprintf.
114 FORMAT_STRING("Three", "Three");
115 FORMAT_STRING("point " << 1, "Three point %d", 1);
116 FORMAT_STRING("four "
117 << "one" << ' ' << 5u,
121 FORMAT_STRING(string, "%s", string);
122 FORMAT_STRING(string << string << string << ' ' << integer << ' ' << boolean,