1*40df464eSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*40df464eSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*40df464eSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*40df464eSAndrew Rist * distributed with this work for additional information 6*40df464eSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*40df464eSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*40df464eSAndrew Rist * "License"); you may not use this file except in compliance 9*40df464eSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*40df464eSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*40df464eSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*40df464eSAndrew Rist * software distributed under the License is distributed on an 15*40df464eSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*40df464eSAndrew Rist * KIND, either express or implied. See the License for the 17*40df464eSAndrew Rist * specific language governing permissions and limitations 18*40df464eSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*40df464eSAndrew Rist *************************************************************/ 21*40df464eSAndrew Rist 22*40df464eSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svl.hxx" 26cdf0e10cSrcweir #include <tools/inetmime.hxx> 27cdf0e10cSrcweir #include <svl/adrparse.hxx> 28cdf0e10cSrcweir 29cdf0e10cSrcweir namespace unnamed_svl_adrparse {} 30cdf0e10cSrcweir using namespace unnamed_svl_adrparse; 31cdf0e10cSrcweir // unnamed namespaces don't work well yet 32cdf0e10cSrcweir 33cdf0e10cSrcweir //============================================================================ 34cdf0e10cSrcweir namespace unnamed_svl_adrparse { 35cdf0e10cSrcweir 36cdf0e10cSrcweir enum ElementType { ELEMENT_START, ELEMENT_DELIM, ELEMENT_ITEM, ELEMENT_END }; 37cdf0e10cSrcweir 38cdf0e10cSrcweir //============================================================================ 39cdf0e10cSrcweir struct ParsedAddrSpec 40cdf0e10cSrcweir { 41cdf0e10cSrcweir sal_Unicode const * m_pBegin; 42cdf0e10cSrcweir sal_Unicode const * m_pEnd; 43cdf0e10cSrcweir ElementType m_eLastElem; 44cdf0e10cSrcweir bool m_bAtFound; 45cdf0e10cSrcweir bool m_bReparse; 46cdf0e10cSrcweir 47cdf0e10cSrcweir ParsedAddrSpec() { reset(); } 48cdf0e10cSrcweir 49cdf0e10cSrcweir bool isPoorlyValid() const { return m_eLastElem >= ELEMENT_ITEM; } 50cdf0e10cSrcweir 51cdf0e10cSrcweir bool isValid() const { return isPoorlyValid() && m_bAtFound; } 52cdf0e10cSrcweir 53cdf0e10cSrcweir inline void reset(); 54cdf0e10cSrcweir 55cdf0e10cSrcweir inline void finish(); 56cdf0e10cSrcweir }; 57cdf0e10cSrcweir 58cdf0e10cSrcweir inline void ParsedAddrSpec::reset() 59cdf0e10cSrcweir { 60cdf0e10cSrcweir m_pBegin = 0; 61cdf0e10cSrcweir m_pEnd = 0; 62cdf0e10cSrcweir m_eLastElem = ELEMENT_START; 63cdf0e10cSrcweir m_bAtFound = false; 64cdf0e10cSrcweir m_bReparse = false; 65cdf0e10cSrcweir } 66cdf0e10cSrcweir 67cdf0e10cSrcweir inline void ParsedAddrSpec::finish() 68cdf0e10cSrcweir { 69cdf0e10cSrcweir if (isPoorlyValid()) 70cdf0e10cSrcweir m_eLastElem = ELEMENT_END; 71cdf0e10cSrcweir else 72cdf0e10cSrcweir reset(); 73cdf0e10cSrcweir } 74cdf0e10cSrcweir 75cdf0e10cSrcweir } 76cdf0e10cSrcweir 77cdf0e10cSrcweir //============================================================================ 78cdf0e10cSrcweir class SvAddressParser_Impl 79cdf0e10cSrcweir { 80cdf0e10cSrcweir enum State { BEFORE_COLON, BEFORE_LESS, AFTER_LESS, AFTER_GREATER }; 81cdf0e10cSrcweir 82cdf0e10cSrcweir enum TokenType { TOKEN_QUOTED = 0x80000000, TOKEN_DOMAIN, TOKEN_COMMENT, 83cdf0e10cSrcweir TOKEN_ATOM }; 84cdf0e10cSrcweir 85cdf0e10cSrcweir sal_Unicode const * m_pInputPos; 86cdf0e10cSrcweir sal_Unicode const * m_pInputEnd; 87cdf0e10cSrcweir sal_uInt32 m_nCurToken; 88cdf0e10cSrcweir sal_Unicode const * m_pCurTokenBegin; 89cdf0e10cSrcweir sal_Unicode const * m_pCurTokenEnd; 90cdf0e10cSrcweir sal_Unicode const * m_pCurTokenContentBegin; 91cdf0e10cSrcweir sal_Unicode const * m_pCurTokenContentEnd; 92cdf0e10cSrcweir bool m_bCurTokenReparse; 93cdf0e10cSrcweir ParsedAddrSpec m_aOuterAddrSpec; 94cdf0e10cSrcweir ParsedAddrSpec m_aInnerAddrSpec; 95cdf0e10cSrcweir ParsedAddrSpec * m_pAddrSpec; 96cdf0e10cSrcweir sal_Unicode const * m_pRealNameBegin; 97cdf0e10cSrcweir sal_Unicode const * m_pRealNameEnd; 98cdf0e10cSrcweir sal_Unicode const * m_pRealNameContentBegin; 99cdf0e10cSrcweir sal_Unicode const * m_pRealNameContentEnd; 100cdf0e10cSrcweir bool m_bRealNameReparse; 101cdf0e10cSrcweir bool m_bRealNameFinished; 102cdf0e10cSrcweir sal_Unicode const * m_pFirstCommentBegin; 103cdf0e10cSrcweir sal_Unicode const * m_pFirstCommentEnd; 104cdf0e10cSrcweir bool m_bFirstCommentReparse; 105cdf0e10cSrcweir State m_eState; 106cdf0e10cSrcweir TokenType m_eType; 107cdf0e10cSrcweir 108cdf0e10cSrcweir inline void resetRealNameAndFirstComment(); 109cdf0e10cSrcweir 110cdf0e10cSrcweir inline void reset(); 111cdf0e10cSrcweir 112cdf0e10cSrcweir inline void addTokenToAddrSpec(ElementType eTokenElem); 113cdf0e10cSrcweir 114cdf0e10cSrcweir inline void addTokenToRealName(); 115cdf0e10cSrcweir 116cdf0e10cSrcweir bool readToken(); 117cdf0e10cSrcweir 118cdf0e10cSrcweir static UniString reparse(sal_Unicode const * pBegin, 119cdf0e10cSrcweir sal_Unicode const * pEnd, bool bAddrSpec); 120cdf0e10cSrcweir 121cdf0e10cSrcweir static UniString reparseComment(sal_Unicode const * pBegin, 122cdf0e10cSrcweir sal_Unicode const * pEnd); 123cdf0e10cSrcweir 124cdf0e10cSrcweir public: 125cdf0e10cSrcweir SvAddressParser_Impl(SvAddressParser * pParser, UniString const & rInput); 126cdf0e10cSrcweir }; 127cdf0e10cSrcweir 128cdf0e10cSrcweir inline void SvAddressParser_Impl::resetRealNameAndFirstComment() 129cdf0e10cSrcweir { 130cdf0e10cSrcweir m_pRealNameBegin = 0; 131cdf0e10cSrcweir m_pRealNameEnd = 0; 132cdf0e10cSrcweir m_pRealNameContentBegin = 0; 133cdf0e10cSrcweir m_pRealNameContentEnd = 0; 134cdf0e10cSrcweir m_bRealNameReparse = false; 135cdf0e10cSrcweir m_bRealNameFinished = false; 136cdf0e10cSrcweir m_pFirstCommentBegin = 0; 137cdf0e10cSrcweir m_pFirstCommentEnd = 0; 138cdf0e10cSrcweir m_bFirstCommentReparse = false; 139cdf0e10cSrcweir } 140cdf0e10cSrcweir 141cdf0e10cSrcweir inline void SvAddressParser_Impl::reset() 142cdf0e10cSrcweir { 143cdf0e10cSrcweir m_aOuterAddrSpec.reset(); 144cdf0e10cSrcweir m_aInnerAddrSpec.reset(); 145cdf0e10cSrcweir m_pAddrSpec = &m_aOuterAddrSpec; 146cdf0e10cSrcweir resetRealNameAndFirstComment(); 147cdf0e10cSrcweir m_eState = BEFORE_COLON; 148cdf0e10cSrcweir m_eType = TOKEN_ATOM; 149cdf0e10cSrcweir } 150cdf0e10cSrcweir 151cdf0e10cSrcweir inline void SvAddressParser_Impl::addTokenToAddrSpec(ElementType eTokenElem) 152cdf0e10cSrcweir { 153cdf0e10cSrcweir if (!m_pAddrSpec->m_pBegin) 154cdf0e10cSrcweir m_pAddrSpec->m_pBegin = m_pCurTokenBegin; 155cdf0e10cSrcweir else if (m_pAddrSpec->m_pEnd < m_pCurTokenBegin) 156cdf0e10cSrcweir m_pAddrSpec->m_bReparse = true; 157cdf0e10cSrcweir m_pAddrSpec->m_pEnd = m_pCurTokenEnd; 158cdf0e10cSrcweir m_pAddrSpec->m_eLastElem = eTokenElem; 159cdf0e10cSrcweir } 160cdf0e10cSrcweir 161cdf0e10cSrcweir inline void SvAddressParser_Impl::addTokenToRealName() 162cdf0e10cSrcweir { 163cdf0e10cSrcweir if (!m_bRealNameFinished && m_eState != AFTER_LESS) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir if (!m_pRealNameBegin) 166cdf0e10cSrcweir m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin; 167cdf0e10cSrcweir else if (m_pRealNameEnd < m_pCurTokenBegin - 1 168cdf0e10cSrcweir || (m_pRealNameEnd == m_pCurTokenBegin - 1 169cdf0e10cSrcweir && *m_pRealNameEnd != ' ')) 170cdf0e10cSrcweir m_bRealNameReparse = true; 171cdf0e10cSrcweir m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd; 172cdf0e10cSrcweir } 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir //============================================================================ 176cdf0e10cSrcweir // 177cdf0e10cSrcweir // SvAddressParser_Impl 178cdf0e10cSrcweir // 179cdf0e10cSrcweir //============================================================================ 180cdf0e10cSrcweir 181cdf0e10cSrcweir bool SvAddressParser_Impl::readToken() 182cdf0e10cSrcweir { 183cdf0e10cSrcweir m_nCurToken = m_eType; 184cdf0e10cSrcweir m_bCurTokenReparse = false; 185cdf0e10cSrcweir switch (m_eType) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir case TOKEN_QUOTED: 188cdf0e10cSrcweir { 189cdf0e10cSrcweir m_pCurTokenBegin = m_pInputPos - 1; 190cdf0e10cSrcweir m_pCurTokenContentBegin = m_pInputPos; 191cdf0e10cSrcweir bool bEscaped = false; 192cdf0e10cSrcweir for (;;) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir if (m_pInputPos >= m_pInputEnd) 195cdf0e10cSrcweir return false; 196cdf0e10cSrcweir sal_Unicode cChar = *m_pInputPos++; 197cdf0e10cSrcweir if (bEscaped) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir m_bCurTokenReparse = true; 200cdf0e10cSrcweir bEscaped = false; 201cdf0e10cSrcweir } 202cdf0e10cSrcweir else if (cChar == '"') 203cdf0e10cSrcweir { 204cdf0e10cSrcweir m_pCurTokenEnd = m_pInputPos; 205cdf0e10cSrcweir m_pCurTokenContentEnd = m_pInputPos - 1; 206cdf0e10cSrcweir return true; 207cdf0e10cSrcweir } 208cdf0e10cSrcweir else if (cChar == '\\') 209cdf0e10cSrcweir bEscaped = true; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir case TOKEN_DOMAIN: 214cdf0e10cSrcweir { 215cdf0e10cSrcweir m_pCurTokenBegin = m_pInputPos - 1; 216cdf0e10cSrcweir m_pCurTokenContentBegin = m_pInputPos; 217cdf0e10cSrcweir bool bEscaped = false; 218cdf0e10cSrcweir for (;;) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir if (m_pInputPos >= m_pInputEnd) 221cdf0e10cSrcweir return false; 222cdf0e10cSrcweir sal_Unicode cChar = *m_pInputPos++; 223cdf0e10cSrcweir if (bEscaped) 224cdf0e10cSrcweir bEscaped = false; 225cdf0e10cSrcweir else if (cChar == ']') 226cdf0e10cSrcweir { 227cdf0e10cSrcweir m_pCurTokenEnd = m_pInputPos; 228cdf0e10cSrcweir return true; 229cdf0e10cSrcweir } 230cdf0e10cSrcweir else if (cChar == '\\') 231cdf0e10cSrcweir bEscaped = true; 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir case TOKEN_COMMENT: 236cdf0e10cSrcweir { 237cdf0e10cSrcweir m_pCurTokenBegin = m_pInputPos - 1; 238cdf0e10cSrcweir m_pCurTokenContentBegin = 0; 239cdf0e10cSrcweir m_pCurTokenContentEnd = 0; 240cdf0e10cSrcweir bool bEscaped = false; 241cdf0e10cSrcweir xub_StrLen nLevel = 0; 242cdf0e10cSrcweir for (;;) 243cdf0e10cSrcweir { 244cdf0e10cSrcweir if (m_pInputPos >= m_pInputEnd) 245cdf0e10cSrcweir return false; 246cdf0e10cSrcweir sal_Unicode cChar = *m_pInputPos++; 247cdf0e10cSrcweir if (bEscaped) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir m_bCurTokenReparse = true; 250cdf0e10cSrcweir m_pCurTokenContentEnd = m_pInputPos; 251cdf0e10cSrcweir bEscaped = false; 252cdf0e10cSrcweir } 253cdf0e10cSrcweir else if (cChar == '(') 254cdf0e10cSrcweir { 255cdf0e10cSrcweir if (!m_pCurTokenContentBegin) 256cdf0e10cSrcweir m_pCurTokenContentBegin = m_pInputPos - 1; 257cdf0e10cSrcweir m_pCurTokenContentEnd = m_pInputPos; 258cdf0e10cSrcweir ++nLevel; 259cdf0e10cSrcweir } 260cdf0e10cSrcweir else if (cChar == ')') 261cdf0e10cSrcweir if (nLevel) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir m_pCurTokenContentEnd = m_pInputPos; 264cdf0e10cSrcweir --nLevel; 265cdf0e10cSrcweir } 266cdf0e10cSrcweir else 267cdf0e10cSrcweir return true; 268cdf0e10cSrcweir else if (cChar == '\\') 269cdf0e10cSrcweir { 270cdf0e10cSrcweir if (!m_pCurTokenContentBegin) 271cdf0e10cSrcweir m_pCurTokenContentBegin = m_pInputPos - 1; 272cdf0e10cSrcweir bEscaped = true; 273cdf0e10cSrcweir } 274cdf0e10cSrcweir else if (cChar > ' ' && cChar != 0x7F) // DEL 275cdf0e10cSrcweir { 276cdf0e10cSrcweir if (!m_pCurTokenContentBegin) 277cdf0e10cSrcweir m_pCurTokenContentBegin = m_pInputPos - 1; 278cdf0e10cSrcweir m_pCurTokenContentEnd = m_pInputPos; 279cdf0e10cSrcweir } 280cdf0e10cSrcweir } 281cdf0e10cSrcweir } 282cdf0e10cSrcweir 283cdf0e10cSrcweir default: 284cdf0e10cSrcweir { 285cdf0e10cSrcweir sal_Unicode cChar; 286cdf0e10cSrcweir for (;;) 287cdf0e10cSrcweir { 288cdf0e10cSrcweir if (m_pInputPos >= m_pInputEnd) 289cdf0e10cSrcweir return false; 290cdf0e10cSrcweir cChar = *m_pInputPos++; 291cdf0e10cSrcweir if (cChar > ' ' && cChar != 0x7F) // DEL 292cdf0e10cSrcweir break; 293cdf0e10cSrcweir } 294cdf0e10cSrcweir m_pCurTokenBegin = m_pInputPos - 1; 295cdf0e10cSrcweir if (cChar == '"' || cChar == '(' || cChar == ')' || cChar == ',' 296cdf0e10cSrcweir || cChar == '.' || cChar == ':' || cChar == ';' 297cdf0e10cSrcweir || cChar == '<' || cChar == '>' || cChar == '@' 298cdf0e10cSrcweir || cChar == '[' || cChar == '\\' || cChar == ']') 299cdf0e10cSrcweir { 300cdf0e10cSrcweir m_nCurToken = cChar; 301cdf0e10cSrcweir m_pCurTokenEnd = m_pInputPos; 302cdf0e10cSrcweir return true; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir else 305cdf0e10cSrcweir for (;;) 306cdf0e10cSrcweir { 307cdf0e10cSrcweir if (m_pInputPos >= m_pInputEnd) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir m_pCurTokenEnd = m_pInputPos; 310cdf0e10cSrcweir return true; 311cdf0e10cSrcweir } 312cdf0e10cSrcweir cChar = *m_pInputPos++; 313cdf0e10cSrcweir if (cChar <= ' ' || cChar == '"' || cChar == '(' 314cdf0e10cSrcweir || cChar == ')' || cChar == ',' || cChar == '.' 315cdf0e10cSrcweir || cChar == ':' || cChar == ';' || cChar == '<' 316cdf0e10cSrcweir || cChar == '>' || cChar == '@' || cChar == '[' 317cdf0e10cSrcweir || cChar == '\\' || cChar == ']' 318cdf0e10cSrcweir || cChar == 0x7F) // DEL 319cdf0e10cSrcweir { 320cdf0e10cSrcweir m_pCurTokenEnd = --m_pInputPos; 321cdf0e10cSrcweir return true; 322cdf0e10cSrcweir } 323cdf0e10cSrcweir } 324cdf0e10cSrcweir } 325cdf0e10cSrcweir } 326cdf0e10cSrcweir } 327cdf0e10cSrcweir 328cdf0e10cSrcweir //============================================================================ 329cdf0e10cSrcweir // static 330cdf0e10cSrcweir UniString SvAddressParser_Impl::reparse(sal_Unicode const * pBegin, 331cdf0e10cSrcweir sal_Unicode const * pEnd, 332cdf0e10cSrcweir bool bAddrSpec) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir UniString aResult; 335cdf0e10cSrcweir TokenType eMode = TOKEN_ATOM; 336cdf0e10cSrcweir bool bEscaped = false; 337cdf0e10cSrcweir bool bEndsWithSpace = false; 338cdf0e10cSrcweir xub_StrLen nLevel = 0; 339cdf0e10cSrcweir while (pBegin < pEnd) 340cdf0e10cSrcweir { 341cdf0e10cSrcweir sal_Unicode cChar = *pBegin++; 342cdf0e10cSrcweir switch (eMode) 343cdf0e10cSrcweir { 344cdf0e10cSrcweir case TOKEN_QUOTED: 345cdf0e10cSrcweir if (bEscaped) 346cdf0e10cSrcweir { 347cdf0e10cSrcweir aResult += cChar; 348cdf0e10cSrcweir bEscaped = false; 349cdf0e10cSrcweir } 350cdf0e10cSrcweir else if (cChar == '"') 351cdf0e10cSrcweir { 352cdf0e10cSrcweir if (bAddrSpec) 353cdf0e10cSrcweir aResult += cChar; 354cdf0e10cSrcweir eMode = TOKEN_ATOM; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir else if (cChar == '\\') 357cdf0e10cSrcweir { 358cdf0e10cSrcweir if (bAddrSpec) 359cdf0e10cSrcweir aResult += cChar; 360cdf0e10cSrcweir bEscaped = true; 361cdf0e10cSrcweir } 362cdf0e10cSrcweir else 363cdf0e10cSrcweir aResult += cChar; 364cdf0e10cSrcweir break; 365cdf0e10cSrcweir 366cdf0e10cSrcweir case TOKEN_DOMAIN: 367cdf0e10cSrcweir if (bEscaped) 368cdf0e10cSrcweir { 369cdf0e10cSrcweir aResult += cChar; 370cdf0e10cSrcweir bEscaped = false; 371cdf0e10cSrcweir } 372cdf0e10cSrcweir else if (cChar == ']') 373cdf0e10cSrcweir { 374cdf0e10cSrcweir aResult += cChar; 375cdf0e10cSrcweir eMode = TOKEN_ATOM; 376cdf0e10cSrcweir } 377cdf0e10cSrcweir else if (cChar == '\\') 378cdf0e10cSrcweir { 379cdf0e10cSrcweir if (bAddrSpec) 380cdf0e10cSrcweir aResult += cChar; 381cdf0e10cSrcweir bEscaped = true; 382cdf0e10cSrcweir } 383cdf0e10cSrcweir else 384cdf0e10cSrcweir aResult += cChar; 385cdf0e10cSrcweir break; 386cdf0e10cSrcweir 387cdf0e10cSrcweir case TOKEN_COMMENT: 388cdf0e10cSrcweir if (bEscaped) 389cdf0e10cSrcweir bEscaped = false; 390cdf0e10cSrcweir else if (cChar == '(') 391cdf0e10cSrcweir ++nLevel; 392cdf0e10cSrcweir else if (cChar == ')') 393cdf0e10cSrcweir if (nLevel) 394cdf0e10cSrcweir --nLevel; 395cdf0e10cSrcweir else 396cdf0e10cSrcweir eMode = TOKEN_ATOM; 397cdf0e10cSrcweir else if (cChar == '\\') 398cdf0e10cSrcweir bEscaped = true; 399cdf0e10cSrcweir break; 400cdf0e10cSrcweir 401cdf0e10cSrcweir case TOKEN_ATOM: 402cdf0e10cSrcweir if (cChar <= ' ' || cChar == 0x7F) // DEL 403cdf0e10cSrcweir { 404cdf0e10cSrcweir if (!bAddrSpec && !bEndsWithSpace) 405cdf0e10cSrcweir { 406cdf0e10cSrcweir aResult += ' '; 407cdf0e10cSrcweir bEndsWithSpace = true; 408cdf0e10cSrcweir } 409cdf0e10cSrcweir } 410cdf0e10cSrcweir else if (cChar == '(') 411cdf0e10cSrcweir { 412cdf0e10cSrcweir if (!bAddrSpec && !bEndsWithSpace) 413cdf0e10cSrcweir { 414cdf0e10cSrcweir aResult += ' '; 415cdf0e10cSrcweir bEndsWithSpace = true; 416cdf0e10cSrcweir } 417cdf0e10cSrcweir eMode = TOKEN_COMMENT; 418cdf0e10cSrcweir } 419cdf0e10cSrcweir else 420cdf0e10cSrcweir { 421cdf0e10cSrcweir bEndsWithSpace = false; 422cdf0e10cSrcweir if (cChar == '"') 423cdf0e10cSrcweir { 424cdf0e10cSrcweir if (bAddrSpec) 425cdf0e10cSrcweir aResult += cChar; 426cdf0e10cSrcweir eMode = TOKEN_QUOTED; 427cdf0e10cSrcweir } 428cdf0e10cSrcweir else if (cChar == '[') 429cdf0e10cSrcweir { 430cdf0e10cSrcweir aResult += cChar; 431cdf0e10cSrcweir eMode = TOKEN_QUOTED; 432cdf0e10cSrcweir } 433cdf0e10cSrcweir else 434cdf0e10cSrcweir aResult += cChar; 435cdf0e10cSrcweir } 436cdf0e10cSrcweir break; 437cdf0e10cSrcweir } 438cdf0e10cSrcweir } 439cdf0e10cSrcweir return aResult; 440cdf0e10cSrcweir } 441cdf0e10cSrcweir 442cdf0e10cSrcweir //============================================================================ 443cdf0e10cSrcweir // static 444cdf0e10cSrcweir UniString SvAddressParser_Impl::reparseComment(sal_Unicode const * pBegin, 445cdf0e10cSrcweir sal_Unicode const * pEnd) 446cdf0e10cSrcweir { 447cdf0e10cSrcweir UniString aResult; 448cdf0e10cSrcweir while (pBegin < pEnd) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir sal_Unicode cChar = *pBegin++; 451cdf0e10cSrcweir if (cChar == '\\') 452cdf0e10cSrcweir cChar = *pBegin++; 453cdf0e10cSrcweir aResult += cChar; 454cdf0e10cSrcweir } 455cdf0e10cSrcweir return aResult; 456cdf0e10cSrcweir } 457cdf0e10cSrcweir 458cdf0e10cSrcweir //============================================================================ 459cdf0e10cSrcweir SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, 460cdf0e10cSrcweir UniString const & rInput) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir m_pInputPos = rInput.GetBuffer(); 463cdf0e10cSrcweir m_pInputEnd = m_pInputPos + rInput.Len(); 464cdf0e10cSrcweir 465cdf0e10cSrcweir reset(); 466cdf0e10cSrcweir bool bDone = false; 467cdf0e10cSrcweir for (;;) 468cdf0e10cSrcweir { 469cdf0e10cSrcweir if (!readToken()) 470cdf0e10cSrcweir { 471cdf0e10cSrcweir m_bRealNameFinished = true; 472cdf0e10cSrcweir if (m_eState == AFTER_LESS) 473cdf0e10cSrcweir m_nCurToken = '>'; 474cdf0e10cSrcweir else 475cdf0e10cSrcweir { 476cdf0e10cSrcweir m_nCurToken = ','; 477cdf0e10cSrcweir bDone = true; 478cdf0e10cSrcweir } 479cdf0e10cSrcweir } 480cdf0e10cSrcweir switch (m_nCurToken) 481cdf0e10cSrcweir { 482cdf0e10cSrcweir case TOKEN_QUOTED: 483cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_END) 484cdf0e10cSrcweir { 485cdf0e10cSrcweir if (m_pAddrSpec->m_bAtFound 486cdf0e10cSrcweir || m_pAddrSpec->m_eLastElem <= ELEMENT_DELIM) 487cdf0e10cSrcweir m_pAddrSpec->reset(); 488cdf0e10cSrcweir addTokenToAddrSpec(ELEMENT_ITEM); 489cdf0e10cSrcweir } 490cdf0e10cSrcweir if (!m_bRealNameFinished && m_eState != AFTER_LESS) 491cdf0e10cSrcweir { 492cdf0e10cSrcweir if (m_bCurTokenReparse) 493cdf0e10cSrcweir { 494cdf0e10cSrcweir if (!m_pRealNameBegin) 495cdf0e10cSrcweir m_pRealNameBegin = m_pCurTokenBegin; 496cdf0e10cSrcweir m_pRealNameEnd = m_pCurTokenEnd; 497cdf0e10cSrcweir m_bRealNameReparse = true; 498cdf0e10cSrcweir } 499cdf0e10cSrcweir else if (m_bRealNameReparse) 500cdf0e10cSrcweir m_pRealNameEnd = m_pCurTokenEnd; 501cdf0e10cSrcweir else if (!m_pRealNameBegin) 502cdf0e10cSrcweir { 503cdf0e10cSrcweir m_pRealNameBegin = m_pCurTokenBegin; 504cdf0e10cSrcweir m_pRealNameContentBegin = m_pCurTokenContentBegin; 505cdf0e10cSrcweir m_pRealNameEnd = m_pRealNameContentEnd 506cdf0e10cSrcweir = m_pCurTokenContentEnd; 507cdf0e10cSrcweir } 508cdf0e10cSrcweir else 509cdf0e10cSrcweir { 510cdf0e10cSrcweir m_pRealNameEnd = m_pCurTokenEnd; 511cdf0e10cSrcweir m_bRealNameReparse = true; 512cdf0e10cSrcweir } 513cdf0e10cSrcweir } 514cdf0e10cSrcweir m_eType = TOKEN_ATOM; 515cdf0e10cSrcweir break; 516cdf0e10cSrcweir 517cdf0e10cSrcweir case TOKEN_DOMAIN: 518cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_END) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir if (m_pAddrSpec->m_bAtFound 521cdf0e10cSrcweir && m_pAddrSpec->m_eLastElem == ELEMENT_DELIM) 522cdf0e10cSrcweir addTokenToAddrSpec(ELEMENT_ITEM); 523cdf0e10cSrcweir else 524cdf0e10cSrcweir m_pAddrSpec->reset(); 525cdf0e10cSrcweir } 526cdf0e10cSrcweir addTokenToRealName(); 527cdf0e10cSrcweir m_eType = TOKEN_ATOM; 528cdf0e10cSrcweir break; 529cdf0e10cSrcweir 530cdf0e10cSrcweir case TOKEN_COMMENT: 531cdf0e10cSrcweir if (!m_bRealNameFinished && m_eState != AFTER_LESS 532cdf0e10cSrcweir && !m_pFirstCommentBegin && m_pCurTokenContentBegin) 533cdf0e10cSrcweir { 534cdf0e10cSrcweir m_pFirstCommentBegin = m_pCurTokenContentBegin; 535cdf0e10cSrcweir m_pFirstCommentEnd = m_pCurTokenContentEnd; 536cdf0e10cSrcweir m_bFirstCommentReparse = m_bCurTokenReparse; 537cdf0e10cSrcweir } 538cdf0e10cSrcweir m_eType = TOKEN_ATOM; 539cdf0e10cSrcweir break; 540cdf0e10cSrcweir 541cdf0e10cSrcweir case TOKEN_ATOM: 542cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_END) 543cdf0e10cSrcweir { 544cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM) 545cdf0e10cSrcweir m_pAddrSpec->reset(); 546cdf0e10cSrcweir addTokenToAddrSpec(ELEMENT_ITEM); 547cdf0e10cSrcweir } 548cdf0e10cSrcweir addTokenToRealName(); 549cdf0e10cSrcweir break; 550cdf0e10cSrcweir 551cdf0e10cSrcweir case '(': 552cdf0e10cSrcweir m_eType = TOKEN_COMMENT; 553cdf0e10cSrcweir break; 554cdf0e10cSrcweir 555cdf0e10cSrcweir case ')': 556cdf0e10cSrcweir case '\\': 557cdf0e10cSrcweir case ']': 558cdf0e10cSrcweir m_pAddrSpec->finish(); 559cdf0e10cSrcweir addTokenToRealName(); 560cdf0e10cSrcweir break; 561cdf0e10cSrcweir 562cdf0e10cSrcweir case '<': 563cdf0e10cSrcweir switch (m_eState) 564cdf0e10cSrcweir { 565cdf0e10cSrcweir case BEFORE_COLON: 566cdf0e10cSrcweir case BEFORE_LESS: 567cdf0e10cSrcweir m_aOuterAddrSpec.finish(); 568cdf0e10cSrcweir if (m_pRealNameBegin) 569cdf0e10cSrcweir m_bRealNameFinished = true; 570cdf0e10cSrcweir m_pAddrSpec = &m_aInnerAddrSpec; 571cdf0e10cSrcweir m_eState = AFTER_LESS; 572cdf0e10cSrcweir break; 573cdf0e10cSrcweir 574cdf0e10cSrcweir case AFTER_LESS: 575cdf0e10cSrcweir m_aInnerAddrSpec.finish(); 576cdf0e10cSrcweir break; 577cdf0e10cSrcweir 578cdf0e10cSrcweir case AFTER_GREATER: 579cdf0e10cSrcweir m_aOuterAddrSpec.finish(); 580cdf0e10cSrcweir addTokenToRealName(); 581cdf0e10cSrcweir break; 582cdf0e10cSrcweir } 583cdf0e10cSrcweir break; 584cdf0e10cSrcweir 585cdf0e10cSrcweir case '>': 586cdf0e10cSrcweir if (m_eState == AFTER_LESS) 587cdf0e10cSrcweir { 588cdf0e10cSrcweir m_aInnerAddrSpec.finish(); 589cdf0e10cSrcweir if (m_aInnerAddrSpec.isValid()) 590cdf0e10cSrcweir m_aOuterAddrSpec.m_eLastElem = ELEMENT_END; 591cdf0e10cSrcweir m_pAddrSpec = &m_aOuterAddrSpec; 592cdf0e10cSrcweir m_eState = AFTER_GREATER; 593cdf0e10cSrcweir } 594cdf0e10cSrcweir else 595cdf0e10cSrcweir { 596cdf0e10cSrcweir m_aOuterAddrSpec.finish(); 597cdf0e10cSrcweir addTokenToRealName(); 598cdf0e10cSrcweir } 599cdf0e10cSrcweir break; 600cdf0e10cSrcweir 601cdf0e10cSrcweir case '@': 602cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_END) 603cdf0e10cSrcweir { 604cdf0e10cSrcweir if (!m_pAddrSpec->m_bAtFound 605cdf0e10cSrcweir && m_pAddrSpec->m_eLastElem == ELEMENT_ITEM) 606cdf0e10cSrcweir { 607cdf0e10cSrcweir addTokenToAddrSpec(ELEMENT_DELIM); 608cdf0e10cSrcweir m_pAddrSpec->m_bAtFound = true; 609cdf0e10cSrcweir } 610cdf0e10cSrcweir else 611cdf0e10cSrcweir m_pAddrSpec->reset(); 612cdf0e10cSrcweir } 613cdf0e10cSrcweir addTokenToRealName(); 614cdf0e10cSrcweir break; 615cdf0e10cSrcweir 616cdf0e10cSrcweir case ',': 617cdf0e10cSrcweir case ';': 618cdf0e10cSrcweir if (m_eState == AFTER_LESS) 619cdf0e10cSrcweir if (m_nCurToken == ',') 620cdf0e10cSrcweir { 621cdf0e10cSrcweir if (m_aInnerAddrSpec.m_eLastElem 622cdf0e10cSrcweir != ELEMENT_END) 623cdf0e10cSrcweir m_aInnerAddrSpec.reset(); 624cdf0e10cSrcweir } 625cdf0e10cSrcweir else 626cdf0e10cSrcweir m_aInnerAddrSpec.finish(); 627cdf0e10cSrcweir else 628cdf0e10cSrcweir { 629cdf0e10cSrcweir m_pAddrSpec = m_aInnerAddrSpec.isValid() 630cdf0e10cSrcweir || (!m_aOuterAddrSpec.isValid() 631cdf0e10cSrcweir && m_aInnerAddrSpec.isPoorlyValid()) ? 632cdf0e10cSrcweir &m_aInnerAddrSpec : 633cdf0e10cSrcweir m_aOuterAddrSpec.isPoorlyValid() ? 634cdf0e10cSrcweir &m_aOuterAddrSpec : 0; 635cdf0e10cSrcweir if (m_pAddrSpec) 636cdf0e10cSrcweir { 637cdf0e10cSrcweir UniString aTheAddrSpec; 638cdf0e10cSrcweir if (m_pAddrSpec->m_bReparse) 639cdf0e10cSrcweir aTheAddrSpec = reparse(m_pAddrSpec->m_pBegin, 640cdf0e10cSrcweir m_pAddrSpec->m_pEnd, true); 641cdf0e10cSrcweir else 642cdf0e10cSrcweir { 643cdf0e10cSrcweir xub_StrLen nLen = 644cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >( 645cdf0e10cSrcweir m_pAddrSpec->m_pEnd 646cdf0e10cSrcweir - m_pAddrSpec->m_pBegin); 647cdf0e10cSrcweir if (nLen == rInput.Len()) 648cdf0e10cSrcweir aTheAddrSpec = rInput; 649cdf0e10cSrcweir else 650cdf0e10cSrcweir aTheAddrSpec 651cdf0e10cSrcweir = rInput.Copy( 652cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >( 653cdf0e10cSrcweir m_pAddrSpec->m_pBegin 654cdf0e10cSrcweir - rInput.GetBuffer()), 655cdf0e10cSrcweir nLen); 656cdf0e10cSrcweir } 657cdf0e10cSrcweir UniString aTheRealName; 658cdf0e10cSrcweir if (!m_pRealNameBegin 659cdf0e10cSrcweir || (m_pAddrSpec == &m_aOuterAddrSpec 660cdf0e10cSrcweir && m_pRealNameBegin 661cdf0e10cSrcweir == m_aOuterAddrSpec.m_pBegin 662cdf0e10cSrcweir && m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd 663cdf0e10cSrcweir && m_pFirstCommentBegin)) 664cdf0e10cSrcweir if (!m_pFirstCommentBegin) 665cdf0e10cSrcweir aTheRealName = aTheAddrSpec; 666cdf0e10cSrcweir else if (m_bFirstCommentReparse) 667cdf0e10cSrcweir aTheRealName 668cdf0e10cSrcweir = reparseComment(m_pFirstCommentBegin, 669cdf0e10cSrcweir m_pFirstCommentEnd); 670cdf0e10cSrcweir else 671cdf0e10cSrcweir aTheRealName 672cdf0e10cSrcweir = rInput.Copy( 673cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >( 674cdf0e10cSrcweir m_pFirstCommentBegin 675cdf0e10cSrcweir - rInput.GetBuffer()), 676cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >( 677cdf0e10cSrcweir m_pFirstCommentEnd 678cdf0e10cSrcweir - m_pFirstCommentBegin)); 679cdf0e10cSrcweir else if (m_bRealNameReparse) 680cdf0e10cSrcweir aTheRealName = reparse(m_pRealNameBegin, 681cdf0e10cSrcweir m_pRealNameEnd, false); 682cdf0e10cSrcweir else 683cdf0e10cSrcweir { 684cdf0e10cSrcweir xub_StrLen nLen = 685cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >( 686cdf0e10cSrcweir m_pRealNameContentEnd 687cdf0e10cSrcweir - m_pRealNameContentBegin); 688cdf0e10cSrcweir if (nLen == rInput.Len()) 689cdf0e10cSrcweir aTheRealName = rInput; 690cdf0e10cSrcweir else 691cdf0e10cSrcweir aTheRealName 692cdf0e10cSrcweir = rInput.Copy( 693cdf0e10cSrcweir sal::static_int_cast< xub_StrLen >( 694cdf0e10cSrcweir m_pRealNameContentBegin 695cdf0e10cSrcweir - rInput.GetBuffer()), 696cdf0e10cSrcweir nLen); 697cdf0e10cSrcweir } 698cdf0e10cSrcweir if (pParser->m_bHasFirst) 699cdf0e10cSrcweir pParser->m_aRest.Insert(new SvAddressEntry_Impl( 700cdf0e10cSrcweir aTheAddrSpec, 701cdf0e10cSrcweir aTheRealName), 702cdf0e10cSrcweir LIST_APPEND); 703cdf0e10cSrcweir else 704cdf0e10cSrcweir { 705cdf0e10cSrcweir pParser->m_bHasFirst = true; 706cdf0e10cSrcweir pParser->m_aFirst.m_aAddrSpec = aTheAddrSpec; 707cdf0e10cSrcweir pParser->m_aFirst.m_aRealName = aTheRealName; 708cdf0e10cSrcweir } 709cdf0e10cSrcweir } 710cdf0e10cSrcweir if (bDone) 711cdf0e10cSrcweir return; 712cdf0e10cSrcweir reset(); 713cdf0e10cSrcweir } 714cdf0e10cSrcweir break; 715cdf0e10cSrcweir 716cdf0e10cSrcweir case ':': 717cdf0e10cSrcweir switch (m_eState) 718cdf0e10cSrcweir { 719cdf0e10cSrcweir case BEFORE_COLON: 720cdf0e10cSrcweir m_aOuterAddrSpec.reset(); 721cdf0e10cSrcweir resetRealNameAndFirstComment(); 722cdf0e10cSrcweir m_eState = BEFORE_LESS; 723cdf0e10cSrcweir break; 724cdf0e10cSrcweir 725cdf0e10cSrcweir case BEFORE_LESS: 726cdf0e10cSrcweir case AFTER_GREATER: 727cdf0e10cSrcweir m_aOuterAddrSpec.finish(); 728cdf0e10cSrcweir addTokenToRealName(); 729cdf0e10cSrcweir break; 730cdf0e10cSrcweir 731cdf0e10cSrcweir case AFTER_LESS: 732cdf0e10cSrcweir m_aInnerAddrSpec.reset(); 733cdf0e10cSrcweir break; 734cdf0e10cSrcweir } 735cdf0e10cSrcweir break; 736cdf0e10cSrcweir 737cdf0e10cSrcweir case '"': 738cdf0e10cSrcweir m_eType = TOKEN_QUOTED; 739cdf0e10cSrcweir break; 740cdf0e10cSrcweir 741cdf0e10cSrcweir case '.': 742cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_END) 743cdf0e10cSrcweir { 744cdf0e10cSrcweir if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM) 745cdf0e10cSrcweir addTokenToAddrSpec(ELEMENT_DELIM); 746cdf0e10cSrcweir else 747cdf0e10cSrcweir m_pAddrSpec->reset(); 748cdf0e10cSrcweir } 749cdf0e10cSrcweir addTokenToRealName(); 750cdf0e10cSrcweir break; 751cdf0e10cSrcweir 752cdf0e10cSrcweir case '[': 753cdf0e10cSrcweir m_eType = TOKEN_DOMAIN; 754cdf0e10cSrcweir break; 755cdf0e10cSrcweir } 756cdf0e10cSrcweir } 757cdf0e10cSrcweir } 758cdf0e10cSrcweir 759cdf0e10cSrcweir //============================================================================ 760cdf0e10cSrcweir // 761cdf0e10cSrcweir // SvAddressParser 762cdf0e10cSrcweir // 763cdf0e10cSrcweir //============================================================================ 764cdf0e10cSrcweir 765cdf0e10cSrcweir SvAddressParser::SvAddressParser(UniString const & rInput): m_bHasFirst(false) 766cdf0e10cSrcweir { 767cdf0e10cSrcweir SvAddressParser_Impl(this, rInput); 768cdf0e10cSrcweir } 769cdf0e10cSrcweir 770cdf0e10cSrcweir //============================================================================ 771cdf0e10cSrcweir SvAddressParser::~SvAddressParser() 772cdf0e10cSrcweir { 773cdf0e10cSrcweir for (sal_uLong i = m_aRest.Count(); i != 0;) 774cdf0e10cSrcweir delete m_aRest.Remove(--i); 775cdf0e10cSrcweir } 776cdf0e10cSrcweir 777cdf0e10cSrcweir //============================================================================ 778cdf0e10cSrcweir // static 779cdf0e10cSrcweir bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, 780cdf0e10cSrcweir String const & rAddrSpec, 781cdf0e10cSrcweir String & rMailbox) 782cdf0e10cSrcweir { 783cdf0e10cSrcweir String aTheAddrSpec; 784cdf0e10cSrcweir sal_Unicode const * p = rAddrSpec.GetBuffer(); 785cdf0e10cSrcweir sal_Unicode const * pEnd = p + rAddrSpec.Len(); 786cdf0e10cSrcweir {for (bool bSegment = false;;) 787cdf0e10cSrcweir { 788cdf0e10cSrcweir p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); 789cdf0e10cSrcweir if (p == pEnd) 790cdf0e10cSrcweir return false; 791cdf0e10cSrcweir if (bSegment) 792cdf0e10cSrcweir { 793cdf0e10cSrcweir sal_Unicode c = *p++; 794cdf0e10cSrcweir if (c == '@') 795cdf0e10cSrcweir break; 796cdf0e10cSrcweir else if (c != '.') 797cdf0e10cSrcweir return false; 798cdf0e10cSrcweir aTheAddrSpec += '.'; 799cdf0e10cSrcweir p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); 800cdf0e10cSrcweir if (p == pEnd) 801cdf0e10cSrcweir return false; 802cdf0e10cSrcweir } 803cdf0e10cSrcweir else 804cdf0e10cSrcweir bSegment = true; 805cdf0e10cSrcweir if (*p == '"') 806cdf0e10cSrcweir { 807cdf0e10cSrcweir aTheAddrSpec += *p++; 808cdf0e10cSrcweir for (;;) 809cdf0e10cSrcweir { 810cdf0e10cSrcweir if (INetMIME::startsWithLineFolding(p, pEnd)) 811cdf0e10cSrcweir p += 2; 812cdf0e10cSrcweir if (p == pEnd) 813cdf0e10cSrcweir return false; 814cdf0e10cSrcweir if (*p == '"') 815cdf0e10cSrcweir break; 816cdf0e10cSrcweir if (*p == '\x0D' || (*p == '\\' && ++p == pEnd) 817cdf0e10cSrcweir || !INetMIME::isUSASCII(*p)) 818cdf0e10cSrcweir return false; 819cdf0e10cSrcweir if (INetMIME::needsQuotedStringEscape(*p)) 820cdf0e10cSrcweir aTheAddrSpec += '\\'; 821cdf0e10cSrcweir aTheAddrSpec += *p++; 822cdf0e10cSrcweir } 823cdf0e10cSrcweir aTheAddrSpec += *p++; 824cdf0e10cSrcweir } 825cdf0e10cSrcweir else if (INetMIME::isAtomChar(*p)) 826cdf0e10cSrcweir while (p != pEnd && INetMIME::isAtomChar(*p)) 827cdf0e10cSrcweir aTheAddrSpec += *p++; 828cdf0e10cSrcweir else 829cdf0e10cSrcweir return false; 830cdf0e10cSrcweir }} 831cdf0e10cSrcweir aTheAddrSpec += '@'; 832cdf0e10cSrcweir {for (bool bSegment = false;;) 833cdf0e10cSrcweir { 834cdf0e10cSrcweir p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); 835cdf0e10cSrcweir if (p == pEnd) 836cdf0e10cSrcweir { 837cdf0e10cSrcweir if (bSegment) 838cdf0e10cSrcweir break; 839cdf0e10cSrcweir else 840cdf0e10cSrcweir return false; 841cdf0e10cSrcweir } 842cdf0e10cSrcweir if (bSegment) 843cdf0e10cSrcweir { 844cdf0e10cSrcweir if (*p++ != '.') 845cdf0e10cSrcweir return false; 846cdf0e10cSrcweir aTheAddrSpec += '.'; 847cdf0e10cSrcweir p = INetMIME::skipLinearWhiteSpaceComment(p, pEnd); 848cdf0e10cSrcweir if (p == pEnd) 849cdf0e10cSrcweir return false; 850cdf0e10cSrcweir } 851cdf0e10cSrcweir else 852cdf0e10cSrcweir bSegment = true; 853cdf0e10cSrcweir if (*p == '[') 854cdf0e10cSrcweir { 855cdf0e10cSrcweir aTheAddrSpec += *p++; 856cdf0e10cSrcweir for (;;) 857cdf0e10cSrcweir { 858cdf0e10cSrcweir if (INetMIME::startsWithLineFolding(p, pEnd)) 859cdf0e10cSrcweir p += 2; 860cdf0e10cSrcweir if (p == pEnd) 861cdf0e10cSrcweir return false; 862cdf0e10cSrcweir if (*p == ']') 863cdf0e10cSrcweir break; 864cdf0e10cSrcweir if (*p == '\x0D' || *p == '[' || (*p == '\\' && ++p == pEnd) 865cdf0e10cSrcweir || !INetMIME::isUSASCII(*p)) 866cdf0e10cSrcweir return false; 867cdf0e10cSrcweir if (*p >= '[' && *p <= ']') 868cdf0e10cSrcweir aTheAddrSpec += '\\'; 869cdf0e10cSrcweir aTheAddrSpec += *p++; 870cdf0e10cSrcweir } 871cdf0e10cSrcweir aTheAddrSpec += *p++; 872cdf0e10cSrcweir } 873cdf0e10cSrcweir else if (INetMIME::isAtomChar(*p)) 874cdf0e10cSrcweir while (p != pEnd && INetMIME::isAtomChar(*p)) 875cdf0e10cSrcweir aTheAddrSpec += *p++; 876cdf0e10cSrcweir else 877cdf0e10cSrcweir return false; 878cdf0e10cSrcweir }} 879cdf0e10cSrcweir 880cdf0e10cSrcweir if (rPhrase.Len() == 0) 881cdf0e10cSrcweir rMailbox = aTheAddrSpec; 882cdf0e10cSrcweir else 883cdf0e10cSrcweir { 884cdf0e10cSrcweir bool bQuotedString = false; 885cdf0e10cSrcweir p = rPhrase.GetBuffer(); 886cdf0e10cSrcweir pEnd = p + rPhrase.Len(); 887cdf0e10cSrcweir for (;p != pEnd; ++p) 888cdf0e10cSrcweir if (!(INetMIME::isAtomChar(*p))) 889cdf0e10cSrcweir { 890cdf0e10cSrcweir bQuotedString = true; 891cdf0e10cSrcweir break; 892cdf0e10cSrcweir } 893cdf0e10cSrcweir String aTheMailbox; 894cdf0e10cSrcweir if (bQuotedString) 895cdf0e10cSrcweir { 896cdf0e10cSrcweir aTheMailbox = '"'; 897cdf0e10cSrcweir for (p = rPhrase.GetBuffer(); p != pEnd; ++p) 898cdf0e10cSrcweir { 899cdf0e10cSrcweir if (INetMIME::needsQuotedStringEscape(*p)) 900cdf0e10cSrcweir aTheMailbox += '\\'; 901cdf0e10cSrcweir aTheMailbox += *p; 902cdf0e10cSrcweir } 903cdf0e10cSrcweir aTheMailbox += '"'; 904cdf0e10cSrcweir } 905cdf0e10cSrcweir else 906cdf0e10cSrcweir aTheMailbox = rPhrase; 907cdf0e10cSrcweir aTheMailbox.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" <")); 908cdf0e10cSrcweir aTheMailbox += aTheAddrSpec; 909cdf0e10cSrcweir aTheMailbox += '>'; 910cdf0e10cSrcweir rMailbox = aTheMailbox; 911cdf0e10cSrcweir } 912cdf0e10cSrcweir return true; 913cdf0e10cSrcweir } 914cdf0e10cSrcweir 915