[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