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 OUString reparse(sal_Unicode const * pBegin,
110 : sal_Unicode const * pEnd, bool bAddrSpec);
111 :
112 : static OUString reparseComment(sal_Unicode const * pBegin,
113 : sal_Unicode const * pEnd);
114 :
115 : public:
116 : SvAddressParser_Impl(SvAddressParser * pParser, const 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 : int 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 : OUString SvAddressParser_Impl::reparse(sal_Unicode const * pBegin,
322 : sal_Unicode const * pEnd, bool bAddrSpec)
323 : {
324 0 : OUStringBuffer aResult;
325 0 : TokenType eMode = TOKEN_ATOM;
326 0 : bool bEscaped = false;
327 0 : bool bEndsWithSpace = false;
328 0 : int 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 : OUString SvAddressParser_Impl::reparseComment(sal_Unicode const * pBegin,
435 : sal_Unicode const * pEnd)
436 : {
437 0 : 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 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 0 : m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenContentEnd;
496 : }
497 : else
498 : {
499 0 : m_pRealNameEnd = m_pCurTokenEnd;
500 0 : m_bRealNameReparse = true;
501 : }
502 : }
503 0 : m_eType = TOKEN_ATOM;
504 0 : break;
505 :
506 : case TOKEN_DOMAIN:
507 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
508 : {
509 0 : if (m_pAddrSpec->m_bAtFound && m_pAddrSpec->m_eLastElem == ELEMENT_DELIM)
510 0 : addTokenToAddrSpec(ELEMENT_ITEM);
511 : else
512 0 : m_pAddrSpec->reset();
513 : }
514 0 : addTokenToRealName();
515 0 : m_eType = TOKEN_ATOM;
516 0 : break;
517 :
518 : case TOKEN_COMMENT:
519 0 : if (!m_bRealNameFinished && m_eState != AFTER_LESS
520 0 : && !m_pFirstCommentBegin && m_pCurTokenContentBegin)
521 : {
522 0 : m_pFirstCommentBegin = m_pCurTokenContentBegin;
523 0 : m_pFirstCommentEnd = m_pCurTokenContentEnd;
524 0 : m_bFirstCommentReparse = m_bCurTokenReparse;
525 : }
526 0 : m_eType = TOKEN_ATOM;
527 0 : break;
528 :
529 : case TOKEN_ATOM:
530 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
531 : {
532 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM)
533 0 : m_pAddrSpec->reset();
534 0 : addTokenToAddrSpec(ELEMENT_ITEM);
535 : }
536 0 : addTokenToRealName();
537 0 : break;
538 :
539 : case '(':
540 0 : m_eType = TOKEN_COMMENT;
541 0 : break;
542 :
543 : case ')':
544 : case '\\':
545 : case ']':
546 0 : m_pAddrSpec->finish();
547 0 : addTokenToRealName();
548 0 : break;
549 :
550 : case '<':
551 0 : switch (m_eState)
552 : {
553 : case BEFORE_COLON:
554 : case BEFORE_LESS:
555 0 : m_aOuterAddrSpec.finish();
556 0 : if (m_pRealNameBegin)
557 0 : m_bRealNameFinished = true;
558 0 : m_pAddrSpec = &m_aInnerAddrSpec;
559 0 : m_eState = AFTER_LESS;
560 0 : break;
561 :
562 : case AFTER_LESS:
563 0 : m_aInnerAddrSpec.finish();
564 0 : break;
565 :
566 : case AFTER_GREATER:
567 0 : m_aOuterAddrSpec.finish();
568 0 : addTokenToRealName();
569 0 : break;
570 : }
571 0 : break;
572 :
573 : case '>':
574 0 : if (m_eState == AFTER_LESS)
575 : {
576 0 : m_aInnerAddrSpec.finish();
577 0 : if (m_aInnerAddrSpec.isValid())
578 0 : m_aOuterAddrSpec.m_eLastElem = ELEMENT_END;
579 0 : m_pAddrSpec = &m_aOuterAddrSpec;
580 0 : m_eState = AFTER_GREATER;
581 : }
582 : else
583 : {
584 0 : m_aOuterAddrSpec.finish();
585 0 : addTokenToRealName();
586 : }
587 0 : break;
588 :
589 : case '@':
590 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
591 : {
592 0 : if (!m_pAddrSpec->m_bAtFound
593 : && m_pAddrSpec->m_eLastElem == ELEMENT_ITEM)
594 : {
595 0 : addTokenToAddrSpec(ELEMENT_DELIM);
596 0 : m_pAddrSpec->m_bAtFound = true;
597 : }
598 : else
599 0 : m_pAddrSpec->reset();
600 : }
601 0 : addTokenToRealName();
602 0 : break;
603 :
604 : case ',':
605 : case ';':
606 0 : if (m_eState == AFTER_LESS)
607 0 : if (m_nCurToken == ',')
608 : {
609 0 : if (m_aInnerAddrSpec.m_eLastElem != ELEMENT_END)
610 0 : m_aInnerAddrSpec.reset();
611 : }
612 : else
613 0 : m_aInnerAddrSpec.finish();
614 : else
615 : {
616 0 : if(m_aInnerAddrSpec.isValid() || (!m_aOuterAddrSpec.isValid() && m_aInnerAddrSpec.isPoorlyValid()))
617 : {
618 0 : m_pAddrSpec = &m_aInnerAddrSpec;
619 : }
620 0 : else if(m_aOuterAddrSpec.isPoorlyValid())
621 : {
622 0 : m_pAddrSpec = &m_aOuterAddrSpec;
623 : }
624 : else
625 : {
626 0 : m_pAddrSpec = 0;
627 : }
628 :
629 0 : if (m_pAddrSpec)
630 : {
631 0 : OUString aTheAddrSpec;
632 0 : if (m_pAddrSpec->m_bReparse)
633 0 : aTheAddrSpec = reparse(m_pAddrSpec->m_pBegin, m_pAddrSpec->m_pEnd, true);
634 : else
635 : {
636 0 : sal_Int32 nLen = ( m_pAddrSpec->m_pEnd - m_pAddrSpec->m_pBegin);
637 0 : if (nLen == rInput.getLength())
638 0 : aTheAddrSpec = rInput;
639 : else
640 0 : aTheAddrSpec = rInput.copy( (m_pAddrSpec->m_pBegin - rInput.getStr()),
641 0 : nLen);
642 : }
643 0 : OUString aTheRealName;
644 0 : if (!m_pRealNameBegin ||
645 : (m_pAddrSpec == &m_aOuterAddrSpec &&
646 : m_pRealNameBegin == m_aOuterAddrSpec.m_pBegin &&
647 : m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd &&
648 : m_pFirstCommentBegin))
649 : {
650 0 : if (!m_pFirstCommentBegin)
651 0 : aTheRealName = aTheAddrSpec;
652 0 : else if (m_bFirstCommentReparse)
653 : aTheRealName = reparseComment(m_pFirstCommentBegin,
654 0 : m_pFirstCommentEnd);
655 : else
656 0 : aTheRealName = rInput.copy( (m_pFirstCommentBegin - rInput.getStr()),
657 0 : (m_pFirstCommentEnd - m_pFirstCommentBegin));
658 : }
659 0 : else if (m_bRealNameReparse)
660 0 : aTheRealName = reparse(m_pRealNameBegin, m_pRealNameEnd, false);
661 : else
662 : {
663 0 : sal_Int32 nLen = (m_pRealNameContentEnd - m_pRealNameContentBegin);
664 0 : if (nLen == rInput.getLength())
665 0 : aTheRealName = rInput;
666 : else
667 0 : aTheRealName = rInput.copy( (m_pRealNameContentBegin - rInput.getStr()), nLen);
668 : }
669 0 : if (pParser->m_bHasFirst)
670 : pParser->m_aRest.push_back(new SvAddressEntry_Impl( aTheAddrSpec,
671 0 : aTheRealName) );
672 : else
673 : {
674 0 : pParser->m_bHasFirst = true;
675 0 : pParser->m_aFirst.m_aAddrSpec = aTheAddrSpec;
676 0 : pParser->m_aFirst.m_aRealName = aTheRealName;
677 0 : }
678 : }
679 0 : if (bDone)
680 0 : return;
681 0 : reset();
682 : }
683 0 : break;
684 :
685 : case ':':
686 0 : switch (m_eState)
687 : {
688 : case BEFORE_COLON:
689 0 : m_aOuterAddrSpec.reset();
690 0 : resetRealNameAndFirstComment();
691 0 : m_eState = BEFORE_LESS;
692 0 : break;
693 :
694 : case BEFORE_LESS:
695 : case AFTER_GREATER:
696 0 : m_aOuterAddrSpec.finish();
697 0 : addTokenToRealName();
698 0 : break;
699 :
700 : case AFTER_LESS:
701 0 : m_aInnerAddrSpec.reset();
702 0 : break;
703 : }
704 0 : break;
705 :
706 : case '"':
707 0 : m_eType = TOKEN_QUOTED;
708 0 : break;
709 :
710 : case '.':
711 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_END)
712 : {
713 0 : if (m_pAddrSpec->m_eLastElem != ELEMENT_DELIM)
714 0 : addTokenToAddrSpec(ELEMENT_DELIM);
715 : else
716 0 : m_pAddrSpec->reset();
717 : }
718 0 : addTokenToRealName();
719 0 : break;
720 :
721 : case '[':
722 0 : m_eType = TOKEN_DOMAIN;
723 0 : break;
724 : }
725 : }
726 : }
727 :
728 : //============================================================================
729 : //
730 : // SvAddressParser
731 : //
732 : //============================================================================
733 :
734 0 : SvAddressParser::SvAddressParser(const OUString& rInput)
735 0 : : m_bHasFirst(false)
736 : {
737 0 : SvAddressParser_Impl aDoParse(this, rInput);
738 0 : }
739 :
740 : //============================================================================
741 0 : SvAddressParser::~SvAddressParser()
742 : {
743 0 : for ( size_t i = m_aRest.size(); i > 0; )
744 0 : delete m_aRest[ --i ];
745 0 : m_aRest.clear();
746 0 : }
747 :
748 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|