Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef BOOTSTRP_XMLPARSE_HXX
21 : #define BOOTSTRP_XMLPARSE_HXX
22 :
23 : #include "sal/config.h"
24 :
25 : #include <cstddef>
26 : #include <vector>
27 :
28 : #include <signal.h>
29 :
30 : #include <libxml/xmlexports.h> // define XMLCALL so expat.h does not redefine it
31 : #include <expat.h>
32 :
33 : #include <rtl/ustring.hxx>
34 : #include <rtl/ustrbuf.hxx>
35 : #include "boost/unordered_map.hpp"
36 : #include "export.hxx"
37 :
38 : class XMLParentNode;
39 : class XMLElement;
40 :
41 :
42 : using namespace ::rtl;
43 : using namespace std;
44 :
45 : #define XML_NODE_TYPE_FILE 0x001
46 : #define XML_NODE_TYPE_ELEMENT 0x002
47 : #define XML_NODE_TYPE_DATA 0x003
48 : #define XML_NODE_TYPE_COMMENT 0x004
49 : #define XML_NODE_TYPE_DEFAULT 0x005
50 :
51 :
52 : //-------------------------------------------------------------------------
53 :
54 : /** Holds data of Attributes
55 : */
56 0 : class XMLAttribute
57 : {
58 : private:
59 : OUString sName;
60 : OUString sValue;
61 :
62 : public:
63 : /// creates an attribute
64 0 : XMLAttribute(
65 : const OUString &rName, // attributes name
66 : const OUString &rValue // attributes data
67 : )
68 0 : : sName( rName ), sValue( rValue ) {}
69 :
70 0 : OUString GetName() const { return sName; }
71 0 : OUString GetValue() const { return sValue; }
72 :
73 0 : void setValue(const OUString &rValue){sValue=rValue;}
74 :
75 : /// returns true if two attributes are equal and have the same value
76 : sal_Bool IsEqual(
77 : const XMLAttribute &rAttribute // the attribute which has to be equal
78 : )
79 : {
80 : return (( rAttribute.sName == sName ) && ( rAttribute.sValue == sValue ));
81 : }
82 : };
83 :
84 : typedef std::vector< XMLAttribute* > XMLAttributeList;
85 :
86 : //-------------------------------------------------------------------------
87 :
88 : /** Virtual base to handle different kinds of XML nodes
89 : */
90 0 : class XMLNode
91 : {
92 : protected:
93 0 : XMLNode() {}
94 :
95 : public:
96 : virtual sal_uInt16 GetNodeType() = 0;
97 0 : virtual ~XMLNode() {}
98 : };
99 :
100 : //-------------------------------------------------------------------------
101 :
102 : /** Virtual base to handle different kinds of child nodes
103 : */
104 : class XMLChildNode : public XMLNode
105 : {
106 : private:
107 : XMLParentNode *pParent;
108 :
109 : protected:
110 : XMLChildNode( XMLParentNode *pPar );
111 : XMLChildNode():pParent( NULL ){};
112 : XMLChildNode( const XMLChildNode& obj);
113 : XMLChildNode& operator=(const XMLChildNode& obj);
114 : public:
115 : virtual sal_uInt16 GetNodeType() = 0;
116 :
117 : /// returns the parent of this node
118 0 : XMLParentNode *GetParent() { return pParent; }
119 0 : virtual ~XMLChildNode(){};
120 : };
121 :
122 : typedef std::vector< XMLChildNode* > XMLChildNodeList;
123 :
124 : //-------------------------------------------------------------------------
125 :
126 : class XMLData;
127 :
128 : /** Virtual base to handle different kinds of parent nodes
129 : */
130 :
131 : class XMLParentNode : public XMLChildNode
132 : {
133 : private:
134 : XMLChildNodeList* pChildList;
135 : static int dbgcnt;
136 :
137 : protected:
138 0 : XMLParentNode( XMLParentNode *pPar )
139 0 : : XMLChildNode( pPar ), pChildList( NULL )
140 : {
141 0 : }
142 : XMLParentNode(): pChildList(NULL){
143 : }
144 :
145 : XMLParentNode( const XMLParentNode& );
146 :
147 : XMLParentNode& operator=(const XMLParentNode& obj);
148 : virtual ~XMLParentNode();
149 :
150 :
151 : public:
152 : virtual sal_uInt16 GetNodeType() = 0;
153 :
154 : /// returns child list of this node
155 0 : XMLChildNodeList *GetChildList() { return pChildList; }
156 :
157 : /// adds a new child
158 : void AddChild(
159 : XMLChildNode *pChild /// the new child
160 : );
161 :
162 : void RemoveAndDeleteAllChildren();
163 : };
164 :
165 : //-------------------------------------------------------------------------
166 :
167 : /// Mapping numeric Language code <-> XML Element
168 : typedef boost::unordered_map<OString, XMLElement*, OStringHash> LangHashMap;
169 :
170 : /// Mapping XML Element string identifier <-> Language Map
171 : typedef boost::unordered_map<OString, LangHashMap*, OStringHash> XMLHashMap;
172 :
173 : /// Mapping iso alpha string code <-> iso numeric code
174 : typedef boost::unordered_map<OString, int, OStringHash> HashMap;
175 :
176 : /// Mapping XML tag names <-> have localizable strings
177 : typedef boost::unordered_map<OString, sal_Bool, OStringHash> TagMap;
178 :
179 : /** Holds information of a XML file, is root node of tree
180 : */
181 :
182 : class XMLFile : public XMLParentNode
183 : {
184 : public:
185 : XMLFile(
186 : const OUString &rFileName // the file name, empty if created from memory stream
187 : );
188 : XMLFile( const XMLFile& obj ) ;
189 : ~XMLFile();
190 :
191 : void Print( XMLNode *pCur = NULL, sal_uInt16 nLevel = 0 );
192 : virtual void SearchL10NElements( XMLParentNode *pCur, int pos = 0 );
193 : void Extract( XMLFile *pCur = NULL );
194 :
195 0 : XMLHashMap* GetStrings(){return XMLStrings;}
196 : void Write( OString const &rFilename );
197 : sal_Bool Write( ofstream &rStream , XMLNode *pCur = NULL );
198 :
199 : bool CheckExportStatus( XMLParentNode *pCur = NULL );// , int pos = 0 );
200 :
201 : XMLFile& operator=(const XMLFile& obj);
202 :
203 : virtual sal_uInt16 GetNodeType();
204 :
205 : /// returns file name
206 0 : OUString GetName() { return sFileName; }
207 0 : void SetName( const OUString &rFilename ) { sFileName = rFilename; }
208 0 : const std::vector<OString> getOrder(){ return order; }
209 :
210 : protected:
211 : /// writes a string as UTF8 with dos line ends to a given stream
212 : void WriteString( ofstream &rStream, const OUString &sString );
213 :
214 : void InsertL10NElement( XMLElement* pElement);
215 :
216 : // DATA
217 : OUString sFileName;
218 :
219 : const OString ID, OLDREF, XML_LANG;
220 :
221 : TagMap nodes_localize;
222 : XMLHashMap* XMLStrings;
223 :
224 : std::vector <OString> order;
225 : };
226 :
227 : /// An Utility class for XML
228 : class XMLUtil{
229 :
230 : public:
231 : /// Quot the XML characters
232 : static OUString QuotHTML( const OUString& rString );
233 :
234 : /// UnQuot the XML characters
235 : static OUString UnQuotHTML( const OUString &rString );
236 : };
237 :
238 :
239 : //-------------------------------------------------------------------------
240 :
241 : /** Hold information of an element node
242 : */
243 : class XMLElement : public XMLParentNode
244 : {
245 : private:
246 : OUString sElementName;
247 : XMLAttributeList *pAttributes;
248 : OString project,
249 : filename,
250 : id,
251 : sOldRef,
252 : resourceType,
253 : languageId;
254 : int nPos;
255 :
256 : protected:
257 : void Print(XMLNode *pCur, OUStringBuffer& buffer , bool rootelement);
258 : public:
259 : /// create an element node
260 : XMLElement(){}
261 0 : XMLElement(
262 : const OUString &rName, // the element name
263 : XMLParentNode *Parent // parent node of this element
264 : ): XMLParentNode( Parent ),
265 : sElementName( rName ),
266 : pAttributes( NULL ),
267 : project(""),
268 : filename(""),
269 : id(""),
270 : sOldRef(""),
271 : resourceType(""),
272 : languageId(""),
273 0 : nPos(0)
274 : {
275 0 : }
276 : ~XMLElement();
277 : XMLElement(const XMLElement&);
278 :
279 : XMLElement& operator=(const XMLElement& obj);
280 : /// returns node type XML_NODE_ELEMENT
281 : virtual sal_uInt16 GetNodeType();
282 :
283 : /// returns element name
284 0 : OUString GetName() { return sElementName; }
285 :
286 : /// returns list of attributes of this element
287 0 : XMLAttributeList *GetAttributeList() { return pAttributes; }
288 :
289 : /// adds a new attribute to this element, typically used by parser
290 : void AddAttribute( const OUString &rAttribute, const OUString &rValue );
291 :
292 : void ChangeLanguageTag( const OUString &rValue );
293 :
294 : /// Return a Unicode String representation of this object
295 : OUString ToOUString();
296 :
297 : void SetProject ( OString const & prj ){ project = prj; }
298 : void SetFileName ( OString const & fn ){ filename = fn; }
299 0 : void SetId ( OString const & theId ){ id = theId; }
300 : void SetResourceType ( OString const & rt ){ resourceType = rt; }
301 0 : void SetLanguageId ( OString const & lid ){ languageId = lid; }
302 0 : void SetPos ( int nPos_in ){ nPos = nPos_in; }
303 0 : void SetOldRef ( OString const & sOldRef_in ){ sOldRef = sOldRef_in; }
304 :
305 0 : virtual int GetPos() { return nPos; }
306 : OString GetProject() { return project; }
307 : OString GetFileName() { return filename; }
308 : OString GetId() { return id; }
309 0 : OString GetOldref() { return sOldRef; }
310 : OString GetResourceType(){ return resourceType; }
311 : OString GetLanguageId() { return languageId; }
312 :
313 :
314 : };
315 : //-------------------------------------------------------------------------
316 :
317 :
318 : /** Holds character data
319 : */
320 0 : class XMLData : public XMLChildNode
321 : {
322 : private:
323 : OUString sData;
324 : bool isNewCreated;
325 :
326 : public:
327 : /// create a data node
328 0 : XMLData(
329 : const OUString &rData, // the initial data
330 : XMLParentNode *Parent // the parent node of this data, typically a element node
331 : )
332 0 : : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( false ){}
333 0 : XMLData(
334 : const OUString &rData, // the initial data
335 : XMLParentNode *Parent, // the parent node of this data, typically a element node
336 : bool newCreated
337 : )
338 0 : : XMLChildNode( Parent ), sData( rData ) , isNewCreated ( newCreated ){}
339 :
340 : XMLData(const XMLData& obj);
341 :
342 : XMLData& operator=(const XMLData& obj);
343 : virtual sal_uInt16 GetNodeType();
344 :
345 : /// returns the data
346 0 : OUString GetData() { return sData; }
347 :
348 : bool isNew() { return isNewCreated; }
349 : /// adds new character data to the existing one
350 : void AddData(
351 : const OUString &rData // the new data
352 : );
353 :
354 :
355 :
356 : };
357 :
358 : //-------------------------------------------------------------------------
359 :
360 : /** Holds comments
361 : */
362 0 : class XMLComment : public XMLChildNode
363 : {
364 : private:
365 : OUString sComment;
366 :
367 : public:
368 : /// create a comment node
369 0 : XMLComment(
370 : const OUString &rComment, // the comment
371 : XMLParentNode *Parent // the parent node of this comemnt, typically a element node
372 : )
373 0 : : XMLChildNode( Parent ), sComment( rComment ) {}
374 :
375 : virtual sal_uInt16 GetNodeType();
376 :
377 : XMLComment( const XMLComment& obj );
378 :
379 : XMLComment& operator=(const XMLComment& obj);
380 :
381 : /// returns the comment
382 0 : OUString GetComment() { return sComment; }
383 : };
384 :
385 : //-------------------------------------------------------------------------
386 :
387 : /** Holds additional file content like those for which no handler exists
388 : */
389 0 : class XMLDefault : public XMLChildNode
390 : {
391 : private:
392 : OUString sDefault;
393 :
394 : public:
395 : /// create a comment node
396 0 : XMLDefault(
397 : const OUString &rDefault, // the comment
398 : XMLParentNode *Parent // the parent node of this comemnt, typically a element node
399 : )
400 0 : : XMLChildNode( Parent ), sDefault( rDefault ) {}
401 :
402 : XMLDefault(const XMLDefault& obj);
403 :
404 : XMLDefault& operator=(const XMLDefault& obj);
405 :
406 : /// returns node type XML_NODE_TYPE_COMMENT
407 : virtual sal_uInt16 GetNodeType();
408 :
409 : /// returns the comment
410 0 : OUString GetDefault() { return sDefault; }
411 : };
412 :
413 : //-------------------------------------------------------------------------
414 :
415 : /** struct for error information, used by class SimpleXMLParser
416 : */
417 0 : struct XMLError {
418 : XML_Error eCode; ///< the error code
419 : std::size_t nLine; ///< error line number
420 : std::size_t nColumn; ///< error column number
421 : OUString sMessage; ///< readable error message
422 : };
423 :
424 : //-------------------------------------------------------------------------
425 :
426 : /** validating xml parser, creates a document tree with xml nodes
427 : */
428 :
429 : class SimpleXMLParser
430 : {
431 : private:
432 : XML_Parser aParser;
433 : XMLError aErrorInformation;
434 :
435 : XMLFile *pXMLFile;
436 : XMLParentNode *pCurNode;
437 : XMLData *pCurData;
438 :
439 :
440 : static void StartElementHandler( void *userData, const XML_Char *name, const XML_Char **atts );
441 : static void EndElementHandler( void *userData, const XML_Char *name );
442 : static void CharacterDataHandler( void *userData, const XML_Char *s, int len );
443 : static void CommentHandler( void *userData, const XML_Char *data );
444 : static void DefaultHandler( void *userData, const XML_Char *s, int len );
445 :
446 :
447 : void StartElement( const XML_Char *name, const XML_Char **atts );
448 : void EndElement( const XML_Char *name );
449 : void CharacterData( const XML_Char *s, int len );
450 : void Comment( const XML_Char *data );
451 : void Default( const XML_Char *s, int len );
452 :
453 : public:
454 : /// creates a new parser
455 : SimpleXMLParser();
456 : ~SimpleXMLParser();
457 :
458 : /// parse a file, returns NULL on criticall errors
459 : XMLFile *Execute(
460 : const OUString &rFileName, // the file name
461 : XMLFile *pXMLFileIn // the XMLFile
462 : );
463 :
464 : /// returns an error struct
465 0 : const XMLError &GetError() { return aErrorInformation; }
466 : };
467 :
468 : #endif // BOOTSTRP_XMLPARSE_HXX
469 :
470 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|