1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* libwps
3 * Version: MPL 2.0 / LGPLv2.1+
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * Major Contributor(s):
10 * Copyright (C) 2003 William Lachance (william.lachance@sympatico.ca)
11 * Copyright (C) 2003-2004 Marc Maurer (uwog@uwog.net)
12 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
13 * Copyright (C) 2006, 2007 Andrew Ziem (andrewziem users sourceforge net)
14 *
15 * For minor contributions see the git repository.
16 *
17 * Alternatively, the contents of this file may be used under the terms
18 * of the GNU Lesser General Public License Version 2.1 or later
19 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
20 * applicable instead of those above.
21 *
22 * For further information visit http://libwps.sourceforge.net
23 */
24
25 #include <libwps/libwps.h>
26 #include "WKS4.h"
27 #include "WPS4.h"
28 #include "WPS8.h"
29 #include "WPSHeader.h"
30 #include "WPSParser.h"
31 #include "libwps_internal.h"
32
33 using namespace libwps;
34
35 /**
36 \mainpage libwps documentation
37 This document contains both the libwps API specification and the normal libwps
38 documentation.
39 \section api_docs libwps API documentation
40 The external libwps API is provided by the WPSDocument class. This class, combined
41 with the librevenge's librevenge::RVNGTextInterface class, are the only two classes that will be
42 of interest for the application programmer using libwps.
43 \section lib_docs libwps documentation
44 If you are interrested in the structure of libwps itself, this whole document
45 would be a good starting point for exploring the interals of libwps. Mind that
46 this document is a work-in-progress, and will most likely not cover libwps for
47 the full 100%.
48
49 \warning When compiled with -DDEBUG_WITH__FILES, code is added to store the results of the parsing in different files: one file by Ole parts and some files to store the read pictures. These files are created in the current repository, therefore it is recommended to launch the tests in an empty repository...*/
50
51 /**
52 Analyzes the content of an input stream to see if it can be parsed
53 \param ip The input stream
54 \param kind The document kind
55 \return A confidence value which represents the likelyhood that the content from
56 the input stream can be parsed
57 */
isFileFormatSupported(librevenge::RVNGInputStream * ip,WPSKind & kind)58 WPSLIB WPSConfidence WPSDocument::isFileFormatSupported(librevenge::RVNGInputStream *ip, WPSKind &kind)
59 {
60 WPS_DEBUG_MSG(("WPSDocument::isFileFormatSupported()\n"));
61
62 if (!ip)
63 return WPS_CONFIDENCE_NONE;
64
65 kind=WPS_TEXT;
66 WPSHeaderPtr header;
67 shared_ptr<librevenge::RVNGInputStream > input(ip, WPS_shared_ptr_noop_deleter<librevenge::RVNGInputStream>());
68 try
69 {
70 header.reset(WPSHeader::constructHeader(input));
71
72 if (!header)
73 return WPS_CONFIDENCE_NONE;
74 kind = header->getKind();
75
76 WPSConfidence confidence = WPS_CONFIDENCE_NONE;
77 if (kind==WPS_TEXT && header->getMajorVersion()<=4)
78 {
79 // create a WPS4Parser to check the header validity
80 WPS4Parser parser(header->getInput(), header);
81 if (!parser.checkHeader(header.get(), true))
82 return WPS_CONFIDENCE_NONE;
83 return WPS_CONFIDENCE_EXCELLENT;
84 }
85 else if (kind==WPS_SPREADSHEET || kind==WPS_DATABASE)
86 {
87 // create a WKS4Parser to check the header validity
88 WKS4Parser parser(header->getInput(), header);
89 if (!parser.checkHeader(header.get(), true))
90 return WPS_CONFIDENCE_NONE;
91 return WPS_CONFIDENCE_EXCELLENT;
92 }
93
94 /* A word document: as WPS8Parser does not have a checkHeader
95 function, only rely on the version
96 */
97 switch (header->getMajorVersion())
98 {
99 case 8:
100 case 7:
101 case 5:
102 confidence = WPS_CONFIDENCE_EXCELLENT;
103 break;
104 default:
105 break;
106 }
107 return confidence;
108 }
109 catch (libwps::FileException)
110 {
111 WPS_DEBUG_MSG(("File exception trapped\n"));
112 }
113 catch (libwps::ParseException)
114 {
115 WPS_DEBUG_MSG(("Parse exception trapped\n"));
116 }
117 catch (...)
118 {
119 //fixme: too generic
120 WPS_DEBUG_MSG(("Unknown Exception trapped\n"));
121 }
122
123 return WPS_CONFIDENCE_NONE;
124 }
125
126 /**
127 Parses the input stream content. It will make callbacks to the functions provided by a
128 librevenge::RVNGTextInterface class implementation when needed. This is often commonly called the
129 'main parsing routine'.
130 \param ip The input stream
131 \param documentInterface A WPSListener implementation
132 */
parse(librevenge::RVNGInputStream * ip,librevenge::RVNGTextInterface * documentInterface)133 WPSLIB WPSResult WPSDocument::parse(librevenge::RVNGInputStream *ip, librevenge::RVNGTextInterface *documentInterface)
134 {
135 if (!ip || !documentInterface)
136 return WPS_UNKNOWN_ERROR;
137
138 WPSResult error = WPS_OK;
139
140 WPSHeaderPtr header;
141 shared_ptr<WPSParser> parser;
142 shared_ptr<librevenge::RVNGInputStream > input(ip, WPS_shared_ptr_noop_deleter<librevenge::RVNGInputStream>());
143 try
144 {
145 header.reset(WPSHeader::constructHeader(input));
146
147 if (!header || header->getKind() != WPS_TEXT)
148 return WPS_UNKNOWN_ERROR;
149
150 switch (header->getMajorVersion())
151 {
152 case 8:
153 case 7:
154 case 6:
155 case 5:
156 {
157 parser.reset(new WPS8Parser(header->getInput(), header));
158 if (!parser) return WPS_UNKNOWN_ERROR;
159 parser->parse(documentInterface);
160 break;
161 }
162
163 case 4:
164 case 3:
165 case 2:
166 case 1:
167 {
168 parser.reset(new WPS4Parser(header->getInput(), header));
169 if (!parser) return WPS_UNKNOWN_ERROR;
170 parser->parse(documentInterface);
171 break;
172 }
173 default:
174 break;
175 }
176 }
177 catch (libwps::FileException)
178 {
179 WPS_DEBUG_MSG(("File exception trapped\n"));
180 error = WPS_FILE_ACCESS_ERROR;
181 }
182 catch (libwps::ParseException)
183 {
184 WPS_DEBUG_MSG(("Parse exception trapped\n"));
185 error = WPS_PARSE_ERROR;
186 }
187 catch (...)
188 {
189 //fixme: too generic
190 WPS_DEBUG_MSG(("Unknown exception trapped\n"));
191 error = WPS_UNKNOWN_ERROR;
192 }
193
194 return error;
195 }
196
197 /**
198 Parses the input stream content. It will make callbacks to the functions provided by a
199 librevenge::RVNGSpreadsheetInterface class implementation when needed. This is often commonly called the
200 'main parsing routine'.
201 \param ip The input stream
202 \param documentInterface A SpreadsheetInterface implementation
203 */
parse(librevenge::RVNGInputStream * ip,librevenge::RVNGSpreadsheetInterface * documentInterface)204 WPSLIB WPSResult WPSDocument::parse(librevenge::RVNGInputStream *ip, librevenge::RVNGSpreadsheetInterface *documentInterface)
205 {
206 if (!ip || !documentInterface)
207 return WPS_UNKNOWN_ERROR;
208
209 WPSResult error = WPS_OK;
210
211 WPSHeaderPtr header;
212 shared_ptr<WKSParser> parser;
213 shared_ptr<librevenge::RVNGInputStream > input(ip, WPS_shared_ptr_noop_deleter<librevenge::RVNGInputStream>());
214 try
215 {
216 header.reset(WPSHeader::constructHeader(input));
217
218 if (!header || (header->getKind() != WPS_SPREADSHEET && header->getKind() != WPS_DATABASE))
219 return WPS_UNKNOWN_ERROR;
220
221 switch (header->getMajorVersion())
222 {
223 case 4:
224 case 3:
225 case 2:
226 case 1:
227 {
228 parser.reset(new WKS4Parser(header->getInput(), header));
229 if (!parser) return WPS_UNKNOWN_ERROR;
230 parser->parse(documentInterface);
231 break;
232 }
233 default:
234 break;
235 }
236 }
237 catch (libwps::FileException)
238 {
239 WPS_DEBUG_MSG(("File exception trapped\n"));
240 error = WPS_FILE_ACCESS_ERROR;
241 }
242 catch (libwps::ParseException)
243 {
244 WPS_DEBUG_MSG(("Parse exception trapped\n"));
245 error = WPS_PARSE_ERROR;
246 }
247 catch (...)
248 {
249 //fixme: too generic
250 WPS_DEBUG_MSG(("Unknown exception trapped\n"));
251 error = WPS_UNKNOWN_ERROR;
252 }
253
254 return error;
255 }
256 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
257