]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmltag.cpp
a864e27fad2f9ac84c78696a396c6cf5a9a1cb76
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxHtmlTag class (represents single tag)
4 // Author: Vaclav Slavik
5 // Copyright: (c) 1999 Vaclav Slavik
6 // Licence: wxWindows Licence
7 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation
14 #include <wx/wxprec.h>
27 #include <wx/html/htmltag.h>
28 #include <stdio.h> // for vsscanf
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 IMPLEMENT_CLASS(wxHtmlTagsCache
,wxObject
)
40 #define CACHE_INCREMENT 64
42 wxHtmlTagsCache::wxHtmlTagsCache(const wxString
& source
)
44 const char *src
= source
.c_str();
45 int i
, tg
, pos
, stpos
;
46 int lng
= source
.Length();
55 if (src
[pos
] == '<') { // tag found:
56 if (m_CacheSize
% CACHE_INCREMENT
== 0)
57 m_Cache
= (sCacheItem
*) realloc(m_Cache
, (m_CacheSize
+ CACHE_INCREMENT
) * sizeof(sCacheItem
));
59 m_Cache
[tg
].Key
= stpos
= pos
++;
61 while ((src
[pos
] != '>') && (src
[pos
] != ' ')) {
62 dummy
[i
] = src
[pos
++];
63 if ((dummy
[i
] >= 'a') && (dummy
[i
] <= 'z')) dummy
[i
] -= ('a' - 'A');
67 m_Cache
[tg
].Name
= new char[i
+1];
68 memcpy(m_Cache
[tg
].Name
, dummy
, i
+1);
70 while (src
[pos
] != '>') pos
++;
72 if (src
[stpos
+1] == '/') { // ending tag:
73 m_Cache
[tg
].End1
= m_Cache
[tg
].End2
= -2;
74 // find matching begin tag:
75 for (i
= tg
; i
>= 0; i
--)
76 if ((m_Cache
[i
].End1
== -1) && (strcmp(m_Cache
[i
].Name
, dummy
+1) == 0)) {
77 m_Cache
[i
].End1
= stpos
;
78 m_Cache
[i
].End2
= pos
+ 1;
83 m_Cache
[tg
].End1
= m_Cache
[tg
].End2
= -1;
90 // ok, we're done, now we'll free .Name members of cache - we don't need it anymore:
91 for (i
= 0; i
< m_CacheSize
; i
++) {
92 delete[] m_Cache
[i
].Name
;
93 m_Cache
[i
].Name
= NULL
;
99 void wxHtmlTagsCache::QueryTag(int at
, int* end1
, int* end2
)
101 if (m_Cache
== NULL
) return;
102 if (m_Cache
[m_CachePos
].Key
!= at
) {
103 int delta
= (at
< m_Cache
[m_CachePos
].Key
) ? -1 : 1;
104 do {m_CachePos
+= delta
;} while (m_Cache
[m_CachePos
].Key
!= at
);
106 *end1
= m_Cache
[m_CachePos
].End1
;
107 *end2
= m_Cache
[m_CachePos
].End2
;
113 //-----------------------------------------------------------------------------
115 //-----------------------------------------------------------------------------
117 IMPLEMENT_CLASS(wxHtmlTag
,wxObject
)
119 wxHtmlTag::wxHtmlTag(const wxString
& source
, int pos
, int end_pos
, wxHtmlTagsCache
* cache
) : wxObject()
124 // fill-in name, params and begin pos:
125 m_Name
= m_Params
= wxEmptyString
;
127 if (source
[i
] == '/') {m_Ending
= TRUE
; i
++;}
128 else m_Ending
= FALSE
;
130 while ((i
< end_pos
) && ((c
= source
[i
++]) != ' ') && (c
!= '>')) {
131 if ((c
>= 'a') && (c
<= 'z')) c
-= ('a' - 'A');
135 if (source
[i
-1] != '>')
136 while ((i
< end_pos
) && ((c
= source
[i
++]) != '>')) {
137 if ((c
>= 'a') && (c
<= 'z')) c
-= ('a' - 'A');
140 while ((i
< end_pos
) && ((c
= source
[i
++]) != '"')) m_Params
+= c
;
143 else if (c
== '\'') {
144 while ((i
< end_pos
) && ((c
= source
[i
++]) != '\'')) m_Params
+= c
;
150 cache
-> QueryTag(pos
, &m_End1
, &m_End2
);
151 if (m_End1
> end_pos
) m_End1
= end_pos
;
152 if (m_End2
> end_pos
) m_End2
= end_pos
;
157 bool wxHtmlTag::HasParam(const wxString
& par
) const
159 const char *st
= m_Params
, *p
= par
;
160 const char *st2
, *p2
;
162 if (*st
== 0) return FALSE
;
163 if (*p
== 0) return FALSE
;
164 for (st2
= st
, p2
= p
; ; st2
++) {
165 if (*p2
== 0) return TRUE
;
166 if (*st2
== 0) return FALSE
;
167 if (*p2
!= *st2
) p2
= p
;
168 if (*p2
== *st2
) p2
++;
169 if (*st2
== ' ') p2
= p
;
170 else if (*st2
== '=') {
172 while (*st2
!= ' ') {
175 while (*st2
!= '"') st2
++;
178 if (*st2
== 0) return FALSE
;
186 wxString
wxHtmlTag::GetParam(const wxString
& par
, bool with_commas
) const
188 const char *st
= m_Params
, *p
= par
;
189 const char *st2
, *p2
;
193 if (*st
== 0) return "";
194 if (*p
== 0) return "";
195 for (st2
= st
, p2
= p
; ; st2
++) {
196 if (*p2
== 0) { // found
198 st2
++; // '=' character
201 if (!with_commas
&& (*(st2
) == '"')) {
206 else if (!with_commas
&& (*(st2
) == '\'')) {
212 if (comma
&& *st2
== comma_char
) comma
= FALSE
;
213 else if ((*st2
== ' ') && (!comma
)) break;
216 if (!with_commas
&& (*(st2
-1) == comma_char
)) fnd
.RemoveLast();
219 if (*st2
== 0) return "";
220 if (*p2
!= *st2
) p2
= p
;
221 if (*p2
== *st2
) p2
++;
222 if (*st2
== ' ') p2
= p
;
223 else if (*st2
== '=') {
225 while (*st2
!= ' ') {
228 while (*st2
!= '"') st2
++;
230 else if (*st2
== '\'') {
232 while (*st2
!= '\'') st2
++;
242 int wxHtmlTag::ScanParam(const wxString
& par
, char *format
, ...) const
246 wxString parval
= GetParam(par
);
248 va_start(argptr
, format
);
250 //#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__VISUALC__)
252 retval
= sscanf((const char*)parval
, format
, va_arg(argptr
, void *));
254 retval
= vsscanf((const char*)parval
, format
, argptr
);
258 --- vsscanf is not defined under some compilers
259 if this module doesn't compile with your compiler,
260 modify the def statement and let me know. Thanks...
262 So far wxHtml functions are scanning only _one_ value
263 so I workarounded this by supposing that there is only