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