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
;
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
[] = {
29 // For the remaining part of the URI.
30 struct expansion expansions_list
[] = {
47 struct expansion
* CommonLookupExpansionByValue(struct expansion
* table
,
49 const std::string
& input
,
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) {
69 struct expansion
* LookupExpansionByValue(const std::string
& input
,
71 return CommonLookupExpansionByValue(
72 expansions_list
, arraysize(expansions_list
), input
, input_index
);
75 struct expansion
* LookupPrefixExpansionByValue(const std::string
& input
,
77 return CommonLookupExpansionByValue(prefix_expansions_list
,
78 arraysize(prefix_expansions_list
), input
,
82 struct expansion
* LookupExpansionByCode(const std::vector
<uint8_t>& input
,
84 if (input
[input_index
] >= arraysize(expansions_list
))
86 return &expansions_list
[input
[input_index
]];
89 struct expansion
* LookupPrefixExpansionByCode(const std::vector
<uint8_t>& input
,
91 if (input
[input_index
] >= arraysize(prefix_expansions_list
))
93 return &prefix_expansions_list
[input
[input_index
]];
98 void device::EncodeUriBeaconUri(const std::string
& input
,
99 std::vector
<uint8_t>& output
) {
101 while (i
< static_cast<int>(input
.size())) {
102 struct expansion
* exp
;
104 exp
= LookupPrefixExpansionByValue(input
, i
);
106 exp
= LookupExpansionByValue(input
, i
);
108 output
.push_back(static_cast<uint8_t>(input
[i
]));
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
;
123 exp
= LookupPrefixExpansionByCode(input
, i
);
125 exp
= LookupExpansionByCode(input
, i
);
127 output
.push_back(static_cast<char>(input
[i
]));
129 output
.append(exp
->value
);