// DLL options compatibility check:
WX_CHECK_BUILD_OPTIONS("wxHTML")
-const wxChar *wxTRACE_HTML_DEBUG = _T("htmldebug");
+const wxChar *wxTRACE_HTML_DEBUG = wxT("htmldebug");
//-----------------------------------------------------------------------------
// wxHtmlParser helpers
IMPLEMENT_ABSTRACT_CLASS(wxHtmlParser,wxObject)
wxHtmlParser::wxHtmlParser()
- : wxObject(), m_HandlersHash(wxKEY_STRING),
- m_FS(NULL), m_HandlersStack(NULL)
+ : wxObject(),
+ m_FS(NULL)
{
m_Source = NULL;
m_entitiesParser = new wxHtmlEntitiesParser;
while (RestoreState()) {}
DestroyDOMTree();
- if (m_HandlersStack)
- {
- wxList& tmp = *m_HandlersStack;
- wxList::iterator it, en;
- for( it = tmp.begin(), en = tmp.end(); it != en; ++it )
- delete (wxHashTable*)*it;
- tmp.clear();
- }
- delete m_HandlersStack;
- m_HandlersHash.Clear();
- WX_CLEAR_LIST(wxList, m_HandlersList);
+ WX_CLEAR_ARRAY(m_HandlersStack);
+ WX_CLEAR_HASH_SET(wxHtmlTagHandlersSet, m_HandlersSet);
delete m_entitiesParser;
delete m_Source;
}
void wxHtmlParser::SetSource(const wxString& src)
{
DestroyDOMTree();
- // NB: this is allocated on heap because wxHtmlTag keeps a pointer to
- // this string if WXWIN_COMPATIBILITY_2_8
+ // NB: This is allocated on heap because wxHtmlTag uses iterators and
+ // making a copy of m_Source string in SetSourceAndSaveState() and
+ // RestoreState() would invalidate them (because wxString::m_impl's
+ // memory would change completely twice and iterators use pointers
+ // into it). So instead, we keep the string object intact and only
+ // store/restore pointer to it, for which we need it to be allocated
+ // on the heap.
delete m_Source;
m_Source = new wxString(src);
CreateDOMTree();
else
{
while (i < end_pos && *i != wxT('>')) ++i;
- textBeginning = i+1;
+ textBeginning = i < end_pos ? i+1 : i;
}
}
else ++i;
}
m_Tags = m_CurTag = NULL;
- delete m_TextPieces;
- m_TextPieces = NULL;
+ wxDELETE(m_TextPieces);
}
void wxHtmlParser::DoParsing()
void wxHtmlParser::AddTag(const wxHtmlTag& tag)
{
- wxHtmlTagHandler *h;
bool inner = false;
- h = (wxHtmlTagHandler*) m_HandlersHash.Get(tag.GetName());
- if (h)
+ wxHtmlTagHandlersHash::const_iterator h = m_HandlersHash.find(tag.GetName());
+ if (h != m_HandlersHash.end())
{
- inner = h->HandleTag(tag);
+ inner = h->second->HandleTag(tag);
if (m_stopParsing)
return;
}
wxStringTokenizer tokenizer(s, wxT(", "));
while (tokenizer.HasMoreTokens())
- m_HandlersHash.Put(tokenizer.GetNextToken(), handler);
+ m_HandlersHash[tokenizer.GetNextToken()] = handler;
- if (m_HandlersList.IndexOf(handler) == wxNOT_FOUND)
- m_HandlersList.Append(handler);
+ m_HandlersSet.insert(handler);
handler->SetParser(this);
}
wxStringTokenizer tokenizer(tags, wxT(", "));
wxString key;
- if (m_HandlersStack == NULL)
- {
- m_HandlersStack = new wxList;
- }
-
- m_HandlersStack->Insert((wxObject*)new wxHashTable(m_HandlersHash));
+ m_HandlersStack.push_back(new wxHtmlTagHandlersHash(m_HandlersHash));
while (tokenizer.HasMoreTokens())
{
key = tokenizer.GetNextToken();
- m_HandlersHash.Delete(key);
- m_HandlersHash.Put(key, handler);
+ m_HandlersHash[key] = handler;
}
}
void wxHtmlParser::PopTagHandler()
{
- wxList::compatibility_iterator first;
+ wxCHECK_RET( !m_HandlersStack.empty(),
+ "attempt to remove HTML tag handler from empty stack" );
- if ( !m_HandlersStack ||
-#if wxUSE_STL
- !(first = m_HandlersStack->GetFirst())
-#else // !wxUSE_STL
- ((first = m_HandlersStack->GetFirst()) == NULL)
-#endif // wxUSE_STL/!wxUSE_STL
- )
- {
- wxLogWarning(_("Warning: attempt to remove HTML tag handler from empty stack."));
- return;
- }
- m_HandlersHash = *((wxHashTable*) first->GetData());
- delete (wxHashTable*) first->GetData();
- m_HandlersStack->Erase(first);
+ wxHtmlTagHandlersHash *prev = m_HandlersStack.back();
+ m_HandlersStack.pop_back();
+ m_HandlersHash = *prev;
+ delete prev;
}
void wxHtmlParser::SetSourceAndSaveState(const wxString& src)
if (!m_SavedStates) return false;
DestroyDOMTree();
+ delete m_Source;
wxHtmlParserState *s = m_SavedStates;
m_SavedStates = s->m_nextState;
IMPLEMENT_DYNAMIC_CLASS(wxHtmlEntitiesParser,wxObject)
wxHtmlEntitiesParser::wxHtmlEntitiesParser()
-#if wxUSE_WCHAR_T && !wxUSE_UNICODE
+#if !wxUSE_UNICODE
: m_conv(NULL), m_encoding(wxFONTENCODING_SYSTEM)
#endif
{
wxHtmlEntitiesParser::~wxHtmlEntitiesParser()
{
-#if wxUSE_WCHAR_T && !wxUSE_UNICODE
+#if !wxUSE_UNICODE
delete m_conv;
#endif
}
+#if !wxUSE_UNICODE
void wxHtmlEntitiesParser::SetEncoding(wxFontEncoding encoding)
{
-#if wxUSE_WCHAR_T && !wxUSE_UNICODE
if (encoding == m_encoding)
return;
m_conv = NULL;
else
m_conv = new wxCSConv(wxFontMapper::GetEncodingName(m_encoding));
-#else
- (void) encoding;
-#endif
}
+#endif // !wxUSE_UNICODE
wxString wxHtmlEntitiesParser::Parse(const wxString& input) const
{
#if !wxUSE_UNICODE
wxChar wxHtmlEntitiesParser::GetCharForCode(unsigned code) const
{
-#if wxUSE_WCHAR_T
char buf[2];
wchar_t wbuf[2];
wbuf[0] = (wchar_t)code;
if (conv->WC2MB(buf, wbuf, 2) == (size_t)-1)
return '?';
return buf[0];
-#else
- return (code < 256) ? (wxChar)code : '?';
-#endif
}
#endif
{
unsigned code = 0;
+ if (entity.empty())
+ return 0; // invalid entity reference
+
if (entity[0] == wxT('#'))
{
// NB: parsed value is a number, so it's OK to use wx_str(), internal
const wxStringCharType *ent_s = entity.wx_str();
const wxStringCharType *format;
- if (ent_s[1] == wxSTRING_TEXT('x') || ent_s[1] == wxSTRING_TEXT('X'))
+ if (ent_s[1] == wxS('x') || ent_s[1] == wxS('X'))
{
- format = wxSTRING_TEXT("%x");
+ format = wxS("%x");
ent_s++;
}
else
- format = wxSTRING_TEXT("%u");
+ format = wxS("%u");
ent_s++;
if (wxSscanf(ent_s, format, &code) != 1)
{
// store the literals in wx's internal representation (either char*
// in UTF-8 or wchar_t*) for best performance:
- #define ENTITY(name, code) { wxSTRING_TEXT(name), code }
+ #define ENTITY(name, code) { wxS(name), code }
static wxHtmlEntityInfo substitutions[] = {
ENTITY("AElig", 198),
ENTITY("amp", 38),
ENTITY("and", 8743),
ENTITY("ang", 8736),
+ ENTITY("apos", 39),
ENTITY("aring", 229),
ENTITY("asymp", 8776),
ENTITY("atilde", 227),
while (substitutions[substitutions_cnt].code != 0)
substitutions_cnt++;
- wxHtmlEntityInfo *info = NULL;
+ wxHtmlEntityInfo *info;
#ifdef __WXWINCE__
// bsearch crashes under WinCE for some reason
+ info = NULL;
size_t i;
for (i = 0; i < substitutions_cnt; i++)
{
return GetCharForCode(code);
}
-wxFSFile *wxHtmlParser::OpenURL(wxHtmlURLType WXUNUSED(type),
+wxFSFile *wxHtmlParser::OpenURL(wxHtmlURLType type,
const wxString& url) const
{
- return m_FS ? m_FS->OpenFile(url) : NULL;
+ int flags = wxFS_READ;
+ if (type == wxHTML_URL_IMAGE)
+ flags |= wxFS_SEEKABLE;
+
+ return m_FS ? m_FS->OpenFile(url, flags) : NULL;
}
protected:
virtual void AddText(const wxString& WXUNUSED(txt)) {}
- DECLARE_NO_COPY_CLASS(wxMetaTagParser)
+ wxDECLARE_NO_COPY_CLASS(wxMetaTagParser);
};
class wxMetaTagHandler : public wxHtmlTagHandler
private:
wxString *m_retval;
- DECLARE_NO_COPY_CLASS(wxMetaTagHandler)
+ wxDECLARE_NO_COPY_CLASS(wxMetaTagHandler);
};
bool wxMetaTagHandler::HandleTag(const wxHtmlTag& tag)
{
- if (tag.GetName() == _T("BODY"))
+ if (tag.GetName() == wxT("BODY"))
{
m_Parser->StopParsing();
return false;
}
- if (tag.HasParam(_T("HTTP-EQUIV")) &&
- tag.GetParam(_T("HTTP-EQUIV")).IsSameAs(_T("Content-Type"), false) &&
- tag.HasParam(_T("CONTENT")))
+ if (tag.HasParam(wxT("HTTP-EQUIV")) &&
+ tag.GetParam(wxT("HTTP-EQUIV")).IsSameAs(wxT("Content-Type"), false) &&
+ tag.HasParam(wxT("CONTENT")))
{
- wxString content = tag.GetParam(_T("CONTENT")).Lower();
- if (content.Left(19) == _T("text/html; charset="))
+ wxString content = tag.GetParam(wxT("CONTENT")).Lower();
+ if (content.Left(19) == wxT("text/html; charset="))
{
*m_retval = content.Mid(19);
m_Parser->StopParsing();
wxHtmlParser::SkipCommentTag(wxString::const_iterator& start,
wxString::const_iterator end)
{
- wxASSERT_MSG( *start == '<', _T("should be called on the tag start") );
+ wxASSERT_MSG( *start == '<', wxT("should be called on the tag start") );
wxString::const_iterator p = start;
// comments begin with "<!--" in HTML 4.0
- if ( p > end - 3 || *++p != '!' || *++p != '-' || *++p != '-' )
+ if ( end - start < 4 || *++p != '!' || *++p != '-' || *++p != '-' )
{
// not a comment at all
return false;