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