1 // Copyright 2016 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 NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TEXT_UTILS_IMPL_H_
6 #define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TEXT_UTILS_IMPL_H_
7 
8 #include <algorithm>
9 #include <cstdint>
10 #include <sstream>
11 #include <string>
12 #include <vector>
13 
14 #include "base/strings/abseil_string_conversions.h"
15 #include "net/base/hex_utils.h"
16 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
17 #include "third_party/abseil-cpp/absl/strings/ascii.h"
18 #include "third_party/abseil-cpp/absl/strings/escaping.h"
19 #include "third_party/abseil-cpp/absl/strings/match.h"
20 #include "third_party/abseil-cpp/absl/strings/str_cat.h"
21 #include "third_party/abseil-cpp/absl/strings/str_split.h"
22 #include "third_party/abseil-cpp/absl/types/optional.h"
23 
24 namespace quiche {
25 
26 // Chromium implementation of quiche::QuicheTextUtils.
27 class QuicheTextUtilsImpl {
28  public:
29   // Returns true of |data| starts with |prefix|, case sensitively.
StartsWith(absl::string_view data,absl::string_view prefix)30   static bool StartsWith(absl::string_view data, absl::string_view prefix) {
31     return absl::StartsWith(data, prefix);
32   }
33 
34   // Returns true if |data| end with |suffix|, case sensitively.
EndsWith(absl::string_view data,absl::string_view suffix)35   static bool EndsWith(absl::string_view data, absl::string_view suffix) {
36     return absl::EndsWith(data, suffix);
37   }
38 
39   // Returns true of |data| ends with |suffix|, case insensitively.
EndsWithIgnoreCase(absl::string_view data,absl::string_view suffix)40   static bool EndsWithIgnoreCase(absl::string_view data,
41                                  absl::string_view suffix) {
42     return absl::EndsWithIgnoreCase(data, suffix);
43   }
44 
45   // Returns a new std::string in which |data| has been converted to lower case.
ToLower(absl::string_view data)46   static std::string ToLower(absl::string_view data) {
47     return absl::AsciiStrToLower(data);
48   }
49 
50   // Remove leading and trailing whitespace from |data|.
RemoveLeadingAndTrailingWhitespace(absl::string_view * data)51   static void RemoveLeadingAndTrailingWhitespace(absl::string_view* data) {
52     *data = absl::StripAsciiWhitespace(*data);
53   }
54 
55   // Returns true if |in| represents a valid uint64, and stores that value in
56   // |out|.
StringToUint64(absl::string_view in,uint64_t * out)57   static bool StringToUint64(absl::string_view in, uint64_t* out) {
58     return absl::SimpleAtoi(in, out);
59   }
60 
61   // Returns true if |in| represents a valid int, and stores that value in
62   // |out|.
StringToInt(absl::string_view in,int * out)63   static bool StringToInt(absl::string_view in, int* out) {
64     return absl::SimpleAtoi(in, out);
65   }
66 
67   // Returns true if |in| represents a valid uint32, and stores that value in
68   // |out|.
StringToUint32(absl::string_view in,uint32_t * out)69   static bool StringToUint32(absl::string_view in, uint32_t* out) {
70     return absl::SimpleAtoi(in, out);
71   }
72 
73   // Returns true if |in| represents a valid size_t, and stores that value in
74   // |out|.
StringToSizeT(absl::string_view in,size_t * out)75   static bool StringToSizeT(absl::string_view in, size_t* out) {
76     return absl::SimpleAtoi(in, out);
77   }
78 
79   // Returns a new std::string representing |in|.
Uint64ToString(uint64_t in)80   static std::string Uint64ToString(uint64_t in) { return absl::StrCat(in); }
81 
82   // This converts |length| bytes of binary to a 2*|length|-character
83   // hexadecimal representation.
84   // Return value: 2*|length| characters of ASCII std::string.
HexEncode(absl::string_view data)85   static std::string HexEncode(absl::string_view data) {
86     return absl::BytesToHexString(data);
87   }
88 
Hex(uint32_t v)89   static std::string Hex(uint32_t v) { return absl::StrCat(absl::Hex(v)); }
90 
91   // Converts |data| from a hexadecimal ASCII string to a binary string
92   // that is |data.length()/2| bytes long. On failure returns empty string.
HexDecode(absl::string_view data)93   static std::string HexDecode(absl::string_view data) {
94     return absl::HexStringToBytes(data);
95   }
96 
97   // Base64 encodes with no padding |data_len| bytes of |data| into |output|.
Base64Encode(const uint8_t * data,size_t data_len,std::string * output)98   static void Base64Encode(const uint8_t* data,
99                            size_t data_len,
100                            std::string* output) {
101     absl::Base64Escape(
102         std::string(reinterpret_cast<const char*>(data), data_len), output);
103     // Remove padding.
104     size_t len = output->size();
105     if (len >= 2) {
106       if ((*output)[len - 1] == '=') {
107         len--;
108         if ((*output)[len - 1] == '=') {
109           len--;
110         }
111         output->resize(len);
112       }
113     }
114   }
115 
116   // Decodes a base64-encoded |input|.  Returns nullopt when the input is
117   // invalid.
Base64Decode(absl::string_view input)118   static absl::optional<std::string> Base64Decode(absl::string_view input) {
119     std::string output;
120     if (!absl::Base64Unescape(input, &output)) {
121       return absl::optional<std::string>();
122     }
123     return output;
124   }
125 
126   // Returns a std::string containing hex and ASCII representations of |binary|,
127   // side-by-side in the style of hexdump. Non-printable characters will be
128   // printed as '.' in the ASCII output.
129   // For example, given the input "Hello, QUIC!\01\02\03\04", returns:
130   // "0x0000:  4865 6c6c 6f2c 2051 5549 4321 0102 0304  Hello,.QUIC!...."
HexDump(absl::string_view binary_input)131   static std::string HexDump(absl::string_view binary_input) {
132     return net::HexDump(base::StringViewToStringPiece(binary_input));
133   }
134 
135   // Returns true if |data| contains any uppercase characters.
ContainsUpperCase(absl::string_view data)136   static bool ContainsUpperCase(absl::string_view data) {
137     return std::any_of(data.begin(), data.end(), absl::ascii_isupper);
138   }
139 
140   // Returns true if |data| contains only decimal digits.
IsAllDigits(absl::string_view data)141   static bool IsAllDigits(absl::string_view data) {
142     return std::all_of(data.begin(), data.end(), absl::ascii_isdigit);
143   }
144 
145   // Splits |data| into a vector of pieces delimited by |delim|.
Split(absl::string_view data,char delim)146   static std::vector<absl::string_view> Split(absl::string_view data,
147                                               char delim) {
148     return absl::StrSplit(data, delim);
149   }
150 };
151 
152 }  // namespace quiche
153 
154 #endif  // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TEXT_UTILS_IMPL_H_
155