UINT_PTR CBkSafeMsgBox2::ShowMutlLineMsg(LPCWSTR pszMsg, LPCWSTR lpszCaption /* = NULL */, UINT uType /* = NULL */, BOOL *pbNoNotifyLater /* = NULL */, HWND hWndParent /* = ::GetActiveWindow */) { CString strMsg = pszMsg, strXml(L""), strXmlPanel(L""); CAtlArray<CString> arrMsgLine; if ( 0 == ParseMsgLine(strMsg, arrMsgLine)) return -1; int nWidth = 0, nLineCount = arrMsgLine.GetCount(), nHeight = nLineCount* 18, nTop = 0; CRect rcText; for (int i = 0; i < nLineCount; i++) { if (1 == nLineCount) nTop = 10; else nTop = i*18; strXml.Format(L"<text pos=\"0,%d\">%s</text>", nTop, arrMsgLine[i]); strXmlPanel += strXml; rcText = GetTextRect(arrMsgLine[i]); if (nWidth < rcText.Width()) nWidth = rcText.Width(); } CRect rc(0, 0, nWidth+10, nHeight); return ShowPanelMsg(strXmlPanel, &rc, NULL, uType, pbNoNotifyLater, hWndParent); }
bool CCharsetDetection::GetXmlEncodingFromDeclaration(const char* const xmlContent, const size_t contentLength, std::string& declaredEncoding) { // following code is std::string-processing analog of regular expression-processing // regular expression: "<\\?xml([ \n\r\t]+[^ \n\t\r>]+)*[ \n\r\t]+encoding[ \n\r\t]*=[ \n\r\t]*('[^ \n\t\r>']+'|\"[^ \n\t\r>\"]+\")" // on win32 x86 machine regular expression is slower that std::string 20-40 times and can slowdown XML processing for several times // seems that this regular expression is too slow due to many variable length parts, regexp for '&'-fixing is much faster declaredEncoding.clear(); // avoid extra large search std::string strXml(xmlContent, std::min(contentLength, m_XmlDeclarationMaxLength)); size_t pos = strXml.find("<?xml"); if (pos == std::string::npos || pos + 6 > strXml.length() || pos > strXml.find('<')) return false; // no "<?xml" declaration, "<?xml" is not first element or "<?xml" is incomplete pos += 5; // 5 is length of "<?xml" const size_t declLength = std::min(std::min(m_XmlDeclarationMaxLength, contentLength - pos), strXml.find('>', pos) - pos); const std::string xmlDecl(xmlContent + pos, declLength); const char* const xmlDeclC = xmlDecl.c_str(); // for faster processing of [] and for null-termination static const char* const whiteSpaceChars = " \n\r\t"; // according to W3C Recommendation for XML, any of them can be used as separator pos = 0; while (pos + 12 <= declLength) // 12 is minimal length of "encoding='x'" { pos = xmlDecl.find_first_of(whiteSpaceChars, pos); if (pos == std::string::npos) return false; // no " encoding=" in declaration pos = xmlDecl.find_first_not_of(whiteSpaceChars, pos); if (pos == std::string::npos) return false; // no "encoding=" in declaration if (xmlDecl.compare(pos, 8, "encoding", 8) != 0) continue; // not "encoding" parameter pos += 8; // length of "encoding" if (xmlDeclC[pos] == ' ' || xmlDeclC[pos] == '\n' || xmlDeclC[pos] == '\r' || xmlDeclC[pos] == '\t') // no buffer overrun as string is null-terminated { pos = xmlDecl.find_first_not_of(whiteSpaceChars, pos); if (pos == std::string::npos) return false; // this " encoding" is incomplete, only whitespace chars remains } if (xmlDeclC[pos] != '=') { // "encoding" without "=", try to find other pos--; // step back to whitespace continue; } pos++; // skip '=' if (xmlDeclC[pos] == ' ' || xmlDeclC[pos] == '\n' || xmlDeclC[pos] == '\r' || xmlDeclC[pos] == '\t') // no buffer overrun as string is null-terminated { pos = xmlDecl.find_first_not_of(whiteSpaceChars, pos); if (pos == std::string::npos) return false; // this " encoding" is incomplete, only whitespace chars remains } size_t encNameEndPos; if (xmlDeclC[pos] == '"') encNameEndPos = xmlDecl.find('"', ++pos); else if (xmlDeclC[pos] == '\'') encNameEndPos = xmlDecl.find('\'', ++pos); else continue; // no quote or double quote after 'encoding=', try to find other if (encNameEndPos != std::string::npos) { declaredEncoding.assign(xmlDecl, pos, encNameEndPos - pos); return true; } // no closing quote or double quote after 'encoding="x', try to find other } return false; }