/* * Copyright (C) 2007 Esmertec AG. * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef WBXML_PARSER_H #define WBXML_PARSER_H #include <setjmp.h> #include <stdint.h> #include "wbxml_const.h" #include "wbxml_stl.h" #include "wbxml_tabledef.h" struct Attribute { string name; string value; }; class WbxmlContentHandler { public: virtual ~WbxmlContentHandler() {} virtual void handlePublicId(uint32_t id) = 0; virtual void startElement(const char * name, const vector<Attribute> & attribs) = 0; virtual void endElement(const char * name) = 0; virtual void characters(const char * data, int len) = 0; virtual void opaque(const char * data, int len) = 0; }; class DefaultWbxmlContentHandler: public WbxmlContentHandler { public: DefaultWbxmlContentHandler() { mPublicId = -1; } void handlePublicId(uint32_t id) { mPublicId = id; } // @return public ID or -1 if no public ID seen int getPublicId(void) const { return mPublicId; } void startElement(const char * name, const vector<Attribute> & attribs) { } void endElement(const char * name) { } void characters(const char * data, int len) { } void opaque(const char * data, int len) { } private: int mPublicId; }; class WbxmlParser { public: WbxmlParser(uint32_t transportEncoding); ~WbxmlParser(); void setContentHandler(WbxmlContentHandler * handler); //void setTokenMappings(uint32_t publicId, TagTable tagTable, AttrTable attrTable); int parse(const char * data, uint32_t len, bool end); void reset(void); int getError(void) const { return mLastError; } private: enum ParserState { EXPECT_HEADER, EXPECT_STRING_TABLE, EXPECT_BODY_START, EXPECT_ELEMENT_START, EXPECT_ELEMENT_END, ELEMENT_END, EXPECT_CONTENT, EXPECT_BODY_END, }; enum ParserError { ERROR_NO_ERROR = 0, ERROR_INVALID_DATA = 1, ERROR_NEED_MORE_DATA, ERROR_UNSUPPORTED_PUBID, ERROR_UNSUPPORTED_CHARSET, ERROR_INVALID_STRING_TABLE, ERROR_INVALID_STRING_TABLE_REFERENCE, ERROR_INVALID_EXT_TOKEN, ERROR_INVALID_MBUINT, ERROR_INVALID_ENTITY, ERROR_UNRECOGNIZED_TAG, ERROR_UNRECOGNIZED_ATTR, ERROR_MISSING_ATTR, ERROR_MISSING_TOKEN_END, ERROR_NOT_SUPPORTED_YET = 999, }; int readByte(); int peekByte(); uint32_t readMbuint32(); void readString(string & str); const char * resolveStrTableRef(void); const char * lookupTagName(int tag) const; const char * lookupAttrName(int tag, const char **valuePrefix) const; void readAttribute(Attribute * attrib); jmp_buf mJmpbuf; string mLastChunk; const char * mExternalChunk; uint32_t mExternalChunkLen; uint32_t mDataOffset; bool mIsDataEnd; int getReadPos(void) const { return mDataOffset; } void setReadPos(int pos) { mDataOffset = pos; } void appendData(const char * data, uint32_t len, bool end); void saveRemainingData(); uint32_t availDataSize(void) const { return mLastChunk.size() + mExternalChunkLen - mDataOffset; } bool selectTokenMapping(int publicId); const TagCodePage * mTagPages; uint32_t mNumTagPages; const AttrCodePage * mAttrPages; uint32_t mNumAttrPages; uint32_t mTransportEncoding; WbxmlContentHandler * mContentHandler; vector<string> mStartElemStack; string mStringTable; uint32_t mCurrTagPage; uint32_t mCurrAttrPage; ParserState mState; ParserError mLastError; int mDocVersion; uint32_t mPublicId; uint32_t mCharset; }; #endif