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