xref: /aosp_15_r20/external/openscreen/util/stringprintf.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef UTIL_STRINGPRINTF_H_
6 #define UTIL_STRINGPRINTF_H_
7 
8 #include <stdint.h>
9 
10 #include <ostream>
11 #include <string>
12 
13 namespace openscreen {
14 
15 // Enable compile-time checking of the printf format argument, if available.
16 #if defined(__GNUC__) || defined(__clang__)
17 #define OSP_CHECK_PRINTF_ARGS(format_param, dots_param) \
18   __attribute__((format(printf, format_param, dots_param)))
19 #else
20 #define OSP_CHECK_PRINTF_ARGS(format_param, dots_param)
21 #endif
22 
23 // Returns a std::string containing the results of a std::sprintf() call. This
24 // is an efficient, zero-copy wrapper.
25 [[nodiscard]] std::string StringPrintf(const char* format, ...)
26     OSP_CHECK_PRINTF_ARGS(1, 2);
27 
28 template <typename It>
PrettyPrintAsciiHex(std::ostream & os,It first,It last)29 void PrettyPrintAsciiHex(std::ostream& os, It first, It last) {
30   auto it = first;
31   while (it != last) {
32     uint8_t c = *it++;
33     if (c >= ' ' && c <= '~') {
34       os.put(c);
35     } else {
36       // Output a hex escape sequence for non-printable values.
37       os.put('\\');
38       os.put('x');
39       char digit = (c >> 4) & 0xf;
40       if (digit >= 0 && digit <= 9) {
41         os.put(digit + '0');
42       } else {
43         os.put(digit - 10 + 'a');
44       }
45       digit = c & 0xf;
46       if (digit >= 0 && digit <= 9) {
47         os.put(digit + '0');
48       } else {
49         os.put(digit - 10 + 'a');
50       }
51     }
52   }
53 }
54 
55 // Returns a hex string representation of the given |bytes|.
56 std::string HexEncode(const uint8_t* bytes, std::size_t len);
57 
58 }  // namespace openscreen
59 
60 #endif  // UTIL_STRINGPRINTF_H_
61