chmxx.h

Go to the documentation of this file.
00001 
00002 #ifndef __chm_h__
00003 #define __chm_h__
00004 
00005 #include <string>
00006 #include <ostream>
00007 #include <istream>
00008 #include <vector>
00009 #include <list>
00010 #include <map>
00011 
00021 struct chmFile;
00022 
00027 namespace chm {
00028 
00030 struct chm_topics_tree {
00031   std::string title;  
00032   std::string path;   
00033   chm_topics_tree *parent; 
00034   std::list<chm_topics_tree *> children; 
00035 
00036   ~chm_topics_tree ();
00037 };
00038 
00040 struct chm_search_document {
00041   std::string title;                
00042   std::string path;                 
00043   std::vector<int> offsets;         
00044 };
00045 
00047 struct chm_search_match {
00048   int is_title;                    
00049   std::string key;                  
00050   std::vector<chm_search_document> documents; 
00051 };
00052 
00054 class chmfile {
00055 public:
00057   chmfile (const std::string& path);
00058   virtual ~chmfile ();
00059 
00061   bool is_open () const;
00062 
00064   void close ();
00065 
00067   inline operator bool() const { return is_open(); }
00068 
00070   bool read (const std::string& path, std::ostream& out) const;
00071 
00074   bool read (const std::string& path, std::vector<char>& out) const;
00075 
00077   bool read (const std::string& path, char *buf, size_t buf_size) const;
00078 
00080   std::streamsize file_size (const std::string& path) const;
00081 
00083   bool file_exists (const std::string& path) const;
00084 
00086   enum readdir_type { files = 1, dirs = 2, special = 4, meta = 8 };
00087 
00090   bool readdir (const std::string& path, std::list<std::string>& entries, int type = files|dirs) const;
00091 
00096   std::streambuf* open (const std::string& path, size_t buf_size = 1024) const;
00097 
00098   inline const std::string& get_title () const { return title; }
00099   inline const std::string& get_home_file () const { return home_file; }
00100   inline const std::string& get_generator () const { return generator; }
00101   inline const std::string& get_index_file () const { return index_file; }
00102   inline const std::string& get_topics_file () const { return topics_file; }
00103   inline const std::string& get_path () const { return path; }
00104 
00108   const chm_topics_tree * get_topics_tree () const;
00109 
00111   bool search_index (const std::string& txt, std::list<chm_search_match>& found,
00112       bool whole_words = true, bool titles_only = true) const;
00113 
00119   bool cache (const std::string& path);
00121   void cache_search_database ();
00122 
00123 private:
00124   mutable chmFile *chm;
00125   std::string path;
00126 
00127   std::string title, home_file, generator, index_file, topics_file;
00128 
00129   mutable chm_topics_tree *tree;
00130 
00131   chmfile (const chmfile&);
00132   chmfile& operator= (const chmfile&);
00133 
00134   typedef std::map<std::string,std::vector<char> > cache_data_t;
00135   cache_data_t cache_data;
00136 };
00137 
00148 class chmistream : public std::istream {
00149 public:
00151   chmistream (const chmfile& chm, const std::string& path, size_t buf_size = 1024);
00152 
00155   std::streamsize read_left () const;
00156 
00157   virtual ~chmistream ();
00158 
00160   inline size_t get_encint()
00161   {
00162       size_t result = 0;
00163       int shift = 0;
00164 
00165       while (1) {
00166           int n = get();
00167           result |= (n & 0x7f) << shift;
00168           shift += 7;
00169           if ( !(n & 0x80) ) break;
00170       };
00171 
00172       return result;
00173   }
00174 
00176   inline unsigned long get_dword ()
00177   {
00178     char buf[4];
00179     read (buf, 4);
00180     size_t res = 0;
00181     res |= (unsigned char)buf[0] << 0;
00182     res |= (unsigned char)buf[1] << 8;
00183     res |= (unsigned char)buf[2] << 16;
00184     res |= (unsigned char)buf[3] << 24;
00185     return res;
00186   }
00187 
00190   inline unsigned int get_word ()
00191   {
00192     char buf[2];
00193     read (buf, 2);
00194     unsigned int res = 0;
00195     res |= (unsigned char)buf[0] << 0;
00196     res |= (unsigned char)buf[1] << 8;
00197     return res;
00198   }
00199 
00203   inline unsigned long get_sr (int /*s*/, int r, int& pos)
00204   {
00205     int b = peek();
00206     int p = 0;
00207     while ( (1 << pos) & b ) {
00208         p++;
00209         pos++;
00210         if ( pos == 8 ) {
00211             get();
00212             b = peek ();
00213             pos = 0;
00214         }
00215     }
00216 
00217     pos++;    // skip the 0 of p
00218     if ( pos == 8 ) {
00219         get ();
00220         b = peek ();
00221         pos = 0;
00222     }
00223 
00224     if ( p > 1 ) r += p - 1; // r now has number of bits for q
00225 
00226     unsigned long res = 0;
00227 
00228     for ( int i = 0; i < r; i++ ) {
00229         res |= ((1 << pos) & b) ? (1 << i) : 0;
00230         pos++;
00231         if ( pos == 8 ) {
00232             get ();
00233             b = peek ();
00234             pos = 0;
00235         }
00236     }
00237 
00238     res |= 1 << r;
00239 
00240     return res;
00241   }
00242 
00243   inline void get_sr_finish (int &pos)
00244   {
00245     if ( pos ) {
00246         get();
00247         pos = 0;
00248     }
00249   }
00250 
00251 private:
00252   std::streambuf *buf;
00253   bool release;
00254 };
00255 
00256 }
00257 
00258 #endif // __chm_h__
00259 

Copyright © 2003, 2008 Indrek Mandre