diff options
Diffstat (limited to 'net/tools/dump_cache/url_utilities.cc')
-rw-r--r-- | net/tools/dump_cache/url_utilities.cc | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/net/tools/dump_cache/url_utilities.cc b/net/tools/dump_cache/url_utilities.cc new file mode 100644 index 0000000..fe64bd9 --- /dev/null +++ b/net/tools/dump_cache/url_utilities.cc @@ -0,0 +1,126 @@ +// Copyright (c) 2010 The Chromium 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 "net/tools/dump_cache/url_utilities.h" + +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/string_util.h" + +namespace net { + +std::string UrlUtilities::GetUrlHost(const std::string& url) { + size_t b = url.find("//"); + if (b == std::string::npos) + b = 0; + else + b += 2; + size_t next_slash = url.find_first_of('/', b); + size_t next_colon = url.find_first_of(':', b); + if (next_slash != std::string::npos + && next_colon != std::string::npos + && next_colon < next_slash) { + return std::string(url, b, next_colon - b); + } + if (next_slash == std::string::npos) { + if (next_colon != std::string::npos) { + return std::string(url, b, next_colon - b); + } else { + next_slash = url.size(); + } + } + return std::string(url, b, next_slash - b); +} + +std::string UrlUtilities::GetUrlHostPath(const std::string& url) { + size_t b = url.find("//"); + if (b == std::string::npos) + b = 0; + else + b += 2; + return std::string(url, b); +} + +std::string UrlUtilities::GetUrlPath(const std::string& url) { + size_t b = url.find("//"); + if (b == std::string::npos) + b = 0; + else + b += 2; + b = url.find("/", b); + if (b == std::string::npos) + return "/"; + + size_t e = url.find("#", b+1); + if (e != std::string::npos) + return std::string(url, b, (e - b)); + return std::string(url, b); +} + +namespace { + +// Parsing states for UrlUtilities::Unescape +enum UnescapeState { + NORMAL, // We are not in the middle of parsing an escape. + ESCAPE1, // We just parsed % . + ESCAPE2 // We just parsed %X for some hex digit X. +}; + +} // namespace + +std::string UrlUtilities::Unescape(const std::string& escaped_url) { + std::string unescaped_url, escape_text; + int escape_value; + UnescapeState state = NORMAL; + std::string::const_iterator iter = escaped_url.begin(); + while (iter < escaped_url.end()) { + char c = *iter; + switch (state) { + case NORMAL: + if (c == '%') { + escape_text.clear(); + state = ESCAPE1; + } else { + unescaped_url.push_back(c); + } + ++iter; + break; + case ESCAPE1: + if (IsHexDigit(c)) { + escape_text.push_back(c); + state = ESCAPE2; + ++iter; + } else { + // Unexpected, % followed by non-hex chars, pass it through. + unescaped_url.push_back('%'); + state = NORMAL; + } + break; + case ESCAPE2: + if (IsHexDigit(c)) { + escape_text.push_back(c); + bool ok = base::HexStringToInt(escape_text, &escape_value); + DCHECK(ok); + unescaped_url.push_back(static_cast<unsigned char>(escape_value)); + state = NORMAL; + ++iter; + } else { + // Unexpected, % followed by non-hex chars, pass it through. + unescaped_url.push_back('%'); + unescaped_url.append(escape_text); + state = NORMAL; + } + break; + } + } + // Unexpected, % followed by end of string, pass it through. + if (state == ESCAPE1 || state == ESCAPE2) { + unescaped_url.push_back('%'); + unescaped_url.append(escape_text); + } + return unescaped_url; +} + +} // namespace net + |