1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef HELPCOMPILER_HXX 29 #define HELPCOMPILER_HXX 30 31 #include <string> 32 #include <hash_map> 33 #include <vector> 34 #include <list> 35 #include <fstream> 36 #include <iostream> 37 #include <sstream> 38 #include <algorithm> 39 #include <ctype.h> 40 #ifdef SYSTEM_DB 41 #include <db.h> 42 #else 43 #include <berkeleydb/db.h> 44 #endif 45 46 #include <boost/shared_ptr.hpp> 47 48 #include <libxml/xmlmemory.h> 49 #include <libxml/debugXML.h> 50 #include <libxml/HTMLtree.h> 51 #include <libxml/xmlIO.h> 52 #include <libxml/xinclude.h> 53 #include <libxml/catalog.h> 54 55 #include <rtl/ustring.hxx> 56 #include <osl/thread.h> 57 #include <osl/process.h> 58 #include <osl/file.hxx> 59 60 #include <compilehelp.hxx> 61 62 #define EMULATEORIGINAL 1 63 64 #ifdef CMCDEBUG 65 #define HCDBG(foo) do { if (1) foo; } while(0) 66 #else 67 #define HCDBG(foo) do { if (0) foo; } while(0) 68 #endif 69 70 namespace fs 71 { 72 rtl_TextEncoding getThreadTextEncoding( void ); 73 74 enum convert { native }; 75 class path 76 { 77 public: 78 ::rtl::OUString data; 79 public: 80 path() {} 81 path(const path &rOther) : data(rOther.data) {} 82 path(const std::string &in, convert) 83 { 84 rtl::OUString sWorkingDir; 85 osl_getProcessWorkingDir(&sWorkingDir.pData); 86 87 rtl::OString tmp(in.c_str()); 88 rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding())); 89 osl::File::getFileURLFromSystemPath(ustrSystemPath, data); 90 osl::File::getAbsoluteFileURL(sWorkingDir, data, data); 91 } 92 path(const std::string &FileURL) 93 { 94 rtl::OString tmp(FileURL.c_str()); 95 data = rtl::OStringToOUString(tmp, getThreadTextEncoding()); 96 } 97 std::string native_file_string() const 98 { 99 ::rtl::OUString ustrSystemPath; 100 osl::File::getSystemPathFromFileURL(data, ustrSystemPath); 101 rtl::OString tmp(rtl::OUStringToOString(ustrSystemPath, getThreadTextEncoding())); 102 HCDBG(std::cerr << "native_file_string is " << tmp.getStr() << std::endl); 103 return std::string(tmp.getStr()); 104 } 105 #ifdef WNT 106 wchar_t const * native_file_string_w() const 107 { 108 ::rtl::OUString ustrSystemPath; 109 osl::File::getSystemPathFromFileURL(data, ustrSystemPath); 110 return reinterpret_cast< wchar_t const * >(ustrSystemPath.getStr()); 111 } 112 #endif 113 std::string native_directory_string() const { return native_file_string(); } 114 std::string toUTF8() const 115 { 116 rtl::OString tmp(rtl::OUStringToOString(data, RTL_TEXTENCODING_UTF8)); 117 return std::string(tmp.getStr()); 118 } 119 bool empty() const { return data.getLength() == 0; } 120 path operator/(const std::string &in) const 121 { 122 path ret(*this); 123 HCDBG(std::cerr << "orig was " << 124 rtl::OUStringToOString(ret.data, RTL_TEXTENCODING_UTF8).getStr() << std::endl); 125 rtl::OString tmp(in.c_str()); 126 rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding())); 127 ret.data += rtl::OUString(sal_Unicode('/')); 128 ret.data += ustrSystemPath; 129 HCDBG(std::cerr << "final is " << 130 rtl::OUStringToOString(ret.data, RTL_TEXTENCODING_UTF8).getStr() << std::endl); 131 return ret; 132 } 133 void append(const char *in) 134 { 135 rtl::OString tmp(in); 136 rtl::OUString ustrSystemPath(rtl::OStringToOUString(tmp, getThreadTextEncoding())); 137 data = data + ustrSystemPath; 138 } 139 void append(const std::string &in) { append(in.c_str()); } 140 }; 141 142 void create_directory(const fs::path indexDirName); 143 void rename(const fs::path &src, const fs::path &dest); 144 void copy(const fs::path &src, const fs::path &dest); 145 bool exists(const fs::path &in); 146 void remove_all(const fs::path &in); 147 void remove(const fs::path &in); 148 } 149 150 struct joaat_hash 151 { 152 size_t operator()(const std::string &str) const 153 { 154 size_t hash = 0; 155 const char *key = str.data(); 156 for (size_t i = 0; i < str.size(); i++) 157 { 158 hash += key[i]; 159 hash += (hash << 10); 160 hash ^= (hash >> 6); 161 } 162 hash += (hash << 3); 163 hash ^= (hash >> 11); 164 hash += (hash << 15); 165 return hash; 166 } 167 }; 168 169 #define get16bits(d) ((((sal_uInt32)(((const sal_uInt8 *)(d))[1])) << 8)\ 170 +(sal_uInt32)(((const sal_uInt8 *)(d))[0]) ) 171 172 struct SuperFastHash 173 { 174 size_t operator()(const std::string &str) const 175 { 176 const char * data = str.data(); 177 int len = str.size(); 178 size_t hash = len, tmp; 179 if (len <= 0 || data == NULL) return 0; 180 181 int rem = len & 3; 182 len >>= 2; 183 184 /* Main loop */ 185 for (;len > 0; len--) 186 { 187 hash += get16bits (data); 188 tmp = (get16bits (data+2) << 11) ^ hash; 189 hash = (hash << 16) ^ tmp; 190 data += 2*sizeof (sal_uInt16); 191 hash += hash >> 11; 192 } 193 194 /* Handle end cases */ 195 switch (rem) 196 { 197 case 3: hash += get16bits (data); 198 hash ^= hash << 16; 199 hash ^= data[sizeof (sal_uInt16)] << 18; 200 hash += hash >> 11; 201 break; 202 case 2: hash += get16bits (data); 203 hash ^= hash << 11; 204 hash += hash >> 17; 205 break; 206 case 1: hash += *data; 207 hash ^= hash << 10; 208 hash += hash >> 1; 209 } 210 211 /* Force "avalanching" of final 127 bits */ 212 hash ^= hash << 3; 213 hash += hash >> 5; 214 hash ^= hash << 4; 215 hash += hash >> 17; 216 hash ^= hash << 25; 217 hash += hash >> 6; 218 219 return hash; 220 } 221 }; 222 223 #define pref_hash joaat_hash 224 225 typedef std::hash_map<std::string, std::string, pref_hash> Stringtable; 226 typedef std::list<std::string> LinkedList; 227 typedef std::vector<std::string> HashSet; 228 229 typedef std::hash_map<std::string, LinkedList, pref_hash> Hashtable; 230 231 class StreamTable 232 { 233 public: 234 std::string document_id; 235 std::string document_path; 236 std::string document_module; 237 std::string document_title; 238 239 HashSet *appl_hidlist; 240 Hashtable *appl_keywords; 241 Stringtable *appl_helptexts; 242 xmlDocPtr appl_doc; 243 244 HashSet *default_hidlist; 245 Hashtable *default_keywords; 246 Stringtable *default_helptexts; 247 xmlDocPtr default_doc; 248 249 StreamTable() : 250 appl_hidlist(NULL), appl_keywords(NULL), appl_helptexts(NULL), appl_doc(NULL), 251 default_hidlist(NULL), default_keywords(NULL), default_helptexts(NULL), default_doc(NULL) 252 {} 253 void dropdefault() 254 { 255 delete default_hidlist; 256 delete default_keywords; 257 delete default_helptexts; 258 if (default_doc) xmlFreeDoc(default_doc); 259 } 260 void dropappl() 261 { 262 delete appl_hidlist; 263 delete appl_keywords; 264 delete appl_helptexts; 265 if (appl_doc) xmlFreeDoc(appl_doc); 266 } 267 ~StreamTable() 268 { 269 dropappl(); 270 dropdefault(); 271 } 272 }; 273 274 struct HelpProcessingException 275 { 276 HelpProcessingErrorClass m_eErrorClass; 277 std::string m_aErrorMsg; 278 std::string m_aXMLParsingFile; 279 int m_nXMLParsingLine; 280 281 HelpProcessingException( HelpProcessingErrorClass eErrorClass, const std::string& aErrorMsg ) 282 : m_eErrorClass( eErrorClass ) 283 , m_aErrorMsg( aErrorMsg ) 284 {} 285 HelpProcessingException( const std::string& aErrorMsg, const std::string& aXMLParsingFile, int nXMLParsingLine ) 286 : m_eErrorClass( HELPPROCESSING_XMLPARSING_ERROR ) 287 , m_aErrorMsg( aErrorMsg ) 288 , m_aXMLParsingFile( aXMLParsingFile ) 289 , m_nXMLParsingLine( nXMLParsingLine ) 290 {} 291 }; 292 293 class HelpCompiler 294 { 295 public: 296 HelpCompiler(StreamTable &streamTable, 297 const fs::path &in_inputFile, 298 const fs::path &in_src, 299 const fs::path &in_resEmbStylesheet, 300 const std::string &in_module, 301 const std::string &in_lang, 302 bool in_bExtensionMode); 303 bool compile( void ) throw (HelpProcessingException); 304 void addEntryToJarFile(const std::string &prefix, 305 const std::string &entryName, const std::string &bytesToAdd); 306 void addEntryToJarFile(const std::string &prefix, 307 const std::string &entryName, const HashSet &bytesToAdd); 308 void addEntryToJarFile(const std::string &prefix, 309 const std::string &entryName, const Stringtable &bytesToAdd); 310 void addEntryToJarFile(const std::string &prefix, 311 const std::string &entryName, const Hashtable &bytesToAdd); 312 private: 313 xmlDocPtr getSourceDocument(const fs::path &filePath); 314 HashSet switchFind(xmlDocPtr doc); 315 xmlNodePtr clone(xmlNodePtr node, const std::string& appl); 316 StreamTable &streamTable; 317 const fs::path inputFile, src; 318 const std::string module, lang; 319 const fs::path resEmbStylesheet; 320 bool bExtensionMode; 321 }; 322 323 #endif 324 325 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 326