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