ReactOS 0.4.17-dev-804-g023d8af
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 = calloc(1, sizeof(SearchItem));
36 if(filename)
37 {
38 item->filename = malloc(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 */
47static 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 */
73static WCHAR *SearchCHM_File(IStorage *pStorage, const WCHAR *file, const char *needle)
74{
75 char *buffer = NULL, *new_buffer;
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;
83
84 hres = IStorage_OpenStream(pStorage, file, NULL, STGM_READ, 0, &temp_stream);
85 if(FAILED(hres)) {
86 FIXME("Could not open '%s' stream: %08lx\n", debugstr_w(file), hres);
87 return NULL;
88 }
89
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(!stricmp(node_name.buf, "title"))
106 {
107 int wlen = MultiByteToWideChar(CP_ACP, 0, text, textlen, NULL, 0);
108 title = malloc((wlen + 1) * sizeof(WCHAR));
109 MultiByteToWideChar(CP_ACP, 0, text, textlen, title, wlen);
110 title[wlen] = 0;
111 }
112
113 new_buffer = realloc(buffer, buffer_size + textlen + 1);
114 if(!new_buffer) goto cleanup;
115 buffer = new_buffer;
116 memcpy(&buffer[buffer_size], text, textlen);
117 buffer[buffer_size + textlen] = '\0';
118 buffer_size += textlen;
119 }
120
123 }
124
125 /* Convert the buffer to lower case for comparison against the
126 * requested text (already in lower case).
127 */
128 for(i=0;i<buffer_size;i++)
129 buffer[i] = tolower(buffer[i]);
130
131 /* Search the decoded buffer for the requested text */
132 if(strstr(buffer, needle))
133 found = TRUE;
134
135cleanup:
138 strbuf_free(&node_name);
139
140 free(buffer);
141 IStream_Release(temp_stream);
142
143 if(!found)
144 {
145 free(title);
146 return NULL;
147 }
148 return title;
149}
150
151/* Search all children of a CHM storage object for the requested text and
152 * return the last found search item.
153 */
155 const char *needle)
156{
157 static const WCHAR szHTMext[] = {'.','h','t','m',0};
160 STATSTG entries;
162 ULONG retr;
163
164 hres = IStorage_EnumElements(pStorage, 0, NULL, 0, &elem);
165 if(hres != S_OK)
166 {
167 FIXME("Could not enumerate '/' storage elements: %08lx\n", hres);
168 return NULL;
169 }
170 while (IEnumSTATSTG_Next(elem, 1, &entries, &retr) == NOERROR)
171 {
172 filename = entries.pwcsName;
173 while(wcschr(filename, '/'))
174 filename = wcschr(filename, '/')+1;
175 switch(entries.type) {
176 case STGTY_STORAGE:
177 item = SearchCHM_Folder(item, pStorage, filename, needle);
178 break;
179 case STGTY_STREAM:
180 if(wcsstr(filename, szHTMext))
181 {
182 WCHAR *title = SearchCHM_File(pStorage, filename, needle);
183
184 if(title)
185 {
186 item->next = alloc_search_item(title, entries.pwcsName);
187 item = item->next;
188 }
189 }
190 break;
191 default:
192 FIXME("Unhandled IStorage stream element.\n");
193 }
194 }
195 IEnumSTATSTG_Release(elem);
196 return item;
197}
198
199/* Open a CHM storage object (folder) by name and find all items with
200 * the requested text. The last found item is returned.
201 */
203 const WCHAR *folder, const char *needle)
204{
205 IStorage *temp_storage = NULL;
207
208 hres = IStorage_OpenStorage(pStorage, folder, NULL, STGM_READ, NULL, 0, &temp_storage);
209 if(FAILED(hres))
210 {
211 FIXME("Could not open '%s' storage object: %08lx\n", debugstr_w(folder), hres);
212 return NULL;
213 }
214 item = SearchCHM_Storage(item, temp_storage, needle);
215
216 IStorage_Release(temp_storage);
217 return item;
218}
219
220/* Search the entire CHM file for the requested text and add all of
221 * the found items to a ListView for the user to choose the item
222 * they want.
223 */
224void InitSearch(HHInfo *info, const char *needle)
225{
226 CHMInfo *chm = info->pCHMInfo;
227 SearchItem *root_item = alloc_search_item(NULL, NULL);
228
229 SearchCHM_Storage(root_item, chm->pStorage, needle);
230 fill_search_tree(info->search.hwndList, root_item->next);
231 if(info->search.root)
233 info->search.root = root_item;
234}
235
236/* Free all of the found Search items. */
238{
239 SearchItem *item = info->search.root;
240
241 info->search.root = NULL;
242 while(item) {
243 free(item->filename);
244 item = item->next;
245 }
246}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:990
static void strbuf_init(strbuf *buf)
Definition: registrar.c:75
#define wcschr
Definition: compat.h:17
#define CP_ACP
Definition: compat.h:109
#define stricmp(_String1, _String2)
Definition: compat.h:24
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
void InitSearch(HHInfo *info, const char *needle)
Definition: search.c:224
static void fill_search_tree(HWND hwndList, SearchItem *item)
Definition: search.c:47
static SearchItem * alloc_search_item(WCHAR *title, const WCHAR *filename)
Definition: search.c:30
static SearchItem * SearchCHM_Storage(SearchItem *item, IStorage *pStorage, const char *needle)
Definition: search.c:154
static WCHAR * SearchCHM_File(IStorage *pStorage, const WCHAR *file, const char *needle)
Definition: search.c:73
static SearchItem * SearchCHM_Folder(SearchItem *item, IStorage *pStorage, const WCHAR *folder, const char *needle)
Definition: search.c:202
void ReleaseSearch(HHInfo *info)
Definition: search.c:237
void strbuf_free(strbuf_t *buf)
Definition: stream.c:38
BOOL next_node(stream_t *stream, strbuf_t *buf)
Definition: stream.c:140
BOOL next_content(stream_t *stream, strbuf_t *buf)
Definition: stream.c:105
void strbuf_zero(strbuf_t *buf)
Definition: stream.c:33
void stream_init(stream_t *stream, IStream *str)
Definition: stream.c:54
void get_node_name(strbuf_t *node, strbuf_t *name)
Definition: stream.c:88
static void cleanup(void)
Definition: main.c:1335
const WCHAR * text
Definition: package.c:1794
int CDECL tolower(int c)
Definition: ctype.c:572
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2998
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3420
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
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
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define debugstr_w
Definition: kernel32.h:32
LONG_PTR LPARAM
Definition: minwindef.h:175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HRESULT hres
Definition: protocol.c:465
static size_t elem
Definition: string.c:71
#define STGM_READ
Definition: objbase.h:936
short WCHAR
Definition: pedump.c:58
static char title[]
Definition: ps.c:92
#define LVM_DELETEALLITEMS
Definition: commctrl.h:2418
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3269
#define LVIF_PARAM
Definition: commctrl.h:2316
#define LVIF_TEXT
Definition: commctrl.h:2314
#define LVM_INSERTITEMW
Definition: commctrl.h:2409
#define calloc
Definition: rosglue.h:14
Console I/O streams.
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
Definition: hhctrl.h:97
IStorage * pStorage
Definition: hhctrl.h:99
Definition: hhctrl.h:184
struct SearchItem * next
Definition: hhctrl.h:89
Definition: fci.c:123
Definition: fci.c:112
char * buf
Definition: stream.h:27
Definition: parse.h:23
LPWSTR pszText
Definition: commctrl.h:2370
int cchTextMax
Definition: commctrl.h:2371
UINT mask
Definition: commctrl.h:2365
LPARAM lParam
Definition: commctrl.h:2373
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
#define NOERROR
Definition: winerror.h:3448
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)