00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef RAG_TIME_5_ZONE_MANAGER
00035 # define RAG_TIME_5_ZONE_MANAGER
00036
00037 #include <map>
00038 #include <ostream>
00039 #include <sstream>
00040 #include <string>
00041 #include <vector>
00042
00043 #include "libmwaw_internal.hxx"
00044 #include "MWAWDebug.hxx"
00045 #include "MWAWEntry.hxx"
00046
00047 #include "RagTime5StructManager.hxx"
00048
00049 class RagTime5Parser;
00050 class RagTime5StructManager;
00051
00052 namespace RagTime5ClusterManagerInternal
00053 {
00054 struct State;
00055 }
00056
00058 class RagTime5ClusterManager
00059 {
00060 public:
00061 struct Link;
00062
00063 struct Cluster;
00064 struct ClusterRoot;
00065 struct ClusterParser;
00066
00067 friend struct ClusterParser;
00068
00070 RagTime5ClusterManager(RagTime5Parser &parser);
00072 ~RagTime5ClusterManager();
00073
00075 bool readCluster(RagTime5Zone &zone, ClusterParser &parser, bool warnForUnparsed=true);
00077 bool readCluster(RagTime5Zone &zone, shared_ptr<Cluster> &cluster, int type=-1);
00079 bool readClusterMainList(ClusterRoot &root, std::vector<int> &list, std::vector<int> const &clusterIdList);
00080
00082 bool readFieldClusters(Link const &link);
00084 bool readUnknownClusterC(Link const &link);
00086 int getClusterFileType(RagTime5Zone &zone);
00088 int getClusterType(RagTime5Zone &zone, int fileType);
00090 bool getClusterBasicHeaderInfo(RagTime5Zone &zone, long &N, long &fSz, long &debHeaderPos);
00091
00092
00093
00095 bool readFieldHeader(RagTime5Zone &zone, long endPos, std::string const &headerName, long &endDataPos, long expectedLVal=-99999);
00097 std::string getClusterName(int id);
00098
00100 struct Link {
00102 enum Type { L_ClusterLink,
00103 L_LinkDef,
00104 L_LongList, L_UnicodeList,
00105 L_FieldsList, L_List,
00106 L_UnknownClusterC,
00107 L_Unknown
00108 };
00110 Link(Type type=L_Unknown) : m_type(type), m_name(""), m_ids(), m_N(0), m_fieldSize(0), m_longList()
00111 {
00112 for (int i=0; i<2; ++i)
00113 m_fileType[i]=0;
00114 }
00116 bool empty() const
00117 {
00118 if (m_type==L_LongList && !m_longList.empty())
00119 return false;
00120 for (size_t i=0; i<m_ids.size(); ++i)
00121 if (m_ids[i]>0) return false;
00122 return true;
00123 }
00125 std::string getZoneName() const
00126 {
00127 switch (m_type) {
00128 case L_ClusterLink:
00129 return "clustLink";
00130 case L_LinkDef:
00131 return "linkDef";
00132 case L_LongList:
00133 if (!m_name.empty())
00134 return m_name;
00135 else {
00136 std::stringstream s;
00137 s << "longList" << m_fieldSize;
00138 return s.str();
00139 }
00140 case L_UnicodeList:
00141 return "unicodeListLink";
00142 case L_UnknownClusterC:
00143 return "unknownClusterC";
00144 case L_FieldsList:
00145 if (!m_name.empty())
00146 return m_name;
00147 return "fieldsList[unkn]";
00148 case L_List:
00149 if (!m_name.empty())
00150 return m_name;
00151 break;
00152 case L_Unknown:
00153 default:
00154 break;
00155 }
00156 std::stringstream s;
00157 if (m_type==L_List)
00158 s << "ListZone";
00159 else
00160 s << "FixZone";
00161 s << std::hex << m_fileType[0] << "_" << m_fileType[1] << std::dec;
00162 if (m_fieldSize)
00163 s << "_" << m_fieldSize;
00164 s << "A";
00165 return s.str();
00166 }
00168 friend std::ostream &operator<<(std::ostream &o, Link const &z)
00169 {
00170 if (z.empty()) return o;
00171 o << z.getZoneName() << ":";
00172 size_t numLinks=z.m_ids.size();
00173 if (numLinks>1) o << "[";
00174 for (size_t i=0; i<numLinks; ++i) {
00175 if (z.m_ids[i]<=0)
00176 o << "_";
00177 else
00178 o << "data" << z.m_ids[i] << "A";
00179 if (i+1!=numLinks) o << ",";
00180 }
00181 if (numLinks>1) o << "]";
00182 if (z.m_fieldSize&0x8000)
00183 o << "[" << std::hex << z.m_fieldSize << std::dec << ":" << z.m_N << "]";
00184 else
00185 o << "[" << z.m_fieldSize << ":" << z.m_N << "]";
00186 return o;
00187 }
00189 Type m_type;
00191 std::string m_name;
00193 std::vector<int> m_ids;
00195 int m_N;
00197 int m_fieldSize;
00199 long m_fileType[2];
00201 std::vector<long> m_longList;
00202 };
00203
00205
00207
00209 struct Cluster {
00211 Cluster() : m_type(C_Unknown), m_zoneId(0), m_hiLoEndian(true), m_dataLink(), m_nameLink(), m_fieldClusterLink(),
00212 m_conditionFormulaLinks(), m_settingLinks(), m_linksList(), m_clusterIdsList()
00213 {
00214 }
00216 virtual ~Cluster() {}
00218 enum Type {
00219 C_ColorPattern, C_Fields, C_Layout, C_Pipeline,
00220 C_Root, C_Script,
00221
00222
00223 C_ColorStyles, C_FormatStyles, C_GraphicStyles, C_TextStyles, C_UnitStyles,
00224
00225 C_ClusterB, C_ClusterC,
00226
00227 C_Unknown
00228 };
00230 Type m_type;
00232 int m_zoneId;
00234 bool m_hiLoEndian;
00236 Link m_dataLink;
00238 Link m_nameLink;
00240 Link m_fieldClusterLink;
00242 std::vector<Link> m_conditionFormulaLinks;
00244 std::vector<Link> m_settingLinks;
00246 std::vector<Link> m_linksList;
00248 std::vector<int> m_clusterIdsList;
00249 };
00250
00252 struct ClusterLayout : public Cluster {
00254 ClusterLayout() : Cluster(), m_zoneDimensions(), m_pipelineLink(), m_listItemLink()
00255 {
00256 }
00258 virtual ~ClusterLayout() {}
00260 std::vector<MWAWVec2f> m_zoneDimensions;
00262 Link m_pipelineLink;
00264 Link m_listItemLink;
00265 };
00266
00268 struct ClusterRoot : public Cluster {
00270 ClusterRoot() : Cluster(), m_graphicTypeLink(), m_docInfoLink(),
00271 m_listClusterId(0), m_listClusterName(), m_linkUnknown(), m_fileName("")
00272 {
00273 for (int i=0; i<8; ++i) m_styleClusterIds[i]=0;
00274 for (int i=0; i<1; ++i) m_clusterIds[i]=0;
00275 }
00277 virtual ~ClusterRoot() {}
00279 int m_styleClusterIds[8];
00280
00282 int m_clusterIds[1];
00283
00285 Link m_graphicTypeLink;
00286
00288 Link m_docInfoLink;
00289
00291 int m_listClusterId;
00293 Link m_listClusterName;
00295 Link m_listClusterLink[2];
00296
00298 Link m_linkUnknown;
00299
00301 librevenge::RVNGString m_fileName;
00302 };
00303
00305 struct ClusterScript : public Cluster {
00307 ClusterScript() : Cluster(), m_scriptComment(), m_scriptName("")
00308 {
00309 }
00311 virtual ~ClusterScript() {}
00313 Link m_scriptComment;
00315 librevenge::RVNGString m_scriptName;
00316 };
00317
00319
00321
00323 struct ClusterParser {
00325 ClusterParser(RagTime5ClusterManager &parser, int type, std::string const &zoneName) :
00326 m_parser(parser), m_type(type), m_hiLoEndian(true), m_name(zoneName), m_dataId(0), m_link()
00327 {
00328 }
00330 virtual ~ClusterParser() {}
00332 virtual shared_ptr<Cluster> getCluster()=0;
00334 virtual std::string getZoneName() const
00335 {
00336 return m_name;
00337 }
00339 virtual std::string getZoneName(int n, int m=-1) const
00340 {
00341 std::stringstream s;
00342 s << m_name << "-" << n;
00343 if (m>=0)
00344 s << "-B" << m;
00345 return s.str();
00346 }
00348 virtual void startZone()
00349 {
00350 }
00352 virtual bool parseZone(MWAWInputStreamPtr &, long , int , int , libmwaw::DebugStream &)
00353 {
00354 return false;
00355 }
00357 virtual void endZone()
00358 {
00359 }
00361 virtual bool parseField(RagTime5StructManager::Field const &, int , libmwaw::DebugStream &)
00362 {
00363 return false;
00364 }
00365
00366
00367
00368
00369
00371 bool isANameHeader(long N) const
00372 {
00373 return (m_hiLoEndian && N==int(0x80000000)) || (!m_hiLoEndian && N==0x8000);
00374 }
00375
00377 bool readLinkHeader(MWAWInputStreamPtr &input, long fSz, Link &link, long(&values)[4], std::string &message);
00379 std::string getClusterName(int id);
00381 RagTime5ClusterManager &m_parser;
00383 int m_type;
00385 bool m_hiLoEndian;
00387 std::string m_name;
00389 int m_dataId;
00391 Link m_link;
00392 private:
00393 ClusterParser(ClusterParser const &orig);
00394 ClusterParser &operator=(ClusterParser const &orig);
00395 };
00396 protected:
00398 shared_ptr<RagTime5ClusterManagerInternal::State> m_state;
00400 RagTime5Parser &m_mainParser;
00402 shared_ptr<RagTime5StructManager> m_structManager;
00403 private:
00404 RagTime5ClusterManager(RagTime5ClusterManager const &orig);
00405 RagTime5ClusterManager operator=(RagTime5ClusterManager const &orig);
00406 };
00407
00408 #endif
00409