ReactOS  0.4.14-dev-376-gaedba84
search.c
Go to the documentation of this file.
1 /*
2  * Copyright 2010 Erich Hoover
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "hhctrl.h"
20 #include "stream.h"
21 
22 #include "wine/debug.h"
23 
25 
27  const WCHAR *folder, const char *needle);
28 
29 /* Allocate a ListView entry for a search result. */
31 {
32  int filename_len = filename ? (lstrlenW(filename)+1)*sizeof(WCHAR) : 0;
34 
35  item = heap_alloc_zero(sizeof(SearchItem));
36  if(filename)
37  {
38  item->filename = heap_alloc(filename_len);
39  memcpy(item->filename, filename, filename_len);
40  }
41  item->title = title; /* Already allocated */
42 
43  return item;
44 }
45 
46 /* Fill the ListView object corresponding to the found Search tab items */
47 static void fill_search_tree(HWND hwndList, SearchItem *item)
48 {
49  int index = 0;
50  LVITEMW lvi;
51 
52  SendMessageW(hwndList, LVM_DELETEALLITEMS, 0, 0);
53  while(item) {
54  TRACE("list debug: %s\n", debugstr_w(item->filename));
55 
56  memset(&lvi, 0, sizeof(lvi));
57  lvi.iItem = index++;
59  lvi.cchTextMax = lstrlenW(item->title)+1;
60  lvi.pszText = item->title;
61  lvi.lParam = (LPARAM)item;
62  item->id = (HTREEITEM)SendMessageW(hwndList, LVM_INSERTITEMW, 0, (LPARAM)&lvi);
63  item = item->next;
64  }
65 }
66 
67 /* Search the CHM storage stream (an HTML file) for the requested text.
68  *
69  * Before searching the HTML file all HTML tags are removed so that only
70  * the content of the document is scanned. If the search string is found
71  * then the title of the document is returned.
72  */
73 static WCHAR *SearchCHM_File(IStorage *pStorage, const WCHAR *file, const char *needle)
74 {
75  char *buffer = heap_alloc(BLOCK_SIZE);
76  strbuf_t content, node, node_name;
77  IStream *temp_stream = NULL;
78  DWORD i, buffer_size = 0;
79  WCHAR *title = NULL;
80  BOOL found = FALSE;
82  HRESULT hres;
83 
84  hres = IStorage_OpenStream(pStorage, file, NULL, STGM_READ, 0, &temp_stream);
85  if(FAILED(hres)) {
86  FIXME("Could not open '%s' stream: %08x\n", debugstr_w(file), hres);
87  goto cleanup;
88  }
89 
90  strbuf_init(&node);
92  strbuf_init(&node_name);
93 
94  stream_init(&stream, temp_stream);
95 
96  /* Remove all HTML formatting and record the title */
97  while(next_node(&stream, &node)) {
98  get_node_name(&node, &node_name);
99 
100  if(next_content(&stream, &content) && content.len > 1)
101  {
102  char *text = &content.buf[1];
103  int textlen = content.len-1;
104 
105  if(!_strnicmp(node_name.buf, "title", -1))
106  {
107  int wlen = MultiByteToWideChar(CP_ACP, 0, text, textlen, NULL, 0);
108  title = heap_alloc((wlen+1)*sizeof(WCHAR));
109  MultiByteToWideChar(CP_ACP, 0, text, textlen, title, wlen);
110  title[wlen] = 0;
111  }
112 
113  buffer = heap_realloc(buffer, buffer_size + textlen + 1);
114  memcpy(&buffer[buffer_size], text, textlen);
115  buffer[buffer_size + textlen] = '\0';
116  buffer_size += textlen;
117  }
118 
119  strbuf_zero(&node);
121  }
122 
123  /* Convert the buffer to lower case for comparison against the
124  * requested text (already in lower case).
125  */
126  for(i=0;i<buffer_size;i++)
127  buffer[i] = tolower(buffer[i]);
128 
129  /* Search the decoded buffer for the requested text */
130  if(strstr(buffer, needle))
131  found = TRUE;
132 
133  strbuf_free(&node);
135  strbuf_free(&node_name);
136 
137 cleanup:
138  heap_free(buffer);
139  if(temp_stream)
140  IStream_Release(temp_stream);
141  if(!found)
142  {
143  heap_free(title);
144  return NULL;
145  }
146  return title;
147 }
148 
149 /* Search all children of a CHM storage object for the requested text and
150  * return the last found search item.
151  */
153  const char *needle)
154 {
155  static const WCHAR szHTMext[] = {'.','h','t','m',0};
157  WCHAR *filename = NULL;
158  STATSTG entries;
159  HRESULT hres;
160  ULONG retr;
161 
162  hres = IStorage_EnumElements(pStorage, 0, NULL, 0, &elem);
163  if(hres != S_OK)
164  {
165  FIXME("Could not enumerate '/' storage elements: %08x\n", hres);
166  return NULL;
167  }
168  while (IEnumSTATSTG_Next(elem, 1, &entries, &retr) == NOERROR)
169  {
170  filename = entries.pwcsName;
171  while(wcschr(filename, '/'))
172  filename = wcschr(filename, '/')+1;
173  switch(entries.type) {
174  case STGTY_STORAGE:
175  item = SearchCHM_Folder(item, pStorage, filename, needle);
176  break;
177  case STGTY_STREAM:
178  if(wcsstr(filename, szHTMext))
179  {
180  WCHAR *title = SearchCHM_File(pStorage, filename, needle);
181 
182  if(title)
183  {
184  item->next = alloc_search_item(title, entries.pwcsName);
185  item = item->next;
186  }
187  }
188  break;
189  default:
190  FIXME("Unhandled IStorage stream element.\n");
191  }
192  }
193  IEnumSTATSTG_Release(elem);
194  return item;
195 }
196 
197 /* Open a CHM storage object (folder) by name and find all items with
198  * the requested text. The last found item is returned.
199  */
201  const WCHAR *folder, const char *needle)
202 {
203  IStorage *temp_storage = NULL;
204  HRESULT hres;
205 
206  hres = IStorage_OpenStorage(pStorage, folder, NULL, STGM_READ, NULL, 0, &temp_storage);
207  if(FAILED(hres))
208  {
209  FIXME("Could not open '%s' storage object: %08x\n", debugstr_w(folder), hres);
210  return NULL;
211  }
212  item = SearchCHM_Storage(item, temp_storage, needle);
213 
214  IStorage_Release(temp_storage);
215  return item;
216 }
217 
218 /* Search the entire CHM file for the requested text and add all of
219  * the found items to a ListView for the user to choose the item
220  * they want.
221  */
222 void InitSearch(HHInfo *info, const char *needle)
223 {
224  CHMInfo *chm = info->pCHMInfo;
225  SearchItem *root_item = alloc_search_item(NULL, NULL);
226 
227  SearchCHM_Storage(root_item, chm->pStorage, needle);
228  fill_search_tree(info->search.hwndList, root_item->next);
229  if(info->search.root)
231  info->search.root = root_item;
232 }
233 
234 /* Free all of the found Search items. */
236 {
237  SearchItem *item = info->search.root;
238 
239  info->search.root = NULL;
240  while(item) {
241  heap_free(item->filename);
242  item = item->next;
243  }
244 }
void get_node_name(strbuf_t *node, strbuf_t *name)
Definition: stream.c:88
#define TRUE
Definition: types.h:120
Definition: fci.c:115
#define NOERROR
Definition: winerror.h:2354
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
const WCHAR * text
Definition: package.c:1827
#define CP_ACP
Definition: compat.h:99
static SearchItem * SearchCHM_Folder(SearchItem *item, IStorage *pStorage, const WCHAR *folder, const char *needle)
Definition: search.c:200
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3260
GLuint buffer
Definition: glext.h:5915
BOOL next_node(stream_t *stream, strbuf_t *buf)
Definition: stream.c:140
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:415
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static void fill_search_tree(HWND hwndList, SearchItem *item)
Definition: search.c:47
#define LVIF_TEXT
Definition: commctrl.h:2305
int cchTextMax
Definition: commctrl.h:2362
struct node node
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
#define debugstr_w
Definition: kernel32.h:32
static size_t elem
Definition: string.c:68
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
LPARAM lParam
Definition: commctrl.h:2364
#define FIXME(fmt,...)
Definition: debug.h:110
void strbuf_free(strbuf_t *buf)
Definition: stream.c:38
content
Definition: atl_ax.c:993
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:927
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
GLuint index
Definition: glext.h:6031
void InitSearch(HHInfo *info, const char *needle)
Definition: search.c:222
Definition: hhctrl.h:97
#define STGM_READ
Definition: objbase.h:916
#define TRACE(s)
Definition: solgame.cpp:4
#define BLOCK_SIZE
Definition: dlist.c:220
HRESULT hres
Definition: protocol.c:465
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static SearchItem * SearchCHM_Storage(SearchItem *item, IStorage *pStorage, const char *needle)
Definition: search.c:152
LONG HRESULT
Definition: typedefs.h:77
Definition: hhctrl.h:185
LPWSTR pszText
Definition: commctrl.h:2361
unsigned long DWORD
Definition: ntddk_ex.h:95
static void strbuf_init(strbuf *buf)
Definition: registrar.c:82
UINT mask
Definition: commctrl.h:2356
BOOL next_content(stream_t *stream, strbuf_t *buf)
Definition: stream.c:105
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
struct SearchItem * next
Definition: hhctrl.h:90
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
IStorage * pStorage
Definition: hhctrl.h:100
void stream_init(stream_t *stream, IStream *str)
Definition: stream.c:54
#define LVM_DELETEALLITEMS
Definition: commctrl.h:2409
#define LVM_INSERTITEMW
Definition: commctrl.h:2400
#define S_OK
Definition: intsafe.h:59
static ATOM item
Definition: dde.c:856
static SearchItem * alloc_search_item(WCHAR *title, const WCHAR *filename)
Definition: search.c:30
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
void ReleaseSearch(HHInfo *info)
Definition: search.c:235
#define MultiByteToWideChar
Definition: compat.h:100
#define LVIF_PARAM
Definition: commctrl.h:2307
unsigned int ULONG
Definition: retypes.h:1
char * cleanup(char *str)
Definition: wpickclick.c:99
WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp)
#define memset(x, y, z)
Definition: compat.h:39
int tolower(int c)
Definition: utclib.c:902
void strbuf_zero(strbuf_t *buf)
Definition: stream.c:33
static char title[]
Definition: ps.c:92
static WCHAR * SearchCHM_File(IStorage *pStorage, const WCHAR *file, const char *needle)
Definition: search.c:73
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: dlist.c:348
Definition: fci.c:126
char * buf
Definition: stream.h:27