2004-10-05 10:28:21 +00:00
|
|
|
//
|
2005-03-18 21:33:11 +00:00
|
|
|
// VMime library (http://www.vmime.org)
|
2007-01-01 20:55:15 +00:00
|
|
|
// Copyright (C) 2002-2007 Vincent Richard <vincent@vincent-richard.net>
|
2004-10-05 10:28:21 +00:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of
|
|
|
|
// the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
2005-09-17 10:10:29 +00:00
|
|
|
// You should have received a copy of the GNU General Public License along
|
|
|
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
//
|
|
|
|
// Linking this library statically or dynamically with other modules is making
|
|
|
|
// a combined work based on this library. Thus, the terms and conditions of
|
|
|
|
// the GNU General Public License cover the whole combination.
|
2004-10-05 10:28:21 +00:00
|
|
|
//
|
|
|
|
|
2004-12-26 20:23:29 +00:00
|
|
|
#include "vmime/address.hpp"
|
2004-10-05 10:28:21 +00:00
|
|
|
|
2004-12-26 20:23:29 +00:00
|
|
|
#include "vmime/mailbox.hpp"
|
|
|
|
#include "vmime/mailboxGroup.hpp"
|
2004-10-05 10:28:21 +00:00
|
|
|
|
2004-12-26 20:23:29 +00:00
|
|
|
#include "vmime/parserHelpers.hpp"
|
2004-10-05 10:28:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace vmime
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
address::address()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
RFC #2822:
|
|
|
|
3.4. ADDRESS SPECIFICATION
|
|
|
|
|
|
|
|
Addresses occur in several message header fields to indicate senders
|
|
|
|
and recipients of messages. An address may either be an individual
|
|
|
|
mailbox, or a group of mailboxes.
|
|
|
|
|
|
|
|
address = mailbox / group
|
|
|
|
|
|
|
|
mailbox = name-addr / addr-spec
|
|
|
|
|
|
|
|
name-addr = [display-name] angle-addr
|
|
|
|
|
|
|
|
angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
|
|
|
|
|
|
|
|
group = display-name ":" [mailbox-list / CFWS] ";"
|
|
|
|
[CFWS]
|
|
|
|
|
|
|
|
display-name = phrase
|
|
|
|
|
|
|
|
mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
|
|
|
|
|
|
|
|
address-list = (address *("," address)) / obs-addr-list
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2005-07-12 22:28:02 +00:00
|
|
|
ref <address> address::parseNext(const string& buffer, const string::size_type position,
|
2004-10-05 10:28:21 +00:00
|
|
|
const string::size_type end, string::size_type* newPosition)
|
|
|
|
{
|
|
|
|
bool escaped = false;
|
|
|
|
bool quoted = false;
|
|
|
|
bool quotedRFC2047 = false;
|
|
|
|
bool inRouteAddr = false;
|
|
|
|
bool isGroup = false;
|
|
|
|
bool stop = false;
|
|
|
|
|
|
|
|
string::size_type pos = position;
|
|
|
|
|
2005-03-16 17:13:08 +00:00
|
|
|
while (pos < end && parserHelpers::isSpace(buffer[pos]))
|
2004-10-05 10:28:21 +00:00
|
|
|
++pos;
|
|
|
|
|
|
|
|
const string::size_type start = pos;
|
|
|
|
|
|
|
|
while (!stop && pos < end)
|
|
|
|
{
|
|
|
|
if (escaped)
|
|
|
|
{
|
|
|
|
escaped = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (buffer[pos])
|
|
|
|
{
|
|
|
|
case '\\':
|
|
|
|
escaped = true;
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
quoted = !quoted;
|
|
|
|
break;
|
|
|
|
case '<':
|
|
|
|
inRouteAddr = true;
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
inRouteAddr = false;
|
|
|
|
break;
|
|
|
|
case '=':
|
|
|
|
|
2007-02-22 14:26:10 +00:00
|
|
|
if (!quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
|
2004-10-05 10:28:21 +00:00
|
|
|
{
|
|
|
|
++pos;
|
|
|
|
quotedRFC2047 = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '?':
|
|
|
|
|
|
|
|
if (quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
|
|
|
|
{
|
|
|
|
++pos;
|
|
|
|
quotedRFC2047 = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if (!quoted && !quotedRFC2047 && !inRouteAddr)
|
|
|
|
{
|
|
|
|
switch (buffer[pos])
|
|
|
|
{
|
|
|
|
case ';':
|
|
|
|
|
|
|
|
if (isGroup)
|
|
|
|
{
|
|
|
|
if (pos + 1 < end && buffer[pos + 1] == ',')
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
stop = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ':':
|
|
|
|
|
|
|
|
isGroup = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ',':
|
|
|
|
|
|
|
|
if (!isGroup) stop = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!stop)
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newPosition)
|
|
|
|
{
|
|
|
|
if (pos == end)
|
|
|
|
*newPosition = end;
|
|
|
|
else
|
|
|
|
*newPosition = pos + 1; // ',' or ';'
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse extracted address (mailbox or group)
|
|
|
|
if (pos != start)
|
|
|
|
{
|
2005-07-12 22:28:02 +00:00
|
|
|
ref <address> parsedAddress = isGroup
|
|
|
|
? create <mailboxGroup>().dynamicCast <address>()
|
|
|
|
: create <mailbox>().dynamicCast <address>();
|
2004-10-05 10:28:21 +00:00
|
|
|
|
2005-07-12 22:28:02 +00:00
|
|
|
parsedAddress->parse(buffer, start, pos, NULL);
|
|
|
|
parsedAddress->setParsedBounds(start, pos);
|
2005-03-15 17:31:26 +00:00
|
|
|
|
2005-07-12 22:28:02 +00:00
|
|
|
return (parsedAddress);
|
2004-10-05 10:28:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // vmime
|