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 // TODO: This header is included in the openscreen discovery public headers (dns_sd_instance.h),
14 // which exposes this abseil header. Need to figure out a way to hide it.
15 #if 0
16 #include "absl/types/span.h"
17 #endif
18
19 namespace openscreen {
20
21 // Enable compile-time checking of the printf format argument, if available.
22 #if defined(__GNUC__) || defined(__clang__)
23 #define OSP_CHECK_PRINTF_ARGS(format_param, dots_param) \
24 __attribute__((format(printf, format_param, dots_param)))
25 #else
26 #define OSP_CHECK_PRINTF_ARGS(format_param, dots_param)
27 #endif
28
29 // Returns a std::string containing the results of a std::sprintf() call. This
30 // is an efficient, zero-copy wrapper.
31 [[nodiscard]] std::string StringPrintf(const char* format, ...)
32 OSP_CHECK_PRINTF_ARGS(1, 2);
33
34 template <typename It>
PrettyPrintAsciiHex(std::ostream & os,It first,It last)35 void PrettyPrintAsciiHex(std::ostream& os, It first, It last) {
36 auto it = first;
37 while (it != last) {
38 uint8_t c = *it++;
39 if (c >= ' ' && c <= '~') {
40 os.put(c);
41 } else {
42 // Output a hex escape sequence for non-printable values.
43 os.put('\\');
44 os.put('x');
45 char digit = (c >> 4) & 0xf;
46 if (digit >= 0 && digit <= 9) {
47 os.put(digit + '0');
48 } else {
49 os.put(digit - 10 + 'a');
50 }
51 digit = c & 0xf;
52 if (digit >= 0 && digit <= 9) {
53 os.put(digit + '0');
54 } else {
55 os.put(digit - 10 + 'a');
56 }
57 }
58 }
59 }
60
61 #if 0
62 // Returns a hex string representation of the given |bytes|.
63 std::string HexEncode(absl::Span<const uint8_t> bytes);
64 #endif
65
66 } // namespace openscreen
67
68 #endif // UTIL_STRINGPRINTF_H_
69