00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef IWAPARSER_H_INCLUDED
00011 #define IWAPARSER_H_INCLUDED
00012
00013 #include <deque>
00014 #include <map>
00015 #include <string>
00016
00017 #include <boost/function.hpp>
00018 #include <boost/optional.hpp>
00019 #include <boost/shared_ptr.hpp>
00020 #include <boost/unordered_map.hpp>
00021 #include <boost/variant.hpp>
00022
00023 #include <mdds/flat_segment_tree.hpp>
00024
00025 #include "libetonyek_utils.h"
00026 #include "IWAMessage.h"
00027 #include "IWORKLanguageManager.h"
00028 #include "IWORKStyle_fwd.h"
00029 #include "IWORKTypes.h"
00030
00031 namespace libetonyek
00032 {
00033
00034 class IWORKCollector;
00035 class IWORKPropertyMap;
00036 class IWORKTable;
00037 class IWORKText;
00038
00039 class IWAParser
00040 {
00041
00042 IWAParser(const IWAParser &);
00043 IWAParser &operator=(const IWAParser &);
00044
00045 public:
00046 struct ObjectRecord
00047 {
00048 ObjectRecord();
00049 ObjectRecord(const RVNGInputStreamPtr_t &stream, unsigned type, long pos, unsigned long headerLen, unsigned long dataLen);
00050
00051 RVNGInputStreamPtr_t m_stream;
00052 unsigned m_type;
00053 std::pair<long, long> m_headerRange;
00054 std::pair<long, long> m_dataRange;
00055 };
00056
00057 typedef std::map<unsigned, std::pair<std::string, RVNGInputStreamPtr_t> > FileMap_t;
00058 typedef std::map<unsigned, std::pair<unsigned, ObjectRecord> > RecordMap_t;
00059
00060 public:
00061 IWAParser(const RVNGInputStreamPtr_t &fragments, const RVNGInputStreamPtr_t &package, IWORKCollector &collector);
00062
00063 bool parse();
00064
00065 protected:
00066 class ObjectMessage
00067 {
00068 public:
00069 ObjectMessage(IWAParser &parser, unsigned id, unsigned type = 0);
00070 ~ObjectMessage();
00071
00072 operator bool() const;
00073 const IWAMessage &get() const;
00074
00075 unsigned getType() const;
00076
00077 friend const IWAMessage &get(const ObjectMessage &msg)
00078 {
00079 return msg.get();
00080 }
00081
00082 private:
00083 IWAParser &m_parser;
00084 boost::optional<IWAMessage> m_message;
00085 const unsigned m_id;
00086 unsigned m_type;
00087 };
00088 friend class ObjectMessage;
00089
00090 typedef std::map<unsigned, IWORKStylePtr_t> StyleMap_t;
00091 typedef boost::function<void(unsigned, IWORKStylePtr_t &)> StyleParseFun_t;
00092
00093 protected:
00094 static boost::optional<unsigned> readRef(const IWAMessage &msg, unsigned field);
00095 static std::deque<unsigned> readRefs(const IWAMessage &msg, unsigned field);
00096 static boost::optional<IWORKPosition> readPosition(const IWAMessage &msg, unsigned field);
00097 static boost::optional<IWORKSize> readSize(const IWAMessage &msg, unsigned field);
00098 static boost::optional<IWORKColor> readColor(const IWAMessage &msg, unsigned field);
00099 static void readStroke(const IWAMessage &msg, IWORKStroke &stroke);
00100 bool readFill(const IWAMessage &msg, IWORKFill &fill);
00101 static void readGradient(const IWAMessage &msg, IWORKGradient &gradient);
00102 static void readShadow(const IWAMessage &msg, IWORKShadow &shadow);
00103 static void readPadding(const IWAMessage &msg, IWORKPadding &padding);
00104
00105 bool dispatchShape(unsigned id);
00106 bool parseText(unsigned id);
00107 void parseComment(unsigned id);
00108
00109 bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry);
00110
00111 const IWORKStylePtr_t queryCharacterStyle(unsigned id) const;
00112 const IWORKStylePtr_t queryParagraphStyle(unsigned id) const;
00113 const IWORKStylePtr_t queryGraphicStyle(unsigned id) const;
00114 const IWORKStylePtr_t queryCellStyle(unsigned id) const;
00115 const IWORKStylePtr_t queryTableStyle(unsigned id) const;
00116 const IWORKStylePtr_t queryListStyle(unsigned id) const;
00117
00118 const IWORKStylePtr_t queryStyle(unsigned id, StyleMap_t &styleMap, StyleParseFun_t parse) const;
00119
00120 protected:
00121 IWORKLanguageManager m_langManager;
00122 boost::shared_ptr<IWORKText> m_currentText;
00123
00124 private:
00125 typedef std::map<unsigned, boost::variant<std::string, unsigned> > DataList_t;
00126
00127 struct TableHeader
00128 {
00129 TableHeader(unsigned count);
00130
00131 mdds::flat_segment_tree<unsigned, float> m_sizes;
00132 mdds::flat_segment_tree<unsigned, bool> m_hidden;
00133 };
00134
00135 struct TableInfo
00136 {
00137 TableInfo(const boost::shared_ptr<IWORKTable> &table, unsigned columns, unsigned rows);
00138
00139 boost::shared_ptr<IWORKTable> m_table;
00140
00141 const unsigned m_columns;
00142 const unsigned m_rows;
00143
00144 IWORKStylePtr_t m_style;
00145
00146 TableHeader m_columnHeader;
00147 TableHeader m_rowHeader;
00148
00149 DataList_t m_simpleTextList;
00150 DataList_t m_cellStyleList;
00151 DataList_t m_formattedTextList;
00152 DataList_t m_commentList;
00153 };
00154
00155 private:
00156 virtual bool parseDocument() = 0;
00157
00158 private:
00159 void queryObject(unsigned id, unsigned &type, boost::optional<IWAMessage> &msg) const;
00160 const RVNGInputStreamPtr_t queryFile(unsigned id) const;
00161
00162 void parseObjectIndex();
00163
00164 void scanFragment(unsigned id);
00165 void scanFragment(unsigned id, const RVNGInputStreamPtr_t &stream);
00166
00167 void parseCharacterStyle(unsigned id, IWORKStylePtr_t &style);
00168 void parseParagraphStyle(unsigned id, IWORKStylePtr_t &style);
00169 void parseGraphicStyle(unsigned id, IWORKStylePtr_t &style);
00170 void parseCellStyle(unsigned id, IWORKStylePtr_t &style);
00171 void parseTableStyle(unsigned id, IWORKStylePtr_t &style);
00172 void parseListStyle(unsigned id, IWORKStylePtr_t &style);
00173
00174 void parseTabularModel(unsigned id);
00175 void parseDataList(unsigned id, DataList_t &dataList);
00176 void parseTile(unsigned id);
00177 void parseHeaders(unsigned id, TableHeader &header);
00178
00179 void parseLink(unsigned id, std::string &url);
00180
00181 bool parseDrawableShape(const IWAMessage &msg);
00182 bool parseGroup(const IWAMessage &msg);
00183 bool parseShapePlacement(const IWAMessage &msg);
00184 void parseCharacterProperties(const IWAMessage &msg, IWORKPropertyMap &props);
00185 bool parseImage(const IWAMessage &msg);
00186 bool parseTabularInfo(const IWAMessage &msg);
00187
00188 private:
00189 const RVNGInputStreamPtr_t m_fragments;
00190 const RVNGInputStreamPtr_t m_package;
00191 IWORKCollector &m_collector;
00192
00193 FileMap_t m_fragmentMap;
00194 mutable RecordMap_t m_fragmentObjectMap;
00195 mutable FileMap_t m_fileMap;
00196
00197 std::deque<unsigned> m_visited;
00198
00199 mutable StyleMap_t m_charStyles;
00200 mutable StyleMap_t m_paraStyles;
00201 mutable StyleMap_t m_graphicStyles;
00202 mutable StyleMap_t m_cellStyles;
00203 mutable StyleMap_t m_tableStyles;
00204 mutable StyleMap_t m_listStyles;
00205
00206 IWORKTableNameMapPtr_t m_tableNameMap;
00207 boost::shared_ptr<TableInfo> m_currentTable;
00208 };
00209
00210 }
00211
00212 #endif
00213
00214