Buffet: Move buffet over to platform2 from src/platform/buffet.
This change also open-sources buffet. The only change in this CL
is the removal of the Makefile and addition of the buffet.gyp file.
BUG=chromium:355180
TEST=USE=buffet emerge-gizmo platform2
Change-Id: Ibf8d3ac3f38313f82a9c07d79932b6f30130f9c5
diff --git a/buffet/data_encoding.cc b/buffet/data_encoding.cc
new file mode 100644
index 0000000..0e040ab
--- /dev/null
+++ b/buffet/data_encoding.cc
@@ -0,0 +1,102 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "buffet/data_encoding.h"
+
+#include <base/strings/stringprintf.h>
+#include <string.h>
+
+#include "buffet/string_utils.h"
+
+namespace {
+
+inline int HexToDec(int hex) {
+ int dec = -1;
+ if (hex >= '0' && hex <= '9') {
+ dec = hex - '0';
+ } else if (hex >= 'A' && hex <= 'F') {
+ dec = hex - 'A' + 10;
+ } else if (hex >= 'a' && hex <= 'f') {
+ dec = hex - 'a' + 10;
+ }
+ return dec;
+}
+
+} // namespace
+
+/////////////////////////////////////////////////////////////////////////
+namespace chromeos {
+namespace data_encoding {
+
+std::string UrlEncode(char const* data, bool encodeSpaceAsPlus) {
+ std::string result;
+
+ while(*data) {
+ char c = *data++;
+ // According to RFC3986 (http://www.faqs.org/rfcs/rfc3986.html),
+ // section 2.3. - Unreserved Characters
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') ||
+ c == '-' || c == '.' || c == '_' || c == '~') {
+ result += c;
+ } else if (c == ' ' && encodeSpaceAsPlus) {
+ // For historical reasons, some URLs have spaces encoded as '+',
+ // this also applies to form data encoded as
+ // 'application/x-www-form-urlencoded'
+ result += '+';
+ } else {
+ base::StringAppendF(&result, "%%%02X", (unsigned char)c); // Encode as %NN
+ }
+ }
+ return result;
+}
+
+std::string UrlDecode(char const* data) {
+ std::string result;
+ while (*data) {
+ char c = *data++;
+ int part1 = 0, part2 = 0;
+ // HexToDec would return -1 even for character 0 (end of string),
+ // so it is safe to access data[0] and data[1] without overrunning the buf.
+ if (c == '%' &&
+ (part1 = HexToDec(data[0])) >= 0 && (part2 = HexToDec(data[1])) >= 0) {
+ c = char((part1 << 4) | part2);
+ data += 2;
+ } else if (c == '+') {
+ c = ' ';
+ }
+ result += c;
+ }
+ return result;
+}
+
+std::string WebParamsEncode(
+ std::vector<std::pair<std::string, std::string>> const& params,
+ bool encodeSpaceAsPlus) {
+ std::vector<std::string> pairs;
+ pairs.reserve(params.size());
+ for (auto const& p : params) {
+ std::string key = UrlEncode(p.first.c_str(), encodeSpaceAsPlus);
+ std::string value = UrlEncode(p.second.c_str(), encodeSpaceAsPlus);
+ pairs.push_back(string_utils::Join('=', key, value));
+ }
+
+ return string_utils::Join('&', pairs);
+}
+
+std::vector<std::pair<std::string, std::string>> WebParamsDecode(
+ std::string const& data) {
+ std::vector<std::pair<std::string, std::string>> result;
+ std::vector<std::string> params = string_utils::Split(data, '&');
+ for (auto p : params) {
+ auto pair = string_utils::SplitAtFirst(p, '=');
+ result.emplace_back(UrlDecode(pair.first.c_str()),
+ UrlDecode(pair.second.c_str()));
+ }
+ return result;
+}
+
+} // namespace data_encoding
+} // namespace chromeos