1983d4c8aSAndrew Rist /**************************************************************
2*facfa769Smseidel  *
3983d4c8aSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4983d4c8aSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5983d4c8aSAndrew Rist  * distributed with this work for additional information
6983d4c8aSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7983d4c8aSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8983d4c8aSAndrew Rist  * "License"); you may not use this file except in compliance
9983d4c8aSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*facfa769Smseidel  *
11983d4c8aSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*facfa769Smseidel  *
13983d4c8aSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14983d4c8aSAndrew Rist  * software distributed under the License is distributed on an
15983d4c8aSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16983d4c8aSAndrew Rist  * KIND, either express or implied.  See the License for the
17983d4c8aSAndrew Rist  * specific language governing permissions and limitations
18983d4c8aSAndrew Rist  * under the License.
19*facfa769Smseidel  *
20983d4c8aSAndrew Rist  *************************************************************/
21983d4c8aSAndrew Rist 
22983d4c8aSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef HELPCOMPILER_HXX
25cdf0e10cSrcweir #define HELPCOMPILER_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <string>
28cdf0e10cSrcweir #include <hash_map>
29cdf0e10cSrcweir #include <vector>
30cdf0e10cSrcweir #include <list>
31cdf0e10cSrcweir #include <fstream>
32cdf0e10cSrcweir #include <iostream>
33cdf0e10cSrcweir #include <sstream>
34cdf0e10cSrcweir #include <algorithm>
35cdf0e10cSrcweir #include <ctype.h>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include <libxml/xmlmemory.h>
40cdf0e10cSrcweir #include <libxml/debugXML.h>
41cdf0e10cSrcweir #include <libxml/HTMLtree.h>
42cdf0e10cSrcweir #include <libxml/xmlIO.h>
43cdf0e10cSrcweir #include <libxml/xinclude.h>
44cdf0e10cSrcweir #include <libxml/catalog.h>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include <rtl/ustring.hxx>
47cdf0e10cSrcweir #include <osl/thread.h>
48cdf0e10cSrcweir #include <osl/process.h>
49cdf0e10cSrcweir #include <osl/file.hxx>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #include <compilehelp.hxx>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #define EMULATEORIGINAL 1
54cdf0e10cSrcweir 
55cdf0e10cSrcweir #ifdef CMCDEBUG
56*facfa769Smseidel 	#define HCDBG(foo) do { if (1) foo; } while(0)
57cdf0e10cSrcweir #else
58*facfa769Smseidel 	#define HCDBG(foo) do { if (0) foo; } while(0)
59cdf0e10cSrcweir #endif
60cdf0e10cSrcweir 
61cdf0e10cSrcweir namespace fs
62cdf0e10cSrcweir {
63cdf0e10cSrcweir 	rtl_TextEncoding getThreadTextEncoding( void );
64cdf0e10cSrcweir 
65*facfa769Smseidel 	enum convert { native };
66*facfa769Smseidel 	class path
67*facfa769Smseidel 	{
68*facfa769Smseidel 	public:
69*facfa769Smseidel 		::rtl::OUString data;
70*facfa769Smseidel 	public:
path()71*facfa769Smseidel 		path() {}
path(const path & rOther)72*facfa769Smseidel 		path(const path &rOther) : data(rOther.data) {}
path(const std::string & in,convert)73*facfa769Smseidel 		path(const std::string &in, convert)
74cdf0e10cSrcweir 		{
75*facfa769Smseidel 			rtl::OUString sWorkingDir;
76*facfa769Smseidel 			osl_getProcessWorkingDir(&sWorkingDir.pData);
77*facfa769Smseidel 
78*facfa769Smseidel 			rtl::OString tmp(in.c_str());
79*facfa769Smseidel 			rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding()));
80*facfa769Smseidel 			osl::File::getFileURLFromSystemPath(ustrSystemPath, data);
81*facfa769Smseidel 			osl::File::getAbsoluteFileURL(sWorkingDir, data, data);
82*facfa769Smseidel 		}
path(const std::string & FileURL)83*facfa769Smseidel 		path(const std::string &FileURL)
84*facfa769Smseidel 		{
85*facfa769Smseidel 			rtl::OString tmp(FileURL.c_str());
86*facfa769Smseidel 			data = rtl::OStringToOUString(tmp, getThreadTextEncoding());
87*facfa769Smseidel 		}
native_file_string() const88*facfa769Smseidel 		std::string native_file_string() const
89*facfa769Smseidel 		{
90*facfa769Smseidel 			::rtl::OUString ustrSystemPath;
91*facfa769Smseidel 			osl::File::getSystemPathFromFileURL(data, ustrSystemPath);
92*facfa769Smseidel 			rtl::OString tmp(rtl::OUStringToOString(ustrSystemPath, getThreadTextEncoding()));
93*facfa769Smseidel 			HCDBG(std::cerr << "native_file_string is " << tmp.getStr() << std::endl);
94*facfa769Smseidel 			return std::string(tmp.getStr());
95cdf0e10cSrcweir 		}
96cdf0e10cSrcweir #ifdef WNT
native_file_string_w() const97*facfa769Smseidel 		wchar_t const * native_file_string_w() const
98*facfa769Smseidel 		{
99*facfa769Smseidel 			::rtl::OUString ustrSystemPath;
100*facfa769Smseidel 			osl::File::getSystemPathFromFileURL(data, ustrSystemPath);
101*facfa769Smseidel 			return reinterpret_cast< wchar_t const * >(ustrSystemPath.getStr());
102*facfa769Smseidel 		}
103cdf0e10cSrcweir #endif
native_directory_string() const104*facfa769Smseidel 		std::string native_directory_string() const { return native_file_string(); }
toUTF8() const105*facfa769Smseidel 		std::string toUTF8() const
106*facfa769Smseidel 		{
107*facfa769Smseidel 			rtl::OString tmp(rtl::OUStringToOString(data, RTL_TEXTENCODING_UTF8));
108*facfa769Smseidel 			return std::string(tmp.getStr());
109*facfa769Smseidel 		}
empty() const110*facfa769Smseidel 		bool empty() const { return data.getLength() == 0; }
operator /(const std::string & in) const111*facfa769Smseidel 		path operator/(const std::string &in) const
112*facfa769Smseidel 		{
113*facfa769Smseidel 			path ret(*this);
114*facfa769Smseidel 			HCDBG(std::cerr << "orig was " <<
115*facfa769Smseidel 				rtl::OUStringToOString(ret.data, RTL_TEXTENCODING_UTF8).getStr() << std::endl);
116*facfa769Smseidel 			rtl::OString tmp(in.c_str());
117*facfa769Smseidel 			rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding()));
118*facfa769Smseidel 			ret.data += rtl::OUString(sal_Unicode('/'));
119*facfa769Smseidel 			ret.data += ustrSystemPath;
120*facfa769Smseidel 			HCDBG(std::cerr << "final is " <<
121*facfa769Smseidel 				rtl::OUStringToOString(ret.data, RTL_TEXTENCODING_UTF8).getStr() << std::endl);
122*facfa769Smseidel 			return ret;
123*facfa769Smseidel 		}
append(const char * in)124*facfa769Smseidel 		void append(const char *in)
125*facfa769Smseidel 		{
126*facfa769Smseidel 			rtl::OString tmp(in);
127*facfa769Smseidel 			rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding()));
128*facfa769Smseidel 			data = data + ustrSystemPath;
129*facfa769Smseidel 		}
append(const std::string & in)130*facfa769Smseidel 		void append(const std::string &in) { append(in.c_str()); }
131*facfa769Smseidel 	};
132*facfa769Smseidel 
133*facfa769Smseidel 	void create_directory(const fs::path indexDirName);
134*facfa769Smseidel 	void rename(const fs::path &src, const fs::path &dest);
135*facfa769Smseidel 	void copy(const fs::path &src, const fs::path &dest);
136*facfa769Smseidel 	bool exists(const fs::path &in);
137*facfa769Smseidel 	void remove_all(const fs::path &in);
138*facfa769Smseidel 	void remove(const fs::path &in);
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir struct joaat_hash
142cdf0e10cSrcweir {
operator ()joaat_hash143*facfa769Smseidel 	size_t operator()(const std::string &str) const
144*facfa769Smseidel 	{
145*facfa769Smseidel 		size_t hash = 0;
146*facfa769Smseidel 		const char *key = str.data();
147*facfa769Smseidel 		for (size_t i = 0; i < str.size(); i++)
148*facfa769Smseidel 		{
149*facfa769Smseidel 			hash += key[i];
150*facfa769Smseidel 			hash += (hash << 10);
151*facfa769Smseidel 			hash ^= (hash >> 6);
152*facfa769Smseidel 		}
153*facfa769Smseidel 		hash += (hash << 3);
154*facfa769Smseidel 		hash ^= (hash >> 11);
155*facfa769Smseidel 		hash += (hash << 15);
156*facfa769Smseidel 		return hash;
157*facfa769Smseidel 	}
158cdf0e10cSrcweir };
159cdf0e10cSrcweir 
160cdf0e10cSrcweir #define get16bits(d) ((((sal_uInt32)(((const sal_uInt8 *)(d))[1])) << 8)\
161*facfa769Smseidel 					   +(sal_uInt32)(((const sal_uInt8 *)(d))[0]) )
162cdf0e10cSrcweir 
163cdf0e10cSrcweir struct SuperFastHash
164cdf0e10cSrcweir {
operator ()SuperFastHash165*facfa769Smseidel 	size_t operator()(const std::string &str) const
166*facfa769Smseidel 	{
167*facfa769Smseidel 		const char * data = str.data();
168*facfa769Smseidel 		int len = str.size();
169*facfa769Smseidel 		size_t hash = len, tmp;
170*facfa769Smseidel 		if (len <= 0 || data == NULL) return 0;
171*facfa769Smseidel 
172*facfa769Smseidel 		int rem = len & 3;
173*facfa769Smseidel 		len >>= 2;
174*facfa769Smseidel 
175*facfa769Smseidel 		/* Main loop */
176*facfa769Smseidel 		for (;len > 0; len--)
177*facfa769Smseidel 		{
178*facfa769Smseidel 			hash  += get16bits (data);
179*facfa769Smseidel 			tmp    = (get16bits (data+2) << 11) ^ hash;
180*facfa769Smseidel 			hash   = (hash << 16) ^ tmp;
181*facfa769Smseidel 			data  += 2*sizeof (sal_uInt16);
182*facfa769Smseidel 			hash  += hash >> 11;
183*facfa769Smseidel 		}
184*facfa769Smseidel 
185*facfa769Smseidel 		/* Handle end cases */
186*facfa769Smseidel 		switch (rem)
187*facfa769Smseidel 		{
188*facfa769Smseidel 			case 3: hash += get16bits (data);
189*facfa769Smseidel 					hash ^= hash << 16;
190*facfa769Smseidel 					hash ^= data[sizeof (sal_uInt16)] << 18;
191*facfa769Smseidel 					hash += hash >> 11;
192*facfa769Smseidel 					break;
193*facfa769Smseidel 			case 2: hash += get16bits (data);
194*facfa769Smseidel 					hash ^= hash << 11;
195*facfa769Smseidel 					hash += hash >> 17;
196*facfa769Smseidel 					break;
197*facfa769Smseidel 			case 1: hash += *data;
198*facfa769Smseidel 					hash ^= hash << 10;
199*facfa769Smseidel 					hash += hash >> 1;
200*facfa769Smseidel 		}
201*facfa769Smseidel 
202*facfa769Smseidel 		/* Force "avalanching" of final 127 bits */
203*facfa769Smseidel 		hash ^= hash << 3;
204*facfa769Smseidel 		hash += hash >> 5;
205*facfa769Smseidel 		hash ^= hash << 4;
206*facfa769Smseidel 		hash += hash >> 17;
207*facfa769Smseidel 		hash ^= hash << 25;
208*facfa769Smseidel 		hash += hash >> 6;
209*facfa769Smseidel 
210*facfa769Smseidel 		return hash;
211*facfa769Smseidel 	}
212cdf0e10cSrcweir };
213cdf0e10cSrcweir 
214cdf0e10cSrcweir #define pref_hash joaat_hash
215cdf0e10cSrcweir 
216cdf0e10cSrcweir typedef std::hash_map<std::string, std::string, pref_hash> Stringtable;
217cdf0e10cSrcweir typedef std::list<std::string> LinkedList;
218cdf0e10cSrcweir typedef std::vector<std::string> HashSet;
219cdf0e10cSrcweir 
220cdf0e10cSrcweir typedef std::hash_map<std::string, LinkedList, pref_hash> Hashtable;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir class StreamTable
223cdf0e10cSrcweir {
224cdf0e10cSrcweir public:
225*facfa769Smseidel 	std::string document_id;
226*facfa769Smseidel 	std::string document_path;
227*facfa769Smseidel 	std::string document_module;
228*facfa769Smseidel 	std::string document_title;
229*facfa769Smseidel 
230*facfa769Smseidel 	HashSet *appl_hidlist;
231*facfa769Smseidel 	Hashtable *appl_keywords;
232*facfa769Smseidel 	Stringtable *appl_helptexts;
233*facfa769Smseidel 	xmlDocPtr appl_doc;
234*facfa769Smseidel 
235*facfa769Smseidel 	HashSet *default_hidlist;
236*facfa769Smseidel 	Hashtable *default_keywords;
237*facfa769Smseidel 	Stringtable *default_helptexts;
238*facfa769Smseidel 	xmlDocPtr default_doc;
239*facfa769Smseidel 
StreamTable()240*facfa769Smseidel 	StreamTable() :
241*facfa769Smseidel 		appl_hidlist(NULL), appl_keywords(NULL), appl_helptexts(NULL), appl_doc(NULL),
242*facfa769Smseidel 		default_hidlist(NULL), default_keywords(NULL), default_helptexts(NULL), default_doc(NULL)
243*facfa769Smseidel 	{}
dropdefault()244*facfa769Smseidel 	void dropdefault()
245*facfa769Smseidel 	{
246*facfa769Smseidel 		delete default_hidlist;
247*facfa769Smseidel 		delete default_keywords;
248*facfa769Smseidel 		delete default_helptexts;
249*facfa769Smseidel 		if (default_doc) xmlFreeDoc(default_doc);
250*facfa769Smseidel 	}
dropappl()251*facfa769Smseidel 	void dropappl()
252*facfa769Smseidel 	{
253*facfa769Smseidel 		delete appl_hidlist;
254*facfa769Smseidel 		delete appl_keywords;
255*facfa769Smseidel 		delete appl_helptexts;
256*facfa769Smseidel 		if (appl_doc) xmlFreeDoc(appl_doc);
257*facfa769Smseidel 	}
~StreamTable()258*facfa769Smseidel 	~StreamTable()
259*facfa769Smseidel 	{
260*facfa769Smseidel 		dropappl();
261*facfa769Smseidel 		dropdefault();
262*facfa769Smseidel 	}
263cdf0e10cSrcweir };
264cdf0e10cSrcweir 
265cdf0e10cSrcweir struct HelpProcessingException
266cdf0e10cSrcweir {
267cdf0e10cSrcweir 	HelpProcessingErrorClass		m_eErrorClass;
268cdf0e10cSrcweir 	std::string						m_aErrorMsg;
269cdf0e10cSrcweir 	std::string						m_aXMLParsingFile;
270cdf0e10cSrcweir 	int								m_nXMLParsingLine;
271cdf0e10cSrcweir 
HelpProcessingExceptionHelpProcessingException272cdf0e10cSrcweir 	HelpProcessingException( HelpProcessingErrorClass eErrorClass, const std::string& aErrorMsg )
273cdf0e10cSrcweir 		: m_eErrorClass( eErrorClass )
274cdf0e10cSrcweir 		, m_aErrorMsg( aErrorMsg )
275cdf0e10cSrcweir 	{}
HelpProcessingExceptionHelpProcessingException276cdf0e10cSrcweir 	HelpProcessingException( const std::string& aErrorMsg, const std::string& aXMLParsingFile, int nXMLParsingLine )
277cdf0e10cSrcweir 		: m_eErrorClass( HELPPROCESSING_XMLPARSING_ERROR )
278cdf0e10cSrcweir 		, m_aErrorMsg( aErrorMsg )
279cdf0e10cSrcweir 		, m_aXMLParsingFile( aXMLParsingFile )
280cdf0e10cSrcweir 		, m_nXMLParsingLine( nXMLParsingLine )
281cdf0e10cSrcweir 	{}
282cdf0e10cSrcweir };
283cdf0e10cSrcweir 
284cdf0e10cSrcweir class HelpCompiler
285cdf0e10cSrcweir {
286*facfa769Smseidel public:
287*facfa769Smseidel 	HelpCompiler(StreamTable &streamTable,
288*facfa769Smseidel 				const fs::path &in_inputFile,
289*facfa769Smseidel 				const fs::path &in_src,
290*facfa769Smseidel 				const fs::path &in_resEmbStylesheet,
291*facfa769Smseidel 				const std::string &in_module,
292*facfa769Smseidel 				const std::string &in_lang,
293cdf0e10cSrcweir 				bool in_bExtensionMode);
294*facfa769Smseidel 	bool compile( void ) throw (HelpProcessingException);
295*facfa769Smseidel 	void addEntryToJarFile(const std::string &prefix,
296*facfa769Smseidel 		const std::string &entryName, const std::string &bytesToAdd);
297*facfa769Smseidel 	void addEntryToJarFile(const std::string &prefix,
298*facfa769Smseidel 				const std::string &entryName, const HashSet &bytesToAdd);
299*facfa769Smseidel 	void addEntryToJarFile(const std::string &prefix,
300*facfa769Smseidel 				const std::string &entryName, const Stringtable &bytesToAdd);
301*facfa769Smseidel 	void addEntryToJarFile(const std::string &prefix,
302*facfa769Smseidel 				const std::string &entryName, const Hashtable &bytesToAdd);
303cdf0e10cSrcweir private:
304*facfa769Smseidel 	xmlDocPtr getSourceDocument(const fs::path &filePath);
305*facfa769Smseidel 	HashSet switchFind(xmlDocPtr doc);
306*facfa769Smseidel 	xmlNodePtr clone(xmlNodePtr node, const std::string& appl);
307*facfa769Smseidel 	StreamTable &streamTable;
308*facfa769Smseidel 	const fs::path inputFile, src;
309*facfa769Smseidel 	const std::string module, lang;
310*facfa769Smseidel 	const fs::path resEmbStylesheet;
311cdf0e10cSrcweir 	bool bExtensionMode;
312cdf0e10cSrcweir };
313cdf0e10cSrcweir 
314cdf0e10cSrcweir #endif
315cdf0e10cSrcweir 
316*facfa769Smseidel /* vim: set noet sw=4 ts=4: */
317