1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2 
3 /* libstaroffice
4 * Version: MPL 2.0 / LGPLv2+
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 2.0 (the "License"); you may not use this file except in compliance with
8 * the License or as specified alternatively below. You may obtain a copy of
9 * the License at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * Major Contributor(s):
17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20 * Copyright (C) 2006, 2007 Andrew Ziem
21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22 *
23 *
24 * All Rights Reserved.
25 *
26 * For minor contributions see the git repository.
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30 * in which case the provisions of the LGPLv2+ are applicable
31 * instead of those above.
32 */
33 
34 #include <algorithm>
35 #include <cstring>
36 #include <iomanip>
37 #include <iostream>
38 #include <limits>
39 #include <set>
40 #include <sstream>
41 
42 #include <librevenge/librevenge.h>
43 
44 #include "StarAttribute.hxx"
45 #include "StarFileManager.hxx"
46 #include "StarObject.hxx"
47 #include "StarState.hxx"
48 #include "StarZone.hxx"
49 #include "STOFFGraphicStyle.hxx"
50 #include "STOFFListener.hxx"
51 #include "STOFFParagraph.hxx"
52 
53 #include "StarItemPool.hxx"
54 
55 /** Internal: the structures of a StarItemPool */
56 namespace StarItemPoolInternal
57 {
58 ////////////////////////////////////////
59 //! Internal: a structure use to read SfxMultiRecord zone of a StarItemPool
60 struct SfxMultiRecord {
61   //! constructor
SfxMultiRecordStarItemPoolInternal::SfxMultiRecord62   SfxMultiRecord()
63     : m_zone(nullptr)
64     , m_zoneType(0)
65     , m_zoneOpened(false)
66     , m_headerType(0)
67     , m_headerVersion(0)
68     , m_headerTag(0)
69     , m_actualRecord(0)
70     , m_numRecord(0)
71     , m_contentSize(0)
72     , m_startPos(0)
73     , m_endPos(0)
74     , m_offsetList()
75     , m_extra("")
76   {
77   }
78   //! returns true if the record is opened
isOpenedStarItemPoolInternal::SfxMultiRecord79   bool isOpened() const
80   {
81     return m_zoneOpened;
82   }
83   //! returns the number of record
getNumRecordsStarItemPoolInternal::SfxMultiRecord84   uint16_t getNumRecords() const
85   {
86     return m_zoneOpened ? m_numRecord : 0;
87   }
88   //! returns the header tag or -1
getHeaderTagStarItemPoolInternal::SfxMultiRecord89   int getHeaderTag() const
90   {
91     return !m_zoneOpened ? -1 : int(m_headerTag);
92   }
93   //! try to open a zone
openStarItemPoolInternal::SfxMultiRecord94   bool open(StarZone &zone)
95   {
96     if (m_zoneOpened) {
97       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord: oops a record has been opened\n"));
98       return false;
99     }
100     m_actualRecord=m_numRecord=0;
101     m_headerType=m_headerVersion=0;
102     m_headerTag=0;
103     m_contentSize=0;
104     m_offsetList.clear();
105     m_zone=&zone;
106     STOFFInputStreamPtr input=m_zone->input();
107     long pos=input->tell();
108     if (!m_zone->openSfxRecord(m_zoneType)) {
109       input->seek(pos, librevenge::RVNG_SEEK_SET);
110       return false;
111     }
112     if (m_zoneType==static_cast<unsigned char>(0xff)) {
113       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord: oops end header\n"));
114       m_extra="###emptyZone,";
115       return true; /* empty zone*/
116     }
117     if (m_zoneType!=0) {
118       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord: find unknown header\n"));
119       m_extra="###badZoneType,";
120       return true;
121     }
122 
123     m_zoneOpened=true;
124     m_endPos=m_zone->getRecordLastPosition();
125     // filerec.cxx: SfxSingleRecordReader::FindHeader_Impl
126     if (input->tell()+10>m_endPos) {
127       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord::open: oops the zone seems too short\n"));
128       m_extra="###zoneShort,";
129       return true;
130     }
131     *input >> m_headerType >> m_headerVersion >> m_headerTag;
132     // filerec.cxx: SfxMultiRecordReader::ReadHeader_Impl
133     *input >> m_numRecord >> m_contentSize;
134     m_startPos=input->tell();
135     std::stringstream s;
136     if (m_headerType==2) {
137       // fixed size
138       if (m_startPos+long(m_numRecord)*long(m_contentSize) > m_endPos) {
139         STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord::open: oops the number of record seems bad\n"));
140         s << "##numRecord=" << m_numRecord << ",";
141         if (m_contentSize && m_endPos>m_startPos)
142           m_numRecord=uint16_t((m_endPos-m_startPos)/long(m_contentSize));
143         else
144           m_numRecord=0;
145       }
146       m_extra=s.str();
147       return true;
148     }
149 
150     long debOffsetList=((m_headerType==3 || m_headerType==7) ? m_startPos : 0) + long(m_contentSize);
151     if (debOffsetList<m_startPos || debOffsetList+4*m_numRecord > m_endPos) {
152       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord::open: can not find the version map offset\n"));
153       s << "###contentCount";
154       m_numRecord=0;
155       m_extra=s.str();
156       return true;
157     }
158     m_endPos=debOffsetList;
159     input->seek(debOffsetList, librevenge::RVNG_SEEK_SET);
160     for (uint16_t i=0; i<m_numRecord; ++i) {
161       uint32_t offset;
162       *input >> offset;
163       m_offsetList.push_back(offset);
164     }
165     input->seek(m_startPos, librevenge::RVNG_SEEK_SET);
166     return true;
167   }
168   //! try to close a zone
closeStarItemPoolInternal::SfxMultiRecord169   void close(std::string const &wh)
170   {
171     if (!m_zone) return;
172     if (!m_zoneOpened) {
173       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord::close: can not find any opened zone\n"));
174       return;
175     }
176     m_zoneOpened=false;
177     STOFFInputStreamPtr input=m_zone->input();
178     if (input->tell()<m_endPos && input->tell()+4>=m_endPos) { // small diff is possible
179       m_zone->ascii().addDelimiter(input->tell(),'|');
180       input->seek(m_zone->getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
181     }
182     else if (input->tell()==m_endPos)
183       input->seek(m_zone->getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
184     m_zone->closeSfxRecord(m_zoneType, wh);
185     m_zone=nullptr;
186   }
187   //! try to go to the new content positon
getNewContentStarItemPoolInternal::SfxMultiRecord188   bool getNewContent(std::string const &wh, int &id)
189   {
190     if (!m_zone) return false;
191     // SfxMultiRecordReader::GetContent
192     long newPos=getLastContentPosition();
193     if (newPos>=m_endPos) return false;
194     STOFFInputStreamPtr input=m_zone->input();
195     id=m_actualRecord++;
196     if (input->tell()<newPos && input->tell()+4>=newPos) { // small diff is possible
197       m_zone->ascii().addDelimiter(input->tell(),'|');
198       input->seek(newPos, librevenge::RVNG_SEEK_SET);
199     }
200     else if (input->tell()!=newPos) {
201       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord::getNewContent: find extra data\n"));
202       m_zone->ascii().addPos(input->tell());
203       libstoff::DebugStream f;
204       f << wh << ":###extra";
205       m_zone->ascii().addNote(f.str().c_str());
206       input->seek(newPos, librevenge::RVNG_SEEK_SET);
207     }
208     if (m_headerType==7) // mixtags?
209       input->seek(2, librevenge::RVNG_SEEK_CUR);
210     else if (m_headerType==8) // relocate
211       id=int(input->readULong(2));
212     return true;
213   }
214   //! returns the last content position
getLastContentPositionStarItemPoolInternal::SfxMultiRecord215   long getLastContentPosition() const
216   {
217     if (m_actualRecord >= m_numRecord) return m_endPos;
218     if (m_headerType==2) return m_startPos+m_actualRecord*long(m_contentSize);
219     if (m_actualRecord >= uint16_t(m_offsetList.size())) {
220       STOFF_DEBUG_MSG(("StarItemPoolInternal::SfxMultiRecord::getLastContentPosition: argh, find unexpected index\n"));
221       return m_endPos;
222     }
223     const long pos = m_startPos+long(m_offsetList[size_t(m_actualRecord)]>>8)-14;
224     return m_zone->input()->checkPosition(pos) ? pos : m_endPos;
225   }
226 
227   //! basic operator<< ; print header data
operator <<(std::ostream & o,SfxMultiRecord const & r)228   friend std::ostream &operator<<(std::ostream &o, SfxMultiRecord const &r)
229   {
230     if (!r.m_zoneOpened) {
231       o << r.m_extra;
232       return o;
233     }
234     if (r.m_headerType) o << "type=" << int(r.m_headerType) << ",";
235     if (r.m_headerVersion) o << "version=" << int(r.m_headerVersion) << ",";
236     if (r.m_headerTag) o << "tag=" << r.m_headerTag << ",";
237     if (r.m_numRecord) o << "num[record]=" << r.m_numRecord << ",";
238     if (r.m_contentSize) o << "content[size/pos]=" << r.m_contentSize << ",";
239     if (!r.m_offsetList.empty()) {
240       o << "offset=[";
241       for (auto const &off : r.m_offsetList) {
242         if (off&0xff)
243           o << (off>>8) << ":" << (off&0xff) << ",";
244         else
245           o << (off>>8) << ",";
246       }
247       o << "],";
248     }
249     o << r.m_extra;
250     return o;
251   }
252 protected:
253   //! the main zone
254   StarZone *m_zone;
255   //! the zone type
256   unsigned char m_zoneType;
257   //! true if a SfxRecord has been opened
258   bool m_zoneOpened;
259   //! the record type
260   uint8_t m_headerType;
261   //! the header version
262   uint8_t m_headerVersion;
263   //! the header tag
264   uint16_t m_headerTag;
265   //! the actual record
266   uint16_t m_actualRecord;
267   //! the number of record
268   uint16_t m_numRecord;
269   //! the record/content/pos size
270   uint32_t m_contentSize;
271   //! the start of data position
272   long m_startPos;
273   //! the end of data position
274   long m_endPos;
275   //! the list of (offset + type)
276   std::vector<uint32_t> m_offsetList;
277   //! extra data
278   std::string m_extra;
279 private:
280   SfxMultiRecord(SfxMultiRecord const &orig) = delete;
281   SfxMultiRecord &operator=(SfxMultiRecord const &orig) = delete;
282 };
283 
284 //! small struct used to keep a list of version
285 struct Version {
286   //! constructor
VersionStarItemPoolInternal::Version287   Version(int vers, int start, std::vector<int> const &list)
288     : m_version(vers)
289     , m_start(start)
290     , m_list(list)
291     , m_invertListMap()
292   {
293     for (size_t i=0; i<m_list.size(); ++i)
294       m_invertListMap[list[i]]=int(i);
295   }
296   //! the version number
297   int m_version;
298   //! int the start value
299   int m_start;
300   //! the list of value
301   std::vector<int> m_list;
302   //! a map offset to which
303   std::map<int,int> m_invertListMap;
304 };
305 
306 //! internal: list of attribute corresponding to a slot id
307 struct Values {
308   //! constructor
ValuesStarItemPoolInternal::Values309   Values()
310     : m_default()
311     , m_idValueMap()
312   {
313   }
314   //! the default values
315   std::shared_ptr<StarAttribute> m_default;
316   //! the list of attribute
317   std::map<int,std::shared_ptr<StarAttribute> > m_idValueMap;
318 };
319 
320 ////////////////////////////////////////
321 //! Internal: a style of a StarItemPool
322 struct StyleId {
323   //! constructor
StyleIdStarItemPoolInternal::StyleId324   StyleId(librevenge::RVNGString const &name, int family)
325     : m_name(name)
326     , m_family(family)
327   {
328   }
329   //! operator==
operator ==StarItemPoolInternal::StyleId330   bool operator==(StyleId const &other) const
331   {
332     return m_family==other.m_family && m_name==other.m_name;
333   }
334   //! operator!=
operator !=StarItemPoolInternal::StyleId335   bool operator!=(StyleId const &other) const
336   {
337     return !operator==(other);
338   }
339   //! operator<
operator <StarItemPoolInternal::StyleId340   bool operator<(StyleId const &other) const
341   {
342     if (m_name<other.m_name) return true;
343     if (m_name>other.m_name) return false;
344     return m_family<other.m_family;
345   }
346   //! the name
347   librevenge::RVNGString m_name;
348   //! the family
349   int m_family;
350 };
351 
352 ////////////////////////////////////////
353 //! Internal: the state of a StarItemPool
354 struct State {
355   //! constructor
StateStarItemPoolInternal::State356   State(StarObject &document, StarItemPool::Type type)
357     : m_document(document)
358     , m_type(StarItemPool::T_Unknown)
359     , m_majorVersion(0)
360     , m_minorVersion(0)
361     , m_loadingVersion(-1)
362     , m_name("")
363     , m_relativeUnit(0)
364     , m_isSecondaryPool(false)
365     , m_secondaryPool()
366     , m_currentVersion(0)
367     , m_verStart(0)
368     , m_verEnd(0)
369     , m_versionList()
370     , m_idToAttributeList()
371     , m_slotIdToValuesMap()
372     , m_styleIdToStyleMap()
373     , m_simplifyNameToStyleNameMap()
374     , m_idToDefaultMap()
375     , m_delayedItemList()
376   {
377     init(type);
378   }
379   //! initialize a pool
380   void init(StarItemPool::Type type);
381   //! clean the state
cleanStarItemPoolInternal::State382   void clean()
383   {
384     if (m_secondaryPool) m_secondaryPool->clean();
385     m_versionList.clear();
386     m_idToAttributeList.clear();
387     m_slotIdToValuesMap.clear();
388     m_styleIdToStyleMap.clear();
389     m_simplifyNameToStyleNameMap.clear();
390     m_idToDefaultMap.clear();
391     m_delayedItemList.clear();
392   }
393   //! set the pool name
setPoolNameStarItemPoolInternal::State394   void setPoolName(librevenge::RVNGString const &name)
395   {
396     m_name=name;
397     auto type=StarItemPool::T_Unknown;
398     if (m_name=="EditEngineItemPool")
399       type=StarItemPool::T_EditEnginePool;
400     else if (m_name=="SchItemPool")
401       type=StarItemPool::T_ChartPool;
402     else if (m_name=="ScDocumentPool")
403       type=StarItemPool::T_SpreadsheetPool;
404     else if (m_name=="SWG")
405       type=StarItemPool::T_WriterPool;
406     else if (m_name=="XOutdevItemPool")
407       type=StarItemPool::T_XOutdevPool;
408     else if (m_name=="VCControls")
409       type=StarItemPool::T_VCControlPool;
410     else {
411       STOFF_DEBUG_MSG(("StarItemPoolInternal::State::setPoolName: find unknown pool type %s\n", name.cstr()));
412     }
413     init(type);
414   }
415   //! returns true if the value is in expected range
isInRangeStarItemPoolInternal::State416   int isInRange(int which) const
417   {
418     if (which>=m_verStart&&which<=m_verEnd) return true;
419     if (m_secondaryPool) return m_secondaryPool->m_state->isInRange(which);
420     return false;
421   }
422   //! add a new version map
addVersionMapStarItemPoolInternal::State423   void addVersionMap(uint16_t nVers, uint16_t nStart, std::vector<int> const &list)
424   {
425     // SfxItemPool::SetVersionMap
426     if (nVers<=m_currentVersion)
427       return;
428     m_versionList.push_back(Version(int(nVers), int(nStart), list));
429     m_currentVersion=nVers;
430     Version const &vers=m_versionList.back();
431     if (vers.m_invertListMap.empty()) return;
432     m_verStart=std::min(m_verStart,vers.m_invertListMap.begin()->first);
433     m_verEnd=std::max(m_verEnd,(--vers.m_invertListMap.end())->first);
434   }
435   //! try to return ???
getWhichStarItemPoolInternal::State436   int getWhich(int nFileWhich) const
437   {
438     // polio.cxx: SfxItemPool::GetNewWhich
439     if (nFileWhich<m_verStart||nFileWhich>m_verEnd) {
440       if (m_secondaryPool)
441         return m_secondaryPool->m_state->getWhich(nFileWhich);
442       STOFF_DEBUG_MSG(("StarItemPoolInternal::State::getWhich: can not find a conversion for which=%d\n", nFileWhich));
443       return 0;
444     }
445     if (m_loadingVersion>m_currentVersion) {
446       for (size_t i=m_versionList.size(); i>0;) {
447         Version const &vers=m_versionList[--i];
448         if (vers.m_version<=m_currentVersion)
449           break;
450         if (vers.m_invertListMap.find(nFileWhich)==vers.m_invertListMap.end())
451           return 0;
452         nFileWhich=vers.m_start+vers.m_invertListMap.find(nFileWhich)->second;
453       }
454     }
455     else if (m_loadingVersion<m_currentVersion) {
456       for (auto const &vers : m_versionList) {
457         if (vers.m_version<=m_loadingVersion)
458           continue;
459         if (nFileWhich<vers.m_start || nFileWhich>=vers.m_start+int(vers.m_list.size())) {
460           STOFF_DEBUG_MSG(("StarItemPoolInternal::State::getWhich: argh nFileWhich=%d is not in good range\n", nFileWhich));
461           break;
462         }
463         else
464           nFileWhich=vers.m_list[size_t(nFileWhich-vers.m_start)];
465       }
466     }
467     return nFileWhich;
468   }
469   //! returns the state corresponding to which
getPoolStateForStarItemPoolInternal::State470   State *getPoolStateFor(int which)
471   {
472     if (which>=m_verStart&&which<=m_verEnd) return this;
473     if (m_secondaryPool) return m_secondaryPool->m_state->getPoolStateFor(which);
474     return nullptr;
475   }
476   //! returns a pointer to the values data
getValuesStarItemPoolInternal::State477   Values *getValues(int id, bool create=false)
478   {
479     if (m_slotIdToValuesMap.find(id)!=m_slotIdToValuesMap.end())
480       return &m_slotIdToValuesMap.find(id)->second;
481     if (!create)
482       return nullptr;
483     m_slotIdToValuesMap[id]=Values();
484     return &m_slotIdToValuesMap.find(id)->second;
485   }
486   //! try to return a default attribute corresponding to which
getDefaultAttributeStarItemPoolInternal::State487   std::shared_ptr<StarAttribute> getDefaultAttribute(int which)
488   {
489     if (m_idToDefaultMap.find(which)!=m_idToDefaultMap.end() && m_idToDefaultMap.find(which)->second)
490       return m_idToDefaultMap.find(which)->second;
491     std::shared_ptr<StarAttribute> res;
492     auto *state=getPoolStateFor(which);
493     if (!state || which<state->m_verStart || which>=state->m_verStart+int(state->m_idToAttributeList.size()) ||
494         !state->m_document.getAttributeManager()) {
495       STOFF_DEBUG_MSG(("StarItemPoolInternal::State::getDefaultAttribute: find unknown attribute\n"));
496       res=StarAttributeManager::getDummyAttribute();
497     }
498     else
499       res=m_document.getAttributeManager()->getDefaultAttribute(state->m_idToAttributeList[size_t(which-state->m_verStart)]);
500     m_idToDefaultMap[which]=res;
501     return res;
502   }
503   //! the document
504   StarObject &m_document;
505   //! the document type
506   StarItemPool::Type m_type;
507   //! the majorVersion
508   int m_majorVersion;
509   //! the minorVersion
510   int m_minorVersion;
511   //! the loading version
512   int m_loadingVersion;
513   //! the name
514   librevenge::RVNGString m_name;
515   //! the relative unit
516   double m_relativeUnit;
517   //! a flag to know if a pool is a secondary pool
518   bool m_isSecondaryPool;
519   //! the secondary pool
520   std::shared_ptr<StarItemPool> m_secondaryPool;
521   //! the current version
522   int m_currentVersion;
523   //! the minimum version
524   int m_verStart;
525   //! the maximum version
526   int m_verEnd;
527   //! the list of version
528   std::vector<Version> m_versionList;
529   //! list whichId to attribute list
530   std::vector<int> m_idToAttributeList;
531   //! a map slot to the attribute list
532   std::map<int, Values> m_slotIdToValuesMap;
533   //! the set of style
534   std::map<StyleId,StarItemStyle> m_styleIdToStyleMap;
535   //! map simplify style name to style name
536   std::map<librevenge::RVNGString, librevenge::RVNGString> m_simplifyNameToStyleNameMap;
537   //! map of created default attribute
538   std::map<int,std::shared_ptr<StarAttribute> > m_idToDefaultMap;
539   //! list of item which need to be read
540   std::vector<std::shared_ptr<StarItem> > m_delayedItemList;
541 private:
542   State(State const &orig) = delete;
543   State operator=(State const &orig) = delete;
544 };
545 
init(StarItemPool::Type type)546 void State::init(StarItemPool::Type type)
547 {
548   if (type==m_type) return;
549   if (m_type!=StarItemPool::T_Unknown) {
550     STOFF_DEBUG_MSG(("StarItemPoolInternal::State::init: arghhhh, change pool type\n"));
551   }
552   m_type=type;
553   // reset internal data
554   m_verStart=m_verEnd=m_currentVersion=0;
555   m_versionList.clear();
556   m_idToAttributeList.clear();
557 
558   // to do VCControls
559   switch (type) {
560   case StarItemPool::T_ChartPool: {
561     // sch_itempool.cxx SchItemPool::SchItemPool
562     m_verStart=1; // SCHATTR_START
563     m_verEnd=100; // SCHATTR_NONPERSISTENT_START
564     // svx_eerdll.cxx GlobalEditData::GetDefItems
565     static int const what[]= {
566       StarAttribute::ATTR_SCH_DATADESCR_DESCR, StarAttribute::ATTR_SCH_DATADESCR_SHOW_SYM, StarAttribute::ATTR_SCH_LEGEND_POS, StarAttribute::ATTR_SCH_TEXT_ORIENT,
567       StarAttribute::ATTR_SCH_TEXT_ORDER, StarAttribute::ATTR_SCH_Y_AXIS_AUTO_MIN, StarAttribute::ATTR_SCH_Y_AXIS_MIN, StarAttribute::ATTR_SCH_Y_AXIS_AUTO_MAX,
568       StarAttribute::ATTR_SCH_Y_AXIS_MAX, StarAttribute::ATTR_SCH_Y_AXIS_AUTO_STEP_MAIN, StarAttribute::ATTR_SCH_Y_AXIS_STEP_MAIN, StarAttribute::ATTR_SCH_Y_AXIS_AUTO_STEP_HELP,
569       StarAttribute::ATTR_SCH_Y_AXIS_STEP_HELP, StarAttribute::ATTR_SCH_Y_AXIS_LOGARITHM, StarAttribute::ATTR_SCH_Y_AXIS_AUTO_ORIGIN, StarAttribute::ATTR_SCH_Y_AXIS_ORIGIN,
570       StarAttribute::ATTR_SCH_X_AXIS_AUTO_MIN, StarAttribute::ATTR_SCH_X_AXIS_MIN, StarAttribute::ATTR_SCH_X_AXIS_AUTO_MAX, StarAttribute::ATTR_SCH_X_AXIS_MAX,
571 
572       StarAttribute::ATTR_SCH_X_AXIS_AUTO_STEP_MAIN, StarAttribute::ATTR_SCH_X_AXIS_STEP_MAIN, StarAttribute::ATTR_SCH_X_AXIS_AUTO_STEP_HELP, StarAttribute::ATTR_SCH_X_AXIS_STEP_HELP,
573       StarAttribute::ATTR_SCH_X_AXIS_LOGARITHM, StarAttribute::ATTR_SCH_X_AXIS_AUTO_ORIGIN, StarAttribute::ATTR_SCH_X_AXIS_ORIGIN, StarAttribute::ATTR_SCH_Z_AXIS_AUTO_MIN,
574       StarAttribute::ATTR_SCH_Z_AXIS_MIN, StarAttribute::ATTR_SCH_Z_AXIS_AUTO_MAX, StarAttribute::ATTR_SCH_Z_AXIS_MAX, StarAttribute::ATTR_SCH_Z_AXIS_AUTO_STEP_MAIN,
575       StarAttribute::ATTR_SCH_Z_AXIS_STEP_MAIN, StarAttribute::ATTR_SCH_Z_AXIS_AUTO_STEP_HELP, StarAttribute::ATTR_SCH_Z_AXIS_STEP_HELP, StarAttribute::ATTR_SCH_Z_AXIS_LOGARITHM,
576       StarAttribute::ATTR_SCH_Z_AXIS_AUTO_ORIGIN, StarAttribute::ATTR_SCH_Z_AXIS_ORIGIN, StarAttribute::ATTR_SCH_AXISTYPE, StarAttribute::ATTR_SCH_DUMMY0,
577 
578       StarAttribute::ATTR_SCH_DUMMY1, StarAttribute::ATTR_SCH_DUMMY2, StarAttribute::ATTR_SCH_DUMMY3, StarAttribute::ATTR_SCH_DUMMY_END,
579       StarAttribute::ATTR_SCH_STAT_AVERAGE, StarAttribute::ATTR_SCH_STAT_KIND_ERROR, StarAttribute::ATTR_SCH_STAT_PERCENT, StarAttribute::ATTR_SCH_STAT_BIGERROR,
580       StarAttribute::ATTR_SCH_STAT_CONSTPLUS, StarAttribute::ATTR_SCH_STAT_CONSTMINUS, StarAttribute::ATTR_SCH_STAT_REGRESSTYPE, StarAttribute::ATTR_SCH_STAT_INDICATE,
581       StarAttribute::ATTR_SCH_TEXT_DEGREES, StarAttribute::ATTR_SCH_TEXT_OVERLAP, StarAttribute::ATTR_SCH_TEXT_DUMMY0, StarAttribute::ATTR_SCH_TEXT_DUMMY1,
582       StarAttribute::ATTR_SCH_TEXT_DUMMY2, StarAttribute::ATTR_SCH_TEXT_DUMMY3, StarAttribute::ATTR_SCH_STYLE_DEEP, StarAttribute::ATTR_SCH_STYLE_3D,
583 
584       StarAttribute::ATTR_SCH_STYLE_VERTICAL, StarAttribute::ATTR_SCH_STYLE_BASETYPE, StarAttribute::ATTR_SCH_STYLE_LINES, StarAttribute::ATTR_SCH_STYLE_PERCENT,
585       StarAttribute::ATTR_SCH_STYLE_STACKED, StarAttribute::ATTR_SCH_STYLE_SPLINES, StarAttribute::ATTR_SCH_STYLE_SYMBOL, StarAttribute::ATTR_SCH_STYLE_SHAPE,
586       StarAttribute::ATTR_SCH_AXIS, StarAttribute::ATTR_SCH_AXIS_AUTO_MIN, StarAttribute::ATTR_SCH_AXIS_MIN, StarAttribute::ATTR_SCH_AXIS_AUTO_MAX,
587       StarAttribute::ATTR_SCH_AXIS_MAX, StarAttribute::ATTR_SCH_AXIS_AUTO_STEP_MAIN, StarAttribute::ATTR_SCH_AXIS_STEP_MAIN, StarAttribute::ATTR_SCH_AXIS_AUTO_STEP_HELP,
588       StarAttribute::ATTR_SCH_AXIS_STEP_HELP, StarAttribute::ATTR_SCH_AXIS_LOGARITHM, StarAttribute::ATTR_SCH_AXIS_AUTO_ORIGIN, StarAttribute::ATTR_SCH_AXIS_ORIGIN,
589 
590       StarAttribute::ATTR_SCH_AXIS_TICKS, StarAttribute::ATTR_SCH_AXIS_NUMFMT, StarAttribute::ATTR_SCH_AXIS_NUMFMTPERCENT, StarAttribute::ATTR_SCH_AXIS_SHOWAXIS,
591       StarAttribute::ATTR_SCH_AXIS_SHOWDESCR, StarAttribute::ATTR_SCH_AXIS_SHOWMAINGRID, StarAttribute::ATTR_SCH_AXIS_SHOWHELPGRID, StarAttribute::ATTR_SCH_AXIS_TOPDOWN,
592       StarAttribute::ATTR_SCH_AXIS_HELPTICKS, StarAttribute::ATTR_SCH_AXIS_DUMMY0, StarAttribute::ATTR_SCH_AXIS_DUMMY1, StarAttribute::ATTR_SCH_AXIS_DUMMY2,
593       StarAttribute::ATTR_SCH_AXIS_DUMMY3, StarAttribute::ATTR_SCH_BAR_OVERLAP, StarAttribute::ATTR_SCH_BAR_GAPWIDTH, StarAttribute::ATTR_SCH_SYMBOL_BRUSH,
594       StarAttribute::ATTR_SCH_STOCK_VOLUME, StarAttribute::ATTR_SCH_STOCK_UPDOWN, StarAttribute::ATTR_SCH_SYMBOL_SIZE, StarAttribute::ATTR_SCH_USER_DEFINED_ATTR
595     };
596 
597     for (auto wh : what)
598       m_idToAttributeList.push_back(wh);
599     break;
600   }
601   case StarItemPool::T_EditEnginePool: {
602     m_verStart=3989;
603     m_verEnd=4037;
604     // svx_editdoc.cxx
605     std::vector<int> list;
606     for (int i = 0; i <= 14; ++i) list.push_back(3999+i);
607     for (int i = 15; i <= 17; ++i) list.push_back(3999+i+3);
608     addVersionMap(1, 3999, list);
609 
610     list.clear();
611     for (int i = 0; i <= 17; ++i) list.push_back(3999+i);
612     for (int i=18; i<=20; ++i)  list.push_back(3999+i+1);
613     addVersionMap(2, 3999, list);
614 
615     list.clear();
616     for (int i = 0; i <= 10; ++i) list.push_back(3997+i);
617     for (int i=11; i<=23; ++i)  list.push_back(3997+i+1);
618     addVersionMap(3, 3997, list);
619 
620     list.clear();
621     for (int i = 0; i <= 24; ++i) list.push_back(3994+i);
622     for (int i=25; i<=28; ++i)  list.push_back(3994+i+15);
623     addVersionMap(4, 3994, list);
624     // svx_eerdll.cxx GlobalEditData::GetDefItems
625     static int const what[]= {
626       StarAttribute::ATTR_SC_WRITINGDIR, StarAttribute::ATTR_EE_PARA_XMLATTRIBS, StarAttribute::ATTR_PARA_HANGINGPUNCTUATION, StarAttribute::ATTR_PARA_FORBIDDEN_RULES,
627       StarAttribute::ATTR_EE_PARA_ASIANCJKSPACING, StarAttribute::ATTR_EE_PARA_NUMBULLET, StarAttribute::ATTR_SC_HYPHENATE, StarAttribute::ATTR_EE_PARA_BULLETSTATE,
628       StarAttribute::ATTR_EE_PARA_OUTLLR_SPACE, StarAttribute::ATTR_EE_PARA_OUTLLEVEL, StarAttribute::ATTR_EE_PARA_BULLET, StarAttribute::ATTR_FRM_LR_SPACE,
629       StarAttribute::ATTR_FRM_UL_SPACE, StarAttribute::ATTR_PARA_LINESPACING, StarAttribute::ATTR_PARA_ADJUST, StarAttribute::ATTR_PARA_TABSTOP,
630       StarAttribute::ATTR_CHR_COLOR, StarAttribute::ATTR_CHR_FONT, StarAttribute::ATTR_CHR_FONTSIZE, StarAttribute::ATTR_EE_CHR_SCALEW,
631 
632       StarAttribute::ATTR_CHR_WEIGHT, StarAttribute::ATTR_CHR_UNDERLINE, StarAttribute::ATTR_CHR_CROSSEDOUT, StarAttribute::ATTR_CHR_POSTURE,
633       StarAttribute::ATTR_CHR_CONTOUR, StarAttribute::ATTR_CHR_SHADOWED, StarAttribute::ATTR_CHR_ESCAPEMENT, StarAttribute::ATTR_CHR_AUTOKERN,
634       StarAttribute::ATTR_CHR_KERNING, StarAttribute::ATTR_CHR_WORDLINEMODE, StarAttribute::ATTR_CHR_LANGUAGE, StarAttribute::ATTR_CHR_CJK_LANGUAGE,
635       StarAttribute::ATTR_CHR_CTL_LANGUAGE, StarAttribute::ATTR_CHR_CJK_FONT, StarAttribute::ATTR_CHR_CTL_FONT, StarAttribute::ATTR_CHR_CJK_FONTSIZE,
636       StarAttribute::ATTR_CHR_CTL_FONTSIZE, StarAttribute::ATTR_CHR_CJK_WEIGHT, StarAttribute::ATTR_CHR_CTL_WEIGHT, StarAttribute::ATTR_CHR_CJK_POSTURE,
637 
638       StarAttribute::ATTR_CHR_CTL_POSTURE, StarAttribute::ATTR_CHR_EMPHASIS_MARK, StarAttribute::ATTR_CHR_RELIEF, StarAttribute::ATTR_EE_CHR_RUBI_DUMMY,
639       StarAttribute::ATTR_EE_CHR_XMLATTRIBS, StarAttribute::ATTR_EE_FEATURE_TAB, StarAttribute::ATTR_EE_FEATURE_LINEBR, StarAttribute::ATTR_CHR_CHARSETCOLOR,
640       StarAttribute::ATTR_EE_FEATURE_FIELD
641     };
642     for (auto wh : what)
643       m_idToAttributeList.push_back(wh);
644     break;
645   }
646   case StarItemPool::T_SpreadsheetPool: {
647     // sc_docpool.cxx
648     m_verStart=100; // ATTR_STARTINDEX
649     m_verEnd=183; // ATTR_ENDINDEX
650 
651     std::vector<int> list;
652     for (int i = 0; i <= 17; i++) list.push_back(100+i);
653     for (int i = 18; i <= 57; i++) list.push_back(100+i+1);
654     addVersionMap(1, 100, list);
655 
656     list.clear();
657     for (int i = 0; i <= 23; i++) list.push_back(100+i);
658     for (int i = 24; i <= 58; i++) list.push_back(100+i+2);
659     addVersionMap(2, 100, list);
660 
661     list.clear();
662     for (int i = 0; i <= 10; i++) list.push_back(100+i);
663     for (int i = 11; i <= 60; i++) list.push_back(100+i+1);
664     addVersionMap(3, 100, list);
665 
666     list.clear();
667     for (int i = 0; i <= 13; i++) list.push_back(100+i);
668     for (int i = 14; i <= 61; i++) list.push_back(100+i+2);
669     addVersionMap(4, 100, list);
670 
671     list.clear();
672     for (int i = 0; i <= 9; i++) list.push_back(100+i);
673     for (int i = 10; i <= 63; i++) list.push_back(100+i+12);
674     addVersionMap(5, 100, list);
675 
676     list.clear();
677     for (int i = 0; i <= 21; i++) list.push_back(100+i);
678     for (int i = 22; i <= 75; i++) list.push_back(100+i+3);
679     addVersionMap(6, 100, list);
680 
681     list.clear();
682     for (int i = 0; i <= 21; i++) list.push_back(100+i);
683     for (int i = 22; i <= 78; i++) list.push_back(100+i+3);
684     addVersionMap(7, 100, list);
685 
686     list.clear();
687     for (int i = 0; i <= 33; i++) list.push_back(100+i);
688     for (int i = 34; i <= 81; i++) list.push_back(100+i+1);
689     addVersionMap(8, 100, list);
690 
691     list.clear();
692     for (int i = 0; i <= 34; i++) list.push_back(100+i);
693     for (int i = 35; i <= 82; i++) list.push_back(100+i+1);
694     addVersionMap(9, 100, list);
695     static int const what[]= {
696       StarAttribute::ATTR_CHR_FONT, StarAttribute::ATTR_CHR_FONTSIZE, StarAttribute::ATTR_CHR_WEIGHT, StarAttribute::ATTR_CHR_POSTURE,
697       StarAttribute::ATTR_CHR_UNDERLINE, StarAttribute::ATTR_CHR_CROSSEDOUT, StarAttribute::ATTR_CHR_CONTOUR, StarAttribute::ATTR_CHR_SHADOWED,
698       StarAttribute::ATTR_CHR_COLOR, StarAttribute::ATTR_CHR_LANGUAGE, StarAttribute::ATTR_CHR_CJK_FONT, StarAttribute::ATTR_CHR_CJK_FONTSIZE,
699       StarAttribute::ATTR_CHR_CJK_WEIGHT, StarAttribute::ATTR_CHR_CJK_POSTURE, StarAttribute::ATTR_CHR_CJK_LANGUAGE, StarAttribute::ATTR_CHR_CTL_FONT,
700       StarAttribute::ATTR_CHR_CTL_FONTSIZE, StarAttribute::ATTR_CHR_CTL_WEIGHT, StarAttribute::ATTR_CHR_CTL_POSTURE, StarAttribute::ATTR_CHR_CTL_LANGUAGE,
701 
702       StarAttribute::ATTR_CHR_EMPHASIS_MARK, StarAttribute::ATTR_SC_USERDEF, StarAttribute::ATTR_CHR_WORDLINEMODE, StarAttribute::ATTR_CHR_RELIEF,
703       StarAttribute::ATTR_SC_HYPHENATE, StarAttribute::ATTR_PARA_SCRIPTSPACE, StarAttribute::ATTR_PARA_HANGINGPUNCTUATION, StarAttribute::ATTR_PARA_FORBIDDEN_RULES,
704       StarAttribute::ATTR_SC_HORJUSTIFY, StarAttribute::ATTR_SC_INDENT, StarAttribute::ATTR_SC_VERJUSTIFY, StarAttribute::ATTR_SC_ORIENTATION,
705       StarAttribute::ATTR_SC_ROTATE_VALUE, StarAttribute::ATTR_SC_ROTATE_MODE, StarAttribute::ATTR_SC_VERTICAL_ASIAN, StarAttribute::ATTR_SC_WRITINGDIR,
706       StarAttribute::ATTR_SC_LINEBREAK, StarAttribute::ATTR_SC_MARGIN, StarAttribute::ATTR_SC_MERGE, StarAttribute::ATTR_SC_MERGE_FLAG,
707 
708       StarAttribute::ATTR_SC_VALUE_FORMAT, StarAttribute::ATTR_SC_LANGUAGE_FORMAT, StarAttribute::ATTR_SC_BACKGROUND, StarAttribute::ATTR_SC_PROTECTION,
709       StarAttribute::ATTR_SC_BORDER, StarAttribute::ATTR_SC_BORDER_INNER, StarAttribute::ATTR_SC_SHADOW, StarAttribute::ATTR_SC_VALIDDATA,
710       StarAttribute::ATTR_SC_CONDITIONAL, StarAttribute::ATTR_SC_PATTERN, StarAttribute::ATTR_FRM_LR_SPACE, StarAttribute::ATTR_FRM_UL_SPACE,
711       StarAttribute::ATTR_SC_PAGE, StarAttribute::ATTR_SC_PAGE_PAPERTRAY, StarAttribute::ATTR_FRM_PAPER_BIN, StarAttribute::ATTR_SC_PAGE_SIZE,
712       StarAttribute::ATTR_SC_PAGE_MAXSIZE, StarAttribute::ATTR_SC_PAGE_HORCENTER, StarAttribute::ATTR_SC_PAGE_VERCENTER, StarAttribute::ATTR_SC_PAGE_ON,
713 
714       StarAttribute::ATTR_SC_PAGE_DYNAMIC, StarAttribute::ATTR_SC_PAGE_SHARED, StarAttribute::ATTR_SC_PAGE_NOTES, StarAttribute::ATTR_SC_PAGE_GRID,
715       StarAttribute::ATTR_SC_PAGE_HEADERS, StarAttribute::ATTR_SC_PAGE_CHARTS, StarAttribute::ATTR_SC_PAGE_OBJECTS, StarAttribute::ATTR_SC_PAGE_DRAWINGS,
716       StarAttribute::ATTR_SC_PAGE_TOPDOWN, StarAttribute::ATTR_SC_PAGE_SCALE, StarAttribute::ATTR_SC_PAGE_SCALETOPAGES, StarAttribute::ATTR_SC_PAGE_FIRSTPAGENO,
717       StarAttribute::ATTR_SC_PAGE_PRINTAREA, StarAttribute::ATTR_SC_PAGE_REPEATROW, StarAttribute::ATTR_SC_PAGE_REPEATCOL, StarAttribute::ATTR_SC_PAGE_PRINTTABLES,
718       StarAttribute::ATTR_SC_PAGE_HEADERLEFT, StarAttribute::ATTR_SC_PAGE_FOOTERLEFT, StarAttribute::ATTR_SC_PAGE_HEADERRIGHT, StarAttribute::ATTR_SC_PAGE_FOOTERRIGHT,
719       StarAttribute::ATTR_SC_PAGE_HEADERSET, StarAttribute::ATTR_SC_PAGE_FOOTERSET, StarAttribute::ATTR_SC_PAGE_FORMULAS, StarAttribute::ATTR_SC_PAGE_NULLVALS
720     };
721     for (auto wh : what)
722       m_idToAttributeList.push_back(wh);
723     break;
724   }
725   case StarItemPool::T_VCControlPool: // never seens with data, so
726     break;
727   case StarItemPool::T_WriterPool: {
728     // SwAttrPool::SwAttrPool set default map
729     m_verStart=1; //POOLATTR_BEGIN
730     m_verEnd=130; //POOLATTR_END-1
731     for (int i=StarAttribute::ATTR_CHR_CASEMAP; i<=StarAttribute::ATTR_BOX_VALUE; ++i)
732       m_idToAttributeList.push_back(i);
733     std::vector<int> list;
734     // sw_swatrset.cxx SwAttrPool::SwAttrPool and sw_init.cxx pVersionMap1
735     for (int i = 1; i <= 17; i++) list.push_back(i);
736     for (int i = 18; i <= 27; i++) list.push_back(i+5);
737     for (int i = 28; i <= 35; i++) list.push_back(i+7);
738     for (int i = 36; i <= 58; i++) list.push_back(i+10);
739     for (int i = 59; i <= 60; i++) list.push_back(i+12);
740     addVersionMap(1, 1, list);
741     list.clear();
742     for (int i = 1; i <= 70; i++) list.push_back(i);
743     for (int i = 71; i <= 75; i++) list.push_back(i+10);
744     addVersionMap(2, 1, list);
745     list.clear();
746     for (int i = 1; i <= 21; i++) list.push_back(i);
747     for (int i = 22; i <= 27; i++) list.push_back(i+15);
748     for (int i = 28; i <= 82; i++) list.push_back(i+20);
749     for (int i = 83; i <= 86; i++) list.push_back(i+35);
750     addVersionMap(3, 1, list);
751     list.clear();
752     for (int i = 1; i <= 65; i++) list.push_back(i);
753     for (int i = 66; i <= 121; i++) list.push_back(i+9);
754     addVersionMap(4, 1, list);
755     break;
756   }
757   case StarItemPool::T_XOutdevPool: {
758     // svx_xpool.cxx XOutdevItemPool::Ctor and svx_svdattr.cxx SdrItemPool::Ctor
759     m_verStart=1000;
760     m_verEnd=1333;
761     std::vector<int> list;
762     for (int i=1000; i<=1021; ++i) list.push_back(i);
763     for (int i=1022; i<=1039; ++i) list.push_back(i+13);
764     addVersionMap(1, 1000, list);
765 
766     list.clear();
767     for (int i=1000; i<=1009; ++i) list.push_back(i);
768     for (int i=1010; i<=1015; ++i) list.push_back(i+7);
769     for (int i=1016; i<=1039; ++i) list.push_back(i+14);
770     for (int i=1040; i<=1050; ++i) list.push_back(i+22);
771     for (int i=1051; i<=1056; ++i) list.push_back(i+27);
772     for (int i=1057; i<=1065; ++i) list.push_back(i+52);
773     addVersionMap(2, 1000, list);
774 
775     list.clear();
776     for (int i=1000; i<=1029; ++i) list.push_back(i);
777     for (int i=1030; i<=1123; ++i) list.push_back(i+17);
778     addVersionMap(3, 1000, list);
779 
780     list.clear();
781     for (int i=1000; i<=1126; ++i) list.push_back(i);
782     for (int i=1127; i<=1140; ++i) list.push_back(i+45);
783     addVersionMap(4, 1000, list);
784 
785     static int const what[]= {
786       StarAttribute::XATTR_LINESTYLE, StarAttribute::XATTR_LINEDASH, StarAttribute::XATTR_LINEWIDTH, StarAttribute::XATTR_LINECOLOR,
787       StarAttribute::XATTR_LINESTART, StarAttribute::XATTR_LINEEND, StarAttribute::XATTR_LINESTARTWIDTH, StarAttribute::XATTR_LINEENDWIDTH,
788       StarAttribute::XATTR_LINESTARTCENTER, StarAttribute::XATTR_LINEENDCENTER, StarAttribute::XATTR_LINETRANSPARENCE, StarAttribute::XATTR_LINEJOINT,
789       StarAttribute::XATTR_LINERESERVED2, StarAttribute::XATTR_LINERESERVED3, StarAttribute::XATTR_LINERESERVED4,StarAttribute::XATTR_LINERESERVED5,
790       StarAttribute::XATTR_LINERESERVED_LAST, StarAttribute::XATTR_SET_LINE, StarAttribute::XATTR_FILLSTYLE, StarAttribute::XATTR_FILLCOLOR,
791 
792       StarAttribute::XATTR_FILLGRADIENT, StarAttribute::XATTR_FILLHATCH, StarAttribute::XATTR_FILLBITMAP, StarAttribute::XATTR_FILLTRANSPARENCE,
793       StarAttribute::XATTR_GRADIENTSTEPCOUNT, StarAttribute::XATTR_FILLBMP_TILE, StarAttribute::XATTR_FILLBMP_POS, StarAttribute::XATTR_FILLBMP_SIZEX,
794       StarAttribute::XATTR_FILLBMP_SIZEY, StarAttribute::XATTR_FILLFLOATTRANSPARENCE, StarAttribute::XATTR_FILLRESERVED2, StarAttribute::XATTR_FILLBMP_SIZELOG,
795       StarAttribute::XATTR_FILLBMP_TILEOFFSETX, StarAttribute::XATTR_FILLBMP_TILEOFFSETY, StarAttribute::XATTR_FILLBMP_STRETCH, StarAttribute::XATTR_FILLRESERVED3,
796       StarAttribute::XATTR_FILLRESERVED4, StarAttribute::XATTR_FILLRESERVED5, StarAttribute::XATTR_FILLRESERVED6, StarAttribute::XATTR_FILLRESERVED7,
797 
798       StarAttribute::XATTR_FILLRESERVED8, StarAttribute::XATTR_FILLBMP_POSOFFSETX, StarAttribute::XATTR_FILLBMP_POSOFFSETY, StarAttribute::XATTR_FILLBACKGROUND,
799       StarAttribute::XATTR_FILLRESERVED10, StarAttribute::XATTR_FILLRESERVED11, StarAttribute::XATTR_FILLRESERVED_LAST, StarAttribute::XATTR_SET_FILL,
800       StarAttribute::XATTR_FORMTXTSTYLE, StarAttribute::XATTR_FORMTXTADJUST, StarAttribute::XATTR_FORMTXTDISTANCE, StarAttribute::XATTR_FORMTXTSTART,
801       StarAttribute::XATTR_FORMTXTMIRROR, StarAttribute::XATTR_FORMTXTOUTLINE, StarAttribute::XATTR_FORMTXTSHADOW, StarAttribute::XATTR_FORMTXTSHDWCOLOR,
802       StarAttribute::XATTR_FORMTXTSHDWXVAL, StarAttribute::XATTR_FORMTXTSHDWYVAL, StarAttribute::XATTR_FORMTXTSTDFORM, StarAttribute::XATTR_FORMTXTHIDEFORM,
803 
804       StarAttribute::XATTR_FORMTXTSHDWTRANSP, StarAttribute::XATTR_FTRESERVED2, StarAttribute::XATTR_FTRESERVED3, StarAttribute::XATTR_FTRESERVED4,
805       StarAttribute::XATTR_FTRESERVED5, StarAttribute::XATTR_FTRESERVED_LAST, StarAttribute::XATTR_SET_TEXT,
806 
807       // SDR 1067...
808       StarAttribute::SDRATTR_SHADOW, StarAttribute::SDRATTR_SHADOWCOLOR, StarAttribute::SDRATTR_SHADOWXDIST, StarAttribute::SDRATTR_SHADOWYDIST,
809       StarAttribute::SDRATTR_SHADOWTRANSPARENCE, StarAttribute::SDRATTR_SHADOW3D, StarAttribute::SDRATTR_SHADOWPERSP, StarAttribute::SDRATTR_SHADOWRESERVE1,
810       StarAttribute::SDRATTR_SHADOWRESERVE2, StarAttribute::SDRATTR_SHADOWRESERVE3, StarAttribute::SDRATTR_SHADOWRESERVE4, StarAttribute::SDRATTR_SHADOWRESERVE5,
811       StarAttribute::SDRATTR_SET_SHADOW, StarAttribute::SDRATTR_CAPTIONTYPE, StarAttribute::SDRATTR_CAPTIONFIXEDANGLE, StarAttribute::SDRATTR_CAPTIONANGLE,
812       StarAttribute::SDRATTR_CAPTIONGAP, StarAttribute::SDRATTR_CAPTIONESCDIR, StarAttribute::SDRATTR_CAPTIONESCISREL, StarAttribute::SDRATTR_CAPTIONESCREL,
813 
814       StarAttribute::SDRATTR_CAPTIONESCABS, StarAttribute::SDRATTR_CAPTIONLINELEN, StarAttribute::SDRATTR_CAPTIONFITLINELEN, StarAttribute::SDRATTR_CAPTIONRESERVE1,
815       StarAttribute::SDRATTR_CAPTIONRESERVE2, StarAttribute::SDRATTR_CAPTIONRESERVE3, StarAttribute::SDRATTR_CAPTIONRESERVE4, StarAttribute::SDRATTR_CAPTIONRESERVE5,
816       StarAttribute::SDRATTR_SET_CAPTION, StarAttribute::SDRATTR_SET_OUTLINER, StarAttribute::SDRATTR_ECKENRADIUS, StarAttribute::SDRATTR_TEXT_MINFRAMEHEIGHT,
817       StarAttribute::SDRATTR_TEXT_AUTOGROWHEIGHT, StarAttribute::SDRATTR_TEXT_FITTOSIZE, StarAttribute::SDRATTR_TEXT_LEFTDIST, StarAttribute::SDRATTR_TEXT_RIGHTDIST,
818       StarAttribute::SDRATTR_TEXT_UPPERDIST, StarAttribute::SDRATTR_TEXT_LOWERDIST, StarAttribute::SDRATTR_TEXT_VERTADJUST, StarAttribute::SDRATTR_TEXT_MAXFRAMEHEIGHT,
819 
820       StarAttribute::SDRATTR_TEXT_MINFRAMEWIDTH, StarAttribute::SDRATTR_TEXT_MAXFRAMEWIDTH, StarAttribute::SDRATTR_TEXT_AUTOGROWWIDTH, StarAttribute::SDRATTR_TEXT_HORZADJUST,
821       StarAttribute::SDRATTR_TEXT_ANIKIND, StarAttribute::SDRATTR_TEXT_ANIDIRECTION, StarAttribute::SDRATTR_TEXT_ANISTARTINSIDE, StarAttribute::SDRATTR_TEXT_ANISTOPINSIDE,
822       StarAttribute::SDRATTR_TEXT_ANICOUNT, StarAttribute::SDRATTR_TEXT_ANIDELAY, StarAttribute::SDRATTR_TEXT_ANIAMOUNT, StarAttribute::SDRATTR_TEXT_CONTOURFRAME,
823       StarAttribute::SDRATTR_AUTOSHAPE_ADJUSTMENT, StarAttribute::SDRATTR_XMLATTRIBUTES, StarAttribute::SDRATTR_RESERVE15, StarAttribute::SDRATTR_RESERVE16,
824       StarAttribute::SDRATTR_RESERVE17, StarAttribute::SDRATTR_RESERVE18, StarAttribute::SDRATTR_RESERVE19, StarAttribute::SDRATTR_SET_MISC,
825 
826       StarAttribute::SDRATTR_EDGEKIND, StarAttribute::SDRATTR_EDGENODE1HORZDIST, StarAttribute::SDRATTR_EDGENODE1VERTDIST, StarAttribute::SDRATTR_EDGENODE2HORZDIST,
827       StarAttribute::SDRATTR_EDGENODE2VERTDIST, StarAttribute::SDRATTR_EDGENODE1GLUEDIST, StarAttribute::SDRATTR_EDGENODE2GLUEDIST, StarAttribute::SDRATTR_EDGELINEDELTAANZ,
828       StarAttribute::SDRATTR_EDGELINE1DELTA, StarAttribute::SDRATTR_EDGELINE2DELTA, StarAttribute::SDRATTR_EDGELINE3DELTA, StarAttribute::SDRATTR_EDGERESERVE02,
829       StarAttribute::SDRATTR_EDGERESERVE03, StarAttribute::SDRATTR_EDGERESERVE04, StarAttribute::SDRATTR_EDGERESERVE05, StarAttribute::SDRATTR_EDGERESERVE06,
830       StarAttribute::SDRATTR_EDGERESERVE07, StarAttribute::SDRATTR_EDGERESERVE08, StarAttribute::SDRATTR_EDGERESERVE09, StarAttribute::SDRATTR_SET_EDGE,
831 
832       StarAttribute::SDRATTR_MEASUREKIND, StarAttribute::SDRATTR_MEASURETEXTHPOS, StarAttribute::SDRATTR_MEASURETEXTVPOS, StarAttribute::SDRATTR_MEASURELINEDIST,
833       StarAttribute::SDRATTR_MEASUREHELPLINEOVERHANG, StarAttribute::SDRATTR_MEASUREHELPLINEDIST, StarAttribute::SDRATTR_MEASUREHELPLINE1LEN, StarAttribute::SDRATTR_MEASUREHELPLINE2LEN,
834       StarAttribute::SDRATTR_MEASUREBELOWREFEDGE, StarAttribute::SDRATTR_MEASURETEXTROTA90, StarAttribute::SDRATTR_MEASURETEXTUPSIDEDOWN, StarAttribute::SDRATTR_MEASUREOVERHANG,
835       StarAttribute::SDRATTR_MEASUREUNIT, StarAttribute::SDRATTR_MEASURESCALE, StarAttribute::SDRATTR_MEASURESHOWUNIT, StarAttribute::SDRATTR_MEASUREFORMATSTRING,
836       StarAttribute::SDRATTR_MEASURETEXTAUTOANGLE, StarAttribute::SDRATTR_MEASURETEXTAUTOANGLEVIEW, StarAttribute::SDRATTR_MEASURETEXTISFIXEDANGLE, StarAttribute::SDRATTR_MEASURETEXTFIXEDANGLE,
837       // 1167
838       StarAttribute::SDRATTR_MEASUREDECIMALPLACES, StarAttribute::SDRATTR_MEASURERESERVE05, StarAttribute::SDRATTR_MEASURERESERVE06, StarAttribute::SDRATTR_MEASURERESERVE07,
839       StarAttribute::SDRATTR_SET_MEASURE, StarAttribute::SDRATTR_CIRCKIND, StarAttribute::SDRATTR_CIRCSTARTANGLE, StarAttribute::SDRATTR_CIRCENDANGLE,
840       StarAttribute::SDRATTR_CIRCRESERVE0, StarAttribute::SDRATTR_CIRCRESERVE1, StarAttribute::SDRATTR_CIRCRESERVE2, StarAttribute::SDRATTR_CIRCRESERVE3,
841       StarAttribute::SDRATTR_SET_CIRC, StarAttribute::SDRATTR_OBJMOVEPROTECT, StarAttribute::SDRATTR_OBJSIZEPROTECT, StarAttribute::SDRATTR_OBJPRINTABLE,
842       StarAttribute::SDRATTR_LAYERID, StarAttribute::SDRATTR_LAYERNAME, StarAttribute::SDRATTR_OBJECTNAME, StarAttribute::SDRATTR_ALLPOSITIONX,
843 
844       StarAttribute::SDRATTR_ALLPOSITIONY, StarAttribute::SDRATTR_ALLSIZEWIDTH, StarAttribute::SDRATTR_ALLSIZEHEIGHT, StarAttribute::SDRATTR_ONEPOSITIONX,
845       StarAttribute::SDRATTR_ONEPOSITIONY, StarAttribute::SDRATTR_ONESIZEWIDTH, StarAttribute::SDRATTR_ONESIZEHEIGHT, StarAttribute::SDRATTR_LOGICSIZEWIDTH,
846       StarAttribute::SDRATTR_LOGICSIZEHEIGHT, StarAttribute::SDRATTR_ROTATEANGLE, StarAttribute::SDRATTR_SHEARANGLE, StarAttribute::SDRATTR_MOVEX,
847       StarAttribute::SDRATTR_MOVEY, StarAttribute::SDRATTR_RESIZEXONE, StarAttribute::SDRATTR_RESIZEYONE, StarAttribute::SDRATTR_ROTATEONE,
848       StarAttribute::SDRATTR_HORZSHEARONE, StarAttribute::SDRATTR_VERTSHEARONE, StarAttribute::SDRATTR_RESIZEXALL, StarAttribute::SDRATTR_RESIZEYALL,
849 
850       StarAttribute::SDRATTR_ROTATEALL, StarAttribute::SDRATTR_HORZSHEARALL, StarAttribute::SDRATTR_VERTSHEARALL, StarAttribute::SDRATTR_TRANSFORMREF1X,
851       StarAttribute::SDRATTR_TRANSFORMREF1Y, StarAttribute::SDRATTR_TRANSFORMREF2X, StarAttribute::SDRATTR_TRANSFORMREF2Y, StarAttribute::SDRATTR_TEXTDIRECTION,
852       StarAttribute::SDRATTR_NOTPERSISTRESERVE2, StarAttribute::SDRATTR_NOTPERSISTRESERVE3, StarAttribute::SDRATTR_NOTPERSISTRESERVE4, StarAttribute::SDRATTR_NOTPERSISTRESERVE5,
853       StarAttribute::SDRATTR_NOTPERSISTRESERVE6, StarAttribute::SDRATTR_NOTPERSISTRESERVE7, StarAttribute::SDRATTR_NOTPERSISTRESERVE8, StarAttribute::SDRATTR_NOTPERSISTRESERVE9,
854       StarAttribute::SDRATTR_NOTPERSISTRESERVE10, StarAttribute::SDRATTR_NOTPERSISTRESERVE11, StarAttribute::SDRATTR_NOTPERSISTRESERVE12, StarAttribute::SDRATTR_NOTPERSISTRESERVE13,
855 
856       StarAttribute::SDRATTR_NOTPERSISTRESERVE14, StarAttribute::SDRATTR_NOTPERSISTRESERVE15, StarAttribute::SDRATTR_GRAFRED, StarAttribute::SDRATTR_GRAFGREEN,
857       StarAttribute::SDRATTR_GRAFBLUE, StarAttribute::SDRATTR_GRAFLUMINANCE, StarAttribute::SDRATTR_GRAFCONTRAST, StarAttribute::SDRATTR_GRAFGAMMA,
858       StarAttribute::SDRATTR_GRAFTRANSPARENCE, StarAttribute::SDRATTR_GRAFINVERT, StarAttribute::SDRATTR_GRAFMODE, StarAttribute::SDRATTR_GRAFCROP,
859       StarAttribute::SDRATTR_GRAFRESERVE3, StarAttribute::SDRATTR_GRAFRESERVE4, StarAttribute::SDRATTR_GRAFRESERVE5, StarAttribute::SDRATTR_GRAFRESERVE6,
860       StarAttribute::SDRATTR_SET_GRAF, StarAttribute::SDRATTR_3DOBJ_PERCENT_DIAGONAL, StarAttribute::SDRATTR_3DOBJ_BACKSCALE, StarAttribute::SDRATTR_3DOBJ_DEPTH,
861 
862       StarAttribute::SDRATTR_3DOBJ_HORZ_SEGS, StarAttribute::SDRATTR_3DOBJ_VERT_SEGS, StarAttribute::SDRATTR_3DOBJ_END_ANGLE, StarAttribute::SDRATTR_3DOBJ_DOUBLE_SIDED,
863       StarAttribute::SDRATTR_3DOBJ_NORMALS_KIND, StarAttribute::SDRATTR_3DOBJ_NORMALS_INVERT, StarAttribute::SDRATTR_3DOBJ_TEXTURE_PROJ_X, StarAttribute::SDRATTR_3DOBJ_TEXTURE_PROJ_Y,
864       StarAttribute::SDRATTR_3DOBJ_SHADOW_3D, StarAttribute::SDRATTR_3DOBJ_MAT_COLOR, StarAttribute::SDRATTR_3DOBJ_MAT_EMISSION, StarAttribute::SDRATTR_3DOBJ_MAT_SPECULAR,
865       StarAttribute::SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY, StarAttribute::SDRATTR_3DOBJ_TEXTURE_KIND, StarAttribute::SDRATTR_3DOBJ_TEXTURE_MODE, StarAttribute::SDRATTR_3DOBJ_TEXTURE_FILTER,
866       StarAttribute::SDRATTR_3DOBJ_SMOOTH_NORMALS, StarAttribute::SDRATTR_3DOBJ_SMOOTH_LIDS, StarAttribute::SDRATTR_3DOBJ_CHARACTER_MODE, StarAttribute::SDRATTR_3DOBJ_CLOSE_FRONT,
867       //1267
868       StarAttribute::SDRATTR_3DOBJ_CLOSE_BACK, StarAttribute::SDRATTR_3DOBJ_RESERVED_06, StarAttribute::SDRATTR_3DOBJ_RESERVED_07, StarAttribute::SDRATTR_3DOBJ_RESERVED_08,
869       StarAttribute::SDRATTR_3DOBJ_RESERVED_09, StarAttribute::SDRATTR_3DOBJ_RESERVED_10, StarAttribute::SDRATTR_3DOBJ_RESERVED_11, StarAttribute::SDRATTR_3DOBJ_RESERVED_12,
870       StarAttribute::SDRATTR_3DOBJ_RESERVED_13, StarAttribute::SDRATTR_3DOBJ_RESERVED_14, StarAttribute::SDRATTR_3DOBJ_RESERVED_15, StarAttribute::SDRATTR_3DOBJ_RESERVED_16,
871       StarAttribute::SDRATTR_3DOBJ_RESERVED_17, StarAttribute::SDRATTR_3DOBJ_RESERVED_18, StarAttribute::SDRATTR_3DOBJ_RESERVED_19, StarAttribute::SDRATTR_3DOBJ_RESERVED_20,
872       StarAttribute::SDRATTR_3DSCENE_PERSPECTIVE, StarAttribute::SDRATTR_3DSCENE_DISTANCE, StarAttribute::SDRATTR_3DSCENE_FOCAL_LENGTH, StarAttribute::SDRATTR_3DSCENE_TWO_SIDED_LIGHTING,
873 
874       StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_1, StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_2, StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_3, StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_4,
875       StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_5, StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_6, StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_7, StarAttribute::SDRATTR_3DSCENE_LIGHTCOLOR_8,
876       StarAttribute::SDRATTR_3DSCENE_AMBIENTCOLOR, StarAttribute::SDRATTR_3DSCENE_LIGHTON_1, StarAttribute::SDRATTR_3DSCENE_LIGHTON_2, StarAttribute::SDRATTR_3DSCENE_LIGHTON_3,
877       StarAttribute::SDRATTR_3DSCENE_LIGHTON_4, StarAttribute::SDRATTR_3DSCENE_LIGHTON_5, StarAttribute::SDRATTR_3DSCENE_LIGHTON_6, StarAttribute::SDRATTR_3DSCENE_LIGHTON_7,
878       StarAttribute::SDRATTR_3DSCENE_LIGHTON_8, StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_1, StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_2, StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_3,
879 
880       StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_4, StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_5, StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_6, StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_7,
881       StarAttribute::SDRATTR_3DSCENE_LIGHTDIRECTION_8, StarAttribute::SDRATTR_3DSCENE_SHADOW_SLANT, StarAttribute::SDRATTR_3DSCENE_SHADE_MODE, StarAttribute::SDRATTR_3DSCENE_RESERVED_01,
882       StarAttribute::SDRATTR_3DSCENE_RESERVED_02, StarAttribute::SDRATTR_3DSCENE_RESERVED_03, StarAttribute::SDRATTR_3DSCENE_RESERVED_04, StarAttribute::SDRATTR_3DSCENE_RESERVED_05,
883       StarAttribute::SDRATTR_3DSCENE_RESERVED_06, StarAttribute::SDRATTR_3DSCENE_RESERVED_07, StarAttribute::SDRATTR_3DSCENE_RESERVED_08, StarAttribute::SDRATTR_3DSCENE_RESERVED_09,
884       StarAttribute::SDRATTR_3DSCENE_RESERVED_10, StarAttribute::SDRATTR_3DSCENE_RESERVED_11, StarAttribute::SDRATTR_3DSCENE_RESERVED_12, StarAttribute::SDRATTR_3DSCENE_RESERVED_13,
885 
886       StarAttribute::SDRATTR_3DSCENE_RESERVED_14, StarAttribute::SDRATTR_3DSCENE_RESERVED_15, StarAttribute::SDRATTR_3DSCENE_RESERVED_16, StarAttribute::SDRATTR_3DSCENE_RESERVED_17,
887       StarAttribute::SDRATTR_3DSCENE_RESERVED_18, StarAttribute::SDRATTR_3DSCENE_RESERVED_19, StarAttribute::SDRATTR_3DSCENE_RESERVED_20 /* 1333*/
888     };
889     for (auto wh : what)
890       m_idToAttributeList.push_back(wh);
891     break;
892   }
893   case StarItemPool::T_Unknown:
894   default:
895     break;
896   }
897 }
898 }
899 
900 ////////////////////////////////////////////////////////////
901 // constructor/destructor, ...
902 ////////////////////////////////////////////////////////////
StarItemPool(StarObject & doc,StarItemPool::Type type)903 StarItemPool::StarItemPool(StarObject &doc, StarItemPool::Type type)
904   : m_isInside(false)
905   , m_state(new StarItemPoolInternal::State(doc, type))
906 {
907 }
908 
~StarItemPool()909 StarItemPool::~StarItemPool()
910 {
911 }
912 
setRelativeUnit(double relUnit)913 void StarItemPool::setRelativeUnit(double relUnit)
914 {
915   m_state->m_relativeUnit=relUnit;
916 }
917 
getRelativeUnit() const918 double StarItemPool::getRelativeUnit() const
919 {
920   if (m_state->m_relativeUnit>0)
921     return m_state->m_relativeUnit;
922   return m_state->m_type==StarItemPool::T_XOutdevPool || m_state->m_type==StarItemPool::T_EditEnginePool ? 0.028346457 : 0.05;
923 }
clean()924 void StarItemPool::clean()
925 {
926   m_state->clean();
927 }
928 
isSecondaryPool() const929 bool StarItemPool::isSecondaryPool() const
930 {
931   return m_state->m_isSecondaryPool;
932 }
933 
addSecondaryPool(std::shared_ptr<StarItemPool> secondary)934 void StarItemPool::addSecondaryPool(std::shared_ptr<StarItemPool> secondary)
935 {
936   if (!secondary) {
937     STOFF_DEBUG_MSG(("StarItemPool::addSecondaryPool: called without pool\n"));
938     return;
939   }
940   secondary->m_state->m_isSecondaryPool=true;
941   if (m_state->m_secondaryPool)
942     m_state->m_secondaryPool->addSecondaryPool(secondary);
943   else
944     m_state->m_secondaryPool=secondary;
945 }
946 
getVersion() const947 int StarItemPool::getVersion() const
948 {
949   return m_state->m_majorVersion;
950 }
951 
getType() const952 StarItemPool::Type StarItemPool::getType() const
953 {
954   return m_state->m_type;
955 }
956 
createItem(int which,int surrogateId,bool localId)957 std::shared_ptr<StarItem> StarItemPool::createItem(int which, int surrogateId, bool localId)
958 {
959   std::shared_ptr<StarItem> res(new StarItem(which));
960   res->m_surrogateId=surrogateId;
961   res->m_localId=localId;
962   m_state->m_delayedItemList.push_back(res);
963   return res;
964 }
965 
readAttribute(StarZone & zone,int which,int vers,long endPos)966 std::shared_ptr<StarAttribute> StarItemPool::readAttribute(StarZone &zone, int which, int vers, long endPos)
967 {
968   if (m_state->m_currentVersion!=m_state->m_loadingVersion)
969     which=m_state->getWhich(which);
970 
971   auto *state=m_state->getPoolStateFor(which);
972   if (!state || which<state->m_verStart || which>=state->m_verStart+int(state->m_idToAttributeList.size()) ||
973       !state->m_document.getAttributeManager()) {
974     STOFFInputStreamPtr input=zone.input();
975     long pos=input->tell();
976     libstoff::DebugFile &ascii=zone.ascii();
977     libstoff::DebugStream f;
978     STOFF_DEBUG_MSG(("StarItemPool::readAttribute: find unknown attribute\n"));
979     f << "Entries(StarAttribute)["<< zone.getRecordLevel() << "]:###wh=" << which;
980     ascii.addPos(pos);
981     ascii.addNote(f.str().c_str());
982     input->seek(endPos, librevenge::RVNG_SEEK_SET);
983     return StarAttributeManager::getDummyAttribute();
984   }
985   zone.openDummyRecord();
986   auto attribute=state->m_document.getAttributeManager()->readAttribute
987                  (zone, state->m_idToAttributeList[size_t(which-state->m_verStart)], vers, endPos, state->m_document);
988   zone.closeDummyRecord();
989   return attribute;
990 }
991 
read(StarZone & zone)992 bool StarItemPool::read(StarZone &zone)
993 {
994   STOFFInputStreamPtr input=zone.input();
995   long pos=input->tell();
996   long endPos=zone.getRecordLevel()>0 ?  zone.getRecordLastPosition() : input->size();
997 
998   if (pos+18>endPos)
999     return false;
1000   uint16_t tag;
1001   uint8_t nMajorVers;
1002   *input >> tag >> nMajorVers;
1003   input->seek(pos, librevenge::RVNG_SEEK_SET);
1004   if ((tag!=0x1111 && tag!=0xbbbb) || nMajorVers<1 || nMajorVers>2)
1005     return false;
1006   StarItemPool *master=nullptr, *pool=this;
1007   // update the inside flag to true
1008   while (pool) {
1009     pool->m_isInside=true;
1010     pool=pool->m_state->m_secondaryPool.get();
1011   }
1012   bool ok=false;
1013   // read the pools
1014   pool=this;
1015   while (input->tell()<endPos) {
1016     if ((nMajorVers==2 && !pool->readV2(zone, master)) ||
1017         (nMajorVers==1 && !pool->readV1(zone, master)))
1018       break;
1019     ok=true;
1020     master=pool;
1021     pool=pool->m_state->m_secondaryPool.get();
1022     if (!pool) break;
1023   }
1024   // reset the inside flag to false
1025   pool=this;
1026   while (pool) {
1027     pool->m_isInside=false;
1028     pool=pool->m_state->m_secondaryPool.get();
1029   }
1030   // update the delayed item
1031   pool=this;
1032   while (pool) {
1033     for (auto it : pool->m_state->m_delayedItemList)
1034       loadSurrogate(*it);
1035     pool->m_state->m_delayedItemList.clear();
1036     pool=pool->m_state->m_secondaryPool.get();
1037   }
1038   return ok;
1039 }
1040 
readItem(StarZone & zone,bool isDirect,long endPos)1041 std::shared_ptr<StarItem> StarItemPool::readItem(StarZone &zone, bool isDirect, long endPos)
1042 {
1043   // polio.cxx SfxItemPool::LoadItem
1044   STOFFInputStreamPtr input=zone.input();
1045   libstoff::DebugFile &ascii=zone.ascii();
1046   libstoff::DebugStream f;
1047   f << "Entries(StarItem)["<< zone.getRecordLevel() << "]:";
1048   long pos=input->tell();
1049   if (pos+4>endPos) {
1050     STOFF_DEBUG_MSG(("StarItemPool::readItem: the zone seems too short\n"));
1051     return std::shared_ptr<StarItem>();
1052   }
1053   uint16_t nWhich, nSlot;
1054   *input>>nWhich >> nSlot;
1055   f << "which=" << nWhich << ",";
1056   if (nSlot) f << "slot=" << nSlot << ",";
1057   std::shared_ptr<StarItem> pItem;
1058   if (!m_state->isInRange(nWhich)) {
1059     uint16_t nSurro;
1060     *input >> nSurro;
1061     bool ok=true;
1062     if (nSurro==0xffff) {
1063       uint16_t nVersion, nLength;
1064       *input >> nVersion >> nLength;
1065       f << "nVersion=" << nVersion << ",";
1066       if (input->tell()+long(nLength)>endPos) {
1067         f << "###length=" << nLength << ",";
1068         STOFF_DEBUG_MSG(("StarItemPool::readItem: find bad surro length\n"));
1069         ok=false;
1070       }
1071       else if (nLength) {
1072         long endAttrPos=input->tell()+long(nLength);
1073         ascii.addDelimiter(input->tell(),'|');
1074         input->seek(endAttrPos, librevenge::RVNG_SEEK_SET);
1075       }
1076     }
1077     else if (nSurro)
1078       f << "surro=" << nSurro << ",";
1079     if (ok && input->tell()>endPos) {
1080       f << "###,";
1081       STOFF_DEBUG_MSG(("StarItemPool::readItem: find bad position\n"));
1082     }
1083     else if (ok)
1084       pItem.reset(new StarItem(StarAttributeManager::getDummyAttribute(), nWhich));
1085     ascii.addPos(pos);
1086     ascii.addNote(f.str().c_str());
1087     return pItem;
1088   }
1089 
1090   if (!isDirect) {
1091     if (nWhich)
1092       pItem=loadSurrogate(zone, nWhich, true, f);
1093     else {
1094       input->seek(2, librevenge::RVNG_SEEK_CUR);
1095       pItem.reset(new StarItem(StarAttributeManager::getDummyAttribute(), nWhich));
1096     }
1097   }
1098   if (isDirect || (nWhich && !pItem)) {
1099     uint16_t nVersion;
1100     uint32_t nLength;
1101     *input >> nVersion >> nLength;
1102     if (nVersion) f << "vers=" << nVersion << ",";
1103     if (input->tell()+long(nLength)>endPos) {
1104       f << "###length=" << nLength << ",";
1105       STOFF_DEBUG_MSG(("StarItemPool::readItem: find bad item\n"));
1106     }
1107     else if (nLength) {
1108       long endAttrPos=input->tell()+long(nLength);
1109       auto attribute=readAttribute(zone, int(nWhich), int(nVersion), endAttrPos);
1110       pItem.reset(new StarItem(attribute, nWhich));
1111       if (!attribute) {
1112         STOFF_DEBUG_MSG(("StarItemPool::readItem: can not read an attribute\n"));
1113         f << "###";
1114       }
1115       if (input->tell()!=endAttrPos) {
1116         ascii.addDelimiter(input->tell(),'|');
1117         input->seek(endAttrPos, librevenge::RVNG_SEEK_SET);
1118       }
1119     }
1120     if (pItem && input->tell()>endPos) {
1121       f << "###,";
1122       STOFF_DEBUG_MSG(("StarItemPool::readItem: find bad position\n"));
1123       pItem.reset();
1124     }
1125     ascii.addPos(pos);
1126     ascii.addNote(f.str().c_str());
1127     return pItem;
1128   }
1129   ascii.addPos(pos);
1130   ascii.addNote(f.str().c_str());
1131   return pItem;
1132 }
1133 
loadSurrogate(StarItem & item)1134 bool StarItemPool::loadSurrogate(StarItem &item)
1135 {
1136   if (item.m_attribute || !item.m_which)
1137     return false;
1138 
1139   if ((item.m_which<m_state->m_verStart||item.m_which>m_state->m_verEnd)&&m_state->m_secondaryPool)
1140     return m_state->m_secondaryPool->loadSurrogate(item);
1141   int aWhich=(item.m_localId && m_state->m_currentVersion!=m_state->m_loadingVersion) ?
1142              m_state->getWhich(item.m_which) : item.m_which;
1143   auto *values=m_state->getValues(aWhich);
1144   if (item.m_surrogateId==0xfffe) {
1145     // default
1146     if (!values || !values->m_default)
1147       item.m_attribute=m_state->getDefaultAttribute(aWhich);
1148     else
1149       item.m_attribute=values->m_default;
1150     return true;
1151   }
1152   if (!values || values->m_idValueMap.find(item.m_surrogateId)==values->m_idValueMap.end()) {
1153     STOFF_DEBUG_MSG(("StarItemPool::loadSurrogate: can not find the attribute array for %d[%d]\n", aWhich, item.m_surrogateId));
1154     item.m_attribute=m_state->getDefaultAttribute(aWhich);
1155     return true;
1156   }
1157   item.m_attribute=values->m_idValueMap.find(item.m_surrogateId)->second;
1158 
1159   return true;
1160 }
1161 
loadSurrogate(StarZone & zone,uint16_t & nWhich,bool localId,libstoff::DebugStream & f)1162 std::shared_ptr<StarItem> StarItemPool::loadSurrogate(StarZone &zone, uint16_t &nWhich, bool localId, libstoff::DebugStream &f)
1163 {
1164   if ((nWhich<m_state->m_verStart||nWhich>m_state->m_verEnd)&&m_state->m_secondaryPool)
1165     return m_state->m_secondaryPool->loadSurrogate(zone, nWhich, localId, f);
1166   // polio.cxx SfxItemPool::LoadSurrogate
1167   uint16_t nSurrog;
1168   *zone.input()>>nSurrog;
1169   if (nSurrog==0xffff) {
1170     f << "direct,";
1171     return std::shared_ptr<StarItem>();
1172   }
1173   if (nSurrog==0xfff0) {
1174     f << "null,";
1175     nWhich=0;
1176     return std::shared_ptr<StarItem>();
1177   }
1178   if (m_state->m_loadingVersion<0) // the pool is not read, so we wait
1179     return createItem(int(nWhich), int(nSurrog), localId);
1180   std::shared_ptr<StarItem> res(new StarItem(int(nWhich)));
1181   int aWhich=(localId && m_state->m_currentVersion!=m_state->m_loadingVersion) ?
1182              m_state->getWhich(nWhich) : nWhich;
1183   StarItemPoolInternal::Values *values=m_state->getValues(aWhich);
1184   if (nSurrog==0xfffe) {
1185     f << "default,";
1186     if (!values || !values->m_default) {
1187       if (!isInside() && m_state->m_document.getAttributeManager())
1188         res->m_attribute=m_state->getDefaultAttribute(aWhich);
1189       else // we must wait that the pool is read
1190         return createItem(int(nWhich), int(nSurrog), localId);
1191     }
1192     else
1193       res->m_attribute=values->m_default;
1194     return res;
1195   }
1196   f << "surrog=" << nSurrog << ",";
1197   if (!values || values->m_idValueMap.find(int(nSurrog))==values->m_idValueMap.end()) {
1198     if (isInside()) {
1199       // ok, we must wait that the pool is read
1200       return createItem(int(nWhich), int(nSurrog), localId);
1201     }
1202     STOFF_DEBUG_MSG(("StarItemPool::loadSurrogate: can not find the attribute array for %d[%d]\n", aWhich, int(nSurrog)));
1203     f << "###notFind,";
1204     res->m_attribute=m_state->getDefaultAttribute(aWhich);
1205     return res;
1206   }
1207   res->m_attribute=values->m_idValueMap.find(int(nSurrog))->second;
1208   return res;
1209 }
1210 
readV2(StarZone & zone,StarItemPool * master)1211 bool StarItemPool::readV2(StarZone &zone, StarItemPool *master)
1212 {
1213   STOFFInputStreamPtr input=zone.input();
1214   libstoff::DebugFile &ascii=zone.ascii();
1215   long endPos=zone.getRecordLevel()>0 ?  zone.getRecordLastPosition() : input->size();
1216   libstoff::DebugStream f;
1217   f << "Entries(PoolDef)["<< zone.getRecordLevel() << "]:";
1218   long pos=input->tell();
1219   if (master) {
1220     f << "secondary,";
1221     m_state->m_majorVersion=2;
1222     m_state->m_minorVersion=master->m_state->m_minorVersion;
1223   }
1224   else {
1225     if (pos+18>endPos) {
1226       STOFF_DEBUG_MSG(("StarItemPool::readV2: the zone seems too short\n"));
1227       return false;
1228     }
1229     uint16_t tag;
1230     // poolio.cxx SfxItemPool::Load
1231     uint8_t nMajorVers, nMinorVers;
1232     *input >> tag >> nMajorVers >> nMinorVers;
1233     if (tag==0x1111)
1234       f << "v4,";
1235     else if (tag==0xbbbb)
1236       f << "v5,";
1237     else {
1238       input->seek(pos, librevenge::RVNG_SEEK_SET);
1239       return false;
1240     }
1241 
1242     if (nMajorVers!=2) {
1243       input->seek(pos, librevenge::RVNG_SEEK_SET);
1244       return false;
1245     }
1246     *input>>tag;
1247     if (tag!=0xffff) {
1248       input->seek(pos, librevenge::RVNG_SEEK_SET);
1249       return false;
1250     }
1251 
1252     m_state->m_majorVersion=2;
1253     m_state->m_minorVersion=int(nMinorVers);
1254     f << "version=2,";
1255     if (m_state->m_minorVersion) f << "vers[minor]=" << m_state->m_minorVersion << ",";
1256     input->seek(4, librevenge::RVNG_SEEK_CUR); // 0,0
1257   }
1258   unsigned char type; // always 1
1259   if (input->peek()!=1 || !zone.openSfxRecord(type)) {
1260     STOFF_DEBUG_MSG(("StarItemPool::readV2: can not open the sfx record\n"));
1261     m_state->m_majorVersion=0;
1262     input->seek(pos, librevenge::RVNG_SEEK_SET);
1263     return false;
1264   }
1265 
1266   endPos=zone.getRecordLastPosition();
1267   if (input->tell()==endPos) {
1268     ascii.addPos(pos);
1269     ascii.addNote(f.str().c_str());
1270     zone.closeSfxRecord(type, "PoolDef");
1271     return true;
1272   }
1273   // string part
1274   unsigned char type1;
1275   if (input->peek()!=16 || !zone.openSfxRecord(type1)) {
1276     STOFF_DEBUG_MSG(("StarItemPool::readV2: can not open the string sfx record\n"));
1277     f << "###openString";
1278     ascii.addPos(pos);
1279     ascii.addNote(f.str().c_str());
1280     zone.closeSfxRecord(type, "PoolDef");
1281     return true;
1282   }
1283   int16_t val;
1284   *input >> val;
1285   if (val)
1286     f << "loadingVersion=" << val << ",";
1287   m_state->m_loadingVersion=val;
1288   std::vector<uint32_t> string;
1289   if (!zone.readString(string)) {
1290     STOFF_DEBUG_MSG(("StarItemPool::readV2: can not readV2 the name\n"));
1291     f << "###name";
1292   }
1293   if (!string.empty()) {
1294     m_state->setPoolName(libstoff::getString(string));
1295     f << "name[ext]=" << libstoff::getString(string).cstr() << ",";
1296   }
1297   zone.closeSfxRecord(type1, "PoolDef");
1298 
1299   ascii.addPos(pos);
1300   ascii.addNote(f.str().c_str());
1301 
1302   pos=input->tell();
1303   f.str("");
1304   f << "PoolDef[versMap]:";
1305   StarItemPoolInternal::SfxMultiRecord mRecord;
1306   if (!mRecord.open(zone) || mRecord.getHeaderTag()!=0x20) {
1307     STOFF_DEBUG_MSG(("StarItemPool::readV2: can not open the versionMap sfx record\n"));
1308     f << "###openVersionMap";
1309     ascii.addPos(pos);
1310     ascii.addNote(f.str().c_str());
1311     if (mRecord.isOpened()) mRecord.close("PoolDef");
1312     zone.closeSfxRecord(type, "PoolDef");
1313     return true;
1314   }
1315   f << mRecord;
1316   ascii.addPos(pos);
1317   ascii.addNote(f.str().c_str());
1318   int id;
1319   while (mRecord.getNewContent("PoolDef", id)) {
1320     pos=input->tell();
1321     f.str("");
1322     f << "PoolDef[versMap-" << id << "]:";
1323     uint16_t nVers, nStart, nEnd;
1324     *input >> nVers >> nStart >> nEnd;
1325     f << "vers=" << nVers << "," << nStart << "<->" << nEnd << ",";
1326     if (nStart>nEnd || input->tell()+2*(nEnd-nStart+1) > mRecord.getLastContentPosition()) {
1327       STOFF_DEBUG_MSG(("StarItemPool::readV2: can not find start|end pos\n"));
1328       f << "###badStartEnd";
1329       ascii.addPos(pos);
1330       ascii.addNote(f.str().c_str());
1331       break;
1332     }
1333     f << "pos=[";
1334     std::vector<int> listData;
1335     for (auto i=int(nStart); i<=int(nEnd); ++i) {
1336       uint16_t nPos;
1337       *input>>nPos;
1338       listData.push_back(int(nPos));
1339       f << nPos << ",";
1340     }
1341     f << "],";
1342     if (!listData.empty()) m_state->addVersionMap(nVers,nStart,listData);
1343 
1344     ascii.addPos(pos);
1345     ascii.addNote(f.str().c_str());
1346   }
1347   mRecord.close("PoolDef");
1348 
1349   for (int step=0; step<2; ++step) {
1350     std::string wh(step==0 ? "attrib" : "default");
1351     pos=input->tell();
1352     f.str("");
1353     f << "PoolDef[" << wh << "]:";
1354     if (!mRecord.open(zone)) {
1355       STOFF_DEBUG_MSG(("StarItemPool::readV2: can not open the sfx record\n"));
1356       f << "###" << wh;
1357       ascii.addPos(pos);
1358       ascii.addNote(f.str().c_str());
1359       zone.closeSfxRecord(type, "PoolDef");
1360       return true;
1361     }
1362     f << mRecord;
1363 
1364     if (mRecord.getHeaderTag()!=(step==0 ? 0x30:0x50)) {
1365       STOFF_DEBUG_MSG(("StarItemPool::readV2: can not find the pool which tag\n"));
1366       f << "###tag";
1367       ascii.addPos(pos);
1368       ascii.addNote(f.str().c_str());
1369       mRecord.close("PoolDef");
1370       continue;
1371     }
1372     ascii.addPos(pos);
1373     ascii.addNote(f.str().c_str());
1374 
1375     while (mRecord.getNewContent("PoolDef", id)) {
1376       pos=input->tell();
1377       f.str("");
1378       f << "PoolDef[" << wh << "-" << id << "]:";
1379       uint16_t nWhich, nVersion, nCount=1;
1380       *input >> nWhich >> nVersion;
1381       if (step==0) *input >> nCount;
1382       int which=nWhich;
1383       if (!m_state->isInRange(which)) {
1384         STOFF_DEBUG_MSG(("StarItemPool::readV2: the which value seems bad\n"));
1385         f << "###";
1386       }
1387       f << "wh=" << which << ",vers=" << nVersion << ",";
1388       if (step==0) f << "count=" << nCount << ",";
1389       ascii.addPos(pos);
1390       ascii.addNote(f.str().c_str());
1391       pos=input->tell();
1392       std::shared_ptr<StarAttribute> attribute;
1393       int aWhich=m_state->m_currentVersion!=m_state->m_loadingVersion ? m_state->getWhich(which) : which;
1394       StarItemPoolInternal::Values *values=m_state->getValues(aWhich, true);
1395       if (step==0) {
1396         if (!values->m_idValueMap.empty()) {
1397           STOFF_DEBUG_MSG(("StarItemPool::readV2: oops, there is already some attributes in values\n"));
1398         }
1399         StarItemPoolInternal::SfxMultiRecord mRecord1;
1400         f.str("");
1401         f << "Entries(StarAttribute):inPool,";
1402         if (!mRecord1.open(zone)) {
1403           STOFF_DEBUG_MSG(("StarItemPool::readV2: can not open record1\n"));
1404           f << "###record1";
1405           ascii.addPos(pos);
1406           ascii.addNote(f.str().c_str());
1407         }
1408         else {
1409           f << mRecord1;
1410           ascii.addPos(pos);
1411           ascii.addNote(f.str().c_str());
1412           while (mRecord1.getNewContent("StarAttribute", id)) {
1413             pos=input->tell();
1414             f.str("");
1415             f << "StarAttribute:inPool,wh=" <<  which << "[" << id << "],";
1416             uint16_t nRef;
1417             *input>>nRef;
1418             f << "ref=" << nRef << ",";
1419             attribute=readAttribute(zone, which, int(nVersion), mRecord1.getLastContentPosition());
1420             if (!attribute)
1421               f << "###";
1422             else if (input->tell()!=mRecord1.getLastContentPosition()) {
1423               STOFF_DEBUG_MSG(("StarItemPool::readV2: find extra attrib data\n"));
1424               f << "###extra";
1425             }
1426             if (values->m_idValueMap.find(id)!=values->m_idValueMap.end()) {
1427               STOFF_DEBUG_MSG(("StarItemPool::readV2: find dupplicated attrib data in %d\n", id));
1428               f << "###id";
1429             }
1430             else
1431               values->m_idValueMap[id]=attribute;
1432             input->seek(mRecord1.getLastContentPosition(), librevenge::RVNG_SEEK_SET);
1433             ascii.addPos(pos);
1434             ascii.addNote(f.str().c_str());
1435           }
1436           mRecord1.close("StarAttribute");
1437         }
1438       }
1439       else {
1440         if (values->m_default) {
1441           STOFF_DEBUG_MSG(("StarItemPool::readV2: the default slot %d is already created\n", aWhich));
1442         }
1443         attribute=readAttribute(zone, which, int(nVersion), mRecord.getLastContentPosition());
1444         if (!attribute) {
1445           f.str("");
1446           f << "Entries(StarAttribute)[" <<  which << "]:";
1447           ascii.addPos(pos);
1448           ascii.addNote(f.str().c_str());
1449         }
1450         else {
1451           values->m_default=attribute;
1452           if (input->tell()!=mRecord.getLastContentPosition()) {
1453             STOFF_DEBUG_MSG(("StarItemPool::readV2: find extra attrib data\n"));
1454             ascii.addPos(pos);
1455             ascii.addNote("extra###");
1456           }
1457         }
1458       }
1459       input->seek(mRecord.getLastContentPosition(), librevenge::RVNG_SEEK_SET);
1460     }
1461     mRecord.close("PoolDef");
1462   }
1463 
1464   zone.closeSfxRecord(type, "PoolDef");
1465   return true;
1466 }
1467 
readV1(StarZone & zone,StarItemPool *)1468 bool StarItemPool::readV1(StarZone &zone, StarItemPool * /*master*/)
1469 {
1470   STOFFInputStreamPtr input=zone.input();
1471   libstoff::DebugFile &ascii=zone.ascii();
1472   long endPos=zone.getRecordLevel()>0 ?  zone.getRecordLastPosition() : input->size();
1473   libstoff::DebugStream f;
1474   f << "Entries(PoolDef)[" << zone.getRecordLevel() << "]:";
1475   long pos=input->tell();
1476   if (pos+18>endPos) {
1477     STOFF_DEBUG_MSG(("StarItemPool::readV1: the zone seems too short\n"));
1478     return false;
1479   }
1480   uint16_t tag;
1481   // poolio.cxx SfxItemPool::Load1_Impl
1482   uint8_t nMajorVers, nMinorVers;
1483   *input >> tag >> nMajorVers >> nMinorVers;
1484   if (tag==0x1111)
1485     f << "v4,";
1486   else if (tag==0xbbbb)
1487     f << "v5,";
1488   else {
1489     input->seek(pos, librevenge::RVNG_SEEK_SET);
1490     return false;
1491   }
1492 
1493   if (nMajorVers!=1) {
1494     input->seek(pos, librevenge::RVNG_SEEK_SET);
1495     return false;
1496   }
1497   m_state->m_majorVersion=1;
1498   f << "version=" << int(nMajorVers) << ",vers[minor]=" << int(nMinorVers) << ",";
1499   if (nMinorVers>=3) {
1500     STOFF_DEBUG_MSG(("StarItemPool::readV1: find a minor version >= 3\n"));
1501     f << "###";
1502   }
1503 
1504   // SfxItemPool::Load1_Impl
1505   if (nMinorVers>=2) {
1506     int16_t nLoadingVersion;
1507     *input >> nLoadingVersion;
1508     m_state->m_loadingVersion=int(nLoadingVersion);
1509     if (nLoadingVersion) f << "vers[loading]=" << nLoadingVersion << ",";
1510   }
1511   else
1512     m_state->m_loadingVersion=0;
1513   std::vector<uint32_t> string;
1514   if (!zone.readString(string)) {
1515     STOFF_DEBUG_MSG(("StarItemPool::readV1: can not read the name\n"));
1516     f << "###name";
1517     ascii.addPos(pos);
1518     ascii.addNote(f.str().c_str());
1519     input->seek(pos, librevenge::RVNG_SEEK_SET);
1520     return false;
1521   }
1522   if (!string.empty()) {
1523     m_state->setPoolName(libstoff::getString(string));
1524     f << "name[ext]=" << libstoff::getString(string).cstr() << ",";
1525   }
1526   uint32_t attribSize;
1527   *input>>attribSize;
1528   long attribPos=input->tell();
1529   if (attribPos+long(attribSize)+10>endPos) {
1530     STOFF_DEBUG_MSG(("StarItemPool::readV1: attribSize is bad\n"));
1531     f << "###";
1532     ascii.addPos(pos);
1533     ascii.addNote(f.str().c_str());
1534     input->seek(pos, librevenge::RVNG_SEEK_SET);
1535     return false;
1536   }
1537   else if (attribSize) {
1538     f << "attr[sz]=" << attribSize << ",";
1539     input->seek(long(attribSize), librevenge::RVNG_SEEK_CUR);
1540   }
1541   else {
1542     STOFF_DEBUG_MSG(("StarItemPool::readV1: attribSize\n"));
1543     f << "###attrib[sz]==0,";
1544   }
1545 
1546   *input >> tag;
1547   if (tag!=0x3333) {
1548     STOFF_DEBUG_MSG(("StarItemPool::readV1: can not find tag size\n"));
1549     f << "###tag=" << std::hex << tag << std::dec;
1550     ascii.addPos(pos);
1551     ascii.addNote(f.str().c_str());
1552     input->seek(pos, librevenge::RVNG_SEEK_SET);
1553     return false;
1554   }
1555   uint32_t tableSize;
1556   *input>>tableSize;
1557   long tablePos=input->tell();
1558   long beginEndPos=tablePos+long(tableSize);
1559   if (beginEndPos+4>endPos) {
1560     STOFF_DEBUG_MSG(("StarItemPool::readV1: tableSize is bad\n"));
1561     f << "###";
1562     ascii.addPos(pos);
1563     ascii.addNote(f.str().c_str());
1564     input->seek(pos, librevenge::RVNG_SEEK_SET);
1565     return false;
1566   }
1567   else if (tableSize)
1568     f << "table[sz]=" << tableSize << ",";
1569   else if (nMinorVers>=3) {
1570     STOFF_DEBUG_MSG(("StarItemPool::readV1: tableSize is null for version 3\n"));
1571     f << "###table[sz]==0,";
1572   }
1573   ascii.addPos(pos);
1574   ascii.addNote(f.str().c_str());
1575 
1576   long endTablePos=tablePos+long(tableSize);
1577   if (nMinorVers>=3 && tableSize>=4) { // CHECKME: never seens
1578     input->seek(endTablePos-4, librevenge::RVNG_SEEK_SET);
1579     pos=long(input->readULong(4));
1580     endTablePos-=4;
1581     if (pos<tablePos || pos>=endTablePos) {
1582       STOFF_DEBUG_MSG(("StarItemPool::readV1: arrgh can not find versionmap position\n"));
1583     }
1584     else {
1585       long lastVersMapPos=endTablePos;
1586       endTablePos=pos;
1587       input->seek(pos, librevenge::RVNG_SEEK_SET);
1588       f.str("");
1589       f << "PoolDef[versionMap]:";
1590       uint16_t nVerCount;
1591       *input >> nVerCount;
1592       ascii.addPos(pos);
1593       ascii.addNote(f.str().c_str());
1594       for (int i=0; i<int(nVerCount); ++i) {
1595         pos=input->tell();
1596         f.str("");
1597         f << "PoolDef[versionMap" << i << "]:";
1598         uint16_t nVers, nStart, nEnd;
1599         *input >> nVers >> nStart >> nEnd;
1600         f << "vers=" << nVers << "," << nStart << "-" << nEnd << ",";
1601         int N=int(nEnd)+1-int(nStart);
1602         if (N<0 || pos+6+2*N>lastVersMapPos) {
1603           STOFF_DEBUG_MSG(("StarItemPool::readV1: arrgh nBytes is bad\n"));
1604           f << "###";
1605           ascii.addPos(pos);
1606           ascii.addNote(f.str().c_str());
1607           break;
1608         }
1609         f << "val=[";
1610         for (int j=0; j<N; ++j) {
1611           uint16_t val;
1612           *input >> val;
1613           if (val) f << val << ",";
1614           else
1615             f << "_,";
1616         }
1617         f << "],";
1618         ascii.addPos(pos);
1619         ascii.addNote(f.str().c_str());
1620       }
1621     }
1622   }
1623 
1624   // now read the table
1625   input->seek(tablePos, librevenge::RVNG_SEEK_SET);
1626   f.str("");
1627   f << "PoolDef[table]:";
1628   std::vector<uint32_t> sizeAttr;
1629   f << "size=[";
1630   while (input->tell()+4<=endTablePos) {
1631     uint32_t sz;
1632     *input>>sz;
1633     sizeAttr.push_back(sz);
1634     f << sz << ",";
1635   }
1636   f << "],";
1637   ascii.addPos(tablePos-6);
1638   ascii.addNote(f.str().c_str());
1639 
1640   // now read the attribute and default
1641   long endDataPos=attribPos+long(attribSize);
1642   size_t n=0;
1643   for (int step=0; step<2; ++step) {
1644     std::string const what(step==0 ? "attrib" : "default");
1645     f.str("");
1646     f << "PoolDef[" << what << "]:";
1647     if (step==1) {
1648       pos=input->tell();
1649       if (nMinorVers>0) {
1650         *input>>tag;
1651         if (tag!=0x4444) {
1652           STOFF_DEBUG_MSG(("StarItemPool::readV1: default tag is bad \n"));
1653           f << "###tag=" << std::hex << tag << std::dec;
1654           ascii.addPos(pos);
1655           ascii.addNote(f.str().c_str());
1656           break;
1657         }
1658       }
1659       ascii.addPos(pos);
1660       ascii.addNote(f.str().c_str());
1661     }
1662     else {
1663       input->seek(attribPos, librevenge::RVNG_SEEK_SET);
1664       if (attribSize!=0)  {
1665         *input >> tag;
1666         if (tag!=0x2222) {
1667           STOFF_DEBUG_MSG(("StarItemPool::readV1: tag is bad \n"));
1668           f << "###tag=" << std::hex << tag << std::dec;
1669           break;
1670         }
1671       }
1672       ascii.addPos(attribPos-4);
1673       ascii.addNote(f.str().c_str());
1674       if (attribSize==0) continue;
1675     }
1676     bool ok=true;
1677     while (ok) {
1678       pos=input->tell();
1679       f.str("");
1680       f << "PoolDef[" << what << "-" << n << "]:";
1681       if (pos+2 > endDataPos) {
1682         ok=false;
1683         STOFF_DEBUG_MSG(("StarItemPool::readV1: can not find some attrib\n"));
1684         f << "###noLast,";
1685         ascii.addPos(pos);
1686         ascii.addNote(f.str().c_str());
1687         break;
1688       }
1689       uint16_t nWhich;
1690       *input >> nWhich;
1691       if (nWhich==0) {
1692         ascii.addPos(pos);
1693         ascii.addNote(f.str().c_str());
1694         break;
1695       }
1696 
1697       uint16_t nSlot, nVersion, nCount=1;
1698       *input >> nSlot >> nVersion;
1699       if (step==0) *input >> nCount;
1700       int which=nWhich;
1701       // checkme: sometimes, we must use slot
1702       if (!m_state->isInRange(which)) {
1703         STOFF_DEBUG_MSG(("StarItemPool::readV1: the which value seems bad\n"));
1704         f << "###";
1705       }
1706       f << "wh=" << which << "[" << std::hex << nSlot << std::dec << "], vers=" << nVersion << ", count=" << nCount << ",";
1707       ascii.addPos(pos);
1708       ascii.addNote(f.str().c_str());
1709       int aWhich=m_state->m_currentVersion!=m_state->m_loadingVersion ? m_state->getWhich(which) : which;
1710       auto *values=m_state->getValues(aWhich, true);
1711       if (step==0 && nCount) {
1712         if (!values->m_idValueMap.empty()) {
1713           STOFF_DEBUG_MSG(("StarItemPool::readV1: the slot %d is already created\n", aWhich));
1714         }
1715       }
1716       else if (step==1) {
1717         if (values->m_default) {
1718           STOFF_DEBUG_MSG(("StarItemPool::readV1: the default slot %d is already created\n", aWhich));
1719         }
1720       }
1721       for (int i=0; i<nCount; ++i) {
1722         long debAttPos=(step==0 ? input->tell() : pos);
1723         pos=input->tell();
1724         f.str("");
1725         f << "StarAttribute:inPool,wh=" <<  which << "->" << aWhich << "[id=" << i << "],";
1726         if (n >= sizeAttr.size() || debAttPos+long(sizeAttr[n])>endDataPos ||
1727             input->tell()>debAttPos+long(sizeAttr[n])) {
1728           ok=false;
1729 
1730           STOFF_DEBUG_MSG(("StarItemPool::readV1: can not find attrib size\n"));
1731           f << "###badSize,";
1732           ascii.addPos(pos);
1733           ascii.addNote(f.str().c_str());
1734           break;
1735         }
1736         long endAttPos=debAttPos+long(sizeAttr[n]);
1737         std::shared_ptr<StarAttribute> attribute;
1738         if (input->tell()==endAttPos) {
1739           ascii.addPos(pos);
1740           ascii.addNote(f.str().c_str());
1741           if (step==0)
1742             values->m_idValueMap[i]=attribute;
1743           continue;
1744         }
1745 
1746         uint16_t nRef=1;
1747         if (step==0) {
1748           *input>>nRef;
1749           f << "ref=" << nRef << ",";
1750         }
1751         if (nRef) {
1752           attribute=readAttribute(zone, which, int(nVersion), debAttPos+long(sizeAttr[n]));
1753           if (!attribute)
1754             f << "###";
1755         }
1756         if (step==0)
1757           values->m_idValueMap[i]=attribute;
1758         else
1759           values->m_default=attribute;
1760         if (input->tell()!=debAttPos+long(sizeAttr[n])) {
1761           STOFF_DEBUG_MSG(("StarItemPool::readV1: find extra attrib data\n"));
1762           f << "###extra,";
1763           if (input->tell()!=pos)
1764             ascii.addDelimiter(input->tell(),'|');
1765           input->seek(debAttPos+long(sizeAttr[n]), librevenge::RVNG_SEEK_SET);
1766         }
1767         ascii.addPos(pos);
1768         ascii.addNote(f.str().c_str());
1769         ++n;
1770       }
1771     }
1772     if (!ok) break;
1773   }
1774 
1775   input->seek(beginEndPos, librevenge::RVNG_SEEK_SET);
1776   pos=input->tell();
1777   f.str("");
1778   f << "PoolDef[end]:";
1779   uint16_t tag1;
1780   *input >> tag >> tag1;
1781   if (tag!=0xeeee || tag1!=0xeeee) {
1782     STOFF_DEBUG_MSG(("StarItemPool::readV1: can not find end tag\n"));
1783     f << "###tag=" << std::hex << tag << std::dec;
1784     ascii.addPos(pos);
1785     ascii.addNote(f.str().c_str());
1786     input->seek(pos, librevenge::RVNG_SEEK_SET);
1787     return false;
1788   }
1789 
1790   ascii.addPos(pos);
1791   ascii.addNote(f.str().c_str());
1792   return true;
1793 }
1794 
readStyles(StarZone & zone,StarObject & doc)1795 bool StarItemPool::readStyles(StarZone &zone, StarObject &doc)
1796 {
1797   STOFFInputStreamPtr input=zone.input();
1798   libstoff::DebugFile &ascii=zone.ascii();
1799   long pos=input->tell();
1800   libstoff::DebugStream f;
1801   int poolVersion=input->peek()==3 ? 2 : 1;
1802   f << "Entries(SfxStylePool)[" << zone.getRecordLevel() << "]:pool[vers]=" << poolVersion << ",";
1803   unsigned char type=3; // to make clang analyzer happy
1804   uint16_t charSet=0, nCount;
1805 
1806   bool helpIdSize32=true, ok=true;
1807   StarItemPoolInternal::SfxMultiRecord mRecord;
1808   if (poolVersion==1) {
1809     // style.cxx SfxStyleSheetBasePool::Load1_Impl
1810     *input >> charSet;
1811     if (charSet==50) {
1812       f << "v50,";
1813       *input >> charSet;
1814     }
1815     else
1816       helpIdSize32=false;
1817     if (charSet) f << "char[set]="<< charSet << ",";
1818     *input >> nCount;
1819     f << "n=" << nCount << ",";
1820     ascii.addPos(pos);
1821     ascii.addNote(f.str().c_str());
1822   }
1823   else {
1824     // style.cxx SfxStyleSheetBasePool::Load(vers==2)
1825     if (input->peek()!=3 || !zone.openSfxRecord(type)) {
1826       STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not open the first zone\n"));
1827       input->seek(pos, librevenge::RVNG_SEEK_SET);
1828       return false;
1829     }
1830 
1831     ascii.addPos(pos);
1832     ascii.addNote(f.str().c_str());
1833 
1834     pos=input->tell();
1835     f.str("");
1836     f << "SfxStylePool[header]:";
1837     unsigned char type1;
1838     if (!zone.openSfxRecord(type1)) {
1839       STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not open the header zone\n"));
1840       f << "###";
1841       ascii.addPos(pos);
1842       ascii.addNote(f.str().c_str());
1843       zone.closeSfxRecord(type, "SfxStylePool");
1844       return false;
1845     }
1846     uint8_t headerType, headerVersion;
1847     uint16_t headerTag;
1848     *input >> headerType >> headerVersion >> headerTag;
1849     if (headerTag!=0x10) {
1850       STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not find header tag\n"));
1851       f << "###";
1852       ascii.addPos(pos);
1853       ascii.addNote(f.str().c_str());
1854       zone.closeSfxRecord(type1, "SfxStylePool");
1855       zone.closeSfxRecord(type, "SfxStylePool");
1856     }
1857     if (headerVersion) f << "vers=" << int(headerVersion) << ",";
1858     if (headerType) f << "type=" << int(headerType) << ",";
1859     *input >> charSet;
1860     if (charSet) f << "char[set]="<< charSet << ",";
1861     zone.closeSfxRecord(type1, "SfxStylePool");
1862     ascii.addPos(pos);
1863     ascii.addNote(f.str().c_str());
1864 
1865     pos=input->tell();
1866     f.str("");
1867     f << "SfxStylePool[styles]:";
1868     if (!mRecord.open(zone)) {
1869       STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not open the versionMap sfx record\n"));
1870       f << "###openVersionMap";
1871       ascii.addPos(pos);
1872       ascii.addNote(f.str().c_str());
1873       zone.closeSfxRecord(type, "PoolDef");
1874       return true;
1875     }
1876     f << mRecord;
1877 
1878     if (mRecord.getHeaderTag()!=0x20) {
1879       STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not find the version map tag\n"));
1880       f << "###tag";
1881       ok=false;
1882     }
1883     ascii.addPos(pos);
1884     ascii.addNote(f.str().c_str());
1885 
1886     nCount=mRecord.getNumRecords();
1887   }
1888   long lastPos=zone.getRecordLevel() ? zone.getRecordLastPosition() : input->size();
1889   for (int i=0; ok && i<int(nCount); ++i) {
1890     pos=input->tell();
1891     if (poolVersion==2) {
1892       int id=0;
1893       if (!mRecord.getNewContent("SfxStylePool", id))
1894         break;
1895       lastPos=mRecord.getLastContentPosition();
1896     }
1897     f.str("");
1898     f << "SfxStylePool[data" << i << "]:";
1899     bool readOk=true;
1900     std::vector<uint32_t> text;
1901     StarItemStyle style;
1902     for (int j=0; j<3; ++j) {
1903       if (!zone.readString(text, charSet) || input->tell()>=lastPos) {
1904         STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not find a string\n"));
1905         f << style << "###string" << j;
1906         readOk=false;
1907         break;
1908       }
1909       style.m_names[j]=libstoff::getString(text);
1910     }
1911     if (!readOk) {
1912       ascii.addPos(pos);
1913       ascii.addNote(f.str().c_str());
1914       if (poolVersion==1) return true;
1915       continue;
1916     }
1917     style.m_family=int(input->readULong(2));
1918     style.m_mask=int(input->readULong(2));
1919     if (!zone.readString(text, charSet) || input->tell()>=lastPos) {
1920       STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not find helpFile\n"));
1921       f << style << "###helpFile";
1922       ascii.addPos(pos);
1923       ascii.addNote(f.str().c_str());
1924       if (poolVersion==1) return true;
1925       continue;
1926     }
1927     style.m_names[3]=libstoff::getString(text);
1928     style.m_helpId=unsigned(input->readULong(helpIdSize32 ? 4 : 2));
1929     std::vector<STOFFVec2i> limits; // unknown
1930     if (!doc.readItemSet(zone, limits, lastPos, style.m_itemSet, this, false)) {
1931       f << style << "###itemList";
1932       ascii.addPos(pos);
1933       ascii.addNote(f.str().c_str());
1934       if (poolVersion==1) return true;
1935       continue;
1936     }
1937     StarItemPoolInternal::StyleId styleId(style.m_names[0], style.m_family);
1938     if (m_state->m_styleIdToStyleMap.find(styleId)!=m_state->m_styleIdToStyleMap.end()) {
1939       STOFF_DEBUG_MSG(("StarItemPool::readStyles: style %s-%d\n", style.m_names[0].cstr(), style.m_family));
1940     }
1941     else
1942       m_state->m_styleIdToStyleMap[styleId]=style;
1943     f << style;
1944     ascii.addDelimiter(input->tell(),'|');
1945     uint16_t nVer;
1946     uint32_t nSize;
1947     *input>>nVer>>nSize;
1948     if (nVer) f << "version=" << nVer << ",";
1949     if (input->tell()+long(nSize)>lastPos) {
1950       STOFF_DEBUG_MSG(("StarItemPool::readStyles: something is bad\n"));
1951       f << "###nSize=" << nSize << ",";
1952       ascii.addPos(pos);
1953       ascii.addNote(f.str().c_str());
1954       if (poolVersion==1) return true;
1955       continue;
1956     }
1957     if (nSize>=3 && m_state->m_type==StarItemPool::T_WriterPool) {
1958       // sw3style.cxx SwStyleSheet::Load
1959       long dataPos=input->tell(), endDataPos=dataPos+long(nSize);
1960       libstoff::DebugStream f2;
1961       f2 << "Entries(SwStyleSheet):sz=" << nSize << ",";
1962       auto nId=int(input->readULong(2));
1963       if (nId) f2 << "id=" << nId << ",";
1964       auto level=int(input->readULong(1));
1965       if (level!=201) {
1966         // checkme: sometimes is more complicated
1967         if (m_state->m_styleIdToStyleMap.find(styleId)!=m_state->m_styleIdToStyleMap.end())
1968           m_state->m_styleIdToStyleMap.find(styleId)->second.m_outlineLevel=level;
1969         f2 << "level=" << level << ",";
1970       }
1971       bool dataOk=true;
1972       if (1<=nVer) {
1973         /*if (nVer==1 && style.m_family==2 && nId==1)
1974           nId=(1<<11)+1; // RES_POOLCOLL_TEXT*/
1975         dataOk=input->tell()+2<=endDataPos;
1976         int val=dataOk ? int(input->readULong(2)) : 0;
1977         if (val==1) {
1978           f2 << "condCol,";
1979           dataOk=input->tell()+2<=endDataPos;
1980           int N=dataOk ? int(input->readULong(2)) : 0;
1981           if (N>255) N=255;
1982           for (int n=0; dataOk && n<N; ++n) {
1983             if (!zone.readString(text, charSet) || input->tell()+4>endDataPos) {
1984               dataOk=false;
1985               break;
1986             }
1987             f2 << "[" << libstoff::getString(text).cstr();
1988             auto cond=int(input->readULong(4));
1989             if (cond) f2 << "cond=" << std::hex << cond << std::dec << ",";
1990             if (cond & 0x8000) {
1991               if (!zone.readString(text, charSet) || input->tell()>endDataPos) {
1992                 dataOk=false;
1993                 break;
1994               }
1995               f2 << libstoff::getString(text).cstr() << ",";
1996             }
1997             else if (input->tell()+4<=endDataPos)
1998               f2 << "subCond=" << std::hex << input->readULong(4) << std::dec << ",";
1999             else
2000               dataOk=false;
2001             f2 << "]";
2002           }
2003         }
2004         int cFlag=0;
2005         if (dataOk && 4<=nVer) {
2006           dataOk=input->tell()+1<=endDataPos;
2007           cFlag=dataOk ? int(input->readULong(1)) : 0;
2008           if (cFlag) f2 << "cFlag=" << std::hex << cFlag << std::dec << ",";
2009         }
2010         if (nVer>=6 && (cFlag&2)) {
2011           dataOk=input->tell()+4<=endDataPos;
2012           long len=dataOk ? long(input->readULong(4)) : 0;
2013           dataOk=input->tell()+len<=endDataPos;
2014           if (dataOk && len>=2 && doc.getAttributeManager()) {
2015             auto nAttrVer=int(input->readULong(2));
2016             auto attrib=doc.getAttributeManager()->readAttribute
2017                         (zone, StarAttribute::ATTR_FRM_LR_SPACE, nAttrVer, endDataPos, doc);
2018             f2 << "LR,";
2019             if (!attrib || input->tell()>endDataPos) {
2020               STOFF_DEBUG_MSG(("StarItemPool::readStyles: reading relative LR is not implemented\n"));
2021               f2 << "###";
2022               dataOk=false;
2023             }
2024           }
2025           else if (len)
2026             dataOk=false;
2027         }
2028       }
2029       if (!dataOk) {
2030         f2 << "###";
2031         STOFF_DEBUG_MSG(("StarItemPool::readStyles: can not read some final data\n"));
2032       }
2033       if (input->tell()!=endDataPos) {
2034         if (!dataOk) {
2035           STOFF_DEBUG_MSG(("StarItemPool::readStyles:  find extra final data\n"));
2036           f << "###extra,";
2037         }
2038         ascii.addDelimiter(input->tell(),'|');
2039       }
2040       ascii.addPos(dataPos-4);
2041       ascii.addNote(f2.str().c_str());
2042       input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
2043     }
2044     else if (nSize) {
2045       f << "#size=" << nSize << ",";
2046       static bool first=true;
2047       if (first) {
2048         STOFF_DEBUG_MSG(("StarItemPool::readStyles: loading the base sheet data is not implemented\n"));
2049         first=false;
2050       }
2051       libstoff::DebugStream f2;
2052       f2 << "Entries(SfxBaseSheet):sz=" << nSize << ",###unknown";
2053       ascii.addPos(input->tell()-4);
2054       ascii.addNote(f2.str().c_str());
2055       ascii.addDelimiter(input->tell(),'|');
2056       input->seek(long(nSize), librevenge::RVNG_SEEK_CUR);
2057     }
2058     ascii.addPos(pos);
2059     ascii.addNote(f.str().c_str());
2060   }
2061 
2062   if (poolVersion==2) {
2063     mRecord.close("SfxStylePool");
2064     zone.closeSfxRecord(type, "SfxStylePool");
2065   }
2066   return true;
2067 }
2068 
updateStyles()2069 void StarItemPool::updateStyles()
2070 {
2071   std::set<StarItemPoolInternal::StyleId> done, toDo;
2072   std::multimap<StarItemPoolInternal::StyleId, StarItemPoolInternal::StyleId> childMap;
2073   std::map<int, std::shared_ptr<StarItem> >::const_iterator iIt;
2074   for (auto it : m_state->m_styleIdToStyleMap) {
2075     if (it.second.m_names[1].empty())
2076       toDo.insert(it.first);
2077     else {
2078       StarItemPoolInternal::StyleId parentId(it.second.m_names[1], it.first.m_family);
2079       // reset the parent name, as it must no longer be used when creating a styles...
2080       it.second.m_names[1].clear();
2081       if (m_state->m_styleIdToStyleMap.find(parentId)==m_state->m_styleIdToStyleMap.end()) {
2082         STOFF_DEBUG_MSG(("StarItemPool::updateStyles: can not find style %s-%d\n", parentId.m_name.cstr(), parentId.m_family));
2083       }
2084       else
2085         childMap.insert(std::multimap<StarItemPoolInternal::StyleId, StarItemPoolInternal::StyleId>::value_type(parentId, it.first));
2086     }
2087   }
2088   while (!toDo.empty()) {
2089     auto styleId=*toDo.begin();
2090     toDo.erase(styleId);
2091     if (done.find(styleId)!=done.end()) {
2092       STOFF_DEBUG_MSG(("StarItemPool::updateStyles: find loop for style %s-%d\n", styleId.m_name.cstr(), styleId.m_family));
2093       continue;
2094     }
2095     done.insert(styleId);
2096     auto it=m_state->m_styleIdToStyleMap.find(styleId);
2097     if (it==m_state->m_styleIdToStyleMap.end()) {
2098       STOFF_DEBUG_MSG(("StarItemPool::updateStyles: can not find style %s-%d\n", styleId.m_name.cstr(), styleId.m_family));
2099       continue;
2100     }
2101     StarItemSet const &parentItemSet=it->second.m_itemSet;
2102     auto cIt=childMap.lower_bound(styleId);
2103     while (cIt!=childMap.end() && cIt->first==styleId) {
2104       auto childId=cIt++->second;
2105       it=m_state->m_styleIdToStyleMap.find(childId);
2106       if (it==m_state->m_styleIdToStyleMap.end() || done.find(childId)!=done.end()) {
2107         STOFF_DEBUG_MSG(("StarItemPool::updateStyles: pb with style %s-%d\n", childId.m_name.cstr(), childId.m_family));
2108         continue;
2109       }
2110       toDo.insert(childId);
2111       auto &childItemSet=it->second.m_itemSet;
2112       for (iIt=parentItemSet.m_whichToItemMap.begin(); iIt!=parentItemSet.m_whichToItemMap.end(); ++iIt) {
2113         if (!iIt->second || childItemSet.m_whichToItemMap.find(iIt->first)!=childItemSet.m_whichToItemMap.end())
2114           continue;
2115         childItemSet.m_whichToItemMap[iIt->first]=iIt->second;
2116       }
2117     }
2118   }
2119   if (done.size()!=m_state->m_styleIdToStyleMap.size()) {
2120     STOFF_DEBUG_MSG(("StarItemPool::updateStyles: convert only %d of %d styles\n", int(done.size()), int(m_state->m_styleIdToStyleMap.size())));
2121   }
2122   /* Sometimes, the attribute encoding when reading style name seems
2123      bad (even in the lastest versions of LibreOffice which read sdc
2124      files), so create a map to try to retrieve the real style name
2125      from a bad encoded style name...
2126    */
2127   std::set<librevenge::RVNGString> dupplicatedSimpName;
2128   for (auto it : m_state->m_styleIdToStyleMap) {
2129     if (it.second.m_names[0].empty()) continue;
2130     auto simpName=libstoff::simplifyString(it.second.m_names[0]);
2131     if (it.second.m_names[0]==simpName || dupplicatedSimpName.find(simpName)!=dupplicatedSimpName.end()) continue;
2132     if (m_state->m_simplifyNameToStyleNameMap.find(simpName)==m_state->m_simplifyNameToStyleNameMap.end())
2133       m_state->m_simplifyNameToStyleNameMap[simpName]=it.second.m_names[0];
2134     else if (m_state->m_simplifyNameToStyleNameMap.find(simpName)->second!=it.second.m_names[0]) {
2135       dupplicatedSimpName.insert(simpName);
2136       m_state->m_simplifyNameToStyleNameMap.erase(simpName);
2137     }
2138   }
2139 }
2140 
findStyleWithFamily(librevenge::RVNGString const & style,int family) const2141 StarItemStyle const *StarItemPool::findStyleWithFamily(librevenge::RVNGString const &style, int family) const
2142 {
2143   if (style.empty())
2144     return nullptr;
2145   for (int step=0; step<2; ++step) {
2146     librevenge::RVNGString name(style);
2147     if (step==1) {
2148       // hack: try to retrieve the original style, ...
2149       librevenge::RVNGString simpName=libstoff::simplifyString(style);
2150       if (m_state->m_simplifyNameToStyleNameMap.find(simpName)==m_state->m_simplifyNameToStyleNameMap.end())
2151         break;
2152       name=m_state->m_simplifyNameToStyleNameMap.find(simpName)->second;
2153     }
2154     StarItemPoolInternal::StyleId styleId(name, 0);
2155     auto it=m_state->m_styleIdToStyleMap.lower_bound(styleId);
2156     while (it!=m_state->m_styleIdToStyleMap.end() && it->first.m_name==name) {
2157       if ((it->first.m_family&family)==family)
2158         return &it->second;
2159       ++it;
2160     }
2161   }
2162   STOFF_DEBUG_MSG(("StarItemPool::findStyleWithFamily: can not find with style %s-%d\n", style.cstr(), family));
2163   return nullptr;
2164 }
2165 
defineGraphicStyle(STOFFListenerPtr listener,librevenge::RVNGString const & styleName,StarObject & object,std::set<librevenge::RVNGString> & done) const2166 void StarItemPool::defineGraphicStyle(STOFFListenerPtr listener, librevenge::RVNGString const &styleName, StarObject &object, std::set<librevenge::RVNGString> &done) const
2167 {
2168   if (styleName.empty() || done.find(styleName)!=done.end())
2169     return;
2170   done.insert(styleName);
2171   if (listener->isGraphicStyleDefined(styleName))
2172     return;
2173   if (!listener) {
2174     STOFF_DEBUG_MSG(("StarItemPool::defineGraphicStyle: can not find the listener"));
2175     return;
2176   }
2177   auto const *style=findStyleWithFamily(styleName, StarItemStyle::F_Paragraph);
2178   if (!style) {
2179     STOFF_DEBUG_MSG(("StarItemPool::defineGraphicStyle: can not find graphic style with name %s", styleName.cstr()));
2180     return;
2181   }
2182   StarState state(this, object);
2183   state.m_frame.addTo(state.m_graphic.m_propertyList);
2184   state.m_graphic.m_propertyList.insert("style:display-name", styleName);
2185   if (!style->m_names[1].empty()) {
2186     if (done.find(style->m_names[1])!=done.end()) {
2187       STOFF_DEBUG_MSG(("StarItemPool::defineGraphicStyle: oops find a look with %s", style->m_names[1].cstr()));
2188     }
2189     else {
2190       defineGraphicStyle(listener, style->m_names[1], object, done);
2191       state.m_graphic.m_propertyList.insert("librevenge:parent-display-name", style->m_names[1]);
2192     }
2193   }
2194   for (auto it : style->m_itemSet.m_whichToItemMap) {
2195     if (it.second && it.second->m_attribute)
2196       it.second->m_attribute->addTo(state);
2197   }
2198   listener->defineStyle(state.m_graphic);
2199 }
2200 
defineParagraphStyle(STOFFListenerPtr listener,librevenge::RVNGString const & styleName,StarObject & object,std::set<librevenge::RVNGString> & done) const2201 void StarItemPool::defineParagraphStyle(STOFFListenerPtr listener, librevenge::RVNGString const &styleName, StarObject &object, std::set<librevenge::RVNGString> &done) const
2202 {
2203   if (styleName.empty() || done.find(styleName)!=done.end())
2204     return;
2205   done.insert(styleName);
2206   if (listener->isParagraphStyleDefined(styleName))
2207     return;
2208   if (!listener) {
2209     STOFF_DEBUG_MSG(("StarItemPool::defineParagraphStyle: can not find the listener"));
2210     return;
2211   }
2212   auto const *style=findStyleWithFamily(styleName, StarItemStyle::F_Paragraph);
2213   if (!style) {
2214     STOFF_DEBUG_MSG(("StarItemPool::defineParagraphStyle: can not find paragraph style with name %s", styleName.cstr()));
2215     return;
2216   }
2217   StarState state(this, object);
2218   if (style->m_outlineLevel>=0 && style->m_outlineLevel<20) {
2219     state.m_paragraph.m_outline=true;
2220     state.m_paragraph.m_listLevelIndex=style->m_outlineLevel+1;
2221   }
2222   state.m_paragraph.m_propertyList.insert("style:display-name", styleName);
2223   if (!style->m_names[1].empty()) {
2224     if (done.find(style->m_names[1])!=done.end()) {
2225       STOFF_DEBUG_MSG(("StarItemPool::defineParagraphStyle: oops find a look with %s", style->m_names[1].cstr()));
2226     }
2227     else {
2228       defineParagraphStyle(listener, style->m_names[1], object, done);
2229       state.m_paragraph.m_propertyList.insert("librevenge:parent-display-name", style->m_names[1]);
2230     }
2231   }
2232   for (auto it : style->m_itemSet.m_whichToItemMap) {
2233     if (it.second && it.second->m_attribute)
2234       it.second->m_attribute->addTo(state);
2235   }
2236   listener->defineStyle(state.m_paragraph);
2237 }
2238 
updateUsingStyles(StarItemSet & itemSet) const2239 void StarItemPool::updateUsingStyles(StarItemSet &itemSet) const
2240 {
2241   auto const *style=findStyleWithFamily(itemSet.m_style, itemSet.m_family);
2242   if (!style) return;
2243   auto const &parentItemSet=style->m_itemSet;
2244   for (auto it : parentItemSet.m_whichToItemMap) {
2245     if (!it.second || itemSet.m_whichToItemMap.find(it.first)!=itemSet.m_whichToItemMap.end())
2246       continue;
2247     itemSet.m_whichToItemMap[it.first]=it.second;
2248   }
2249 }
2250 
2251 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
2252