Main Page   Namespace List   Compound List   File List   Compound Members   File Members  

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 #if __BYTE_ORDER == __LITTLE_ENDIAN // convenience shortcut
00179     unsigned long res = 0;  // long guatanteed to be 4 bytes
00180     read ((char *)&res, 4);
00181     return res;
00182 #else
00183     char buf[4];
00184     read (buf, 4);
00185     size_t res = buf[0];
00186     res |= buf[1] << 8;
00187     res |= buf[2] << 16;
00188     res |= buf[3] << 24;
00189     return res;
00190 #endif
00191   }
00192 
00195   inline unsigned int get_word ()
00196   {
00197 #if __BYTE_ORDER == __LITTLE_ENDIAN // convenience shortcut
00198     unsigned int res = 0;   // int guaranteed to be 2 bytes
00199     read ((char *)&res, 2);
00200     return res;
00201 #else
00202     char buf[2];
00203     read (buf, 2);
00204     unsigned int res = buf[0];
00205     res |= buf[1] << 8;
00206     return res;
00207 #endif
00208   }
00209 
00213   inline unsigned long get_sr (int s, int r, int& pos)
00214   {
00215     int b = peek();
00216     int p = 0;
00217     while ( (1 << pos) & b ) {
00218         p++;
00219         pos++;
00220         if ( pos == 8 ) {
00221             get();
00222             b = peek ();
00223             pos = 0;
00224         }
00225     }
00226 
00227     pos++;    // skip the 0 of p
00228     if ( pos == 8 ) {
00229         get ();
00230         b = peek ();
00231         pos = 0;
00232     }
00233 
00234     if ( p > 1 ) r += p - 1; // r now has number of bits for q
00235 
00236     unsigned long res = 0;
00237 
00238     for ( int i = 0; i < r; i++ ) {
00239         res |= ((1 << pos) & b) ? (1 << i) : 0;
00240         pos++;
00241         if ( pos == 8 ) {
00242             get ();
00243             b = peek ();
00244             pos = 0;
00245         }
00246     }
00247 
00248     res |= 1 << r;
00249 
00250     return res;
00251   }
00252 
00253   inline void get_sr_finish (int &pos)
00254   {
00255     if ( pos ) {
00256         get();
00257         pos = 0;
00258     }
00259   }
00260 
00261 private:
00262   std::streambuf *buf;
00263   bool release;
00264 };
00265 
00266 }
00267 
00268 #endif // __chm_h__
00269 

Copyright © 2003 Indrek Mandre