/******************************************************************************** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).** All rights reserved.** Contact: Nokia Corporation (qt-info@nokia.com)**** This file is part of the qt3to4 porting application of the Qt Toolkit.**** $QT_BEGIN_LICENSE:LGPL$** No Commercial Usage** This file contains pre-release code and may not be distributed.** You may use this file in accordance with the terms and conditions** contained in the Technology Preview License Agreement accompanying** this package.**** GNU Lesser General Public License Usage** Alternatively, this file may be used under the terms of the GNU Lesser** General Public License version 2.1 as published by the Free Software** Foundation and appearing in the file LICENSE.LGPL included in the** packaging of this file. Please review the following information to** ensure the GNU Lesser General Public License version 2.1 requirements** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.**** In addition, as a special exception, Nokia gives you certain additional** rights. These rights are described in the Nokia Qt LGPL Exception** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.**** If you have questions regarding the use of this file, please contact** Nokia at qt-info@nokia.com.****************** $QT_END_LICENSE$******************************************************************************/#ifndef TOKENENGINE_H#define TOKENENGINE_H#include <QByteArray>#include <QVector>#include <QString>#include <QSharedData>#include <QSharedDataPointer>#include <QMap>QT_BEGIN_NAMESPACEnamespace TokenEngine {class TokenContainer;/* A token is defined as a start-postion and a lenght. Since the actual text storage is not reffered to here, Token needs to be used together with a TokenContainer in order to be useful.*/class Token{public: Token() :start(0), length(0) {} Token(int p_start, int p_lenght) :start(p_start), length(p_lenght) {} int start; int length;};/* Each TokenContainer has a TypeInfo object with meta-information.*/class FileInfo;class GeneratedInfo;class TypeInfo{public: virtual ~TypeInfo() {}; virtual FileInfo *toFileInfo() const {return 0;} virtual GeneratedInfo *toGeneratedInfo() const {return 0;}};/* MetaInfo for containers that contains tokens from a file*/class FileInfo: public TypeInfo{public: FileInfo *toFileInfo() const {return const_cast<FileInfo *>(this);} QString filename;};/* MetaInfo for containers that contains generated tokens.*/class GeneratedInfo: public TypeInfo{public: GeneratedInfo *toGeneratedInfo() const {return const_cast<GeneratedInfo *>(this);} //preprocessor tree pointer?};class TokenAttributes{public: void addAttribute(const QByteArray &name, const QByteArray &value); QByteArray attribute(const QByteArray &name) const; void addAttribute(const int index, const QByteArray &name, const QByteArray &value); QByteArray attribute(const int index, const QByteArray &name) const;private: inline QByteArray makeKeyText(const int index, const QByteArray &name) const; QMap<QByteArray, QByteArray> attributes;};/* A TokenSequence that stores text and tokens referencing that text.*/class TokenContainerData : public QSharedData{public: TokenContainerData() : typeInfo(0) {tokenAttributes = new TokenAttributes();} ~TokenContainerData() {delete tokenAttributes; delete typeInfo; } QByteArray text; QVector<Token> tokens; TypeInfo *typeInfo; TokenAttributes *tokenAttributes;};class TokenTempRef;class TokenContainer{public: TokenContainer(); TokenContainer(QByteArray text, QVector<Token> tokens, TypeInfo *typeInfo = 0); int count() const; QByteArray text(const int index) const; QByteArray tempText(const int index) const; QByteArray fullText() const; TokenContainer tokenContainer(const int index) const; inline int containerIndex(const int index) const { return index; } Token token(const int index) const; TypeInfo *typeInfo(); TokenAttributes *tokenAttributes(); const TokenAttributes *tokenAttributes() const; int line(int index) const; int column(int index) const; TokenTempRef tokenTempRef(const int index) const;private: const QByteArray &textRef() { return d->text; } QExplicitlySharedDataPointer<TokenContainerData> d;};/* A reference to a single token in a container*/class TokenRef{public: TokenRef(): m_index(-1) {} TokenRef(TokenContainer tokenContainer, int containerIndex) : m_tokenContainer(tokenContainer), m_index(containerIndex) {} inline int count() const { return m_index == -1 ? 0 : 1; } inline QByteArray text(const int index = 0) const { Q_UNUSED(index); return m_tokenContainer.text(m_index); } inline QByteArray tempText(const int index) const { Q_UNUSED(index); return m_tokenContainer.tempText(m_index); } inline QByteArray fullText() const { return text(); } inline TokenContainer tokenContainer(const int index = 0) const { Q_UNUSED(index); return m_tokenContainer; } inline int containerIndex(const int index = 0) const { Q_UNUSED(index); return m_index; }private: TokenContainer m_tokenContainer; int m_index;};/* A temporary reference to a single token in a container. This reference does not increase the refcount on the TokenContainer.*/class TokenTempRef{public: TokenTempRef(const char *text, int length) : m_text(text), m_length(length) {} inline const char *constData() const { return m_text; } inline int length() const { return m_length; } char at(int index) const { Q_ASSERT(index < m_length); return m_text[index]; }private: const char *m_text; int m_length;};/* Contains a selected range from a TokenSequence.*/class TokenSection{public: TokenSection() : m_start(0), m_count(0) {} TokenSection(TokenContainer tokenContainer, const int start, const int count) :m_tokenContainer(tokenContainer), m_start(start), m_count(count) {} inline int count() const { return m_count; } inline QByteArray text(const int index) const { const int cIndex = containerIndex(index); Q_ASSERT(cIndex < m_tokenContainer.count()); return m_tokenContainer.text(cIndex); } inline QByteArray tempText(const int index) const { const int cIndex = containerIndex(index); Q_ASSERT(cIndex < m_tokenContainer.count()); return m_tokenContainer.tempText(cIndex); } QByteArray fullText() const; inline TokenContainer tokenContainer(const int index = 0) const { Q_UNUSED(index); return m_tokenContainer; } inline int containerIndex(const int index) const { return m_start + index; } TokenTempRef tokenTempRef(const int index) const { const int cIndex = containerIndex(index); Q_ASSERT(cIndex < m_tokenContainer.count()); return m_tokenContainer.tokenTempRef(cIndex); }private: TokenContainer m_tokenContainer; int m_start; int m_count;};/* A list of tokens from a tokenContainer*/class TokenList{public: TokenList() {}; TokenList(TokenContainer tokenContainer, QVector<int> tokenList) :m_tokenContainer(tokenContainer), m_tokenList(tokenList) {} inline int count() const { return m_tokenList.count(); } inline QByteArray text(const int index) const { const int cIndex = containerIndex(index); Q_ASSERT(cIndex < m_tokenContainer.count()); return m_tokenContainer.text(cIndex); } inline QByteArray tempText(const int index) const { const int cIndex = containerIndex(index); Q_ASSERT(cIndex < m_tokenContainer.count()); return m_tokenContainer.tempText(cIndex); } QByteArray fullText() const; inline TokenContainer tokenContainer(const int index) const { Q_UNUSED(index); return m_tokenContainer; } inline int containerIndex(const int index) const { return m_tokenList.at(index); } Token token(const int index) const { const int cIndex = containerIndex(index); Q_ASSERT(cIndex < m_tokenContainer.count()); return m_tokenContainer.token(cIndex); }private: TokenContainer m_tokenContainer; QVector<int> m_tokenList;};/* Combines a list of TokenSequences into one TokenSectionSequence*/class TokenSectionSequenceIterator;class TokenSectionSequence{public: TokenSectionSequence() :m_count(0) {}; TokenSectionSequence(QVector<TokenSection> tokenSections); QByteArray fullText() const; int count() const; QVector<TokenSection> tokenSections() const; //random access interface, access time is linear on the number of sections QByteArray text(const int index) const; QByteArray tempText(const int index) const; TokenContainer tokenContainer(const int index) const; int containerIndex(const int index) const;protected: int findSection(const int index) const; int calculateInternalIndex(const int index, const int sectionIndex) const;private: QVector<TokenSection> m_tokenSections; QVector<int> m_startIndexes; int m_count; friend class TokenSectionSequenceIterator;};//sequental access interface, constant access time.class TokenSectionSequenceIterator{public: TokenSectionSequenceIterator(const TokenSectionSequence &tokenSectionSequence); void reset(); bool nextToken(); QByteArray text() const; QByteArray tempText() const; TokenContainer tokenContainer() const; int containerIndex() const; TokenTempRef tokenTempRef() const;private: int m_currentSection; int m_currentToken; // token index in currentTokenSequence; const int m_numSections; const TokenSectionSequence &m_tokenSectionSequence;};template <typename TokenSequence>QByteArray getText(TokenSequence tokenSequence){ QByteArray text; for (int t = 0; t<tokenSequence.count(); ++t) { text += tokenSequence.text(t); } return text;}/* Append the text and the tokens from the range [startToken, startToken + numTokens> to text and tokenList.*/template <typename TokenSequenceType>void copy(QByteArray &text, QVector<TokenEngine::Token> &tokenList, const TokenSequenceType &tokenSequence, int startToken, int numTokens){ const int endToken = startToken + numTokens; int textIndex = text.count(); for(int t = startToken; t < endToken; ++t) { const QByteArray tokenText = tokenSequence.text(t); const int tokenLength = tokenText.count(); TokenEngine::Token token(textIndex, tokenLength); tokenList.append(token); text += tokenSequence.text(t); textIndex += tokenText.count(); }}/* Copy a the range [startToken, startToken + numTokens> from a tokenSequence to a new TokenConrtainer.*/template <typename TokenSequenceType>TokenContainer copy(const TokenSequenceType &tokenSequence, int startToken, int numTokens){ QByteArray containerText; QVector<Token> tokens; tokens.reserve(numTokens); TokenEngine::copy(containerText, tokens, tokenSequence, startToken, numTokens); return TokenContainer(containerText, tokens);}} //namespace TokenEngineQT_END_NAMESPACE#endif