Make castv2 performance test work.
[chromium-blink-merge.git] / device / bluetooth / uribeacon / uri_encoder.cc
blob4c40d65a39b9a9d40d71c0ac24f5b40349ae3510
1 // Copyright 2015 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.
5 #include "uri_encoder.h"
7 using base::StringPiece;
9 namespace {
11 struct expansion {
12 uint8_t code;
13 const char* value;
16 // The two following data structures are the expansions code tables for URI
17 // encoding described in the following specification:
18 // https://github.com/google/uribeacon/blob/master/specification/AdvertisingMode.md
20 // For the prefix of the URI.
21 struct expansion prefix_expansions_list[] = {
22 {0, "http://www."},
23 {1, "https://www."},
24 {2, "http://"},
25 {3, "https://"},
26 {4, "urn:uuid:"},
29 // For the remaining part of the URI.
30 struct expansion expansions_list[] = {
31 {0, ".com/"},
32 {1, ".org/"},
33 {2, ".edu/"},
34 {3, ".net/"},
35 {4, ".info/"},
36 {5, ".biz/"},
37 {6, ".gov/"},
38 {7, ".com"},
39 {8, ".org"},
40 {9, ".edu"},
41 {10, ".net"},
42 {11, ".info"},
43 {12, ".biz"},
44 {13, ".gov"},
47 struct expansion* CommonLookupExpansionByValue(struct expansion* table,
48 int table_length,
49 const std::string& input,
50 int input_index) {
51 int found = -1;
52 int found_length = -1;
54 for (int k = 0; k < table_length; k++) {
55 const char* value = table[k].value;
56 int len = static_cast<int>(strlen(table[k].value));
57 if (input_index + len <= static_cast<int>(input.size())) {
58 if (len > found_length && strncmp(&input[input_index], value, len) == 0) {
59 found = k;
60 found_length = len;
64 if (found == -1)
65 return NULL;
66 return &table[found];
69 struct expansion* LookupExpansionByValue(const std::string& input,
70 int input_index) {
71 return CommonLookupExpansionByValue(
72 expansions_list, arraysize(expansions_list), input, input_index);
75 struct expansion* LookupPrefixExpansionByValue(const std::string& input,
76 int input_index) {
77 return CommonLookupExpansionByValue(prefix_expansions_list,
78 arraysize(prefix_expansions_list), input,
79 input_index);
82 struct expansion* LookupExpansionByCode(const std::vector<uint8_t>& input,
83 int input_index) {
84 if (input[input_index] >= arraysize(expansions_list))
85 return NULL;
86 return &expansions_list[input[input_index]];
89 struct expansion* LookupPrefixExpansionByCode(const std::vector<uint8_t>& input,
90 int input_index) {
91 if (input[input_index] >= arraysize(prefix_expansions_list))
92 return NULL;
93 return &prefix_expansions_list[input[input_index]];
96 } // namespace
98 void device::EncodeUriBeaconUri(const std::string& input,
99 std::vector<uint8_t>& output) {
100 int i = 0;
101 while (i < static_cast<int>(input.size())) {
102 struct expansion* exp;
103 if (i == 0)
104 exp = LookupPrefixExpansionByValue(input, i);
105 else
106 exp = LookupExpansionByValue(input, i);
107 if (exp == NULL) {
108 output.push_back(static_cast<uint8_t>(input[i]));
109 i++;
110 } else {
111 output.push_back(exp->code);
112 i += static_cast<int>(strlen(exp->value));
117 void device::DecodeUriBeaconUri(const std::vector<uint8_t>& input,
118 std::string& output) {
119 int length = static_cast<int>(input.size());
120 for (int i = 0; i < length; i++) {
121 struct expansion* exp;
122 if (i == 0)
123 exp = LookupPrefixExpansionByCode(input, i);
124 else
125 exp = LookupExpansionByCode(input, i);
126 if (exp == NULL)
127 output.push_back(static_cast<char>(input[i]));
128 else
129 output.append(exp->value);