1 // Copyright 2021 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 #include "quiche/common/quiche_text_utils.h"
6
7 #include "absl/strings/escaping.h"
8 #include "absl/strings/str_cat.h"
9 #include "absl/strings/str_format.h"
10
11 namespace quiche {
12
13 // static
Base64Encode(const uint8_t * data,size_t data_len,std::string * output)14 void QuicheTextUtils::Base64Encode(const uint8_t* data, size_t data_len,
15 std::string* output) {
16 absl::Base64Escape(std::string(reinterpret_cast<const char*>(data), data_len),
17 output);
18 // Remove padding.
19 size_t len = output->size();
20 if (len >= 2) {
21 if ((*output)[len - 1] == '=') {
22 len--;
23 if ((*output)[len - 1] == '=') {
24 len--;
25 }
26 output->resize(len);
27 }
28 }
29 }
30
31 // static
Base64Decode(absl::string_view input)32 std::optional<std::string> QuicheTextUtils::Base64Decode(
33 absl::string_view input) {
34 std::string output;
35 if (!absl::Base64Unescape(input, &output)) {
36 return std::nullopt;
37 }
38 return output;
39 }
40
41 // static
HexDump(absl::string_view binary_data)42 std::string QuicheTextUtils::HexDump(absl::string_view binary_data) {
43 const int kBytesPerLine = 16; // Maximum bytes dumped per line.
44 int offset = 0;
45 const char* p = binary_data.data();
46 int bytes_remaining = binary_data.size();
47 std::string output;
48 while (bytes_remaining > 0) {
49 const int line_bytes = std::min(bytes_remaining, kBytesPerLine);
50 absl::StrAppendFormat(&output, "0x%04x: ", offset);
51 for (int i = 0; i < kBytesPerLine; ++i) {
52 if (i < line_bytes) {
53 absl::StrAppendFormat(&output, "%02x",
54 static_cast<unsigned char>(p[i]));
55 } else {
56 absl::StrAppend(&output, " ");
57 }
58 if (i % 2) {
59 absl::StrAppend(&output, " ");
60 }
61 }
62 absl::StrAppend(&output, " ");
63 for (int i = 0; i < line_bytes; ++i) {
64 // Replace non-printable characters and 0x20 (space) with '.'
65 output += absl::ascii_isgraph(p[i]) ? p[i] : '.';
66 }
67
68 bytes_remaining -= line_bytes;
69 offset += line_bytes;
70 p += line_bytes;
71 absl::StrAppend(&output, "\n");
72 }
73 return output;
74 }
75
76 } // namespace quiche
77