Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <tools/inetmime.hxx>
21 : : #include <rtl/ustrbuf.hxx>
22 : : #include <svl/adrparse.hxx>
23 : :
24 : : namespace
25 : : {
26 : :
27 : : enum ElementType { ELEMENT_START, ELEMENT_DELIM, ELEMENT_ITEM, ELEMENT_END };
28 : :
29 : : //============================================================================
30 : : struct ParsedAddrSpec
31 : : {
32 : : sal_Unicode const * m_pBegin;
33 : : sal_Unicode const * m_pEnd;
34 : : ElementType m_eLastElem;
35 : : bool m_bAtFound;
36 : : bool m_bReparse;
37 : :
38 : 0 : ParsedAddrSpec() { reset(); }
39 : :
40 : 0 : bool isPoorlyValid() const { return m_eLastElem >= ELEMENT_ITEM; }
41 : :
42 [ # # ][ # # ]: 0 : bool isValid() const { return isPoorlyValid() && m_bAtFound; }
43 : :
44 : : inline void reset();
45 : :
46 : : inline void finish();
47 : : };
48 : :
49 : 0 : inline void ParsedAddrSpec::reset()
50 : : {
51 : 0 : m_pBegin = 0;
52 : 0 : m_pEnd = 0;
53 : 0 : m_eLastElem = ELEMENT_START;
54 : 0 : m_bAtFound = false;
55 : 0 : m_bReparse = false;
56 : 0 : }
57 : :
58 : 0 : inline void ParsedAddrSpec::finish()
59 : : {
60 [ # # ]: 0 : if (isPoorlyValid())
61 : 0 : m_eLastElem = ELEMENT_END;
62 : : else
63 : 0 : reset();
64 : 0 : }
65 : :
66 : : }
67 : :
68 : : //============================================================================
69 : : class SvAddressParser_Impl
70 : : {
71 : : enum State { BEFORE_COLON, BEFORE_LESS, AFTER_LESS, AFTER_GREATER };
72 : :
73 : : enum TokenType { TOKEN_QUOTED = 0x80000000, TOKEN_DOMAIN, TOKEN_COMMENT,
74 : : TOKEN_ATOM };
75 : :
76 : : sal_Unicode const * m_pInputPos;
77 : : sal_Unicode const * m_pInputEnd;
78 : : sal_uInt32 m_nCurToken;
79 : : sal_Unicode const * m_pCurTokenBegin;
80 : : sal_Unicode const * m_pCurTokenEnd;
81 : : sal_Unicode const * m_pCurTokenContentBegin;
82 : : sal_Unicode const * m_pCurTokenContentEnd;
83 : : bool m_bCurTokenReparse;
84 : : ParsedAddrSpec m_aOuterAddrSpec;
85 : : ParsedAddrSpec m_aInnerAddrSpec;
86 : : ParsedAddrSpec * m_pAddrSpec;
87 : : sal_Unicode const * m_pRealNameBegin;
88 : : sal_Unicode const * m_pRealNameEnd;
89 : : sal_Unicode const * m_pRealNameContentBegin;
90 : : sal_Unicode const * m_pRealNameContentEnd;
91 : : bool m_bRealNameReparse;
92 : : bool m_bRealNameFinished;
93 : : sal_Unicode const * m_pFirstCommentBegin;
94 : : sal_Unicode const * m_pFirstCommentEnd;
95 : : bool m_bFirstCommentReparse;
96 : : State m_eState;
97 : : TokenType m_eType;
98 : :
99 : : inline void resetRealNameAndFirstComment();
100 : :
101 : : inline void reset();
102 : :
103 : : inline void addTokenToAddrSpec(ElementType eTokenElem);
104 : :
105 : : inline void addTokenToRealName();
106 : :
107 : : bool readToken();
108 : :
109 : : static rtl::OUString reparse(sal_Unicode const * pBegin,
110 : : sal_Unicode const * pEnd, bool bAddrSpec);
111 : :
112 : : static rtl::OUString reparseComment(sal_Unicode const * pBegin,
113 : : sal_Unicode const * pEnd);
114 : :
115 : : public:
116 : : SvAddressParser_Impl(SvAddressParser * pParser, const rtl::OUString& rIn);
117 : : };
118 : :
119 : 0 : inline void SvAddressParser_Impl::resetRealNameAndFirstComment()
120 : : {
121 : 0 : m_pRealNameBegin = 0;
122 : 0 : m_pRealNameEnd = 0;
123 : 0 : m_pRealNameContentBegin = 0;
124 : 0 : m_pRealNameContentEnd = 0;
125 : 0 : m_bRealNameReparse = false;
126 : 0 : m_bRealNameFinished = false;
127 : 0 : m_pFirstCommentBegin = 0;
128 : 0 : m_pFirstCommentEnd = 0;
129 : 0 : m_bFirstCommentReparse = false;
130 : 0 : }
131 : :
132 : 0 : inline void SvAddressParser_Impl::reset()
133 : : {
134 : 0 : m_aOuterAddrSpec.reset();
135 : 0 : m_aInnerAddrSpec.reset();
136 : 0 : m_pAddrSpec = &m_aOuterAddrSpec;
137 : 0 : resetRealNameAndFirstComment();
138 : 0 : m_eState = BEFORE_COLON;
139 : 0 : m_eType = TOKEN_ATOM;
140 : 0 : }
141 : :
142 : 0 : inline void SvAddressParser_Impl::addTokenToAddrSpec(ElementType eTokenElem)
143 : : {
144 [ # # ]: 0 : if (!m_pAddrSpec->m_pBegin)
145 : 0 : m_pAddrSpec->m_pBegin = m_pCurTokenBegin;
146 [ # # ]: 0 : else if (m_pAddrSpec->m_pEnd < m_pCurTokenBegin)
147 : 0 : m_pAddrSpec->m_bReparse = true;
148 : 0 : m_pAddrSpec->m_pEnd = m_pCurTokenEnd;
149 : 0 : m_pAddrSpec->m_eLastElem = eTokenElem;
150 : 0 : }
151 : :
152 : 0 : inline void SvAddressParser_Impl::addTokenToRealName()
153 : : {
154 [ # # ][ # # ]: 0 : if (!m_bRealNameFinished && m_eState != AFTER_LESS)
155 : : {
156 [ # # ]: 0 : if (!m_pRealNameBegin)
157 : 0 : m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin;
158 [ # # ][ # # ]: 0 : else if (m_pRealNameEnd < m_pCurTokenBegin - 1
[ # # ]
159 : 0 : || (m_pRealNameEnd == m_pCurTokenBegin - 1
160 : : && *m_pRealNameEnd != ' '))
161 : 0 : m_bRealNameReparse = true;
162 : 0 : m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd;
163 : : }
164 : 0 : }
165 : :
166 : : //============================================================================
167 : : //
168 : : // SvAddressParser_Impl
169 : : //
170 : : //============================================================================
171 : :
172 : 0 : bool SvAddressParser_Impl::readToken()
173 : : {
174 : 0 : m_nCurToken = m_eType;
175 : 0 : m_bCurTokenReparse = false;
176 [ # # # # ]: 0 : switch (m_eType)
177 : : {
178 : : case TOKEN_QUOTED:
179 : : {
180 : 0 : m_pCurTokenBegin = m_pInputPos - 1;
181 : 0 : m_pCurTokenContentBegin = m_pInputPos;
182 : 0 : bool bEscaped = false;
183 : 0 : for (;;)
184 : : {
185 [ # # ]: 0 : if (m_pInputPos >= m_pInputEnd)
186 : 0 : return false;
187 : 0 : sal_Unicode cChar = *m_pInputPos++;
188 [ # # ]: 0 : if (bEscaped)
189 : : {
190 : 0 : m_bCurTokenReparse = true;
191 : 0 : bEscaped = false;
192 : : }
193 [ # # ]: 0 : else if (cChar == '"')
194 : : {
195 : 0 : m_pCurTokenEnd = m_pInputPos;
196 : 0 : m_pCurTokenContentEnd = m_pInputPos - 1;
197 : 0 : return true;
198 : : }
199 [ # # ]: 0 : else if (cChar == '\\')
200 : 0 : bEscaped = true;
201 : : }
202 : : }
203 : :
204 : : case TOKEN_DOMAIN:
205 : : {
206 : 0 : m_pCurTokenBegin = m_pInputPos - 1;
207 : 0 : m_pCurTokenContentBegin = m_pInputPos;
208 : 0 : bool bEscaped = false;
209 : 0 : for (;;)
210 : : {
211 [ # # ]: 0 : if (m_pInputPos >= m_pInputEnd)
212 : 0 : return false;
213 : 0 : sal_Unicode cChar = *m_pInputPos++;
214 [ # # ]: 0 : if (bEscaped)
215 : 0 : bEscaped = false;
216 [ # # ]: 0 : else if (cChar == ']')
217 : : {
218 : 0 : m_pCurTokenEnd = m_pInputPos;
219 : 0 : return true;
220 : : }
221 [ # # ]: 0 : else if (cChar == '\\')
222 : 0 : bEscaped = true;
223 : : }
224 : : }
225 : :
226 : : case TOKEN_COMMENT:
227 : : {
228 : 0 : m_pCurTokenBegin = m_pInputPos - 1;
229 : 0 : m_pCurTokenContentBegin = 0;
230 : 0 : m_pCurTokenContentEnd = 0;
231 : 0 : bool bEscaped = false;
232 : 0 : xub_StrLen nLevel = 0;
233 : 0 : for (;;)
234 : : {
235 [ # # ]: 0 : if (m_pInputPos >= m_pInputEnd)
236 : 0 : return false;
237 : 0 : sal_Unicode cChar = *m_pInputPos++;
238 [ # # ]: 0 : if (bEscaped)
239 : : {
240 : 0 : m_bCurTokenReparse = true;
241 : 0 : m_pCurTokenContentEnd = m_pInputPos;
242 : 0 : bEscaped = false;
243 : : }
244 [ # # ]: 0 : else if (cChar == '(')
245 : : {
246 [ # # ]: 0 : if (!m_pCurTokenContentBegin)
247 : 0 : m_pCurTokenContentBegin = m_pInputPos - 1;
248 : 0 : m_pCurTokenContentEnd = m_pInputPos;
249 : 0 : ++nLevel;
250 : : }
251 [ # # ]: 0 : else if (cChar == ')')
252 [ # # ]: 0 : if (nLevel)
253 : : {
254 : 0 : m_pCurTokenContentEnd = m_pInputPos;
255 : 0 : --nLevel;
256 : : }
257 : : else
258 : 0 : return true;
259 [ # # ]: 0 : else if (cChar == '\\')
260 : : {
261 [ # # ]: 0 : if (!m_pCurTokenContentBegin)
262 : 0 : m_pCurTokenContentBegin = m_pInputPos - 1;
263 : 0 : bEscaped = true;
264 : : }
265 [ # # ][ # # ]: 0 : else if (cChar > ' ' && cChar != 0x7F) // DEL
266 : : {
267 [ # # ]: 0 : if (!m_pCurTokenContentBegin)
268 : 0 : m_pCurTokenContentBegin = m_pInputPos - 1;
269 : 0 : m_pCurTokenContentEnd = m_pInputPos;
270 : : }
271 : : }
272 : : }
273 : :
274 : : default:
275 : : {
276 : : sal_Unicode cChar;
277 : 0 : for (;;)
278 : : {
279 [ # # ]: 0 : if (m_pInputPos >= m_pInputEnd)
280 : 0 : return false;
281 : 0 : cChar = *m_pInputPos++;
282 [ # # ][ # # ]: 0 : if (cChar > ' ' && cChar != 0x7F) // DEL
283 : 0 : break;
284 : : }
285 : 0 : m_pCurTokenBegin = m_pInputPos - 1;
286 [ # # ][ # # ]: 0 : if (cChar == '"' || cChar == '(' || cChar == ')' || cChar == ','
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
287 : : || cChar == '.' || cChar == ':' || cChar == ';'
288 : : || cChar == '<' || cChar == '>' || cChar == '@'
289 : : || cChar == '[' || cChar == '\\' || cChar == ']')
290 : : {
291 : 0 : m_nCurToken = cChar;
292 : 0 : m_pCurTokenEnd = m_pInputPos;
293 : 0 : return true;
294 : : }
295 : : else
296 : 0 : for (;;)
297 : : {
298 [ # # ]: 0 : if (m_pInputPos >= m_pInputEnd)
299 : : {
300 : 0 : m_pCurTokenEnd = m_pInputPos;
301 : 0 : return true;
302 : : }
303 : 0 : cChar = *m_pInputPos++;
304 [ # # ][ # # ]: 0 : if (cChar <= ' ' || cChar == '"' || cChar == '('
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
305 : : || cChar == ')' || cChar == ',' || cChar == '.'
306 : : || cChar == ':' || cChar == ';' || cChar == '<'
307 : : || cChar == '>' || cChar == '@' || cChar == '['
308 : : || cChar == '\\' || cChar == ']'
309 : : || cChar == 0x7F) // DEL
310 : : {
311 : 0 : m_pCurTokenEnd = --m_pInputPos;
312 : 0 : return true;
313 : : }
314 : : }
315 : : }
316 : : }
317 : : }
318 : :
319 : : //============================================================================
320 : : // static
321 : 0 : rtl::OUString SvAddressParser_Impl::reparse(sal_Unicode const * pBegin,
322 : : sal_Unicode const * pEnd, bool bAddrSpec)
323 : : {
324 : 0 : rtl::OUStringBuffer aResult;
325 : 0 : TokenType eMode = TOKEN_ATOM;
326 : 0 : bool bEscaped = false;
327 : 0 : bool bEndsWithSpace = false;
328 : 0 : xub_StrLen nLevel = 0;
329 [ # # ]: 0 : while (pBegin < pEnd)
330 : : {
331 : 0 : sal_Unicode cChar = *pBegin++;
332 [ # # # # : 0 : switch (eMode)
# ]
333 : : {
334 : : case TOKEN_QUOTED:
335 [ # # ]: 0 : if (bEscaped)
336 : : {
337 [ # # ]: 0 : aResult.append(cChar);
338 : 0 : bEscaped = false;
339 : : }
340 [ # # ]: 0 : else if (cChar == '"')
341 : : {
342 [ # # ]: 0 : if (bAddrSpec)
343 [ # # ]: 0 : aResult.append(cChar);
344 : 0 : eMode = TOKEN_ATOM;
345 : : }
346 [ # # ]: 0 : else if (cChar == '\\')
347 : : {
348 [ # # ]: 0 : if (bAddrSpec)
349 [ # # ]: 0 : aResult.append(cChar);
350 : 0 : bEscaped = true;
351 : : }
352 : : else
353 [ # # ]: 0 : aResult.append(cChar);
354 : 0 : break;
355 : :
356 : : case TOKEN_DOMAIN:
357 [ # # ]: 0 : if (bEscaped)
358 : : {
359 [ # # ]: 0 : aResult.append(cChar);
360 : 0 : bEscaped = false;
361 : : }
362 [ # # ]: 0 : else if (cChar == ']')
363 : : {
364 [ # # ]: 0 : aResult.append(cChar);
365 : 0 : eMode = TOKEN_ATOM;
366 : : }
367 [ # # ]: 0 : else if (cChar == '\\')
368 : : {
369 [ # # ]: 0 : if (bAddrSpec)
370 [ # # ]: 0 : aResult.append(cChar);
371 : 0 : bEscaped = true;
372 : : }
373 : : else
374 [ # # ]: 0 : aResult.append(cChar);
375 : 0 : break;
376 : :
377 : : case TOKEN_COMMENT:
378 [ # # ]: 0 : if (bEscaped)
379 : 0 : bEscaped = false;
380 [ # # ]: 0 : else if (cChar == '(')
381 : 0 : ++nLevel;
382 [ # # ]: 0 : else if (cChar == ')')
383 [ # # ]: 0 : if (nLevel)
384 : 0 : --nLevel;
385 : : else
386 : 0 : eMode = TOKEN_ATOM;
387 [ # # ]: 0 : else if (cChar == '\\')
388 : 0 : bEscaped = true;
389 : 0 : break;
390 : :
391 : : case TOKEN_ATOM:
392 [ # # ][ # # ]: 0 : if (cChar <= ' ' || cChar == 0x7F) // DEL
393 : : {
394 [ # # ][ # # ]: 0 : if (!bAddrSpec && !bEndsWithSpace)
395 : : {
396 [ # # ]: 0 : aResult.append(' ');
397 : 0 : bEndsWithSpace = true;
398 : : }
399 : : }
400 [ # # ]: 0 : else if (cChar == '(')
401 : : {
402 [ # # ][ # # ]: 0 : if (!bAddrSpec && !bEndsWithSpace)
403 : : {
404 [ # # ]: 0 : aResult.append(' ');
405 : 0 : bEndsWithSpace = true;
406 : : }
407 : 0 : eMode = TOKEN_COMMENT;
408 : : }
409 : : else
410 : : {
411 : 0 : bEndsWithSpace = false;
412 [ # # ]: 0 : if (cChar == '"')
413 : : {
414 [ # # ]: 0 : if (bAddrSpec)
415 [ # # ]: 0 : aResult.append(cChar);
416 : 0 : eMode = TOKEN_QUOTED;
417 : : }
418 [ # # ]: 0 : else if (cChar == '[')
419 : : {
420 [ # # ]: 0 : aResult.append(cChar);
421 : 0 : eMode = TOKEN_QUOTED;
422 : : }
423 : : else
424 [ # # ]: 0 : aResult.append(cChar);
425 : : }
426 : 0 : break;
427 : : }
428 : : }
429 [ # # ]: 0 : return aResult.makeStringAndClear();
430 : : }
431 : :
432 : : //============================================================================
433 : : // static
434 : 0 : rtl::OUString SvAddressParser_Impl::reparseComment(sal_Unicode const * pBegin,
435 : : sal_Unicode const * pEnd)
436 : : {
437 : 0 : rtl::OUStringBuffer aResult;
438 [ # # ]: 0 : while (pBegin < pEnd)
439 : : {
440 : 0 : sal_Unicode cChar = *pBegin++;
441 [ # # ]: 0 : if (cChar == '\\')
442 : 0 : cChar = *pBegin++;
443 [ # # ]: 0 : aResult.append(cChar);
444 : : }
445 [ # # ]: 0 : return aResult.makeStringAndClear();
446 : : }
447 : :
448 : : //============================================================================
449 : 0 : SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser,
450 : 0 : const rtl::OUString& rInput)
451 : : {
452 : 0 : m_pInputPos = rInput.getStr();
453 : 0 : m_pInputEnd = m_pInputPos + rInput.getLength();
454 : :
455 : 0 : reset();
456 : 0 : bool bDone = false;
457 : 0 : for (;;)
458 : : {
459 [ # # ]: 0 : if (!readToken())
460 : : {
461 : 0 : m_bRealNameFinished = true;
462 [ # # ]: 0 : if (m_eState == AFTER_LESS)
463 : 0 : m_nCurToken = '>';
464 : : else
465 : : {
466 : 0 : m_nCurToken = ',';
467 : 0 : bDone = true;
468 : : }
469 : : }
470 [ # # # # : 0 : switch (m_nCurToken)
# # # # #
# # # # #
# ]
471 : : {
472 : : case TOKEN_QUOTED:
473 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
474 : : {
475 [ # # ][ # # ]: 0 : if (m_pAddrSpec->m_bAtFound
476 : : || m_pAddrSpec->m_eLastElem <= ELEMENT_DELIM)
477 : 0 : m_pAddrSpec->reset();
478 : 0 : addTokenToAddrSpec(ELEMENT_ITEM);
479 : : }
480 [ # # ][ # # ]: 0 : if (!m_bRealNameFinished && m_eState != AFTER_LESS)
481 : : {
482 [ # # ]: 0 : if (m_bCurTokenReparse)
483 : : {
484 [ # # ]: 0 : if (!m_pRealNameBegin)
485 : 0 : m_pRealNameBegin = m_pCurTokenBegin;
486 : 0 : m_pRealNameEnd = m_pCurTokenEnd;
487 : 0 : m_bRealNameReparse = true;
488 : : }
489 [ # # ]: 0 : else if (m_bRealNameReparse)
490 : 0 : m_pRealNameEnd = m_pCurTokenEnd;
491 [ # # ]: 0 : else if (!m_pRealNameBegin)
492 : : {
493 : 0 : m_pRealNameBegin = m_pCurTokenBegin;
494 : 0 : m_pRealNameContentBegin = m_pCurTokenContentBegin;
495 : : m_pRealNameEnd = m_pRealNameContentEnd
496 : 0 : = m_pCurTokenContentEnd;
497 : : }
498 : : else
499 : : {
500 : 0 : m_pRealNameEnd = m_pCurTokenEnd;
501 : 0 : m_bRealNameReparse = true;
502 : : }
503 : : }
504 : 0 : m_eType = TOKEN_ATOM;
505 : 0 : break;
506 : :
507 : : case TOKEN_DOMAIN:
508 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
509 : : {
510 [ # # ][ # # ]: 0 : if (m_pAddrSpec->m_bAtFound
511 : : && m_pAddrSpec->m_eLastElem == ELEMENT_DELIM)
512 : 0 : addTokenToAddrSpec(ELEMENT_ITEM);
513 : : else
514 : 0 : m_pAddrSpec->reset();
515 : : }
516 : 0 : addTokenToRealName();
517 : 0 : m_eType = TOKEN_ATOM;
518 : 0 : break;
519 : :
520 : : case TOKEN_COMMENT:
521 [ # # ][ # # ]: 0 : if (!m_bRealNameFinished && m_eState != AFTER_LESS
[ # # ][ # # ]
522 : 0 : && !m_pFirstCommentBegin && m_pCurTokenContentBegin)
523 : : {
524 : 0 : m_pFirstCommentBegin = m_pCurTokenContentBegin;
525 : 0 : m_pFirstCommentEnd = m_pCurTokenContentEnd;
526 : 0 : m_bFirstCommentReparse = m_bCurTokenReparse;
527 : : }
528 : 0 : m_eType = TOKEN_ATOM;
529 : 0 : break;
530 : :
531 : : case TOKEN_ATOM:
532 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
533 : : {
534 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM)
535 : 0 : m_pAddrSpec->reset();
536 : 0 : addTokenToAddrSpec(ELEMENT_ITEM);
537 : : }
538 : 0 : addTokenToRealName();
539 : 0 : break;
540 : :
541 : : case '(':
542 : 0 : m_eType = TOKEN_COMMENT;
543 : 0 : break;
544 : :
545 : : case ')':
546 : : case '\\':
547 : : case ']':
548 : 0 : m_pAddrSpec->finish();
549 : 0 : addTokenToRealName();
550 : 0 : break;
551 : :
552 : : case '<':
553 [ # # # # ]: 0 : switch (m_eState)
554 : : {
555 : : case BEFORE_COLON:
556 : : case BEFORE_LESS:
557 : 0 : m_aOuterAddrSpec.finish();
558 [ # # ]: 0 : if (m_pRealNameBegin)
559 : 0 : m_bRealNameFinished = true;
560 : 0 : m_pAddrSpec = &m_aInnerAddrSpec;
561 : 0 : m_eState = AFTER_LESS;
562 : 0 : break;
563 : :
564 : : case AFTER_LESS:
565 : 0 : m_aInnerAddrSpec.finish();
566 : 0 : break;
567 : :
568 : : case AFTER_GREATER:
569 : 0 : m_aOuterAddrSpec.finish();
570 : 0 : addTokenToRealName();
571 : 0 : break;
572 : : }
573 : 0 : break;
574 : :
575 : : case '>':
576 [ # # ]: 0 : if (m_eState == AFTER_LESS)
577 : : {
578 : 0 : m_aInnerAddrSpec.finish();
579 [ # # ]: 0 : if (m_aInnerAddrSpec.isValid())
580 : 0 : m_aOuterAddrSpec.m_eLastElem = ELEMENT_END;
581 : 0 : m_pAddrSpec = &m_aOuterAddrSpec;
582 : 0 : m_eState = AFTER_GREATER;
583 : : }
584 : : else
585 : : {
586 : 0 : m_aOuterAddrSpec.finish();
587 : 0 : addTokenToRealName();
588 : : }
589 : 0 : break;
590 : :
591 : : case '@':
592 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
593 : : {
594 [ # # ][ # # ]: 0 : if (!m_pAddrSpec->m_bAtFound
595 : : && m_pAddrSpec->m_eLastElem == ELEMENT_ITEM)
596 : : {
597 : 0 : addTokenToAddrSpec(ELEMENT_DELIM);
598 : 0 : m_pAddrSpec->m_bAtFound = true;
599 : : }
600 : : else
601 : 0 : m_pAddrSpec->reset();
602 : : }
603 : 0 : addTokenToRealName();
604 : 0 : break;
605 : :
606 : : case ',':
607 : : case ';':
608 [ # # ]: 0 : if (m_eState == AFTER_LESS)
609 [ # # ]: 0 : if (m_nCurToken == ',')
610 : : {
611 [ # # ]: 0 : if (m_aInnerAddrSpec.m_eLastElem
612 : : != ELEMENT_END)
613 : 0 : m_aInnerAddrSpec.reset();
614 : : }
615 : : else
616 : 0 : m_aInnerAddrSpec.finish();
617 : : else
618 : : {
619 : 0 : m_pAddrSpec = m_aInnerAddrSpec.isValid()
620 : 0 : || (!m_aOuterAddrSpec.isValid()
621 : 0 : && m_aInnerAddrSpec.isPoorlyValid()) ?
622 : : &m_aInnerAddrSpec :
623 : 0 : m_aOuterAddrSpec.isPoorlyValid() ?
624 [ # # ][ # # : 0 : &m_aOuterAddrSpec : 0;
# # # # ]
625 [ # # ]: 0 : if (m_pAddrSpec)
626 : : {
627 : 0 : rtl::OUString aTheAddrSpec;
628 [ # # ]: 0 : if (m_pAddrSpec->m_bReparse)
629 : : aTheAddrSpec = reparse(m_pAddrSpec->m_pBegin,
630 [ # # ]: 0 : m_pAddrSpec->m_pEnd, true);
631 : : else
632 : : {
633 : : sal_Int32 nLen = (
634 : : m_pAddrSpec->m_pEnd
635 : 0 : - m_pAddrSpec->m_pBegin);
636 [ # # ]: 0 : if (nLen == rInput.getLength())
637 : 0 : aTheAddrSpec = rInput;
638 : : else
639 : : aTheAddrSpec
640 : : = rInput.copy(
641 : : (m_pAddrSpec->m_pBegin
642 : 0 : - rInput.getStr()),
643 : 0 : nLen);
644 : : }
645 : 0 : rtl::OUString aTheRealName;
646 [ # # ][ # # ]: 0 : if (!m_pRealNameBegin
[ # # ][ # # ]
[ # # ]
647 : : || (m_pAddrSpec == &m_aOuterAddrSpec
648 : : && m_pRealNameBegin
649 : : == m_aOuterAddrSpec.m_pBegin
650 : : && m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd
651 : : && m_pFirstCommentBegin))
652 [ # # ]: 0 : if (!m_pFirstCommentBegin)
653 : 0 : aTheRealName = aTheAddrSpec;
654 [ # # ]: 0 : else if (m_bFirstCommentReparse)
655 : : aTheRealName
656 : : = reparseComment(m_pFirstCommentBegin,
657 [ # # ]: 0 : m_pFirstCommentEnd);
658 : : else
659 : : aTheRealName
660 : : = rInput.copy(
661 : : (m_pFirstCommentBegin
662 : 0 : - rInput.getStr()),
663 : : (m_pFirstCommentEnd
664 : 0 : - m_pFirstCommentBegin));
665 [ # # ]: 0 : else if (m_bRealNameReparse)
666 : : aTheRealName = reparse(m_pRealNameBegin,
667 [ # # ]: 0 : m_pRealNameEnd, false);
668 : : else
669 : : {
670 : : sal_Int32 nLen =
671 : : (m_pRealNameContentEnd
672 : 0 : - m_pRealNameContentBegin);
673 [ # # ]: 0 : if (nLen == rInput.getLength())
674 : 0 : aTheRealName = rInput;
675 : : else
676 : : aTheRealName
677 : : = rInput.copy(
678 : : (m_pRealNameContentBegin
679 : 0 : - rInput.getStr()), nLen);
680 : : }
681 [ # # ]: 0 : if (pParser->m_bHasFirst)
682 : : pParser->m_aRest.push_back(new SvAddressEntry_Impl(
683 : : aTheAddrSpec,
684 : 0 : aTheRealName)
685 [ # # # # ]: 0 : );
686 : : else
687 : : {
688 : 0 : pParser->m_bHasFirst = true;
689 : 0 : pParser->m_aFirst.m_aAddrSpec = aTheAddrSpec;
690 : 0 : pParser->m_aFirst.m_aRealName = aTheRealName;
691 : 0 : }
692 : : }
693 [ # # ]: 0 : if (bDone)
694 : 0 : return;
695 : 0 : reset();
696 : : }
697 : 0 : break;
698 : :
699 : : case ':':
700 [ # # # # ]: 0 : switch (m_eState)
701 : : {
702 : : case BEFORE_COLON:
703 : 0 : m_aOuterAddrSpec.reset();
704 : 0 : resetRealNameAndFirstComment();
705 : 0 : m_eState = BEFORE_LESS;
706 : 0 : break;
707 : :
708 : : case BEFORE_LESS:
709 : : case AFTER_GREATER:
710 : 0 : m_aOuterAddrSpec.finish();
711 : 0 : addTokenToRealName();
712 : 0 : break;
713 : :
714 : : case AFTER_LESS:
715 : 0 : m_aInnerAddrSpec.reset();
716 : 0 : break;
717 : : }
718 : 0 : break;
719 : :
720 : : case '"':
721 : 0 : m_eType = TOKEN_QUOTED;
722 : 0 : break;
723 : :
724 : : case '.':
725 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
726 : : {
727 [ # # ]: 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM)
728 : 0 : addTokenToAddrSpec(ELEMENT_DELIM);
729 : : else
730 : 0 : m_pAddrSpec->reset();
731 : : }
732 : 0 : addTokenToRealName();
733 : 0 : break;
734 : :
735 : : case '[':
736 : 0 : m_eType = TOKEN_DOMAIN;
737 : 0 : break;
738 : : }
739 : : }
740 : : }
741 : :
742 : : //============================================================================
743 : : //
744 : : // SvAddressParser
745 : : //
746 : : //============================================================================
747 : :
748 : 0 : SvAddressParser::SvAddressParser(const rtl::OUString& rInput)
749 [ # # ]: 0 : : m_bHasFirst(false)
750 : : {
751 [ # # ]: 0 : SvAddressParser_Impl aDoParse(this, rInput);
752 : 0 : }
753 : :
754 : : //============================================================================
755 : 0 : SvAddressParser::~SvAddressParser()
756 : : {
757 [ # # ]: 0 : for ( size_t i = m_aRest.size(); i > 0; )
758 [ # # ]: 0 : delete m_aRest[ --i ];
759 : 0 : m_aRest.clear();
760 : 0 : }
761 : :
762 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|