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 INCLUDED_L10NTOOLS_INC_XMLPARSE_HXX
21 : #define INCLUDED_L10NTOOLS_INC_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>
31 : #include <expat.h>
32 :
33 : #include <rtl/string.hxx>
34 : #include <rtl/strbuf.hxx>
35 : #include "export.hxx"
36 : #include <unordered_map>
37 :
38 : class XMLParentNode;
39 : class XMLElement;
40 :
41 : #define XML_NODE_TYPE_FILE 0x001
42 : #define XML_NODE_TYPE_ELEMENT 0x002
43 : #define XML_NODE_TYPE_DATA 0x003
44 : #define XML_NODE_TYPE_COMMENT 0x004
45 : #define XML_NODE_TYPE_DEFAULT 0x005
46 :
47 : /** Holds data of Attributes
48 : */
49 0 : class XMLAttribute
50 : {
51 : private:
52 : OString m_sName;
53 : OString m_sValue;
54 :
55 : public:
56 : /// creates an attribute
57 0 : XMLAttribute(
58 : const OString &rName, // attributes name
59 : const OString &rValue // attributes data
60 : )
61 0 : : m_sName( rName ), m_sValue( rValue ) {}
62 :
63 0 : OString GetName() const { return m_sName; }
64 0 : OString GetValue() const { return m_sValue; }
65 :
66 0 : void setValue( const OString &rValue ){ m_sValue = rValue; }
67 : };
68 :
69 :
70 : typedef std::vector< XMLAttribute* > XMLAttributeList;
71 :
72 : /** Virtual base to handle different kinds of XML nodes
73 : */
74 0 : class XMLNode
75 : {
76 : protected:
77 0 : XMLNode(){}
78 :
79 : public:
80 : virtual sal_uInt16 GetNodeType() const = 0;
81 0 : virtual ~XMLNode(){}
82 : };
83 :
84 :
85 : /** Virtual base to handle different kinds of child nodes
86 : */
87 : class XMLChildNode : public XMLNode
88 : {
89 : private:
90 : XMLParentNode *m_pParent;
91 :
92 : protected:
93 : XMLChildNode( XMLParentNode *pPar );
94 : XMLChildNode(): m_pParent( NULL ){};
95 : XMLChildNode( const XMLChildNode& rObj);
96 : XMLChildNode& operator=(const XMLChildNode& rObj);
97 : public:
98 : /// returns the parent of this node
99 0 : XMLParentNode *GetParent() { return m_pParent; }
100 0 : virtual ~XMLChildNode(){};
101 : };
102 :
103 : typedef std::vector< XMLChildNode* > XMLChildNodeList;
104 :
105 : class XMLData;
106 :
107 : /** Virtual base to handle different kinds of parent nodes
108 : */
109 :
110 : class XMLParentNode : public XMLChildNode
111 : {
112 : private:
113 : XMLChildNodeList* m_pChildList;
114 :
115 : protected:
116 0 : XMLParentNode( XMLParentNode *pPar )
117 0 : : XMLChildNode( pPar ), m_pChildList( NULL ){}
118 : XMLParentNode(): m_pChildList(NULL){}
119 :
120 : XMLParentNode( const XMLParentNode& );
121 :
122 : XMLParentNode& operator=(const XMLParentNode& rObj);
123 : virtual ~XMLParentNode();
124 :
125 : public:
126 : /// returns child list of this node
127 0 : XMLChildNodeList *GetChildList() { return m_pChildList; }
128 :
129 : /// adds a new child
130 : void AddChild(
131 : XMLChildNode *pChild /// the new child
132 : );
133 :
134 : void RemoveAndDeleteAllChildren();
135 : };
136 :
137 : /// Mapping numeric Language code <-> XML Element
138 : typedef std::unordered_map<OString, XMLElement*, OStringHash> LangHashMap;
139 :
140 : /// Mapping XML Element string identifier <-> Language Map
141 : typedef std::unordered_map<OString, LangHashMap*, OStringHash> XMLHashMap;
142 :
143 : /// Mapping XML tag names <-> have localizable strings
144 : typedef std::unordered_map<OString, sal_Bool, OStringHash> TagMap;
145 :
146 : /** Holds information of a XML file, is root node of tree
147 : */
148 : class XMLFile : public XMLParentNode
149 : {
150 : public:
151 : XMLFile(
152 : const OString &rFileName // the file name, empty if created from memory stream
153 : );
154 : XMLFile( const XMLFile& rObj ) ;
155 : virtual ~XMLFile();
156 :
157 : void Print( XMLNode *pCur = NULL, sal_uInt16 nLevel = 0 );
158 : void SearchL10NElements( XMLChildNode *pCur, int pos = 0 );
159 : void Extract( XMLFile *pCur = NULL );
160 :
161 0 : XMLHashMap* GetStrings(){ return m_pXMLStrings; }
162 : void Write( OString const &rFilename );
163 : bool Write( std::ofstream &rStream, XMLNode *pCur = NULL );
164 :
165 : bool CheckExportStatus( XMLParentNode *pCur = NULL );
166 :
167 : XMLFile& operator=(const XMLFile& rObj);
168 :
169 0 : virtual sal_uInt16 GetNodeType() const SAL_OVERRIDE { return XML_NODE_TYPE_FILE; }
170 :
171 : /// returns file name
172 0 : OString GetName() const { return m_sFileName; }
173 0 : void SetName( const OString &rFilename ) { m_sFileName = rFilename; }
174 0 : const std::vector<OString>& getOrder() const { return m_vOrder; }
175 :
176 : protected:
177 :
178 : void InsertL10NElement( XMLElement* pElement);
179 :
180 : // DATA
181 : OString m_sFileName;
182 :
183 : TagMap m_aNodes_localize;
184 : XMLHashMap* m_pXMLStrings;
185 :
186 : std::vector <OString> m_vOrder;
187 : };
188 :
189 : /// An Utility class for XML
190 : class XMLUtil
191 : {
192 : public:
193 : /// Quot the XML characters
194 : static OString QuotHTML( const OString& rString );
195 : };
196 :
197 :
198 : /** Hold information of an element node
199 : */
200 : class XMLElement : public XMLParentNode
201 : {
202 : private:
203 : OString m_sElementName;
204 : XMLAttributeList *m_pAttributes;
205 : OString m_sProject;
206 : OString m_sFilename;
207 : OString m_sId;
208 : OString m_sOldRef;
209 : OString m_sResourceType;
210 : OString m_sLanguageId;
211 : int m_nPos;
212 :
213 : protected:
214 : void Print(XMLNode *pCur, OStringBuffer& rBuffer, bool bRootelement) const;
215 : public:
216 : /// create an element node
217 : XMLElement(){}
218 : XMLElement(
219 : const OString &rName, // the element name
220 : XMLParentNode *pParent // parent node of this element
221 : );
222 :
223 : virtual ~XMLElement();
224 : XMLElement(const XMLElement&);
225 :
226 : XMLElement& operator=(const XMLElement& rObj);
227 0 : virtual sal_uInt16 GetNodeType() const SAL_OVERRIDE { return XML_NODE_TYPE_ELEMENT; }
228 :
229 : /// returns element name
230 0 : OString GetName() const { return m_sElementName; }
231 :
232 : /// returns list of attributes of this element
233 0 : XMLAttributeList *GetAttributeList() { return m_pAttributes; }
234 :
235 : /// adds a new attribute to this element, typically used by parser
236 : void AddAttribute( const OString &rAttribute, const OString &rValue );
237 :
238 : void ChangeLanguageTag( const OString &rValue );
239 :
240 : /// Return a Unicode String representation of this object
241 : OString ToOString();
242 :
243 : void SetProject ( OString const & sPrj ) { m_sProject = sPrj; }
244 : void SetFileName ( OString const & sFileName ) { m_sFilename = sFileName; }
245 0 : void SetId ( OString const & sTheId ) { m_sId = sTheId; }
246 : void SetResourceType ( OString const & sResType ) { m_sResourceType = sResType; }
247 0 : void SetLanguageId ( OString const & sLangId ) { m_sLanguageId = sLangId; }
248 0 : void SetPos ( int nPos ) { m_nPos = nPos; }
249 0 : void SetOldRef ( OString const & sOldRef ) { m_sOldRef = sOldRef; }
250 :
251 : int GetPos() { return m_nPos; }
252 : OString GetProject() const { return m_sProject; }
253 : OString GetFileName() const { return m_sFilename; }
254 : OString GetId() const { return m_sId; }
255 0 : OString GetOldref() const { return m_sOldRef; }
256 : OString GetResourceType() const { return m_sResourceType; }
257 : OString GetLanguageId() const { return m_sLanguageId; }
258 :
259 :
260 : };
261 :
262 : /** Holds character data
263 : */
264 0 : class XMLData : public XMLChildNode
265 : {
266 : private:
267 : OString m_sData;
268 : bool m_bIsNewCreated;
269 :
270 : public:
271 : /// create a data node
272 0 : XMLData(
273 : const OString &rData, // the initial data
274 : XMLParentNode *pParent, // the parent node of this data, typically a element node
275 : bool bNewCreated = false
276 : )
277 0 : : XMLChildNode( pParent ), m_sData( rData ), m_bIsNewCreated( bNewCreated ){}
278 :
279 : // Default copy constructor and copy operator work well.
280 :
281 0 : virtual sal_uInt16 GetNodeType() const SAL_OVERRIDE { return XML_NODE_TYPE_DATA; }
282 :
283 : /// returns the data
284 0 : OString GetData() const { return m_sData; }
285 :
286 : bool isNew() const { return m_bIsNewCreated; }
287 :
288 : /// adds new character data to the existing one
289 0 : void AddData( const OString &rData ) { m_sData += rData; }
290 : };
291 :
292 : /** Holds comments
293 : */
294 0 : class XMLComment : public XMLChildNode
295 : {
296 : private:
297 : OString m_sComment;
298 :
299 : public:
300 : /// create a comment node
301 0 : XMLComment(
302 : const OString &rComment, // the comment
303 : XMLParentNode *pParent // the parent node of this comemnt, typically a element node
304 : )
305 0 : : XMLChildNode( pParent ), m_sComment( rComment ) {}
306 :
307 : // Default copy constructor and copy operator work well.
308 :
309 0 : virtual sal_uInt16 GetNodeType() const SAL_OVERRIDE { return XML_NODE_TYPE_COMMENT; }
310 :
311 : /// returns the comment
312 0 : OString GetComment() const { return m_sComment; }
313 : };
314 :
315 : /** Holds additional file content like those for which no handler exists
316 : */
317 0 : class XMLDefault : public XMLChildNode
318 : {
319 : private:
320 : OString m_sDefault;
321 :
322 : public:
323 : /// create a comment node
324 0 : XMLDefault(
325 : const OString &rDefault, // the comment
326 : XMLParentNode *pParent // the parent node of this comemnt, typically a element node
327 : )
328 0 : : XMLChildNode( pParent ), m_sDefault( rDefault ) {}
329 :
330 : // Default copy constructor and copy operator work well.
331 :
332 0 : virtual sal_uInt16 GetNodeType() const SAL_OVERRIDE { return XML_NODE_TYPE_DEFAULT; }
333 :
334 : /// returns the comment
335 0 : OString GetDefault() const { return m_sDefault; }
336 : };
337 :
338 : /** struct for error information, used by class SimpleXMLParser
339 : */
340 0 : struct XMLError {
341 : XML_Error m_eCode; ///< the error code
342 : std::size_t m_nLine; ///< error line number
343 : std::size_t m_nColumn; ///< error column number
344 : OString m_sMessage; ///< readable error message
345 : };
346 :
347 : /** validating xml parser, creates a document tree with xml nodes
348 : */
349 :
350 : class SimpleXMLParser
351 : {
352 : private:
353 : XML_Parser m_aParser;
354 : XMLError m_aErrorInformation;
355 :
356 : XMLFile *m_pXMLFile;
357 : XMLParentNode *m_pCurNode;
358 : XMLData *m_pCurData;
359 :
360 :
361 : static void StartElementHandler( void *userData, const XML_Char *name, const XML_Char **atts );
362 : static void EndElementHandler( void *userData, const XML_Char *name );
363 : static void CharacterDataHandler( void *userData, const XML_Char *s, int len );
364 : static void CommentHandler( void *userData, const XML_Char *data );
365 : static void DefaultHandler( void *userData, const XML_Char *s, int len );
366 :
367 :
368 : void StartElement( const XML_Char *name, const XML_Char **atts );
369 : void EndElement( const XML_Char *name );
370 : void CharacterData( const XML_Char *s, int len );
371 : void Comment( const XML_Char *data );
372 : void Default( const XML_Char *s, int len );
373 :
374 : public:
375 : /// creates a new parser
376 : SimpleXMLParser();
377 : ~SimpleXMLParser();
378 :
379 : /// parse a file, returns NULL on criticall errors
380 : XMLFile *Execute(
381 : const OString &rFileName, // the file name
382 : XMLFile *pXMLFileIn // the XMLFile
383 : );
384 :
385 : /// returns an error struct
386 0 : const XMLError &GetError() const { return m_aErrorInformation; }
387 : };
388 :
389 : #endif // INCLUDED_L10NTOOLS_INC_XMLPARSE_HXX
390 :
391 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|