📄 libchmfileimpl.cpp
字号:
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;}bool LCHMFileImpl::ResolveObject(const QString& fileName, chmUnitInfo *ui) const{ return m_chmFile != NULL && ::chm_resolve_object(m_chmFile, fileName.ascii(), ui) == CHM_RESOLVE_SUCCESS;}size_t LCHMFileImpl::RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) const{#if USE_BUILTIN_CHMLIB return ::chm_retrieve_object(m_chmFile, ui, buffer, fileOffset, bufferSize);#else return ::chm_retrieve_object(m_chmFile, const_cast<chmUnitInfo*>(ui), buffer, fileOffset, bufferSize);#endif}inline u_int32_t LCHMFileImpl::GetLeafNodeOffset(const QString& text, u_int32_t initialOffset, u_int32_t buffSize, u_int16_t treeDepth){ u_int32_t test_offset = 0; unsigned char* cursor16, *cursor32; unsigned char word_len, pos; u_int32_t i = sizeof(u_int16_t); QMemArray<unsigned char> buffer(buffSize); QString word; while(--treeDepth) { if ( initialOffset == test_offset ) return 0; test_offset = initialOffset; if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), initialOffset, buffSize) == 0 ) return 0; cursor16 = buffer.data(); u_int16_t free_space = UINT16ARRAY(cursor16); while (i < buffSize - 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; if ( text <= word ) { cursor32 = buffer.data() + i + word_len + 1; initialOffset = UINT32ARRAY(cursor32); break; } i += word_len + sizeof(unsigned char) + sizeof(u_int32_t) + sizeof(u_int16_t); } } if ( initialOffset == test_offset ) return 0; return initialOffset;}inline bool LCHMFileImpl::ProcessWLC (u_int64_t wlc_count, u_int64_t wlc_size, u_int32_t wlc_offset, unsigned char ds, unsigned char dr, unsigned char cs, unsigned char cr, unsigned char ls, unsigned char lr, LCHMSearchProgressResults& results, bool phrase_search){ int wlc_bit = 7; u_int64_t index = 0, count; size_t length, off = 0; QMemArray<unsigned char> buffer (wlc_size); unsigned char *cursor32; unsigned char entry[TOPICS_ENTRY_LEN]; unsigned char combuf[13]; if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), wlc_offset, wlc_size) == 0 ) return false; for ( u_int64_t i = 0; i < wlc_count; ++i ) { if ( wlc_bit != 7 ) { ++off; wlc_bit = 7; } index += sr_int (buffer.data() + off, &wlc_bit, ds, dr, length); off += length; if ( RetrieveObject (&m_chmTOPICS, entry, index * 16, TOPICS_ENTRY_LEN) == 0 ) return false; LCHMSearchProgressResult progres; cursor32 = entry + 4; progres.titleoff = UINT32ARRAY(cursor32); cursor32 = entry + 8; progres.urloff = UINT32ARRAY(cursor32); if ( RetrieveObject (&m_chmURLTBL, combuf, progres.urloff, 12) == 0 ) return false; cursor32 = combuf + 8; progres.urloff = UINT32ARRAY (cursor32); count = sr_int (buffer.data() + off, &wlc_bit, cs, cr, length); off += length; if ( phrase_search ) progres.offsets.reserve (count); for (u_int64_t j = 0; j < count; ++j) { u_int64_t lcode = sr_int (buffer.data() + off, &wlc_bit, ls, lr, length); off += length; if ( phrase_search ) progres.offsets.push_back (lcode); } results.push_back (progres); } return true;}bool LCHMFileImpl::getInfoFromWindows(){#define WIN_HEADER_LEN 0x08 unsigned char buffer[BUF_SIZE]; unsigned int factor; chmUnitInfo ui; long size = 0; if ( ResolveObject("/#WINDOWS", &ui) ) { if ( !RetrieveObject(&ui, buffer, 0, WIN_HEADER_LEN) ) return false; u_int32_t entries = get_int32_le( (u_int32_t *)(buffer) ); u_int32_t entry_size = get_int32_le( (u_int32_t *)(buffer + 0x04) ); QByteArray uptr(entries * entry_size); unsigned char* raw = (unsigned char*) uptr.data(); if ( !RetrieveObject (&ui, raw, 8, entries * entry_size) ) return false; if( !ResolveObject ("/#STRINGS", &ui) ) return false; for ( u_int32_t i = 0; i < entries; ++i ) { u_int32_t offset = i * entry_size; u_int32_t off_title = get_int32_le( (u_int32_t *)(raw + offset + 0x14) ); u_int32_t off_home = get_int32_le( (u_int32_t *)(raw + offset + 0x68) ); u_int32_t off_hhc = get_int32_le( (u_int32_t *)(raw + offset + 0x60) ); u_int32_t off_hhk = get_int32_le( (u_int32_t *)(raw + offset + 0x64) ); factor = off_title / 4096; if ( size == 0 ) size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); if ( size && off_title ) m_title = QString ((const char*) (buffer + off_title % 4096)); if ( factor != off_home / 4096) { factor = off_home / 4096; size = RetrieveObject (&ui, buffer, factor * 4096, BUF_SIZE); } if ( size && off_home ) m_home = QString("/") + QString( (const char*) buffer + off_home % 4096); if ( factor != off_hhc / 4096) { factor = off_hhc / 4096; size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); } if ( size && off_hhc ) m_topicsFile = QString("/") + QString ((const char*) buffer + off_hhc % 4096); if ( factor != off_hhk / 4096) { factor = off_hhk / 4096; size = RetrieveObject (&ui, buffer, factor * 4096, BUF_SIZE); } if ( size && off_hhk ) m_indexFile = QString("/") + QString((const char*) buffer + off_hhk % 4096); } } return true;}bool LCHMFileImpl::getInfoFromSystem(){ unsigned char buffer[BUF_SIZE]; chmUnitInfo ui; int index = 0; unsigned char* cursor = NULL, *p; u_int16_t value = 0; long size = 0; // Run the first loop to detect the encoding. We need this, because title could be // already encoded in user encoding. Same for file names if ( !ResolveObject ("/#SYSTEM", &ui) ) return false; // Can we pull BUFF_SIZE bytes of the #SYSTEM file? if ( (size = RetrieveObject (&ui, buffer, 4, BUF_SIZE)) == 0 ) return false; buffer[size - 1] = 0; // First loop to detect the encoding for ( index = 0; index < (size - 1 - (long)sizeof(u_int16_t)) ;) { cursor = buffer + index; value = UINT16ARRAY(cursor); switch(value) { case 0: index += 2; cursor = buffer + index; if(m_topicsFile.isEmpty()) m_topicsFile = QString("/") + QString((const char*) buffer + index + 2); break; case 1: index += 2; cursor = buffer + index; if(m_indexFile.isEmpty()) m_indexFile = QString("/") + QString ((const char*)buffer + index + 2); break; case 2: index += 2; cursor = buffer + index; if(m_home.isEmpty() || m_home == "/") m_home = QString("/") + QString ((const char*) buffer + index + 2); break; case 3: index += 2; cursor = buffer + index; m_title = QString((const char*) (buffer + index + 2)); break; case 4: index += 2; cursor = buffer + index; p = buffer + index + 2; m_detectedLCID = (short) (p[0] | (p[1]<<8)); break; case 6: index += 2; cursor = buffer + index; if(m_topicsFile.isEmpty()) { QString topicAttempt = "/", tmp; topicAttempt += QString ((const char*) buffer +index +2); tmp = topicAttempt + ".hhc"; if ( ResolveObject (tmp.ascii(), &ui) ) m_topicsFile = tmp; tmp = topicAttempt + ".hhk"; if ( ResolveObject(tmp.ascii(), &ui) ) m_indexFile = tmp; } break; case 16: index += 2; cursor = buffer + index; m_font = QString ((const char*) buffer + index + 2); break; default: index += 2; cursor = buffer + index; } value = UINT16ARRAY(cursor); index += value + 2; } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -