| // Copyright 2013 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. | 
 |  | 
 | // Functions for canonicalizing "mailto:" URLs. | 
 |  | 
 | #include "url/url_canon.h" | 
 | #include "url/url_canon_internal.h" | 
 | #include "url/url_file.h" | 
 | #include "url/url_parse_internal.h" | 
 |  | 
 | namespace url { | 
 |  | 
 | namespace { | 
 |  | 
 | template <typename CHAR, typename UCHAR> | 
 | bool DoCanonicalizeMailtoURL(const URLComponentSource<CHAR>& source, | 
 |                              const Parsed& parsed, | 
 |                              CanonOutput* output, | 
 |                              Parsed* new_parsed) { | 
 |   // mailto: only uses {scheme, path, query} -- clear the rest. | 
 |   new_parsed->username = Component(); | 
 |   new_parsed->password = Component(); | 
 |   new_parsed->host = Component(); | 
 |   new_parsed->port = Component(); | 
 |   new_parsed->ref = Component(); | 
 |  | 
 |   // Scheme (known, so we don't bother running it through the more | 
 |   // complicated scheme canonicalizer). | 
 |   new_parsed->scheme.begin = output->length(); | 
 |   output->Append("mailto:", 7); | 
 |   new_parsed->scheme.len = 6; | 
 |  | 
 |   bool success = true; | 
 |  | 
 |   // Path | 
 |   if (parsed.path.is_valid()) { | 
 |     new_parsed->path.begin = output->length(); | 
 |  | 
 |     // Copy the path using path URL's more lax escaping rules. | 
 |     // We convert to UTF-8 and escape non-ASCII, but leave all | 
 |     // ASCII characters alone. | 
 |     int end = parsed.path.end(); | 
 |     for (int i = parsed.path.begin; i < end; ++i) { | 
 |       UCHAR uch = static_cast<UCHAR>(source.path[i]); | 
 |       if (uch < 0x20 || uch >= 0x80) | 
 |         success &= AppendUTF8EscapedChar(source.path, &i, end, output); | 
 |       else | 
 |         output->push_back(static_cast<char>(uch)); | 
 |     } | 
 |  | 
 |     new_parsed->path.len = output->length() - new_parsed->path.begin; | 
 |   } else { | 
 |     // No path at all | 
 |     new_parsed->path.reset(); | 
 |   } | 
 |  | 
 |   // Query -- always use the default utf8 charset converter. | 
 |   CanonicalizeQuery(source.query, parsed.query, NULL, | 
 |                     output, &new_parsed->query); | 
 |  | 
 |   return success; | 
 | } | 
 |  | 
 | } // namespace | 
 |  | 
 | bool CanonicalizeMailtoURL(const char* spec, | 
 |                            int spec_len, | 
 |                            const Parsed& parsed, | 
 |                            CanonOutput* output, | 
 |                            Parsed* new_parsed) { | 
 |   return DoCanonicalizeMailtoURL<char, unsigned char>( | 
 |       URLComponentSource<char>(spec), parsed, output, new_parsed); | 
 | } | 
 |  | 
 | bool CanonicalizeMailtoURL(const base::char16* spec, | 
 |                            int spec_len, | 
 |                            const Parsed& parsed, | 
 |                            CanonOutput* output, | 
 |                            Parsed* new_parsed) { | 
 |   return DoCanonicalizeMailtoURL<base::char16, base::char16>( | 
 |       URLComponentSource<base::char16>(spec), parsed, output, new_parsed); | 
 | } | 
 |  | 
 | bool ReplaceMailtoURL(const char* base, | 
 |                       const Parsed& base_parsed, | 
 |                       const Replacements<char>& replacements, | 
 |                       CanonOutput* output, | 
 |                       Parsed* new_parsed) { | 
 |   URLComponentSource<char> source(base); | 
 |   Parsed parsed(base_parsed); | 
 |   SetupOverrideComponents(base, replacements, &source, &parsed); | 
 |   return DoCanonicalizeMailtoURL<char, unsigned char>( | 
 |       source, parsed, output, new_parsed); | 
 | } | 
 |  | 
 | bool ReplaceMailtoURL(const char* base, | 
 |                       const Parsed& base_parsed, | 
 |                       const Replacements<base::char16>& replacements, | 
 |                       CanonOutput* output, | 
 |                       Parsed* new_parsed) { | 
 |   RawCanonOutput<1024> utf8; | 
 |   URLComponentSource<char> source(base); | 
 |   Parsed parsed(base_parsed); | 
 |   SetupUTF16OverrideComponents(base, replacements, &utf8, &source, &parsed); | 
 |   return DoCanonicalizeMailtoURL<char, unsigned char>( | 
 |       source, parsed, output, new_parsed); | 
 | } | 
 |  | 
 | }  // namespace url |