15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/indexeddb/IDBKeyPath.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/ASCIICType.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/dtoa.h"
311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "wtf/unicode/CharacterNames.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "wtf/unicode/Unicode.h"
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)using namespace WTF::Unicode;
351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IDBKeyPathLexer {
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum TokenType {
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TokenIdentifier,
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TokenDot,
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TokenEnd,
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TokenError
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    explicit IDBKeyPathLexer(const String& s)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_string(s)
49591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        , m_length(s.length())
50f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        , m_index(0)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_currentTokenType(TokenError)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TokenType currentTokenType() const { return m_currentTokenType; }
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TokenType nextTokenType()
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_currentTokenType = lex(m_currentElement);
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_currentTokenType;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const String& currentElement() { return m_currentElement; }
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TokenType lex(String&);
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TokenType lexIdentifier(String&);
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_currentElement;
69591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const String m_string;
70591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    const unsigned m_length;
71591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    unsigned m_index;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TokenType m_currentTokenType;
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IDBKeyPathLexer::TokenType IDBKeyPathLexer::lex(String& element)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
77591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (m_index >= m_length)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return TokenEnd;
79591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    ASSERT(m_index < m_length);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
81591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (m_string[m_index] == '.') {
82591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ++m_index;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return TokenDot;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return lexIdentifier(element);
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WTF::Unicode;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// The following correspond to grammar in ECMA-262.
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t unicodeLetter = Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other | Number_Letter;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t unicodeCombiningMark = Mark_NonSpacing | Mark_SpacingCombining;
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t unicodeDigit = Number_DecimalDigit;
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t unicodeConnectorPunctuation = Punctuation_Connector;
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isIdentifierStartCharacter(UChar c)
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (category(c) & unicodeLetter) || (c == '$') || (c == '_');
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isIdentifierCharacter(UChar c)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return (category(c) & (unicodeLetter | unicodeCombiningMark | unicodeDigit | unicodeConnectorPunctuation)) || (c == '$') || (c == '_') || (c == zeroWidthNonJoiner) || (c == zeroWidthJoiner);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IDBKeyPathLexer::TokenType IDBKeyPathLexer::lexIdentifier(String& element)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
112591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    unsigned start = m_index;
113591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    if (m_index < m_length && isIdentifierStartCharacter(m_string[m_index]))
114591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ++m_index;
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return TokenError;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
118591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    while (m_index < m_length && isIdentifierCharacter(m_string[m_index]))
119591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ++m_index;
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
121591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    element = m_string.substring(start, m_index - start);
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return TokenIdentifier;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool IDBIsValidKeyPath(const String& keyPath)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBKeyPathParseError error;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<String> keyPathElements;
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBParseKeyPath(keyPath, keyPathElements, error);
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return error == IDBKeyPathParseErrorNone;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void IDBParseKeyPath(const String& keyPath, Vector<String>& elements, IDBKeyPathParseError& error)
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // IDBKeyPath ::= EMPTY_STRING | identifier ('.' identifier)*
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The basic state machine is:
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //   Start => {Identifier, End}
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //   Identifier => {Dot, End}
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //   Dot => {Identifier}
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // It bails out as soon as it finds an error, but doesn't discard the bits it managed to parse.
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum ParserState { Identifier, Dot, End };
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBKeyPathLexer lexer(keyPath);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IDBKeyPathLexer::TokenType tokenType = lexer.nextTokenType();
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ParserState state;
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (tokenType == IDBKeyPathLexer::TokenIdentifier)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        state = Identifier;
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else if (tokenType == IDBKeyPathLexer::TokenEnd)
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        state = End;
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else {
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        error = IDBKeyPathParseErrorStart;
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (1) {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (state) {
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case Identifier : {
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            IDBKeyPathLexer::TokenType tokenType = lexer.currentTokenType();
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(tokenType == IDBKeyPathLexer::TokenIdentifier);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String element = lexer.currentElement();
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            elements.append(element);
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            tokenType = lexer.nextTokenType();
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (tokenType == IDBKeyPathLexer::TokenDot)
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                state = Dot;
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else if (tokenType == IDBKeyPathLexer::TokenEnd)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                state = End;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else {
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                error = IDBKeyPathParseErrorIdentifier;
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case Dot: {
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            IDBKeyPathLexer::TokenType tokenType = lexer.currentTokenType();
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(tokenType == IDBKeyPathLexer::TokenDot);
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            tokenType = lexer.nextTokenType();
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (tokenType == IDBKeyPathLexer::TokenIdentifier)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                state = Identifier;
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else {
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                error = IDBKeyPathParseErrorDot;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case End: {
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            error = IDBKeyPathParseErrorNone;
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IDBKeyPath::IDBKeyPath(const String& string)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_type(StringType)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_string(string)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_string.isNull());
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)IDBKeyPath::IDBKeyPath(const Vector<String>& array)
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_type(ArrayType)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_array(array)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
207197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = 0; i < m_array.size(); ++i)
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!m_array[i].isNull());
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool IDBKeyPath::isValid() const
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_type) {
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NullType:
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case StringType:
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return IDBIsValidKeyPath(m_string);
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ArrayType:
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_array.isEmpty())
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (size_t i = 0; i < m_array.size(); ++i) {
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!IDBIsValidKeyPath(m_array[i]))
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return false;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool IDBKeyPath::operator==(const IDBKeyPath& other) const
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_type != other.m_type)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (m_type) {
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case NullType:
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case StringType:
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_string == other.m_string;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case ArrayType:
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_array == other.m_array;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
252c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
253