From b1a3a964997a143de68f2e3c75fa8dd82a4e3361 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sun, 26 Aug 2007 10:04:11 +0000 Subject: [PATCH] fixed wxHTML parsing to run in O(n) even in UTF8 build git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@48390 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/html/htmlpars.h | 12 ++-- include/wx/html/htmltag.h | 45 +++++++++--- src/html/htmlpars.cpp | 112 ++++++++++++++++-------------- src/html/htmltag.cpp | 138 +++++++++++++++++++++++-------------- src/html/m_layout.cpp | 4 +- 5 files changed, 191 insertions(+), 120 deletions(-) diff --git a/include/wx/html/htmlpars.h b/include/wx/html/htmlpars.h index 66f2de8db4..6fe3d7f780 100644 --- a/include/wx/html/htmlpars.h +++ b/include/wx/html/htmlpars.h @@ -73,7 +73,8 @@ public: // Parses the m_Source from begin_pos to end_pos-1. // (in noparams version it parses whole m_Source) - void DoParsing(int begin_pos, int end_pos); + void DoParsing(const wxString::const_iterator& begin_pos, + const wxString::const_iterator& end_pos); void DoParsing(); // Returns pointer to the tag at parser's current position @@ -104,7 +105,7 @@ public: // Restores state before last call to PushTagHandler void PopTagHandler(); - wxString* GetSource() {return &m_Source;} + const wxString* GetSource() {return m_Source;} void SetSource(const wxString& src); // Sets HTML source and remembers current parser's state so that it can @@ -140,7 +141,8 @@ protected: void CreateDOMTree(); void DestroyDOMTree(); void CreateDOMSubTree(wxHtmlTag *cur, - int begin_pos, int end_pos, + const wxString::const_iterator& begin_pos, + const wxString::const_iterator& end_pos, wxHtmlTagsCache *cache); // Adds text to the output. @@ -163,7 +165,7 @@ protected: wxHtmlTextPieces *m_TextPieces; size_t m_CurTextPiece; - wxString m_Source; + const wxString *m_Source; wxHtmlParserState *m_SavedStates; @@ -232,7 +234,7 @@ protected: // parses input between beginning and ending tag. // m_Parser must be set. void ParseInner(const wxHtmlTag& tag) - { m_Parser->DoParsing(tag.GetBeginPos(), tag.GetEndPos1()); } + { m_Parser->DoParsing(tag.GetBeginIter(), tag.GetEndIter1()); } // Parses given source as if it was tag's inner code (see // wxHtmlParser::GetInnerSource). Unlike ParseInner(), this method lets diff --git a/include/wx/html/htmltag.h b/include/wx/html/htmltag.h index e92bb40eba..56f042096a 100644 --- a/include/wx/html/htmltag.h +++ b/include/wx/html/htmltag.h @@ -31,7 +31,7 @@ class WXDLLIMPEXP_HTML wxHtmlTagsCache { private: wxHtmlTagsCacheData *m_Cache; - size_t m_CachePos; + int m_CachePos; wxHtmlTagsCacheData& Cache() { return *m_Cache; } @@ -41,7 +41,11 @@ public: virtual ~wxHtmlTagsCache(); // Finds parameters for tag starting at at and fills the variables - void QueryTag(int at, int* end1, int* end2); + void QueryTag(const wxString::const_iterator& at, + const wxString::const_iterator& inputEnd, + wxString::const_iterator *end1, + wxString::const_iterator *end2, + bool *hasEnding); DECLARE_NO_COPY_CLASS(wxHtmlTagsCache) }; @@ -60,7 +64,9 @@ protected: // The tag begins (with '<' character) at position pos in source // end_pos is position where parsing ends (usually end of document) wxHtmlTag(wxHtmlTag *parent, - const wxString& source, int pos, int end_pos, + const wxString *source, + const wxString::const_iterator& pos, + const wxString::const_iterator& end_pos, wxHtmlTagsCache *cache, wxHtmlEntitiesParser *entParser); friend class wxHtmlParser; @@ -108,24 +114,37 @@ public: // Returns string containing all params. wxString GetAllParams() const; - // return true if this there is matching ending tag - inline bool HasEnding() const {return m_End1 >= 0;} + // return true if there is matching ending tag + inline bool HasEnding() const {return m_hasEnding;} // returns beginning position of _internal_ block of text // See explanation (returned value is marked with *): // bla bla bla * bla bla intenal text bla bla - inline int GetBeginPos() const {return m_Begin;} + wxString::const_iterator GetBeginIter() const + { return m_Begin; } // returns ending position of _internal_ block of text. // bla bla bla bla bla intenal text* bla bla - inline int GetEndPos1() const {return m_End1;} + wxString::const_iterator GetEndIter1() const + { wxASSERT(m_hasEnding); return m_End1; } // returns end position 2 : // bla bla bla bla bla internal text* bla bla - inline int GetEndPos2() const {return m_End2;} + wxString::const_iterator GetEndIter2() const + { wxASSERT(m_hasEnding); return m_End2; } + +#if WXWIN_COMPATIBILITY_2_8 + wxDEPRECATED( inline int GetBeginPos() const ); + wxDEPRECATED( inline int GetEndPos1() const ); + wxDEPRECATED( inline int GetEndPos2() const ); +#endif // WXWIN_COMPATIBILITY_2_8 private: wxString m_Name; - int m_Begin, m_End1, m_End2; + bool m_hasEnding; + wxString::const_iterator m_Begin, m_End1, m_End2; wxArrayString m_ParamNames, m_ParamValues; +#if WXWIN_COMPATIBILITY_2_8 + wxString::const_iterator m_sourceStart; +#endif // DOM tree relations: wxHtmlTag *m_Next; @@ -137,10 +156,16 @@ private: }; +#if WXWIN_COMPATIBILITY_2_8 +inline int wxHtmlTag::GetBeginPos() const { return m_Begin - m_sourceStart; } +inline int wxHtmlTag::GetEndPos1() const { return m_End1 - m_sourceStart; } +inline int wxHtmlTag::GetEndPos2() const { return m_End2 - m_sourceStart; } +#endif // WXWIN_COMPATIBILITY_2_8 -#endif + +#endif // wxUSE_HTML #endif // _WX_HTMLTAG_H_ diff --git a/src/html/htmlpars.cpp b/src/html/htmlpars.cpp index c51181a3fa..01e1b30671 100644 --- a/src/html/htmlpars.cpp +++ b/src/html/htmlpars.cpp @@ -48,8 +48,10 @@ class wxHtmlTextPiece { public: wxHtmlTextPiece() {} - wxHtmlTextPiece(int pos, int lng) : m_pos(pos), m_lng(lng) {} - int m_pos, m_lng; + wxHtmlTextPiece(const wxString::const_iterator& start, + const wxString::const_iterator& end) + : m_start(start), m_end(end) {} + wxString::const_iterator m_start, m_end; }; // NB: this is an empty class and not typedef because of forward declaration @@ -64,7 +66,7 @@ public: wxHtmlTag *m_tags; wxHtmlTextPieces *m_textPieces; int m_curTextPiece; - wxString m_source; + const wxString *m_source; wxHtmlParserState *m_nextState; }; @@ -78,6 +80,7 @@ wxHtmlParser::wxHtmlParser() : wxObject(), m_HandlersHash(wxKEY_STRING), m_FS(NULL), m_HandlersStack(NULL) { + m_Source = NULL; m_entitiesParser = new wxHtmlEntitiesParser; m_Tags = NULL; m_CurTag = NULL; @@ -103,6 +106,7 @@ wxHtmlParser::~wxHtmlParser() m_HandlersHash.Clear(); WX_CLEAR_LIST(wxList, m_HandlersList); delete m_entitiesParser; + delete m_Source; } wxObject* wxHtmlParser::Parse(const wxString& source) @@ -128,7 +132,10 @@ void wxHtmlParser::DoneParser() void wxHtmlParser::SetSource(const wxString& src) { DestroyDOMTree(); - m_Source = src; + // NB: this is allocated on heap because wxHtmlTag keeps a pointer to + // this string if WXWIN_COMPATIBILITY_2_8 + delete m_Source; + m_Source = new wxString(src); CreateDOMTree(); m_CurTag = NULL; m_CurTextPiece = 0; @@ -136,54 +143,53 @@ void wxHtmlParser::SetSource(const wxString& src) void wxHtmlParser::CreateDOMTree() { - wxHtmlTagsCache cache(m_Source); + wxHtmlTagsCache cache(*m_Source); m_TextPieces = new wxHtmlTextPieces; - CreateDOMSubTree(NULL, 0, m_Source.length(), &cache); + CreateDOMSubTree(NULL, m_Source->begin(), m_Source->end(), &cache); m_CurTextPiece = 0; } -extern bool wxIsCDATAElement(const wxChar *tag); +extern bool wxIsCDATAElement(const wxString& tag); void wxHtmlParser::CreateDOMSubTree(wxHtmlTag *cur, - int begin_pos, int end_pos, + const wxString::const_iterator& begin_pos, + const wxString::const_iterator& end_pos, wxHtmlTagsCache *cache) { - if (end_pos <= begin_pos) return; + if (end_pos <= begin_pos) + return; wxChar c; - int i = begin_pos; - int textBeginning = begin_pos; + wxString::const_iterator i = begin_pos; + wxString::const_iterator textBeginning = begin_pos; // If the tag contains CDATA text, we include the text between beginning // and ending tag verbosely. Setting i=end_pos will skip to the very // end of this function where text piece is added, bypassing any child // tags parsing (CDATA element can't have child elements by definition): - if (cur != NULL && wxIsCDATAElement(cur->GetName().c_str())) + if (cur != NULL && wxIsCDATAElement(cur->GetName())) { i = end_pos; } while (i < end_pos) { - c = m_Source.GetChar(i); + c = *i; if (c == wxT('<')) { // add text to m_TextPieces: - if (i - textBeginning > 0) - m_TextPieces->push_back( - wxHtmlTextPiece(textBeginning, i - textBeginning)); + if (i > textBeginning) + m_TextPieces->push_back(wxHtmlTextPiece(textBeginning, i)); // if it is a comment, skip it: - wxString::const_iterator iter = m_Source.begin() + i; - if ( SkipCommentTag(iter, m_Source.end()) ) + if ( SkipCommentTag(i, m_Source->end()) ) { - textBeginning = - i = iter - m_Source.begin() + 1; // skip closing '>' too + textBeginning = i = i + 1; // skip closing '>' too } // add another tag to the tree: - else if (i < end_pos-1 && m_Source.GetChar(i+1) != wxT('/')) + else if (i < end_pos-1 && *(i+1) != wxT('/')) { wxHtmlTag *chd; if (cur) @@ -211,12 +217,12 @@ void wxHtmlParser::CreateDOMSubTree(wxHtmlTag *cur, if (chd->HasEnding()) { CreateDOMSubTree(chd, - chd->GetBeginPos(), chd->GetEndPos1(), + chd->GetBeginIter(), chd->GetEndIter1(), cache); - i = chd->GetEndPos2(); + i = chd->GetEndIter2(); } else - i = chd->GetBeginPos(); + i = chd->GetBeginIter(); textBeginning = i; } @@ -224,17 +230,16 @@ void wxHtmlParser::CreateDOMSubTree(wxHtmlTag *cur, // ... or skip ending tag: else { - while (i < end_pos && m_Source.GetChar(i) != wxT('>')) i++; + while (i < end_pos && *i != wxT('>')) ++i; textBeginning = i+1; } } - else i++; + else ++i; } // add remaining text to m_TextPieces: - if (end_pos - textBeginning > 0) - m_TextPieces->push_back( - wxHtmlTextPiece(textBeginning, end_pos - textBeginning)); + if (end_pos > textBeginning) + m_TextPieces->push_back(wxHtmlTextPiece(textBeginning, end_pos)); } void wxHtmlParser::DestroyDOMTree() @@ -257,42 +262,45 @@ void wxHtmlParser::DoParsing() { m_CurTag = m_Tags; m_CurTextPiece = 0; - DoParsing(0, m_Source.length()); + DoParsing(m_Source->begin(), m_Source->end()); } -void wxHtmlParser::DoParsing(int begin_pos, int end_pos) +void wxHtmlParser::DoParsing(const wxString::const_iterator& begin_pos_, + const wxString::const_iterator& end_pos) { - if (end_pos <= begin_pos) return; + wxString::const_iterator begin_pos(begin_pos_); + + if (end_pos <= begin_pos) + return; wxHtmlTextPieces& pieces = *m_TextPieces; size_t piecesCnt = pieces.size(); while (begin_pos < end_pos) { - while (m_CurTag && m_CurTag->GetBeginPos() < begin_pos) + while (m_CurTag && m_CurTag->GetBeginIter() < begin_pos) m_CurTag = m_CurTag->GetNextTag(); while (m_CurTextPiece < piecesCnt && - pieces[m_CurTextPiece].m_pos < begin_pos) + pieces[m_CurTextPiece].m_start < begin_pos) m_CurTextPiece++; if (m_CurTextPiece < piecesCnt && (!m_CurTag || - pieces[m_CurTextPiece].m_pos < m_CurTag->GetBeginPos())) + pieces[m_CurTextPiece].m_start < m_CurTag->GetBeginIter())) { // Add text: AddText(GetEntitiesParser()->Parse( - m_Source.Mid(pieces[m_CurTextPiece].m_pos, - pieces[m_CurTextPiece].m_lng))); - begin_pos = pieces[m_CurTextPiece].m_pos + - pieces[m_CurTextPiece].m_lng; + wxString(pieces[m_CurTextPiece].m_start, + pieces[m_CurTextPiece].m_end))); + begin_pos = pieces[m_CurTextPiece].m_end; m_CurTextPiece++; } else if (m_CurTag) { if (m_CurTag->HasEnding()) - begin_pos = m_CurTag->GetEndPos2(); + begin_pos = m_CurTag->GetEndIter2(); else - begin_pos = m_CurTag->GetBeginPos(); + begin_pos = m_CurTag->GetBeginIter(); wxHtmlTag *t = m_CurTag; m_CurTag = m_CurTag->GetNextTag(); AddTag(*t); @@ -318,7 +326,7 @@ void wxHtmlParser::AddTag(const wxHtmlTag& tag) if (!inner) { if (tag.HasEnding()) - DoParsing(tag.GetBeginPos(), tag.GetEndPos1()); + DoParsing(tag.GetBeginIter(), tag.GetEndIter1()); } } @@ -393,7 +401,7 @@ void wxHtmlParser::SetSourceAndSaveState(const wxString& src) m_Tags = NULL; m_TextPieces = NULL; m_CurTextPiece = 0; - m_Source = wxEmptyString; + m_Source = NULL; SetSource(src); } @@ -419,8 +427,7 @@ bool wxHtmlParser::RestoreState() wxString wxHtmlParser::GetInnerSource(const wxHtmlTag& tag) { - return GetSource()->Mid(tag.GetBeginPos(), - tag.GetEndPos1() - tag.GetBeginPos()); + return wxString(tag.GetBeginIter(), tag.GetEndIter1()); } //----------------------------------------------------------------------------- @@ -501,11 +508,16 @@ wxString wxHtmlEntitiesParser::Parse(const wxString& input) const const wxString::const_iterator ent_s = c; wxChar entity_char; - for (; c != end && - ((*c >= wxT('a') && *c <= wxT('z')) || - (*c >= wxT('A') && *c <= wxT('Z')) || - (*c >= wxT('0') && *c <= wxT('9')) || - *c == wxT('_') || *c == wxT('#')); ++c) {} + for ( ; c != end; ++c ) + { + wxChar ch = *c; + if ( !((ch >= wxT('a') && ch <= wxT('z')) || + (ch >= wxT('A') && ch <= wxT('Z')) || + (ch >= wxT('0') && ch <= wxT('9')) || + ch == wxT('_') || ch == wxT('#')) ) + break; + } + entity.append(ent_s, c); if (c == end || *c != wxT(';')) --c; last = c+1; diff --git a/src/html/htmltag.cpp b/src/html/htmltag.cpp index a0f9b6af37..4365a26554 100644 --- a/src/html/htmltag.cpp +++ b/src/html/htmltag.cpp @@ -36,14 +36,21 @@ struct wxHtmlCacheItem { // this is "pos" value passed to wxHtmlTag's constructor. // it is position of '<' character of the tag - int Key; + wxString::const_iterator Key; + + // Tag type + enum Type + { + Type_Normal, // normal tag with a matching ending tag + Type_NoMatchingEndingTag, // there's no ending tag for this tag + Type_EndingTag // this is ending tag + }; + Type type; // end positions for the tag: // end1 is '<' of ending tag, // end2 is '>' or both are - // -1 if there is no ending tag for this one... - // or -2 if this is ending tag - int End1, End2; + wxString::const_iterator End1, End2; // name of this tag wxChar *Name; @@ -60,95 +67,108 @@ bool wxIsCDATAElement(const wxChar *tag) (wxStrcmp(tag, _T("STYLE")) == 0); } +bool wxIsCDATAElement(const wxString& tag) +{ + return (wxStrcmp(tag.wx_str(), wxSTRING_TEXT("SCRIPT")) == 0) || + (wxStrcmp(tag.wx_str(), wxSTRING_TEXT("STYLE")) == 0); +} + wxHtmlTagsCache::wxHtmlTagsCache(const wxString& source) { m_Cache = new wxHtmlTagsCacheData; m_CachePos = 0; - const wxChar *src = source.c_str(); - int lng = source.length(); wxChar tagBuffer[256]; - for ( int pos = 0; pos < lng; pos++ ) + const wxString::const_iterator end = source.end(); + for ( wxString::const_iterator pos = source.begin(); pos < end; ++pos ) { - if (src[pos] == wxT('<')) // tag found: + if (*pos == wxT('<')) // tag found: { // don't cache comment tags - wxString::const_iterator iter = source.begin() + pos; - if ( wxHtmlParser::SkipCommentTag(iter, source.end()) ) - { - pos = iter - source.begin(); + if ( wxHtmlParser::SkipCommentTag(pos, source.end()) ) continue; - } size_t tg = Cache().size(); Cache().push_back(wxHtmlCacheItem()); - int stpos = pos++; + wxString::const_iterator stpos = pos++; Cache()[tg].Key = stpos; int i; for ( i = 0; - pos < lng && i < (int)WXSIZEOF(tagBuffer) - 1 && - src[pos] != wxT('>') && !wxIsspace(src[pos]); - i++, pos++ ) + pos < end && i < (int)WXSIZEOF(tagBuffer) - 1 && + *pos != wxT('>') && !wxIsspace(*pos); + ++i, ++pos ) { - tagBuffer[i] = (wxChar)wxToupper(src[pos]); + tagBuffer[i] = (wxChar)wxToupper(*pos); } tagBuffer[i] = _T('\0'); Cache()[tg].Name = new wxChar[i+1]; memcpy(Cache()[tg].Name, tagBuffer, (i+1)*sizeof(wxChar)); - while (pos < lng && src[pos] != wxT('>')) pos++; + while (pos < end && *pos != wxT('>')) + ++pos; - if (src[stpos+1] == wxT('/')) // ending tag: + if ((stpos+1) < end && *(stpos+1) == wxT('/')) // ending tag: { - Cache()[tg].End1 = Cache()[tg].End2 = -2; + Cache()[tg].type = wxHtmlCacheItem::Type_EndingTag; // find matching begin tag: for (i = tg; i >= 0; i--) - if ((Cache()[i].End1 == -1) && (wxStrcmp(Cache()[i].Name, tagBuffer+1) == 0)) + { + if ((Cache()[i].type == wxHtmlCacheItem::Type_NoMatchingEndingTag) && (wxStrcmp(Cache()[i].Name, tagBuffer+1) == 0)) { + Cache()[i].type = wxHtmlCacheItem::Type_Normal; Cache()[i].End1 = stpos; Cache()[i].End2 = pos + 1; break; } + } } else { - Cache()[tg].End1 = Cache()[tg].End2 = -1; + Cache()[tg].type = wxHtmlCacheItem::Type_NoMatchingEndingTag; if (wxIsCDATAElement(tagBuffer)) { // store the orig pos in case we are missing the closing // tag (see below) - wxInt32 old_pos = pos; + const wxString::const_iterator old_pos = pos; bool foundCloseTag = false; // find next matching tag int tag_len = wxStrlen(tagBuffer); - while (pos < lng) + while (pos < end) { // find the ending tag - while (pos + 1 < lng && - (src[pos] != '<' || src[pos+1] != '/')) + while (pos + 1 < end && + (*pos != '<' || *(pos+1) != '/')) ++pos; - if (src[pos] == '<') + if (*pos == '<') ++pos; // see if it matches int match_pos = 0; - while (pos < lng && match_pos < tag_len && src[pos] != '>' && src[pos] != '<') { + while (pos < end && match_pos < tag_len ) + { + wxChar c = *pos; + if ( c == '>' || c == '<' ) + break; + // cast to wxChar needed to suppress warning in // Unicode build - if ((wxChar)wxToupper(src[pos]) == tagBuffer[match_pos]) { + if ((wxChar)wxToupper(c) == tagBuffer[match_pos]) + { ++match_pos; } - else if (src[pos] == wxT(' ') || src[pos] == wxT('\n') || - src[pos] == wxT('\r') || src[pos] == wxT('\t')) { + else if (c == wxT(' ') || c == wxT('\n') || + c == wxT('\r') || c == wxT('\t')) + { // need to skip over these } - else { + else + { match_pos = 0; } ++pos; @@ -193,7 +213,11 @@ wxHtmlTagsCache::~wxHtmlTagsCache() delete m_Cache; } -void wxHtmlTagsCache::QueryTag(int at, int* end1, int* end2) +void wxHtmlTagsCache::QueryTag(const wxString::const_iterator& at, + const wxString::const_iterator& inputEnd, + wxString::const_iterator *end1, + wxString::const_iterator *end2, + bool *hasEnding) { if (Cache().empty()) return; @@ -203,22 +227,28 @@ void wxHtmlTagsCache::QueryTag(int at, int* end1, int* end2) int delta = (at < Cache()[m_CachePos].Key) ? -1 : 1; do { - if ( m_CachePos < 0 || m_CachePos == Cache().size() ) + m_CachePos += delta; + + if ( m_CachePos < 0 || m_CachePos >= (int)Cache().size() ) { + if ( m_CachePos < 0 ) + m_CachePos = 0; + else + m_CachePos = Cache().size() - 1; // something is very wrong with HTML, give up by returning an // impossibly large value which is going to be ignored by the // caller *end1 = - *end2 = INT_MAX; + *end2 = inputEnd; + *hasEnding = true; return; } - - m_CachePos += delta; } while (Cache()[m_CachePos].Key != at); } *end1 = Cache()[m_CachePos].End1; *end2 = Cache()[m_CachePos].End2; + *hasEnding = (Cache()[m_CachePos].type == wxHtmlCacheItem::Type_Normal); } @@ -229,7 +259,9 @@ void wxHtmlTagsCache::QueryTag(int at, int* end1, int* end2) //----------------------------------------------------------------------------- wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, - const wxString& source, int pos, int end_pos, + const wxString *source, + const wxString::const_iterator& pos, + const wxString::const_iterator& end_pos, wxHtmlTagsCache *cache, wxHtmlEntitiesParser *entParser) { @@ -252,15 +284,14 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, /* Find parameters and their values: */ - int i; wxChar c; // fill-in name, params and begin pos: - i = pos+1; + wxString::const_iterator i(pos+1); // find tag's name and convert it to uppercase: while ((i < end_pos) && - ((c = source[i++]) != wxT(' ') && c != wxT('\r') && + ((c = *(i++)) != wxT(' ') && c != wxT('\r') && c != wxT('\n') && c != wxT('\t') && c != wxT('>'))) { @@ -272,7 +303,7 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, // if the tag has parameters, read them and "normalize" them, // i.e. convert to uppercase, replace whitespaces by spaces and // remove whitespaces around '=': - if (source[i-1] != wxT('>')) + if (*(i-1) != wxT('>')) { #define IS_WHITE(c) (c == wxT(' ') || c == wxT('\r') || \ c == wxT('\n') || c == wxT('\t')) @@ -291,14 +322,14 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, state = ST_BEFORE_NAME; while (i < end_pos) { - c = source[i++]; + c = *(i++); if (c == wxT('>') && !(state == ST_VALUE && quote != 0)) { if (state == ST_BEFORE_EQ || state == ST_NAME) { m_ParamNames.Add(pname); - m_ParamValues.Add(wxEmptyString); + m_ParamValues.Add(wxGetEmptyString()); } else if (state == ST_VALUE && quote == 0) { @@ -333,7 +364,7 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, else if (!IS_WHITE(c)) { m_ParamNames.Add(pname); - m_ParamValues.Add(wxEmptyString); + m_ParamValues.Add(wxGetEmptyString()); pname = c; state = ST_NAME; } @@ -342,7 +373,7 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, if (!IS_WHITE(c)) { if (c == wxT('"') || c == wxT('\'')) - quote = c, pvalue = wxEmptyString; + quote = c, pvalue = wxGetEmptyString(); else quote = 0, pvalue = c; state = ST_VALUE; @@ -374,10 +405,13 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, #undef IS_WHITE } m_Begin = i; - - cache->QueryTag(pos, &m_End1, &m_End2); + cache->QueryTag(pos, source->end(), &m_End1, &m_End2, &m_hasEnding); if (m_End1 > end_pos) m_End1 = end_pos; if (m_End2 > end_pos) m_End2 = end_pos; + +#if WXWIN_COMPATIBILITY_2_8 + m_sourceStart = source->begin(); +#endif } wxHtmlTag::~wxHtmlTag() @@ -401,7 +435,7 @@ wxString wxHtmlTag::GetParam(const wxString& par, bool with_commas) const { int index = m_ParamNames.Index(par, false); if (index == wxNOT_FOUND) - return wxEmptyString; + return wxGetEmptyString(); if (with_commas) { // VS: backward compatibility, seems to be never used by wxHTML... @@ -438,8 +472,8 @@ bool wxHtmlTag::GetParamAsColour(const wxString& par, wxColour *clr) const // handle colours defined in HTML 4.0 first: if (str.length() > 1 && str[0] != _T('#')) { - #define HTML_COLOUR(name, r, g, b) \ - if (str.IsSameAs(wxT(name), false)) \ + #define HTML_COLOUR(name, r, g, b) \ + if (str.IsSameAs(wxSTRING_TEXT(name), false)) \ { clr->Set(r, g, b); return true; } HTML_COLOUR("black", 0x00,0x00,0x00) HTML_COLOUR("silver", 0xC0,0xC0,0xC0) diff --git a/src/html/m_layout.cpp b/src/html/m_layout.cpp index 1bea340201..2451f2fb53 100644 --- a/src/html/m_layout.cpp +++ b/src/html/m_layout.cpp @@ -289,9 +289,7 @@ TAG_HANDLER_BEGIN(TITLE, "TITLE") wxHtmlWindowInterface *winIface = m_WParser->GetWindowInterface(); if (winIface) { - wxString title = m_WParser->GetSource()->Mid( - tag.GetBeginPos(), - tag.GetEndPos1()-tag.GetBeginPos()); + wxString title(tag.GetBeginIter(), tag.GetEndIter1()); #if !wxUSE_UNICODE && wxUSE_WCHAR_T const wxFontEncoding enc = m_WParser->GetInputEncoding(); if ( enc != wxFONTENCODING_DEFAULT ) -- 2.45.2