⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chmxx.h

📁 It is a chm file viewer lib with source code
💻 H
字号:
#ifndef __chm_h__#define __chm_h__#include <string>#include <ostream>#include <istream>#include <vector>#include <list>#include <map>/** * @mainpage * This is a c++ library for accessing the Microsoft(TM) * help files (mostly .chm files).<br> For latest updates * and more information please see<br> *      <ul>http://www.mare.ee/indrek/libchmxx/</ul> */struct chmFile;/** This is the namespace for libchmxx library.  * The library should not export any sumbols to global  * namespace.  */namespace chm {/** This represents a tree of topics with titles and paths. */struct chm_topics_tree {  std::string title;  ///< Title of the tree node  std::string path;   ///< Path to file under given topic or empty  chm_topics_tree *parent; ///< Pointer to parent tree node, NULL if no parent  std::list<chm_topics_tree *> children; ///< std::list of children node  ~chm_topics_tree ();};/** Matched document inside the search result. */struct chm_search_document {  std::string title;                ///< Document title.  std::string path;                 ///< Document path.  std::vector<int> offsets;         ///< Where inside this document the result was found};/** Search match for keyword found inside the index. */struct chm_search_match {  int is_title;                    ///< Given key is inside a title  std::string key;                  ///< Key that was found inside the index.  std::vector<chm_search_document> documents; ///< Documents matching to this index.};/** A chm archive. */class chmfile {public:  /** Construct a new chmfile object from given path. */  chmfile (const std::string& path);  virtual ~chmfile ();  /** Tests whether archive is valid and open. */  bool is_open () const;  /** Close the archive and free resources. */  void close ();  /** Tests whether opened archive is valid. */  inline operator bool() const { return is_open(); }  /** Read the entire contents of given file and write to stream out. */  bool read (const std::string& path, std::ostream& out) const;  /** Read the entire contents of a file and store inside given vector.   * The vector is resized to file size. */  bool read (const std::string& path, std::vector<char>& out) const;  /** Read buf_size bytes from path and place into buf. */  bool read (const std::string& path, char *buf, size_t buf_size) const;  /** Returns the size of given file inside archive, returns 0 if file does not exist. */  std::streamsize file_size (const std::string& path) const;  /** Returns a boolean value whether given file exists inside the archive. */  bool file_exists (const std::string& path) const;  /** Use a combination of these as argument to the readdir. */  enum readdir_type { files = 1, dirs = 2, special = 4, meta = 8 };  /** Read entries under given path and append them to the list.    * Files of directory type will have '/' at the end of their names. */  bool readdir (const std::string& path, std::list<std::string>& entries, int type = files|dirs) const;  /** Open given path inside the archive for reading and return a streambuf object.    * Returns 0 in case file does not exist or an error happened. You're    * better off to using chmistream than this method. The returned object should    * be deleted after use. */  std::streambuf* open (const std::string& path, size_t buf_size = 1024) const;  inline const std::string& get_title () const { return title; }  inline const std::string& get_home_file () const { return home_file; }  inline const std::string& get_generator () const { return generator; }  inline const std::string& get_index_file () const { return index_file; }  inline const std::string& get_topics_file () const { return topics_file; }  inline const std::string& get_path () const { return path; }  /** Gets the topics tree. If this is called first time the tree    * is calculated and stored for later use. In case the chm file    * has no soptics tree NULL is returned. */  const chm_topics_tree * get_topics_tree () const;  /** Search the archive for given keyword and return found entries in found. */  bool search_index (const std::string& txt, std::list<chm_search_match>& found,      bool whole_words = true, bool titles_only = true) const;  /** Cache given file for _fast_ access inside memory. All streams opened    * for that file will be memory cached. I know this caching business    * is a bit superfluous. It's not all good too - if you start    * unreading stuff using the stream the cache will be changed.    */  bool cache (const std::string& path);  /** Cache all metadata that is required to perform fast searches inside the index. */  void cache_search_database ();private:  mutable chmFile *chm;  std::string path;  std::string title, home_file, generator, index_file, topics_file;  mutable chm_topics_tree *tree;  chmfile (const chmfile&);  chmfile& operator= (const chmfile&);  typedef std::map<std::string,std::vector<char> > cache_data_t;  cache_data_t cache_data;};/** Inputstream for reading files inside a chm archives.  * @code        chm::chmfile chm("/chmfile.chm");        chm::chmistream in(chm, "/path");        string line;        while ( readline(chm, line) ) {            cout << line;        }  * @endcode  */class chmistream : public std::istream {public:  /** Create a new input stream from archive for given path. */  chmistream (const chmfile& chm, const std::string& path, size_t buf_size = 1024);  /** Returns the number of bytes that are left to be read from this stream.   * So returns the size of file when nothing has been read. */  std::streamsize read_left () const;  virtual ~chmistream ();  /** Get little endian MS encint from the stream. */  inline size_t get_encint()  {      size_t result = 0;      int shift = 0;      while (1) {          int n = get();          result |= (n & 0x7f) << shift;          shift += 7;          if ( !(n & 0x80) ) break;      };      return result;  }  /** Get local endianized MS dword (2 x 2 bytes) from the stream. */  inline unsigned long get_dword ()  {#if __BYTE_ORDER == __LITTLE_ENDIAN // convenience shortcut    unsigned long res = 0;  // long guatanteed to be 4 bytes    read ((char *)&res, 4);    return res;#else    char buf[4];    read (buf, 4);    size_t res = buf[0];    res |= buf[1] << 8;    res |= buf[2] << 16;    res |= buf[3] << 24;    return res;#endif  }  /** Get local endianized MS word (2 bytes) from the stream.    */  inline unsigned int get_word ()  {#if __BYTE_ORDER == __LITTLE_ENDIAN // convenience shortcut    unsigned int res = 0;   // int guaranteed to be 2 bytes    read ((char *)&res, 2);    return res;#else    char buf[2];    read (buf, 2);    unsigned int res = buf[0];    res |= buf[1] << 8;    return res;#endif  }  /** Get a s-r encoded value from the stream. Scale must alwqays be 2.    * Use 0 for initial pos. When finished reading an entry of sr-s    * call the get_sr_finish(pos).*/  inline unsigned long get_sr (int s, int r, int& pos)  {    int b = peek();    int p = 0;    while ( (1 << pos) & b ) {        p++;        pos++;        if ( pos == 8 ) {            get();            b = peek ();            pos = 0;        }    }    pos++;    // skip the 0 of p    if ( pos == 8 ) {        get ();        b = peek ();        pos = 0;    }    if ( p > 1 ) r += p - 1; // r now has number of bits for q    unsigned long res = 0;    for ( int i = 0; i < r; i++ ) {        res |= ((1 << pos) & b) ? (1 << i) : 0;        pos++;        if ( pos == 8 ) {            get ();            b = peek ();            pos = 0;        }    }    res |= 1 << r;    return res;  }  inline void get_sr_finish (int &pos)  {    if ( pos ) {        get();        pos = 0;    }  }private:  std::streambuf *buf;  bool release;};}#endif // __chm_h__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -