Home | History | Annotate | Download | only in src
      1 // Copyright 2010, Google Inc. All rights reserved.
      2 //
      3 // Redistribution and use in source and binary forms, with or without
      4 // modification, are permitted provided that the following conditions are
      5 // met:
      6 //
      7 //     * Redistributions of source code must retain the above copyright
      8 // notice, this list of conditions and the following disclaimer.
      9 //     * Redistributions in binary form must reproduce the above
     10 // copyright notice, this list of conditions and the following disclaimer
     11 // in the documentation and/or other materials provided with the
     12 // distribution.
     13 //     * Neither the name of Google Inc. nor the names of its
     14 // contributors may be used to endorse or promote products derived from
     15 // this software without specific prior written permission.
     16 //
     17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 
     30 #ifndef URLQueryCanonicalizer_h
     31 #define URLQueryCanonicalizer_h
     32 
     33 #include "RawURLBuffer.h"
     34 #include "URLBuffer.h"
     35 #include "URLCharacterTypes.h"
     36 #include "URLComponent.h"
     37 #include "URLEscape.h"
     38 
     39 namespace WTF {
     40 
     41 template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)>
     42 class URLQueryCanonicalizer {
     43 public:
     44     static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery)
     45     {
     46         if (query.length() < 0) {
     47             resultQuery = URLComponent();
     48             return;
     49         }
     50 
     51         buffer->append('?');
     52         resultQuery.setBegin(buffer->length());
     53         convertToQueryEncoding(spec, query, buffer);
     54         resultQuery.setLength(buffer->length() - resultQuery.begin());
     55     }
     56 
     57 private:
     58     static bool isAllASCII(const InChar* spec, const URLComponent& query)
     59     {
     60         int end = query.end();
     61         for (int i = query.begin(); i < end; ++i) {
     62             if (static_cast<unsigned>(spec[i]) >= 0x80)
     63                 return false;
     64         }
     65         return true;
     66     }
     67 
     68 #ifndef NDEBUG
     69     static bool isRaw8Bit(const InChar* source, int length)
     70     {
     71         for (int i = source; i < length; ++i) {
     72             if (source[i] & 0xFF != source[i])
     73                 return false;
     74         }
     75         return true;
     76     }
     77 #endif
     78 
     79     static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer)
     80     {
     81         ASSERT(isRaw8Bit(source, length));
     82         for (int i = 0; i < length; ++i) {
     83             if (!URLCharacterTypes::isQueryChar(source[i]))
     84                 appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer);
     85             else
     86                 buffer->append(static_cast<char>(source[i]));
     87         }
     88     }
     89 
     90     static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer)
     91     {
     92         if (isAllASCII(spec, query)) {
     93             appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer);
     94             return;
     95         }
     96 
     97         RawURLBuffer<char, 1024> convertedQuery;
     98         convertCharset(spec, query, convertedQuery);
     99         appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer);
    100     }
    101 };
    102 
    103 }
    104 
    105 #endif
    106 
    107 
    108