• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 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 #include "quiche/quic/core/quic_tag.h"
6 
7 #include <algorithm>
8 #include <string>
9 
10 #include "absl/base/macros.h"
11 #include "absl/strings/escaping.h"
12 #include "absl/strings/str_split.h"
13 #include "quiche/quic/platform/api/quic_flag_utils.h"
14 #include "quiche/quic/platform/api/quic_flags.h"
15 #include "quiche/common/quiche_text_utils.h"
16 
17 namespace quic {
18 
FindMutualQuicTag(const QuicTagVector & our_tags,const QuicTagVector & their_tags,QuicTag * out_result,size_t * out_index)19 bool FindMutualQuicTag(const QuicTagVector& our_tags,
20                        const QuicTagVector& their_tags, QuicTag* out_result,
21                        size_t* out_index) {
22   const size_t num_our_tags = our_tags.size();
23   const size_t num_their_tags = their_tags.size();
24   for (size_t i = 0; i < num_our_tags; i++) {
25     for (size_t j = 0; j < num_their_tags; j++) {
26       if (our_tags[i] == their_tags[j]) {
27         *out_result = our_tags[i];
28         if (out_index != nullptr) {
29           *out_index = j;
30         }
31         return true;
32       }
33     }
34   }
35 
36   return false;
37 }
38 
QuicTagToString(QuicTag tag)39 std::string QuicTagToString(QuicTag tag) {
40   if (tag == 0) {
41     return "0";
42   }
43   char chars[sizeof tag];
44   bool ascii = true;
45   const QuicTag orig_tag = tag;
46 
47   for (size_t i = 0; i < ABSL_ARRAYSIZE(chars); i++) {
48     chars[i] = static_cast<char>(tag);
49     if ((chars[i] == 0 || chars[i] == '\xff') &&
50         i == ABSL_ARRAYSIZE(chars) - 1) {
51       chars[i] = ' ';
52     }
53     if (!isprint(static_cast<unsigned char>(chars[i]))) {
54       ascii = false;
55       break;
56     }
57     tag >>= 8;
58   }
59 
60   if (ascii) {
61     return std::string(chars, sizeof(chars));
62   }
63 
64   return absl::BytesToHexString(absl::string_view(
65       reinterpret_cast<const char*>(&orig_tag), sizeof(orig_tag)));
66 }
67 
MakeQuicTag(uint8_t a,uint8_t b,uint8_t c,uint8_t d)68 uint32_t MakeQuicTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
69   return static_cast<uint32_t>(a) | static_cast<uint32_t>(b) << 8 |
70          static_cast<uint32_t>(c) << 16 | static_cast<uint32_t>(d) << 24;
71 }
72 
ContainsQuicTag(const QuicTagVector & tag_vector,QuicTag tag)73 bool ContainsQuicTag(const QuicTagVector& tag_vector, QuicTag tag) {
74   return std::find(tag_vector.begin(), tag_vector.end(), tag) !=
75          tag_vector.end();
76 }
77 
ParseQuicTag(absl::string_view tag_string)78 QuicTag ParseQuicTag(absl::string_view tag_string) {
79   quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tag_string);
80   std::string tag_bytes;
81   if (tag_string.length() == 8) {
82     tag_bytes = absl::HexStringToBytes(tag_string);
83     tag_string = tag_bytes;
84   }
85   QuicTag tag = 0;
86   // Iterate over every character from right to left.
87   for (auto it = tag_string.rbegin(); it != tag_string.rend(); ++it) {
88     // The cast here is required on platforms where char is signed.
89     unsigned char token_char = static_cast<unsigned char>(*it);
90     tag <<= 8;
91     tag |= token_char;
92   }
93   return tag;
94 }
95 
ParseQuicTagVector(absl::string_view tags_string)96 QuicTagVector ParseQuicTagVector(absl::string_view tags_string) {
97   QuicTagVector tag_vector;
98   quiche::QuicheTextUtils::RemoveLeadingAndTrailingWhitespace(&tags_string);
99   if (!tags_string.empty()) {
100     std::vector<absl::string_view> tag_strings =
101         absl::StrSplit(tags_string, ',');
102     for (absl::string_view tag_string : tag_strings) {
103       tag_vector.push_back(ParseQuicTag(tag_string));
104     }
105   }
106   return tag_vector;
107 }
108 
109 }  // namespace quic
110