[PATCH 12/45] [WinHelp]: no longer loading all the pages at once, but instead reference the pages at once, and then allow to browse them one by one
Eric Pouech
eric.pouech at orange.fr
Sun Mar 23 04:18:19 CDT 2008
A+
---
programs/winhelp/hlpfile.c | 126 ++++++++++++++++++++++++++++++++++++--------
programs/winhelp/hlpfile.h | 3 +
2 files changed, 105 insertions(+), 24 deletions(-)
diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c
index 55bb0c2..3c7ee7b 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -63,8 +63,8 @@ static BOOL HLPFILE_Uncompress_Topic(HLPFILE*);
static BOOL HLPFILE_GetContext(HLPFILE*);
static BOOL HLPFILE_GetKeywords(HLPFILE*);
static BOOL HLPFILE_GetMap(HLPFILE*);
-static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned);
-static BOOL HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*);
+static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned, unsigned);
+static BOOL HLPFILE_SkipParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*);
static void HLPFILE_Uncompress2(HLPFILE*, const BYTE*, const BYTE*, BYTE*, const BYTE*);
static BOOL HLPFILE_Uncompress3(HLPFILE*, char*, const char*, const BYTE*, const BYTE*);
static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz);
@@ -334,13 +334,13 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
switch (buf[0x14])
{
case 0x02:
- if (!HLPFILE_AddPage(hlpfile, buf, end, index * 0x8000L + offs)) return FALSE;
+ if (!HLPFILE_AddPage(hlpfile, buf, end, ref, index * 0x8000L + offs)) return FALSE;
break;
case 0x01:
case 0x20:
- case 0x23:
- if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE;
+ case 0x23:
+ if (!HLPFILE_SkipParagraph(hlpfile, buf, end, &len)) return FALSE;
offs += len;
break;
@@ -368,7 +368,7 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
*
* HLPFILE_AddPage
*/
-static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned offset)
+static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, DWORD ref, unsigned offset)
{
HLPFILE_PAGE* page;
BYTE* title;
@@ -423,6 +423,7 @@ static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned off
page->first_macro = NULL;
page->wNumber = GET_UINT(buf, 0x21);
page->offset = offset;
+ page->reference = ref;
page->browse_bwd = GET_UINT(buf, 0x19);
page->browse_fwd = GET_UINT(buf, 0x1D);
@@ -807,20 +808,39 @@ static BOOL HLPFILE_LoadGfxByIndex(HLPFILE *hlpfile, unsigned index,
/***********************************************************************
*
- * HLPFILE_AddParagraph
+ * HLPFILE_SkipParagraph
*/
-static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len)
+static BOOL HLPFILE_SkipParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len)
+{
+ BYTE *tmp;
+
+ if (!hlpfile->first_page) {WINE_WARN("no page\n"); return FALSE;};
+ if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;};
+
+ tmp = buf + 0x15;
+ if (buf[0x14] == 0x20 || buf[0x14] == 0x23)
+ {
+ fetch_long(&tmp);
+ *len = fetch_ushort(&tmp);
+ }
+ else *len = end-buf-15;
+
+ return TRUE;
+}
+
+/***********************************************************************
+ *
+ * HLPFILE_BrowseParagraph
+ */
+BOOL HLPFILE_BrowseParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end)
{
- HLPFILE_PAGE *page;
UINT textsize;
BYTE *format, *format_end;
char *text, *text_base, *text_end;
long size, blocksize, datalen;
unsigned short bits;
unsigned nc, ncol = 1;
-
- if (!hlpfile->last_page) {WINE_WARN("no page\n"); return FALSE;};
- page = hlpfile->last_page;
+ BOOL ret = FALSE;
if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;};
@@ -851,12 +871,8 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
format = buf + 0x15;
format_end = buf + GET_UINT(buf, 0x10);
- if (buf[0x14] == 0x20 || buf[0x14] == 0x23)
- {
- fetch_long(&format);
- *len = fetch_ushort(&format);
- }
- else *len = end-buf-15;
+ fetch_long(&format);
+ fetch_ushort(&format);
if (buf[0x14] == 0x23)
{
@@ -907,13 +923,12 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
while (text < text_end && format < format_end)
{
WINE_TRACE("Got text: %s (%p/%p - %p/%p)\n", wine_dbgstr_a(text), text, text_end, format, format_end);
- textsize = strlen(text) + 1;
- if (textsize > 1)
+ textsize = strlen(text);
+ if (textsize)
{
-
}
/* else: null text, keep on storing attributes */
- text += textsize;
+ text += textsize + 1;
if (*format == 0xff)
{
@@ -935,8 +950,11 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
break;
case 0x80:
- WINE_TRACE("Changing font to %d\n", GET_USHORT(format, 1));
- format += 3;
+ {
+ unsigned font = GET_USHORT(format, 1);
+ WINE_TRACE("Changing font to %u\n", font);
+ format += 3;
+ }
break;
case 0x81:
@@ -1078,7 +1096,67 @@ static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigne
}
}
}
+ ret = TRUE;
HeapFree(GetProcessHeap(), 0, text_base);
+ return ret;
+}
+
+BOOL HLPFILE_BrowsePage(HLPFILE_PAGE* page)
+{
+ HLPFILE *hlpfile = page->file;
+ BYTE *buf, *end;
+ DWORD ref = page->reference;
+ unsigned index, old_index = -1, offset, count = 0;
+
+ do
+ {
+ if (hlpfile->version <= 16)
+ {
+ index = (ref - 0x0C) / hlpfile->dsize;
+ offset = (ref - 0x0C) % hlpfile->dsize;
+ }
+ else
+ {
+ index = (ref - 0x0C) >> 14;
+ offset = (ref - 0x0C) & 0x3FFF;
+ }
+
+ if (hlpfile->version <= 16 && index != old_index && index != 0)
+ {
+ /* we jumped to the next block, adjust pointers */
+ ref -= 12;
+ offset -= 12;
+ }
+
+ if (index >= hlpfile->topic_maplen) {WINE_WARN("maplen\n"); break;}
+ buf = hlpfile->topic_map[index] + offset;
+ if (buf + 0x15 >= hlpfile->topic_end) {WINE_WARN("extra\n"); break;}
+ end = min(buf + GET_UINT(buf, 0), hlpfile->topic_end);
+ if (index != old_index) {old_index = index;}
+
+ switch (buf[0x14])
+ {
+ case 0x02:
+ if (count++) goto done;
+ break;
+ case 0x20:
+ case 0x23:
+ if (!HLPFILE_BrowseParagraph(hlpfile, buf, end)) return FALSE;
+ break;
+
+ default:
+ WINE_ERR("buf[0x14] = %x\n", buf[0x14]);
+ }
+ if (hlpfile->version <= 16)
+ {
+ ref += GET_UINT(buf, 0xc);
+ if (GET_UINT(buf, 0xc) == 0)
+ break;
+ }
+ else
+ ref = GET_UINT(buf, 0xc);
+ } while (ref != 0xffffffff);
+done:
return TRUE;
}
diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h
index e43a9ef..75e6f7b 100644
--- a/programs/winhelp/hlpfile.h
+++ b/programs/winhelp/hlpfile.h
@@ -48,6 +48,7 @@ typedef struct tagHlpFilePage
unsigned wNumber;
unsigned offset;
+ DWORD reference;
struct tagHlpFilePage* next;
struct tagHlpFilePage* prev;
@@ -148,3 +149,5 @@ void HLPFILE_FreeHlpFile(HLPFILE*);
void* HLPFILE_BPTreeSearch(BYTE*, const void*, HLPFILE_BPTreeCompare);
void HLPFILE_BPTreeEnum(BYTE*, HLPFILE_BPTreeCallback cb, void *cookie);
+
+BOOL HLPFILE_BrowsePage(HLPFILE_PAGE*);
More information about the wine-patches
mailing list