1 // Copyright 2019 The Pigweed Authors
2 //
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
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
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
13 // the License.
14 
15 // This size report uses pw::string::Format and std::snprintf to write a single
16 // printf-style string to a buffer. The number of bytes written is returned.
17 //
18 // This compares the overhead of using pw::string::Format to directly calling
19 // std::snprintf and determining the number of bytes written. It demonstrates
20 // that the code for using pw::string::Format is much simpler.
21 
22 #include <cstddef>
23 #include <cstdio>
24 
25 #include "pw_bloat/bloat_this_binary.h"
26 #include "pw_string/format.h"
27 
28 #ifndef USE_FORMAT
29 #error "USE_FORMAT must be defined!"
30 #endif  // USE_FORMAT
31 
32 namespace pw::string {
33 
34 char buffer_1[128];
35 char buffer_2[128];
36 
37 char* volatile get_buffer_1 = buffer_1;
38 char* volatile get_buffer_2 = buffer_2;
39 volatile unsigned get_size;
40 
OutputStringsToBuffer()41 unsigned OutputStringsToBuffer() {
42   char* buffer = get_buffer_1;
43   unsigned buffer_size = get_size;
44 
45 #if USE_FORMAT
46   // The code for using pw::string::Format is much simpler and safer.
47   return Format(std::span(buffer, buffer_size),
48                 "hello %s %d",
49                 get_buffer_2,
50                 get_size)
51       .size();
52 #else  // std::snprintf
53   if (buffer_size == 0u) {
54     return 0;
55   }
56 
57   int result =
58       std::snprintf(buffer, buffer_size, "hello %s %d", get_buffer_2, get_size);
59   if (result < 0) {
60     buffer[0] = '\0';
61     return 0;
62   }
63   if (static_cast<size_t>(result) >= buffer_size) {
64     return buffer_size - 1;
65   }
66   return result;
67 #endif  // USE_FORMAT
68 }
69 
70 }  // namespace pw::string
71 
main()72 int main() {
73   pw::bloat::BloatThisBinary();
74   return pw::string::OutputStringsToBuffer();
75 }
76