📄 chmfile.cpp
字号:
return (retw || rets);}inline u_int32_t CHMFile::GetLeafNodeOffset(const wxString& text, u_int32_t initialOffset, u_int32_t buffSize, u_int16_t treeDepth, chmUnitInfo *ui){ u_int32_t test_offset = 0; unsigned char* cursor16; unsigned char* cursor32; unsigned char word_len, pos; u_int32_t i = sizeof(u_int16_t); UCharPtr buffer(new unsigned char[buffSize]); wxString word; if(!buffer.get()) return 0; while(--treeDepth) { if(initialOffset == test_offset) return 0; test_offset = initialOffset; if(::chm_retrieve_object(_chmFile, ui, buffer.get(), initialOffset, buffSize) == 0) return 0; cursor16 = buffer.get(); u_int16_t free_space = UINT16ARRAY(cursor16); while(i < buffSize - free_space) { word_len = *(buffer.get() + i); pos = *(buffer.get() + i + 1); char *wrd_buf = new char[word_len]; memcpy(wrd_buf, buffer.get() + i + 2, word_len - 1); wrd_buf[word_len - 1] = 0; if(pos == 0) word = CURRENT_CHAR_STRING(wrd_buf); else word = word.Mid(0, pos) + CURRENT_CHAR_STRING(wrd_buf); delete[] wrd_buf; if(text.CmpNoCase(word) <= 0) { cursor32 = buffer.get() + 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 CHMFile::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, chmUnitInfo *uimain, chmUnitInfo* uitbl, chmUnitInfo *uistrings, chmUnitInfo* topics, chmUnitInfo *urlstr, CHMSearchResults *results){ int wlc_bit = 7; u_int64_t index = 0, count; size_t length, off = 0; UCharPtr buffer(new unsigned char[wlc_size]); unsigned char *cursor32; u_int32_t stroff, urloff;#define TOPICS_ENTRY_LEN 16 unsigned char entry[TOPICS_ENTRY_LEN];#define COMMON_BUF_LEN 1025 unsigned char combuf[COMMON_BUF_LEN]; if(::chm_retrieve_object(_chmFile, uimain, buffer.get(), 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.get() + off, &wlc_bit, ds, dr, length); off += length; if(::chm_retrieve_object(_chmFile, topics, entry, index * 16, TOPICS_ENTRY_LEN) == 0) return false; cursor32 = entry + 4; combuf[COMMON_BUF_LEN - 1] = 0; stroff = UINT32ARRAY(cursor32); wxString topic; if(::chm_retrieve_object(_chmFile, uistrings, combuf, stroff, COMMON_BUF_LEN - 1) == 0) { topic = wxString(_("Untitled in index")); } else { combuf[COMMON_BUF_LEN - 1] = 0;#if wxUSE_UNICODE if(_enc == wxFONTENCODING_SYSTEM)#endif topic = CURRENT_CHAR_STRING(combuf);#if wxUSE_UNICODE else { wxCSConv cv(_enc); topic = wxString((const char *)combuf, cv); }#endif } cursor32 = entry + 8; urloff = UINT32ARRAY(cursor32); if(::chm_retrieve_object(_chmFile, uitbl, combuf, urloff, 12) == 0) return false; cursor32 = combuf + 8; urloff = UINT32ARRAY(cursor32); if(::chm_retrieve_object(_chmFile, urlstr, combuf, urloff + 8, COMMON_BUF_LEN - 1) == 0) return false; combuf[COMMON_BUF_LEN - 1] = 0; wxString url = CURRENT_CHAR_STRING(combuf); if(!url.IsEmpty() && !topic.IsEmpty()) { if(results->size() >= MAX_SEARCH_RESULTS) return true; (*results)[url] = topic; } count = sr_int(buffer.get() + off, &wlc_bit, cs, cr, length); off += length; for(u_int64_t j = 0; j < count; ++j) { sr_int(buffer.get() + off, &wlc_bit, ls, lr, length); off += length; } } return true;}inlinevoid CHMFile::GetFileAsString(wxString& str, chmUnitInfo *ui){#define BUF_SIZE2 1025 char buffer[BUF_SIZE2]; size_t ret = BUF_SIZE2 - 1, curr = 0; buffer[0] = '\0'; do { ret = RetrieveObject(ui, reinterpret_cast<unsigned char *>( buffer), curr, BUF_SIZE2 - 1); buffer[ret] = '\0'; str.Append(CURRENT_CHAR_STRING(buffer)); curr += ret; } while(ret == BUF_SIZE2 - 1);}inlinebool CHMFile::InfoFromWindows(){#define WIN_HEADER_LEN 0x08 unsigned char buffer[BUF_SIZE]; unsigned int factor; chmUnitInfo ui; long size = 0; if(::chm_resolve_object(_chmFile, "/#WINDOWS", &ui) == CHM_RESOLVE_SUCCESS) { if(!::chm_retrieve_object(_chmFile, &ui, buffer, 0, WIN_HEADER_LEN)) return false; u_int32_t entries = *(u_int32_t *)(buffer); FIXENDIAN32(entries); u_int32_t entry_size = *(u_int32_t *)(buffer + 0x04); FIXENDIAN32(entry_size); UCharPtr uptr(new unsigned char[entries * entry_size]); unsigned char* raw = uptr.get(); if(!::chm_retrieve_object(_chmFile, &ui, raw, 8, entries * entry_size)) return false; if(::chm_resolve_object(_chmFile, "/#STRINGS", &ui) != CHM_RESOLVE_SUCCESS) return false; for(u_int32_t i = 0; i < entries; ++i) { u_int32_t offset = i * entry_size; u_int32_t off_title = *(u_int32_t *)(raw + offset + 0x14); FIXENDIAN32(off_title); u_int32_t off_home = *(u_int32_t *)(raw + offset + 0x68); FIXENDIAN32(off_home); u_int32_t off_hhc = *(u_int32_t *)(raw + offset + 0x60); FIXENDIAN32(off_hhc); u_int32_t off_hhk = *(u_int32_t *)(raw + offset + 0x64); FIXENDIAN32(off_hhk); factor = off_title / 4096; if(size == 0) size = ::chm_retrieve_object(_chmFile, &ui, buffer, factor * 4096, BUF_SIZE); if(size && off_title) _title = CURRENT_CHAR_STRING(buffer + off_title % 4096); if(factor != off_home / 4096) { factor = off_home / 4096; size = ::chm_retrieve_object(_chmFile, &ui, buffer, factor * 4096, BUF_SIZE); } if(size && off_home) _home = wxString(wxT("/")) + CURRENT_CHAR_STRING(buffer + off_home % 4096); if(factor != off_hhc / 4096) { factor = off_hhc / 4096; size = ::chm_retrieve_object(_chmFile, &ui, buffer, factor * 4096, BUF_SIZE); } if(size && off_hhc) { _topicsFile = wxString(wxT("/")) + CURRENT_CHAR_STRING(buffer + off_hhc % 4096); } if(factor != off_hhk / 4096) { factor = off_hhk / 4096; size = ::chm_retrieve_object(_chmFile, &ui, buffer, factor * 4096, BUF_SIZE); } if(size && off_hhk) _indexFile = wxString(wxT("/")) + CURRENT_CHAR_STRING(buffer + off_hhk % 4096); } } return true;}inlinebool CHMFile::InfoFromSystem(){ unsigned char buffer[BUF_SIZE]; chmUnitInfo ui; int index = 0; unsigned char* cursor = NULL; u_int16_t value = 0; u_int32_t lcid = 0; long size = 0; long cs = -1; // Do we have the #SYSTEM file in the archive? if(::chm_resolve_object(_chmFile, "/#SYSTEM", &ui) != CHM_RESOLVE_SUCCESS) return false; // Can we pull BUFF_SIZE bytes of the #SYSTEM file? if((size = ::chm_retrieve_object(_chmFile, &ui, buffer, 4, BUF_SIZE)) == 0) return false; buffer[size - 1] = 0; for(;;) { // This condition won't hold if I process anything // except NUL-terminated strings! if(index > size - 1 - (long)sizeof(u_int16_t)) break; cursor = buffer + index; value = UINT16ARRAY(cursor); switch(value) { case 0: index += 2; cursor = buffer + index; if(_topicsFile.IsEmpty()) _topicsFile = wxString(wxT("/")) + CURRENT_CHAR_STRING(buffer + index + 2); break; case 1: index += 2; cursor = buffer + index; if(_indexFile.IsEmpty()) _indexFile = wxString(wxT("/")) + CURRENT_CHAR_STRING(buffer + index + 2); break; case 2: index += 2; cursor = buffer + index; if(_home.IsEmpty() || _home == wxString(wxT("/"))) _home = wxString(wxT("/")) + CURRENT_CHAR_STRING(buffer + index + 2); break; case 3: index += 2; cursor = buffer + index; if(_title.IsEmpty()) _title = CURRENT_CHAR_STRING(buffer + index + 2); break; case 4: // LCID stuff index += 2; cursor = buffer + index; lcid = UINT32ARRAY(buffer + index + 2); _enc = GetFontEncFromLCID(lcid); break; case 6: index += 2; cursor = buffer + index; if(_topicsFile.IsEmpty()) { wxString topicAttempt = wxT("/"), tmp; topicAttempt += CURRENT_CHAR_STRING(buffer +index +2); tmp = topicAttempt + wxT(".hhc"); if(chm_resolve_object(_chmFile, tmp.mb_str(), &ui) == CHM_RESOLVE_SUCCESS) _topicsFile = tmp; tmp = topicAttempt + wxT(".hhk"); if(chm_resolve_object(_chmFile, tmp.mb_str(), &ui) == CHM_RESOLVE_SUCCESS) _indexFile = tmp; } break; case 16: index += 2; cursor = buffer + index; _font = CURRENT_CHAR_STRING(buffer + index + 2); _font.AfterLast(wxT(',')).ToLong(&cs); if(_enc != wxFONTENCODING_SYSTEM) break; _enc = GetFontEncFromCharSet(cs); break; default: index += 2; cursor = buffer + index; } value = UINT16ARRAY(cursor); index += value + 2; } return true;}inlinewxFontEncoding CHMFile::GetFontEncFromCharSet(int cs){ wxFontEncoding fontEncoding; switch(cs) { case ANSI_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_1; break; case EASTEUROPE_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_2; break; case BALTIC_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_13; break; case RUSSIAN_CHARSET: fontEncoding = wxFONTENCODING_CP1251; break; case ARABIC_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_6; break; case GREEK_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_7; break; case HEBREW_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_8; break; case TURKISH_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_9; break; case THAI_CHARSET: fontEncoding = wxFONTENCODING_ISO8859_11; break; case SHIFTJIS_CHARSET: fontEncoding = wxFONTENCODING_CP932; break; case GB2312_CHARSET: fontEncoding = wxFONTENCODING_CP936; break; case HANGUL_CHARSET: fontEncoding = wxFONTENCODING_CP949; break; case CHINESEBIG5_CHARSET: fontEncoding = wxFONTENCODING_CP950; break; case OEM_CHARSET: fontEncoding = wxFONTENCODING_CP437; break; default: // assume the system charset fontEncoding = wxFONTENCODING_SYSTEM; break; } return fontEncoding;}inline wxFontEncoding CHMFile::GetFontEncFromLCID(u_int32_t lcid){ wxFontEncoding fontEncoding; u_int32_t lid = lcid & 0xff; switch(lid) { case LANG_ARABIC: fontEncoding = wxFONTENCODING_ISO8859_6; break; case LANG_RUSSIAN: fontEncoding = wxFONTENCODING_CP1251; break; case LANG_UKRAINIAN: fontEncoding = wxFONTENCODING_KOI8_U; break; case LANG_BULGARIAN: fontEncoding = wxFONTENCODING_BULGARIAN; break; case LANG_GREEK: fontEncoding = wxFONTENCODING_ISO8859_7; break; case LANG_HEBREW: fontEncoding = wxFONTENCODING_ISO8859_8; break; case LANG_THAI: fontEncoding = wxFONTENCODING_ISO8859_11; break; case LANG_TURKISH: fontEncoding = wxFONTENCODING_ISO8859_9; break; case LANG_CHINESE: fontEncoding = wxFONTENCODING_CP950; break; case LANG_KOREAN: fontEncoding = wxFONTENCODING_CP949; break; case LANG_JAPANESE: fontEncoding = wxFONTENCODING_CP932; break; case LANG_NEUTRAL: default: fontEncoding = wxFONTENCODING_SYSTEM; break; } return fontEncoding;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -