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 /*
35  * StarZone zone of StarOffice document
36  *
37  */
38 #ifndef STAR_ZONE
39 #  define STAR_ZONE
40 
41 #include <vector>
42 #include <stack>
43 
44 #include "libstaroffice_internal.hxx"
45 
46 #include "STOFFDebug.hxx"
47 #include "StarEncoding.hxx"
48 
49 class StarEncryption;
50 
51 /** \brief a zone in a StarOffice file
52  *
53  *
54  *
55  */
56 class StarZone
57 {
58 public:
59   //! constructor
60   StarZone(STOFFInputStreamPtr const &input, std::string const &ascName, std::string const &zoneName, char const *password);
61   //! destructor
62   virtual ~StarZone();
63   //! read the zone header present in a SW file
64   bool readSWHeader();
65 
66   //! check encryption
67   bool checkEncryption(uint32_t date, uint32_t time, std::vector<uint8_t> const &passwd);
68   //! open a zone header present in a SDR file
69   bool openSDRHeader(std::string &magic);
70   //! close a zone header
71   bool closeSDRHeader(std::string const &debugName);
72 
73   //! open a zone header present in a SCH file
74   bool openSCHHeader();
75   //! close a zone header
76   bool closeSCHHeader(std::string const &debugName);
77 
78   //! open a version compat header (version+size)
79   bool openVersionCompatHeader();
80   //! close a zone header
81   bool closeVersionCompatHeader(std::string const &debugName);
82 
83   //! returns the StarOffice version: 3-5
getVersion() const84   int getVersion() const
85   {
86     return m_version;
87   }
88   //! returns the StarOffice document version
getDocumentVersion() const89   int getDocumentVersion() const
90   {
91     return m_documentVersion;
92   }
93   //! returns the StarOffice header version (if set)
getHeaderVersion() const94   int getHeaderVersion() const
95   {
96     return m_headerVersionStack.empty() ? 0 : m_headerVersionStack.top();
97   }
98   //! checks if the document is compatible with vers
isCompatibleWith(int vers) const99   int isCompatibleWith(int vers) const
100   {
101     return m_documentVersion>=vers;
102   }
103   //! checks if the document is compatible with vers1 and not vers2
isCompatibleWith(int vers1,int vers2) const104   int isCompatibleWith(int vers1, int vers2) const
105   {
106     return m_documentVersion>=vers1 && m_documentVersion<vers2;
107   }
108   //! checks if the document is compatible with vers1 and not vers2 or vers3
isCompatibleWith(int vers1,int vers2,int vers3) const109   int isCompatibleWith(int vers1, int vers2, int vers3) const
110   {
111     return (m_documentVersion>=vers1 && m_documentVersion<vers2) ||
112            m_documentVersion>=vers3;
113   }
114   //! checks if the document is compatible with vers1 and not vers2 or vers3 and not vers4
isCompatibleWith(int vers1,int vers2,int vers3,int vers4) const115   int isCompatibleWith(int vers1, int vers2, int vers3, int vers4) const
116   {
117     return (m_documentVersion>=vers1 && m_documentVersion<vers2) ||
118            (m_documentVersion>=vers3 && m_documentVersion<vers4);
119   }
120   //! returns the zone encoding
getEncoding() const121   StarEncoding::Encoding getEncoding() const
122   {
123     return m_encoding;
124   }
125   //! sets the zone encoding
setEncoding(StarEncoding::Encoding encod)126   void setEncoding(StarEncoding::Encoding encod)
127   {
128     m_encoding=encod;
129   }
130   //! returns the zone GUI type
getGuiType() const131   int getGuiType() const
132   {
133     return m_guiType;
134   }
135   //! sets the zone GUI type
setGuiType(int type)136   void setGuiType(int type)
137   {
138     m_guiType=type;
139   }
140   //
141   // basic
142   //
143 
144   //! try to open a classic record: size (32 bytes) +  size-4 bytes
145   bool openRecord();
146   //! try to close a record
closeRecord(std::string const & debugName)147   bool closeRecord(std::string const &debugName)
148   {
149     return closeRecord(' ', debugName);
150   }
151   //! open a dummy record
152   bool openDummyRecord();
153   //! close a dummy record
closeDummyRecord()154   bool closeDummyRecord()
155   {
156     return closeRecord('@', "Entries(BadDummy)");
157   }
158   //
159   // sc record
160   //
161 
162   //! try to open a SC record: size (32 bytes) + size bytes
163   bool openSCRecord();
164   //! try to close a record
closeSCRecord(std::string const & debugName)165   bool closeSCRecord(std::string const &debugName)
166   {
167     return closeRecord('_', debugName);
168   }
169 
170   //
171   // sw record
172   //
173 
174   //! try to open a SW record: type + size (24 bytes)
175   bool openSWRecord(unsigned char &type);
176   //! try to close a record
closeSWRecord(unsigned char type,std::string const & debugName)177   bool closeSWRecord(unsigned char type, std::string const &debugName)
178   {
179     return closeRecord(type, debugName);
180   }
181 
182   //
183   // sfx record
184   //
185 
186   //! try to open a Sfx record: type + size (24 bytes)
187   bool openSfxRecord(unsigned char &type);
188   //! try to close a record
closeSfxRecord(unsigned char type,std::string const & debugName)189   bool closeSfxRecord(unsigned char type, std::string const &debugName)
190   {
191     return closeRecord(type, debugName);
192   }
193 
194   //! returns the record level
getRecordLevel() const195   int getRecordLevel() const
196   {
197     return int(m_positionStack.size());
198   }
199   //! returns the actual record last position
getRecordLastPosition() const200   long getRecordLastPosition() const
201   {
202     if (m_positionStack.empty()) {
203       STOFF_DEBUG_MSG(("StarZone::getRecordLastPosition: can not find last position\n"));
204       return 0;
205     }
206     return m_positionStack.top();
207   }
208 
209   //! try to open a cflag zone
210   unsigned char openFlagZone();
211   //! close the cflag zone
212   void closeFlagZone();
213   //! returns the flag last position
getFlagLastPosition() const214   long getFlagLastPosition() const
215   {
216     return m_flagEndZone;
217   }
218 
219   //! try to read an unicode string
readString(std::vector<uint32_t> & string,int encoding=-1) const220   bool readString(std::vector<uint32_t> &string, int encoding=-1) const
221   {
222     std::vector<size_t> srcPositions;
223     return readString(string, srcPositions, encoding);
224   }
225   //! try to read an unicode string
226   bool readString(std::vector<uint32_t> &string, std::vector<size_t> &srcPositions, int encoding=-1, bool checkEncryption=false) const;
227   //! try to read a pool of strings
228   bool readStringsPool();
229   //! return the number of pool name
getNumPoolNames() const230   int getNumPoolNames() const
231   {
232     return int(m_poolList.size());
233   }
234   //! try to return a pool name
getPoolName(int poolId,librevenge::RVNGString & res) const235   bool getPoolName(int poolId, librevenge::RVNGString &res) const
236   {
237     res="";
238     if (poolId>=0 && poolId<int(m_poolList.size())) {
239       res=m_poolList[size_t(poolId)];
240       return true;
241     }
242     if (poolId==0xFFF0) return true;
243     STOFF_DEBUG_MSG(("StarZone::getPoolName: can not find pool name for %d\n", poolId));
244     return false;
245   }
246   //! return the zone input
input()247   STOFFInputStreamPtr input()
248   {
249     return m_input;
250   }
251   //! reset the current input
252   void setInput(STOFFInputStreamPtr input);
253   //! returns the ascii file
ascii()254   libstoff::DebugFile &ascii()
255   {
256     return m_ascii;
257   }
258   //! return the zone name
name() const259   std::string const &name() const
260   {
261     return m_zoneName;
262   }
263 protected:
264   //
265   // low level
266   //
267 
268   //! try to read the record sizes
269   bool readRecordSizes(long pos);
270   //! try to close a record
271   bool closeRecord(unsigned char type, std::string const &debugName);
272 
273   //
274   // data
275   //
276 
277   //! the input stream
278   STOFFInputStreamPtr m_input;
279   //! the ascii zone
280   libstoff::DebugFile m_ascii;
281   //! the zone version
282   int m_version;
283   //! the document version
284   int m_documentVersion;
285   //! the header version (for SDR zone)
286   std::stack<int> m_headerVersionStack;
287   //! the zone encoding
288   StarEncoding::Encoding m_encoding;
289   //! the zone GUI type
290   int m_guiType;
291   //! the encryption
292   std::shared_ptr<StarEncryption> m_encryption;
293   //! the file ascii name
294   std::string m_asciiName;
295   //! the zone name
296   std::string m_zoneName;
297 
298   //! the type stack
299   std::stack<unsigned char> m_typeStack;
300   //! the position stack
301   std::stack<long> m_positionStack;
302   //! other position to end position zone
303   std::map<long, long> m_beginToEndMap;
304   //! end of a cflags zone
305   long m_flagEndZone;
306 
307   //! the pool name list
308   std::vector<librevenge::RVNGString> m_poolList;
309 };
310 #endif
311 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
312