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
ParsedAddrSpecunnamed_svl_adrparse::ParsedAddrSpec47cdf0e10cSrcweir ParsedAddrSpec() { reset(); }
48cdf0e10cSrcweir
isPoorlyValidunnamed_svl_adrparse::ParsedAddrSpec49cdf0e10cSrcweir bool isPoorlyValid() const { return m_eLastElem >= ELEMENT_ITEM; }
50cdf0e10cSrcweir
isValidunnamed_svl_adrparse::ParsedAddrSpec51cdf0e10cSrcweir bool isValid() const { return isPoorlyValid() && m_bAtFound; }
52cdf0e10cSrcweir
53cdf0e10cSrcweir inline void reset();
54cdf0e10cSrcweir
55cdf0e10cSrcweir inline void finish();
56cdf0e10cSrcweir };
57cdf0e10cSrcweir
reset()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
finish()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
resetRealNameAndFirstComment()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
reset()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
addTokenToAddrSpec(ElementType eTokenElem)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
addTokenToRealName()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
readToken()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
reparse(sal_Unicode const * pBegin,sal_Unicode const * pEnd,bool bAddrSpec)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
reparseComment(sal_Unicode const * pBegin,sal_Unicode const * pEnd)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 //============================================================================
SvAddressParser_Impl(SvAddressParser * pParser,UniString const & rInput)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
SvAddressParser(UniString const & rInput)765cdf0e10cSrcweir SvAddressParser::SvAddressParser(UniString const & rInput): m_bHasFirst(false)
766cdf0e10cSrcweir {
767cdf0e10cSrcweir SvAddressParser_Impl(this, rInput);
768cdf0e10cSrcweir }
769cdf0e10cSrcweir
770cdf0e10cSrcweir //============================================================================
~SvAddressParser()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
createRFC822Mailbox(String const & rPhrase,String const & rAddrSpec,String & rMailbox)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