annotate 3rdparty/vmime/src/vmime/address.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
rev   line source
ferencd@0 1 //
ferencd@0 2 // VMime library (http://www.vmime.org)
ferencd@0 3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
ferencd@0 4 //
ferencd@0 5 // This program is free software; you can redistribute it and/or
ferencd@0 6 // modify it under the terms of the GNU General Public License as
ferencd@0 7 // published by the Free Software Foundation; either version 3 of
ferencd@0 8 // the License, or (at your option) any later version.
ferencd@0 9 //
ferencd@0 10 // This program is distributed in the hope that it will be useful,
ferencd@0 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
ferencd@0 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ferencd@0 13 // General Public License for more details.
ferencd@0 14 //
ferencd@0 15 // You should have received a copy of the GNU General Public License along
ferencd@0 16 // with this program; if not, write to the Free Software Foundation, Inc.,
ferencd@0 17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ferencd@0 18 //
ferencd@0 19 // Linking this library statically or dynamically with other modules is making
ferencd@0 20 // a combined work based on this library. Thus, the terms and conditions of
ferencd@0 21 // the GNU General Public License cover the whole combination.
ferencd@0 22 //
ferencd@0 23
ferencd@0 24 #include "vmime/address.hpp"
ferencd@0 25
ferencd@0 26 #include "vmime/mailbox.hpp"
ferencd@0 27 #include "vmime/mailboxGroup.hpp"
ferencd@0 28
ferencd@0 29 #include "vmime/parserHelpers.hpp"
ferencd@0 30
ferencd@0 31
ferencd@0 32 namespace vmime
ferencd@0 33 {
ferencd@0 34
ferencd@0 35
ferencd@0 36 address::address()
ferencd@0 37 {
ferencd@0 38 }
ferencd@0 39
ferencd@0 40
ferencd@0 41 /*
ferencd@0 42
ferencd@0 43 RFC #2822:
ferencd@0 44 3.4. ADDRESS SPECIFICATION
ferencd@0 45
ferencd@0 46 Addresses occur in several message header fields to indicate senders
ferencd@0 47 and recipients of messages. An address may either be an individual
ferencd@0 48 mailbox, or a group of mailboxes.
ferencd@0 49
ferencd@0 50 address = mailbox / group
ferencd@0 51
ferencd@0 52 mailbox = name-addr / addr-spec
ferencd@0 53
ferencd@0 54 name-addr = [display-name] angle-addr
ferencd@0 55
ferencd@0 56 angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
ferencd@0 57
ferencd@0 58 group = display-name ":" [mailbox-list / CFWS] ";"
ferencd@0 59 [CFWS]
ferencd@0 60
ferencd@0 61 display-name = phrase
ferencd@0 62
ferencd@0 63 mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
ferencd@0 64
ferencd@0 65 address-list = (address *("," address)) / obs-addr-list
ferencd@0 66
ferencd@0 67 */
ferencd@0 68
ferencd@0 69 shared_ptr <address> address::parseNext
ferencd@0 70 (const parsingContext& ctx, const string& buffer, const size_t position,
ferencd@0 71 const size_t end, size_t* newPosition, bool *isLastAddressOfGroup)
ferencd@0 72 {
ferencd@0 73 bool escaped = false;
ferencd@0 74 bool quoted = false;
ferencd@0 75 bool quotedRFC2047 = false;
ferencd@0 76 bool inRouteAddr = false;
ferencd@0 77 bool isGroup = false;
ferencd@0 78 bool stop = false;
ferencd@0 79 int commentLevel = 0;
ferencd@0 80
ferencd@0 81 if (isLastAddressOfGroup)
ferencd@0 82 *isLastAddressOfGroup = false;
ferencd@0 83
ferencd@0 84 size_t pos = position;
ferencd@0 85
ferencd@0 86 while (pos < end && parserHelpers::isSpace(buffer[pos]))
ferencd@0 87 ++pos;
ferencd@0 88
ferencd@0 89 const size_t start = pos;
ferencd@0 90
ferencd@0 91 while (!stop && pos < end)
ferencd@0 92 {
ferencd@0 93 if (escaped)
ferencd@0 94 {
ferencd@0 95 escaped = false;
ferencd@0 96 }
ferencd@0 97 else
ferencd@0 98 {
ferencd@0 99 switch (buffer[pos])
ferencd@0 100 {
ferencd@0 101 case '\\':
ferencd@0 102 escaped = true;
ferencd@0 103 break;
ferencd@0 104 case '"':
ferencd@0 105 quoted = !quoted;
ferencd@0 106 break;
ferencd@0 107 case '<':
ferencd@0 108 inRouteAddr = true;
ferencd@0 109 break;
ferencd@0 110 case '>':
ferencd@0 111 inRouteAddr = false;
ferencd@0 112 break;
ferencd@0 113
ferencd@0 114 case '(':
ferencd@0 115
ferencd@0 116 ++commentLevel;
ferencd@0 117 break;
ferencd@0 118
ferencd@0 119 case ')':
ferencd@0 120
ferencd@0 121 if (commentLevel > 0)
ferencd@0 122 --commentLevel;
ferencd@0 123
ferencd@0 124 break;
ferencd@0 125
ferencd@0 126 case '=':
ferencd@0 127
ferencd@0 128 if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
ferencd@0 129 {
ferencd@0 130 ++pos;
ferencd@0 131 quotedRFC2047 = true;
ferencd@0 132 }
ferencd@0 133
ferencd@0 134 break;
ferencd@0 135
ferencd@0 136 case '?':
ferencd@0 137
ferencd@0 138 if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
ferencd@0 139 {
ferencd@0 140 ++pos;
ferencd@0 141 quotedRFC2047 = false;
ferencd@0 142 }
ferencd@0 143
ferencd@0 144 break;
ferencd@0 145
ferencd@0 146 default:
ferencd@0 147 {
ferencd@0 148 if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr)
ferencd@0 149 {
ferencd@0 150 switch (buffer[pos])
ferencd@0 151 {
ferencd@0 152 case ';':
ferencd@0 153
ferencd@0 154 if (isGroup)
ferencd@0 155 {
ferencd@0 156 if (pos + 1 < end && buffer[pos + 1] == ',')
ferencd@0 157 ++pos;
ferencd@0 158 }
ferencd@0 159
ferencd@0 160 if (isLastAddressOfGroup)
ferencd@0 161 *isLastAddressOfGroup = true;
ferencd@0 162
ferencd@0 163 stop = true;
ferencd@0 164 break;
ferencd@0 165
ferencd@0 166 case ':':
ferencd@0 167
ferencd@0 168 isGroup = true;
ferencd@0 169 break;
ferencd@0 170
ferencd@0 171 case ',':
ferencd@0 172
ferencd@0 173 if (!isGroup) stop = true;
ferencd@0 174 break;
ferencd@0 175 }
ferencd@0 176 }
ferencd@0 177
ferencd@0 178 break;
ferencd@0 179 }
ferencd@0 180
ferencd@0 181 }
ferencd@0 182 }
ferencd@0 183
ferencd@0 184 if (!stop)
ferencd@0 185 ++pos;
ferencd@0 186 }
ferencd@0 187
ferencd@0 188 if (newPosition)
ferencd@0 189 {
ferencd@0 190 if (pos == end)
ferencd@0 191 *newPosition = end;
ferencd@0 192 else
ferencd@0 193 *newPosition = pos + 1; // ',' or ';'
ferencd@0 194 }
ferencd@0 195
ferencd@0 196 // Parse extracted address (mailbox or group)
ferencd@0 197 if (pos != start)
ferencd@0 198 {
ferencd@0 199 shared_ptr <address> parsedAddress;
ferencd@0 200
ferencd@0 201 if (isGroup)
ferencd@0 202 parsedAddress = make_shared <mailboxGroup>();
ferencd@0 203 else
ferencd@0 204 parsedAddress = make_shared <mailbox>();
ferencd@0 205
ferencd@0 206 parsedAddress->parse(ctx, buffer, start, pos, NULL);
ferencd@0 207 parsedAddress->setParsedBounds(start, pos);
ferencd@0 208
ferencd@0 209 return (parsedAddress);
ferencd@0 210 }
ferencd@0 211
ferencd@0 212 return null;
ferencd@0 213 }
ferencd@0 214
ferencd@0 215
ferencd@0 216 } // vmime