IWAParser.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /*
00003  * This file is part of the libetonyek project.
00004  *
00005  * This Source Code Form is subject to the terms of the Mozilla Public
00006  * License, v. 2.0. If a copy of the MPL was not distributed with this
00007  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
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   // disable copying
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 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */