Logo Search packages:      
Sourcecode: kchmviewer version File versions  Download package

bool CHMFile::SearchWord ( const QString &  word,
bool  wholeWords,
bool  titlesOnly,
KCHMSearchProgressResults_t &  results,
bool  phrase_search 
)

Fast search using the $FIftiMain file in the .chm.

Parameters:
text The text we're looking for.
wholeWords Are we looking for whole words only?
titlesOnly Are we looking for titles only?
results A string-string hashmap that will hold the results in case of successful search. The keys are the URLs and the values are the page titles.
phrase_search Indicates that word offset information should be kept.
Returns:
true if the search found something, false otherwise.

Definition at line 519 of file xchmfile.cpp.

References convertSearchWord(), GetLeafNodeOffset(), m_chmFIftiMain, m_searchAvailable, ProcessWLC(), and RetrieveObject().

{
      bool partial = false;

      if ( text.isEmpty() || !m_searchAvailable )
            return false;

      QString searchword = (QString) convertSearchWord (text);

#define FTS_HEADER_LEN 0x32
      unsigned char header[FTS_HEADER_LEN];

      if ( RetrieveObject (&m_chmFIftiMain, header, 0, FTS_HEADER_LEN) == 0 )
            return false;
      
      unsigned char doc_index_s = header[0x1E], doc_index_r = header[0x1F];
      unsigned char code_count_s = header[0x20], code_count_r = header[0x21];
      unsigned char loc_codes_s = header[0x22], loc_codes_r = header[0x23];

      if(doc_index_s != 2 || code_count_s != 2 || loc_codes_s != 2)
      {
            // Don't know how to use values other than 2 yet. Maybe next chmspec.
            return false;
      }

      unsigned char* cursor32 = header + 0x14;
      u_int32_t node_offset = UINT32ARRAY(cursor32);

      cursor32 = header + 0x2e;
      u_int32_t node_len = UINT32ARRAY(cursor32);

      unsigned char* cursor16 = header + 0x18;
      u_int16_t tree_depth = UINT16ARRAY(cursor16);

      unsigned char word_len, pos;
      QString word;
      u_int32_t i = sizeof(u_int16_t);
      u_int16_t free_space;

      QMemArray<unsigned char> buffer(node_len);

      node_offset = GetLeafNodeOffset (searchword, node_offset, node_len, tree_depth);

      if ( !node_offset )
            return false;

      do
      {
            // got a leaf node here.
            if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), node_offset, node_len) == 0 )
                  return false;

            cursor16 = buffer.data() + 6;
            free_space = UINT16ARRAY(cursor16);

            i = sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int16_t);
            u_int64_t wlc_count, wlc_size;
            u_int32_t wlc_offset;

            while (i < node_len - free_space)
            {
                  word_len = *(buffer.data() + i);
                  pos = *(buffer.data() + i + 1);

                  char *wrd_buf = new char[word_len];
                  memcpy (wrd_buf, buffer.data() + i + 2, word_len - 1);
                  wrd_buf[word_len - 1] = 0;

                  if ( pos == 0 )
                        word = wrd_buf;
                  else
                        word = word.mid (0, pos) + wrd_buf;

                  delete[] wrd_buf;

                  i += 2 + word_len;
                  unsigned char title = *(buffer.data() + i - 1);

                  size_t encsz;
                  wlc_count = be_encint (buffer.data() + i, encsz);
                  i += encsz;
            
                  cursor32 = buffer.data() + i;
                  wlc_offset = UINT32ARRAY(cursor32);

                  i += sizeof(u_int32_t) + sizeof(u_int16_t);
                  wlc_size =  be_encint (buffer.data() + i, encsz);
                  i += encsz;

                  cursor32 = buffer.data();
                  node_offset = UINT32ARRAY(cursor32);
            
                  if ( !title && titlesOnly )
                        continue;

                  if ( wholeWords && searchword == word )
                        return ProcessWLC(wlc_count, wlc_size,
                                      wlc_offset, doc_index_s,
                                      doc_index_r,code_count_s,
                                      code_count_r, loc_codes_s,
                                      loc_codes_r, results, phrase_search);

                  if ( !wholeWords )
                  {
                        if ( word.startsWith (searchword))
                        {
                              partial = true;
                              
                              ProcessWLC(wlc_count, wlc_size,
                                       wlc_offset, doc_index_s,
                                       doc_index_r,code_count_s,
                                       code_count_r, loc_codes_s,
                                       loc_codes_r, results, phrase_search);

                        }
                        else if ( QString::compare (searchword, word.mid(0, searchword.length())) < -1 )
                              break;
                  }
            }     
      }
      while ( !wholeWords && word.startsWith (searchword) && node_offset );
      
      return partial;
}


Generated by  Doxygen 1.6.0   Back to index