]> git.saurik.com Git - wxWidgets.git/blob - src/html/htmltag.cpp
Corrected off-by-one bug in wxRect(const wxPoint&, const wxPoint&) ctor
[wxWidgets.git] / src / html / htmltag.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: htmltag.cpp
3 // Purpose: wxHtmlTag class (represents single tag)
4 // Author: Vaclav Slavik
5 // RCS-ID: $Id$
6 // Copyright: (c) 1999 Vaclav Slavik
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
9
10
11 #ifdef __GNUG__
12 #pragma implementation
13 #endif
14
15 #include "wx/wxprec.h"
16
17 #include "wx/defs.h"
18 #if wxUSE_HTML
19
20 #ifdef __BORDLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WXPRECOMP
25 #include "wx/wx.h"
26 #endif
27
28 #include "wx/html/htmltag.h"
29 #include <stdio.h> // for vsscanf
30 #include <stdarg.h>
31
32
33
34
35 //-----------------------------------------------------------------------------
36 // wxHtmlTagsCache
37 //-----------------------------------------------------------------------------
38
39 IMPLEMENT_CLASS(wxHtmlTagsCache,wxObject)
40
41 #define CACHE_INCREMENT 64
42
43 wxHtmlTagsCache::wxHtmlTagsCache(const wxString& source)
44 {
45 const wxChar *src = source.c_str();
46 int i, tg, pos, stpos;
47 int lng = source.Length();
48 wxChar dummy[256];
49
50 m_Cache = NULL;
51 m_CacheSize = 0;
52 m_CachePos = 0;
53
54 pos = 0;
55 while (pos < lng) {
56 if (src[pos] == wxT('<')) { // tag found:
57 if (m_CacheSize % CACHE_INCREMENT == 0)
58 m_Cache = (sCacheItem*) realloc(m_Cache, (m_CacheSize + CACHE_INCREMENT) * sizeof(sCacheItem));
59 tg = m_CacheSize++;
60 m_Cache[tg].Key = stpos = pos++;
61 dummy[0] = 0; i = 0;
62 while (src[pos] != wxT('>') &&
63 src[pos] != wxT(' ') && src[pos] != wxT('\r') &&
64 src[pos] != wxT('\n') && src[pos] != wxT('\t')) {
65 dummy[i] = src[pos++];
66 if ((dummy[i] >= wxT('a')) && (dummy[i] <= wxT('z'))) dummy[i] -= (wxT('a') - wxT('A'));
67 i++;
68 }
69 dummy[i] = 0;
70 m_Cache[tg].Name = new wxChar[i+1];
71 memcpy(m_Cache[tg].Name, dummy, (i+1)*sizeof(wxChar));
72
73 while (src[pos] != wxT('>')) pos++;
74
75 if (src[stpos+1] == wxT('/')) { // ending tag:
76 m_Cache[tg].End1 = m_Cache[tg].End2 = -2;
77 // find matching begin tag:
78 for (i = tg; i >= 0; i--)
79 if ((m_Cache[i].End1 == -1) && (wxStrcmp(m_Cache[i].Name, dummy+1) == 0)) {
80 m_Cache[i].End1 = stpos;
81 m_Cache[i].End2 = pos + 1;
82 break;
83 }
84 }
85 else {
86 m_Cache[tg].End1 = m_Cache[tg].End2 = -1;
87 }
88 }
89
90 pos++;
91 }
92
93 // ok, we're done, now we'll free .Name members of cache - we don't need it anymore:
94 for (i = 0; i < m_CacheSize; i++) {
95 delete[] m_Cache[i].Name;
96 m_Cache[i].Name = NULL;
97 }
98 }
99
100
101
102 void wxHtmlTagsCache::QueryTag(int at, int* end1, int* end2)
103 {
104 if (m_Cache == NULL) return;
105 if (m_Cache[m_CachePos].Key != at) {
106 int delta = (at < m_Cache[m_CachePos].Key) ? -1 : 1;
107 do {m_CachePos += delta;} while (m_Cache[m_CachePos].Key != at);
108 }
109 *end1 = m_Cache[m_CachePos].End1;
110 *end2 = m_Cache[m_CachePos].End2;
111 }
112
113
114
115
116 //-----------------------------------------------------------------------------
117 // wxHtmlTag
118 //-----------------------------------------------------------------------------
119
120 IMPLEMENT_CLASS(wxHtmlTag,wxObject)
121
122 wxHtmlTag::wxHtmlTag(const wxString& source, int pos, int end_pos, wxHtmlTagsCache* cache) : wxObject()
123 {
124 int i;
125 char c;
126
127 // fill-in name, params and begin pos:
128 m_Name = m_Params = wxEmptyString;
129 i = pos+1;
130 if (source[i] == '/') {m_Ending = TRUE; i++;}
131 else m_Ending = FALSE;
132
133 while ((i < end_pos) &&
134 ((c = source[i++]) != ' ' && c != '\r' && c != '\n' && c != '\t' &&
135 c != '>')) {
136 if ((c >= 'a') && (c <= 'z')) c -= ('a' - 'A');
137 m_Name += c;
138 }
139
140 if (source[i-1] != '>')
141 while ((i < end_pos) && ((c = source[i++]) != '>')) {
142 if ((c >= 'a') && (c <= 'z')) c -= ('a' - 'A');
143 if (c == '\r' || c == '\n' || c == '\t') c = ' '; // make future parsing a bit simpler
144 m_Params += c;
145 if (c == '"') {
146 while ((i < end_pos) && ((c = source[i++]) != '"')) m_Params += c;
147 m_Params += c;
148 }
149 else if (c == '\'') {
150 while ((i < end_pos) && ((c = source[i++]) != '\'')) m_Params += c;
151 m_Params += c;
152 }
153 }
154 m_Begin = i;
155
156 cache -> QueryTag(pos, &m_End1, &m_End2);
157 if (m_End1 > end_pos) m_End1 = end_pos;
158 if (m_End2 > end_pos) m_End2 = end_pos;
159 }
160
161
162
163 bool wxHtmlTag::HasParam(const wxString& par) const
164 {
165 const wxChar *st = m_Params, *p = par;
166 const wxChar *st2, *p2;
167
168 if (*st == 0) return FALSE;
169 if (*p == 0) return FALSE;
170 for (st2 = st, p2 = p; ; st2++) {
171 if (*p2 == 0) return TRUE;
172 if (*st2 == 0) return FALSE;
173 if (*p2 != *st2) p2 = p;
174 if (*p2 == *st2) p2++;
175 if (*st2 == ' ') p2 = p;
176 else if (*st2 == '=') {
177 p2 = p;
178 while (*st2 != ' ') {
179 if (*st2 == '"') {
180 st2++;
181 while (*st2 != '"') st2++;
182 }
183 st2++;
184 if (*st2 == 0) return FALSE;
185 }
186 }
187 }
188 }
189
190
191
192 wxString wxHtmlTag::GetParam(const wxString& par, bool with_commas) const
193 {
194 const wxChar *st = m_Params, *p = par;
195 const wxChar *st2, *p2;
196 bool comma;
197 char comma_char;
198
199 if (*st == 0) return "";
200 if (*p == 0) return "";
201 for (st2 = st, p2 = p; ; st2++) {
202 if (*p2 == 0) { // found
203 wxString fnd = "";
204 st2++; // '=' character
205 comma = FALSE;
206 comma_char = '\0';
207 if (!with_commas && (*(st2) == '"')) {
208 st2++;
209 comma = TRUE;
210 comma_char = '"';
211 }
212 else if (!with_commas && (*(st2) == '\'')) {
213 st2++;
214 comma = TRUE;
215 comma_char = '\'';
216 }
217 while (*st2 != 0) {
218 if (comma && *st2 == comma_char) comma = FALSE;
219 else if ((*st2 == ' ') && (!comma)) break;
220 fnd += (*(st2++));
221 }
222 if (!with_commas && (*(st2-1) == comma_char)) fnd.RemoveLast();
223 return fnd;
224 }
225 if (*st2 == 0) return "";
226 if (*p2 != *st2) p2 = p;
227 if (*p2 == *st2) p2++;
228 if (*st2 == ' ') p2 = p;
229 else if (*st2 == '=') {
230 p2 = p;
231 while (*st2 != ' ') {
232 if (*st2 == '"') {
233 st2++;
234 while (*st2 != '"') st2++;
235 }
236 else if (*st2 == '\'') {
237 st2++;
238 while (*st2 != '\'') st2++;
239 }
240 st2++;
241 }
242 }
243 }
244 }
245
246
247
248 int wxHtmlTag::ScanParam(const wxString& par, wxChar *format, void *param) const
249 {
250 wxString parval = GetParam(par);
251 return wxSscanf((const wxChar*)parval, format, param);
252 }
253
254 #endif