2 * Copyright 2007 Jacek Caban for CodeWeavers
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.
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.
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
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(htmlhelp
);
26 void strbuf_init(strbuf_t
*buf
)
30 buf
->buf
= heap_alloc(buf
->size
);
33 void strbuf_zero(strbuf_t
*buf
)
38 void strbuf_free(strbuf_t
*buf
)
43 static void strbuf_append(strbuf_t
*buf
, const char *data
, int len
)
45 if(buf
->len
+len
> buf
->size
) {
46 buf
->size
= buf
->len
+len
;
47 buf
->buf
= heap_realloc(buf
->buf
, buf
->size
);
50 memcpy(buf
->buf
+buf
->len
, data
, len
);
54 void stream_init(stream_t
*stream
, IStream
*str
)
56 memset(stream
, 0, sizeof(stream_t
));
60 static BOOL
stream_chr(stream_t
*stream
, strbuf_t
*buf
, char c
)
66 for(i
=stream
->p
; i
<stream
->size
; i
++) {
67 if(stream
->buf
[i
] == c
) {
73 if(buf
&& i
> stream
->p
)
74 strbuf_append(buf
, stream
->buf
+stream
->p
, i
-stream
->p
);
77 if(stream
->p
== stream
->size
) {
79 IStream_Read(stream
->str
, stream
->buf
, sizeof(stream
->buf
), &stream
->size
);
85 return stream
->size
!= 0;
88 void get_node_name(strbuf_t
*node
, strbuf_t
*name
)
90 const char *ptr
= node
->buf
+1;
94 while(*ptr
!= '>' && !isspace(*ptr
))
97 strbuf_append(name
, node
->buf
+1, ptr
-node
->buf
-1);
98 strbuf_append(name
, "", 1);
101 /* Return the stream content up to the next HTML tag.
103 * Note: the first returned character is the end of the last tag (>).
105 BOOL
next_content(stream_t
*stream
, strbuf_t
*buf
)
107 if(!stream_chr(stream
, buf
, '<'))
113 BOOL
next_node(stream_t
*stream
, strbuf_t
*buf
)
115 if(!stream_chr(stream
, NULL
, '<'))
118 if(!stream_chr(stream
, buf
, '>'))
121 strbuf_append(buf
, ">", 2);
127 * Find the value of a named HTML attribute.
129 * Note: Attribute names are case insensitive, so it is necessary to
130 * put both the node text and the attribute name in the same case
131 * before attempting a string search.
133 const char *get_attr(const char *node
, const char *name
, int *len
)
135 const char *ptr
, *ptr2
;
136 int name_len
, node_len
;
141 /* Create a lower case copy of the node */
142 node_len
= strlen(node
)+1;
143 node_buf
= heap_alloc(node_len
*sizeof(char));
146 memcpy(node_buf
, node
, node_len
);
147 for(i
=0;i
<node_len
;i
++)
148 node_buf
[i
] = tolower(node_buf
[i
]);
149 /* Create a lower case copy of the attribute name (search string) */
150 name_len
= strlen(name
);
151 memcpy(name_buf
, name
, name_len
);
152 for(i
=0;i
<name_len
;i
++)
153 name_buf
[i
] = tolower(name_buf
[i
]);
154 name_buf
[name_len
++] = '=';
155 name_buf
[name_len
++] = '\"';
156 name_buf
[name_len
] = 0;
158 ptr
= strstr(node_buf
, name_buf
);
160 WARN("name not found\n");
166 ptr2
= strchr(ptr
, '\"');
174 /* Return the pointer offset within the original string */
175 ptr
= node
+(ptr
-node_buf
);