1 /* -*- c++ -*- 2 kmime_header_parsing.h 3 4 KMime, the KDE Internet mail/usenet news message library. 5 SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org> 6 7 SPDX-License-Identifier: LGPL-2.0-or-later 8 */ 9 10 #pragma once 11 12 #include "kmime_export.h" 13 #include "kmime_types.h" 14 15 #include <QString> 16 #include <QPair> 17 18 #include <QDateTime> 19 20 template <typename K, typename V> class QMap; 21 #include <QStringList> 22 23 namespace KMime 24 { 25 26 namespace Headers 27 { 28 class Base; 29 } 30 31 namespace Types 32 { 33 34 } // namespace KMime::Types 35 36 namespace HeaderParsing 37 { 38 39 /** 40 Parses the encoded word. 41 42 @param scursor pointer to the first character beyond the initial '=' of 43 the input string. 44 @param send pointer to end of input buffer. 45 @param result the decoded string the encoded work represented. 46 @param language The language parameter according to RFC 2231, section 5. 47 @param usedCS the used charset is returned here 48 @param defaultCS the charset to use in case the detected 49 one isn't known to us. 50 @param forceCS force the use of the default charset. 51 52 @return true if the input string was successfully decode; false otherwise. 53 */ 54 Q_REQUIRED_RESULT KMIME_EXPORT bool parseEncodedWord(const char *&scursor, 55 const char *const send, 56 QString &result, QByteArray &language, 57 QByteArray &usedCS, const QByteArray &defaultCS = QByteArray(), 58 bool forceCS = false); 59 60 // 61 // The parsing squad: 62 // 63 64 /** You may or may not have already started parsing into the 65 atom. This function will go on where you left off. 66 */ 67 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAtom(const char *&scursor, const char *const send, 68 QByteArray &result, bool allow8Bit = false); 69 70 /** 71 * More efficient overload, to avoid a copy of the substring 72 */ 73 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAtom(const char *&scursor, const char *const send, 74 QPair<const char *, int> &result, 75 bool allow8Bit = false); 76 77 enum ParseTokenFlag { 78 ParseTokenNoFlag = 0, 79 ParseTokenAllow8Bit = 1, 80 ParseTokenRelaxedTText = 2 81 }; 82 Q_DECLARE_FLAGS(ParseTokenFlags, ParseTokenFlag) 83 84 /** You may or may not have already started parsing into the 85 token. This function will go on where you left off. */ 86 Q_REQUIRED_RESULT KMIME_EXPORT bool parseToken(const char *&scursor, const char *const send, 87 QByteArray &result, ParseTokenFlags flags = ParseTokenNoFlag); 88 89 Q_REQUIRED_RESULT KMIME_EXPORT bool parseToken(const char *&scursor, const char *const send, 90 QPair<const char *, int> &result, 91 ParseTokenFlags flags = ParseTokenNoFlag); 92 93 /** @p scursor must be positioned after the opening openChar. */ 94 Q_REQUIRED_RESULT KMIME_EXPORT bool parseGenericQuotedString(const char *&scursor, 95 const char *const send, 96 QString &result, bool isCRLF, 97 const char openChar = '"', 98 const char closeChar = '"'); 99 100 /** @p scursor must be positioned right after the opening '(' */ 101 Q_REQUIRED_RESULT KMIME_EXPORT bool parseComment(const char *&scursor, const char *const send, 102 QString &result, bool isCRLF = false, 103 bool reallySave = true); 104 105 /** 106 Parses a phrase. 107 108 You may or may not have already started parsing into the phrase, but 109 only if it starts with atext. If you setup this function to parse a 110 phrase starting with an encoded-word or quoted-string, @p scursor has 111 to point to the char introducing the encoded-word or quoted-string, resp. 112 113 @param scursor pointer to the first character beyond the initial '=' of 114 the input string. 115 @param send pointer to end of input buffer. 116 @param result the parsed string. 117 118 @return true if the input phrase was successfully parsed; false otherwise. 119 */ 120 Q_REQUIRED_RESULT KMIME_EXPORT bool parsePhrase(const char *&scursor, const char *const send, 121 QString &result, bool isCRLF = false); 122 123 /** 124 Parses into the initial atom. 125 You may or may not have already started parsing into the initial 126 atom, but not up to it's end. 127 128 @param scursor pointer to the first character beyond the initial '=' of 129 the input string. 130 @param send pointer to end of input buffer. 131 @param result the parsed string. 132 133 @return true if the input phrase was successfully parsed; false otherwise. 134 */ 135 Q_REQUIRED_RESULT KMIME_EXPORT bool parseDotAtom(const char *&scursor, const char *const send, 136 QByteArray &result, bool isCRLF = false); 137 138 /** 139 Eats comment-folding-white-space, skips whitespace, folding and comments 140 (even nested ones) and stops at the next non-CFWS character. After 141 calling this function, you should check whether @p scursor == @p send 142 (end of header reached). 143 144 If a comment with unbalanced parentheses is encountered, @p scursor 145 is being positioned on the opening '(' of the outmost comment. 146 147 @param scursor pointer to the first character beyond the initial '=' of 148 the input string. 149 @param send pointer to end of input buffer. 150 @param isCRLF true if input string is terminated with a CRLF. 151 */ 152 KMIME_EXPORT void eatCFWS(const char *&scursor, const char *const send, 153 bool isCRLF); 154 155 Q_REQUIRED_RESULT KMIME_EXPORT bool parseDomain(const char *&scursor, const char *const send, 156 QString &result, bool isCRLF = false); 157 158 Q_REQUIRED_RESULT KMIME_EXPORT bool parseObsRoute(const char *&scursor, const char *const send, 159 QStringList &result, bool isCRLF = false, 160 bool save = false); 161 162 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAddrSpec(const char *&scursor, const char *const send, 163 Types::AddrSpec &result, bool isCRLF = false); 164 165 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAngleAddr(const char *&scursor, const char *const send, 166 Types::AddrSpec &result, bool isCRLF = false); 167 168 /** 169 Parses a single mailbox. 170 171 RFC 2822, section 3.4 defines a mailbox as follows: 172 <pre>mailbox := addr-spec / ([ display-name ] angle-addr)</pre> 173 174 KMime also accepts the legacy format of specifying display names: 175 <pre>mailbox := (addr-spec [ "(" display-name ")" ]) 176 / ([ display-name ] angle-addr) 177 / (angle-addr "(" display-name ")")</pre> 178 179 @param scursor pointer to the first character of the input string 180 @param send pointer to end of input buffer 181 @param result the parsing result 182 @param isCRLF true if input string is terminated with a CRLF. 183 */ 184 KMIME_EXPORT bool parseMailbox(const char *&scursor, const char *const send, 185 Types::Mailbox &result, bool isCRLF = false); 186 187 Q_REQUIRED_RESULT KMIME_EXPORT bool parseGroup(const char *&scursor, const char *const send, 188 Types::Address &result, bool isCRLF = false); 189 190 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAddress(const char *&scursor, const char *const send, 191 Types::Address &result, bool isCRLF = false); 192 193 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAddressList(const char *&scursor, 194 const char *const send, 195 Types::AddressList &result, 196 bool isCRLF = false); 197 198 Q_REQUIRED_RESULT KMIME_EXPORT bool parseParameterList(const char *&scursor, 199 const char *const send, 200 QMap<QString, QString> &result, 201 bool isCRLF = false); 202 203 /** 204 * Extract the charset embedded in the parameter list if there is one. 205 * 206 * @since 4.5 207 */ 208 Q_REQUIRED_RESULT KMIME_EXPORT bool parseParameterListWithCharset(const char *&scursor, 209 const char *const send, 210 QMap<QString, QString> &result, 211 QByteArray &charset, bool isCRLF = false); 212 213 /** 214 Parses an integer number. 215 @param scursor pointer to the first character of the input string 216 @param send pointer to end of input buffer 217 @param result the parsing result 218 @returns The number of parsed digits (don't confuse with @p result!) 219 */ 220 Q_REQUIRED_RESULT KMIME_EXPORT int parseDigits(const char *&scursor, const char *const send, int &result); 221 222 Q_REQUIRED_RESULT KMIME_EXPORT bool parseTime(const char *&scursor, const char *const send, 223 int &hour, int &min, int &sec, 224 long int &secsEastOfGMT, 225 bool &timeZoneKnown, bool isCRLF = false); 226 227 Q_REQUIRED_RESULT KMIME_EXPORT bool parseDateTime(const char *&scursor, const char *const send, 228 QDateTime &result, bool isCRLF = false); 229 230 /** 231 * Extracts and returns the first header that is contained in the given byte array. 232 * The header will also be removed from the passed-in byte array head. 233 * 234 * @since 4.4 235 */ 236 Q_REQUIRED_RESULT KMIME_EXPORT KMime::Headers::Base *extractFirstHeader(QByteArray &head); 237 238 /** 239 * Extract the header header and the body from a complete content. 240 * Internally, it will simply look for the first newline and use that as a 241 * separator between the header and the body. 242 * 243 * @param content the complete mail 244 * @param header return value for the extracted header 245 * @param body return value for the extracted body 246 * @since 4.6 247 */ 248 KMIME_EXPORT void extractHeaderAndBody(const QByteArray &content, 249 QByteArray &header, QByteArray &body); 250 251 } // namespace HeaderParsing 252 253 } // namespace KMime 254 255 Q_DECLARE_OPERATORS_FOR_FLAGS(KMime::HeaderParsing::ParseTokenFlags) 256 257 258