Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#398 に対する回避策 (特定のファイルで描画が遅くなる) #792

Merged
Merged
Prev Previous commit
Detect wordboundary inside IsMailAddress.
  • Loading branch information
ds14050 authored and berryzplus committed Feb 25, 2019
commit b32afa240202e4ec181d072feb84edd25210929a
59 changes: 33 additions & 26 deletions sakura_core/parse/CWordParse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,9 @@ uchar_t wc_to_c(wchar_t wc)
*/
BOOL IsURL(
const wchar_t* pszLine, //!< [in] 文字列
int offset, //!< [in] 検査を開始する位置。
int nLineLen, //!< [in] 文字列の長さ
int* pnMatchLen //!< [out] URLの長さ
int* pnMatchLen //!< [out] URLの長さ。offset からの距離。
)
{
struct _url_table_t {
Expand Down Expand Up @@ -397,63 +398,69 @@ BOOL IsURL(
*/
};

const wchar_t *p = pszLine;
const wchar_t * const begin = pszLine + offset;
const wchar_t * const end = pszLine + nLineLen;
const struct _url_table_t *urlp;
int i;

if( wc_to_c(*p)==0 ) return FALSE; /* 2バイト文字 */
if( 0 < url_char[wc_to_c(*p)] ){ /* URL開始文字 */
for(urlp = &url_table[url_char[wc_to_c(*p)]-1]; urlp->name[0] == wc_to_c(*p); urlp++){ /* URLテーブルを探索 */
if( (urlp->length <= nLineLen) && (auto_memcmp(urlp->name, pszLine, urlp->length) == 0) ){ /* URLヘッダは一致した */
p += urlp->length; /* URLヘッダ分をスキップする */
if( wc_to_c(*begin)==0 ) return FALSE; /* 2バイト文字 */
if( 0 < url_char[wc_to_c(*begin)] ){ /* URL開始文字 */
for(urlp = &url_table[url_char[wc_to_c(*begin)]-1]; urlp->name[0] == wc_to_c(*begin); urlp++){ /* URLテーブルを探索 */
if( (urlp->length <= end - begin) && (auto_memcmp(urlp->name, begin, urlp->length) == 0) ){ /* URLヘッダは一致した */
if( urlp->is_mail ){ /* メール専用の解析へ */
if( IsMailAddress(p, nLineLen - urlp->length, pnMatchLen) ){
if( IsMailAddress(begin, urlp->length, end - begin - urlp->length, pnMatchLen) ){
*pnMatchLen = *pnMatchLen + urlp->length;
return TRUE;
}
return FALSE;
}
for(i = urlp->length; i < nLineLen; i++, p++){ /* 通常の解析へ */
if( wc_to_c(*p)==0 || (!(url_char[wc_to_c(*p)])) ) break; /* 終端に達した */
for(i = urlp->length; i < end - begin; i++){ /* 通常の解析へ */
if( wc_to_c(begin[i])==0 || (!(url_char[wc_to_c(begin[i])])) ) break; /* 終端に達した */
}
if( i == urlp->length ) return FALSE; /* URLヘッダだけ */
*pnMatchLen = i;
return TRUE;
}
}
}
return IsMailAddress(pszLine, nLineLen, pnMatchLen);
return IsMailAddress(pszLine, offset, nLineLen, pnMatchLen);
}

/* 現在位置がメールアドレスならば、NULL以外と、その長さを返す
@date 2016.04.27 記号類を許可
*/
BOOL IsMailAddress( const wchar_t* pszBuf, int nBufLen, int* pnAddressLenfth )
BOOL IsMailAddress( const wchar_t* pszBuf, int offset, int nBufLen, int* pnAddressLenfth )
{
struct {
bool operator()(const wchar_t ch)
{
return 0x21 <= ch && ch <= 0x7E && NULL == wcschr(L"\"(),:;<>@[\\]", ch);
}
} IsValidChar;

/*
直前の文字を利用した境界判定
*/
if (0 < offset && IsValidChar(pszBuf[offset-1])) {
return FALSE;
}

pszBuf += offset;
nBufLen -= offset;
offset = 0;

int j;
int nDotCount;
int nBgn;


j = 0;
if( (pszBuf[j] >= L'a' && pszBuf[j] <= L'z')
|| (pszBuf[j] >= L'A' && pszBuf[j] <= L'Z')
|| (pszBuf[j] >= L'0' && pszBuf[j] <= L'9')
|| NULL != wcschr(L"!#$%&'*+-/=?^_`{|}~", pszBuf[j])
){
if(pszBuf[j] != L'.' && IsValidChar(pszBuf[j])){
j++;
}else{
return FALSE;
}
while( j < nBufLen - 2 &&
(
(pszBuf[j] >= L'a' && pszBuf[j] <= L'z')
|| (pszBuf[j] >= L'A' && pszBuf[j] <= L'Z')
|| (pszBuf[j] >= L'0' && pszBuf[j] <= L'9')
|| (pszBuf[j] == L'.')
|| NULL != wcschr(L"!#$%&'*+-/=?^_`{|}~", pszBuf[j])
)
){
while( j < nBufLen - 2 && IsValidChar(pszBuf[j]) ){
j++;
}
if( j == 0 || j >= nBufLen - 2 ){
Expand Down
14 changes: 12 additions & 2 deletions sakura_core/parse/CWordParse.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,18 @@ class CWordParse{
static bool _match_charlist( const WCHAR c, const WCHAR *pszList );
};

BOOL IsURL( const wchar_t*, int, int* );/* 指定アドレスがURLの先頭ならばTRUEとその長さを返す */
BOOL IsMailAddress( const wchar_t*, int, int* ); /* 現在位置がメールアドレスならば、NULL以外と、その長さを返す */
BOOL IsURL( const wchar_t* psz, int offset, int length, int* outLength);/* offset 引数の追加により境界判定が行える高速版 */
inline
BOOL IsURL( const wchar_t* psz, int length, int* outLength) /* 指定アドレスがURLの先頭ならばTRUEとその長さを返す。高速版の追加により obsolete. */
{
return IsURL(psz, 0, length, outLength);
}
BOOL IsMailAddress( const wchar_t* psz, int offset, int length, int* outLength); /* offset 引数の追加により境界判定が行える高速版 */
inline
BOOL IsMailAddress( const wchar_t* psz, int length, int* outLength) /* 現在位置がメールアドレスならば、NULL以外と、その長さを返す。高速版の追加により obsolete. */
{
return IsMailAddress(psz, 0, length, outLength);
}

// ACHAR 版
inline bool CWordParse::_match_charlist( const ACHAR c, const ACHAR *pszList )
Expand Down
2 changes: 1 addition & 1 deletion sakura_core/view/colors/CColor_Url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ bool CColor_Url::BeginColor(const CStringRef& cStr, int nPos)
int nUrlLen;

if( _IsPosKeywordHead(cStr,nPos) /* URLを表示する */
&& IsURL( cStr.GetPtr() + nPos, cStr.GetLength() - nPos, &nUrlLen ) /* 指定アドレスがURLの先頭ならばTRUEとその長さを返す */
&& IsURL( cStr.GetPtr(), nPos, cStr.GetLength(), &nUrlLen ) /* 指定アドレスがURLの先頭ならばTRUEとその長さを返す */
){
this->m_nCOMMENTEND = nPos + nUrlLen;
return true;
Expand Down