ReactOS 0.4.15-dev-7961-gdcf9eb0
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 */
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{
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: %08x\n", debugstr_w(file), hres);
87 goto cleanup;
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(!_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
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
135 strbuf_free(&node_name);
136
137cleanup:
139 if(temp_stream)
140 IStream_Release(temp_stream);
141 if(!found)
142 {
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};
158 STATSTG entries;
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;
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 */
222void 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}
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int tolower(int c)
Definition: utclib.c:902
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: debug.h:111
#define BLOCK_SIZE
Definition: dlist.c:220
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
content
Definition: atl_ax.c:994
static void strbuf_init(strbuf *buf)
Definition: registrar.c:82
#define wcschr
Definition: compat.h:17
#define CP_ACP
Definition: compat.h:109
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
void InitSearch(HHInfo *info, const char *needle)
Definition: search.c:222
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:152
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:200
void ReleaseSearch(HHInfo *info)
Definition: search.c:235
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:1799
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
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#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
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HRESULT hres
Definition: protocol.c:465
static size_t elem
Definition: string.c:68
static ATOM item
Definition: dde.c:856
#define STGM_READ
Definition: objbase.h:917
static char title[]
Definition: ps.c:92
#define LVM_DELETEALLITEMS
Definition: commctrl.h:2413
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3264
#define LVIF_PARAM
Definition: commctrl.h:2311
#define LVIF_TEXT
Definition: commctrl.h:2309
#define LVM_INSERTITEMW
Definition: commctrl.h:2404
Console I/O streams.
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
Definition: hhctrl.h:98
IStorage * pStorage
Definition: hhctrl.h:100
Definition: hhctrl.h:185
struct SearchItem * next
Definition: hhctrl.h:90
Definition: fci.c:127
Definition: fci.c:116
char * buf
Definition: stream.h:27
Definition: parse.h:23
LPWSTR pszText
Definition: commctrl.h:2365
int cchTextMax
Definition: commctrl.h:2366
UINT mask
Definition: commctrl.h:2360
LPARAM lParam
Definition: commctrl.h:2368
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:888
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
LONG_PTR LPARAM
Definition: windef.h:208
#define NOERROR
Definition: winerror.h:2354
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180