File indexing completed on 2022-11-29 19:53:38

0001 /*  -*- c++ -*-
0002     kmime_header_parsing.h
0003 
0004     KMime, the KDE Internet mail/usenet news message library.
0005     SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "kmime_export.h"
0013 #include "kmime_types.h"
0014 
0015 #include <QString>
0016 #include <QPair>
0017 
0018 #include <QDateTime>
0019 
0020 template <typename K, typename V> class QMap;
0021 #include <QStringList>
0022 
0023 namespace KMime
0024 {
0025 
0026 namespace Headers
0027 {
0028 class Base;
0029 }
0030 
0031 namespace Types
0032 {
0033 
0034 } // namespace KMime::Types
0035 
0036 namespace HeaderParsing
0037 {
0038 
0039 /**
0040   Parses the encoded word.
0041 
0042   @param scursor pointer to the first character beyond the initial '=' of
0043   the input string.
0044   @param send pointer to end of input buffer.
0045   @param result the decoded string the encoded work represented.
0046   @param language The language parameter according to RFC 2231, section 5.
0047   @param usedCS    the used charset is returned here
0048   @param defaultCS the charset to use in case the detected
0049                    one isn't known to us.
0050   @param forceCS   force the use of the default charset.
0051 
0052   @return true if the input string was successfully decode; false otherwise.
0053 */
0054 Q_REQUIRED_RESULT KMIME_EXPORT bool parseEncodedWord(const char *&scursor,
0055                                    const char *const send,
0056                                    QString &result, QByteArray &language,
0057                                    QByteArray &usedCS, const QByteArray &defaultCS = QByteArray(),
0058                                    bool forceCS = false);
0059 
0060 //
0061 // The parsing squad:
0062 //
0063 
0064 /** You may or may not have already started parsing into the
0065     atom. This function will go on where you left off.
0066  */
0067 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAtom(const char *&scursor, const char *const send,
0068                             QByteArray &result, bool allow8Bit = false);
0069 
0070 /**
0071  * More efficient overload, to avoid a copy of the substring
0072  */
0073 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAtom(const char *&scursor, const char *const send,
0074                             QPair<const char *, int> &result,
0075                             bool allow8Bit = false);
0076 
0077 enum ParseTokenFlag {
0078     ParseTokenNoFlag = 0,
0079     ParseTokenAllow8Bit = 1,
0080     ParseTokenRelaxedTText = 2
0081 };
0082 Q_DECLARE_FLAGS(ParseTokenFlags, ParseTokenFlag)
0083 
0084 /** You may or may not have already started parsing into the
0085     token. This function will go on where you left off. */
0086 Q_REQUIRED_RESULT KMIME_EXPORT bool parseToken(const char *&scursor, const char *const send,
0087                              QByteArray &result, ParseTokenFlags flags = ParseTokenNoFlag);
0088 
0089 Q_REQUIRED_RESULT KMIME_EXPORT bool parseToken(const char *&scursor, const char *const send,
0090                              QPair<const char *, int> &result,
0091                              ParseTokenFlags flags = ParseTokenNoFlag);
0092 
0093 /** @p scursor must be positioned after the opening openChar. */
0094 Q_REQUIRED_RESULT KMIME_EXPORT bool parseGenericQuotedString(const char *&scursor,
0095         const char *const send,
0096         QString &result, bool isCRLF,
0097         const char openChar = '"',
0098         const char closeChar = '"');
0099 
0100 /** @p scursor must be positioned right after the opening '(' */
0101 Q_REQUIRED_RESULT KMIME_EXPORT bool parseComment(const char *&scursor, const char *const send,
0102                                QString &result, bool isCRLF = false,
0103                                bool reallySave = true);
0104 
0105 /**
0106   Parses a phrase.
0107 
0108   You may or may not have already started parsing into the phrase, but
0109   only if it starts with atext. If you setup this function to parse a
0110   phrase starting with an encoded-word or quoted-string, @p scursor has
0111   to point to the char introducing the encoded-word or quoted-string, resp.
0112 
0113   @param scursor pointer to the first character beyond the initial '=' of
0114   the input string.
0115   @param send pointer to end of input buffer.
0116   @param result the parsed string.
0117 
0118   @return true if the input phrase was successfully parsed; false otherwise.
0119 */
0120 Q_REQUIRED_RESULT KMIME_EXPORT bool parsePhrase(const char *&scursor, const char *const send,
0121                               QString &result, bool isCRLF = false);
0122 
0123 /**
0124   Parses into the initial atom.
0125   You may or may not have already started parsing into the initial
0126   atom, but not up to it's end.
0127 
0128   @param scursor pointer to the first character beyond the initial '=' of
0129   the input string.
0130   @param send pointer to end of input buffer.
0131   @param result the parsed string.
0132 
0133   @return true if the input phrase was successfully parsed; false otherwise.
0134 */
0135 Q_REQUIRED_RESULT KMIME_EXPORT bool parseDotAtom(const char *&scursor, const char *const send,
0136                                QByteArray &result, bool isCRLF = false);
0137 
0138 /**
0139   Eats comment-folding-white-space, skips whitespace, folding and comments
0140   (even nested ones) and stops at the next non-CFWS character.  After
0141   calling this function, you should check whether @p scursor == @p send
0142   (end of header reached).
0143 
0144   If a comment with unbalanced parentheses is encountered, @p scursor
0145   is being positioned on the opening '(' of the outmost comment.
0146 
0147   @param scursor pointer to the first character beyond the initial '=' of
0148   the input string.
0149   @param send pointer to end of input buffer.
0150   @param isCRLF true if input string is terminated with a CRLF.
0151 */
0152 KMIME_EXPORT void eatCFWS(const char *&scursor, const char *const send,
0153                           bool isCRLF);
0154 
0155 Q_REQUIRED_RESULT KMIME_EXPORT bool parseDomain(const char *&scursor, const char *const send,
0156                               QString &result, bool isCRLF = false);
0157 
0158 Q_REQUIRED_RESULT KMIME_EXPORT bool parseObsRoute(const char *&scursor, const char *const send,
0159                                 QStringList &result, bool isCRLF = false,
0160                                 bool save = false);
0161 
0162 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAddrSpec(const char *&scursor, const char *const send,
0163                                 Types::AddrSpec &result, bool isCRLF = false);
0164 
0165 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAngleAddr(const char *&scursor, const char *const send,
0166                                  Types::AddrSpec &result, bool isCRLF = false);
0167 
0168 /**
0169   Parses a single mailbox.
0170 
0171   RFC 2822, section 3.4 defines a mailbox as follows:
0172   <pre>mailbox := addr-spec / ([ display-name ] angle-addr)</pre>
0173 
0174   KMime also accepts the legacy format of specifying display names:
0175   <pre>mailbox := (addr-spec [ "(" display-name ")" ])
0176   / ([ display-name ] angle-addr)
0177   / (angle-addr "(" display-name ")")</pre>
0178 
0179   @param scursor pointer to the first character of the input string
0180   @param send pointer to end of input buffer
0181   @param result the parsing result
0182   @param isCRLF true if input string is terminated with a CRLF.
0183 */
0184 KMIME_EXPORT bool parseMailbox(const char *&scursor, const char *const send,
0185                                Types::Mailbox &result, bool isCRLF = false);
0186 
0187 Q_REQUIRED_RESULT KMIME_EXPORT bool parseGroup(const char *&scursor, const char *const send,
0188                              Types::Address &result, bool isCRLF = false);
0189 
0190 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAddress(const char *&scursor, const char *const send,
0191                                Types::Address &result, bool isCRLF = false);
0192 
0193 Q_REQUIRED_RESULT KMIME_EXPORT bool parseAddressList(const char *&scursor,
0194                                    const char *const send,
0195                                    Types::AddressList &result,
0196                                    bool isCRLF = false);
0197 
0198 Q_REQUIRED_RESULT KMIME_EXPORT bool parseParameterList(const char *&scursor,
0199                                      const char *const send,
0200                                      QMap<QString, QString> &result,
0201                                      bool isCRLF = false);
0202 
0203 /**
0204  * Extract the charset embedded in the parameter list if there is one.
0205  *
0206  * @since 4.5
0207  */
0208 Q_REQUIRED_RESULT KMIME_EXPORT bool parseParameterListWithCharset(const char *&scursor,
0209         const char *const send,
0210         QMap<QString, QString> &result,
0211         QByteArray &charset, bool isCRLF = false);
0212 
0213 /**
0214   Parses an integer number.
0215   @param scursor pointer to the first character of the input string
0216   @param send pointer to end of input buffer
0217   @param result the parsing result
0218   @returns The number of parsed digits (don't confuse with @p result!)
0219 */
0220 Q_REQUIRED_RESULT KMIME_EXPORT int parseDigits(const char *&scursor, const char *const send, int &result);
0221 
0222 Q_REQUIRED_RESULT KMIME_EXPORT bool parseTime(const char *&scursor, const char *const send,
0223                             int &hour, int &min, int &sec,
0224                             long int &secsEastOfGMT,
0225                             bool &timeZoneKnown, bool isCRLF = false);
0226 
0227 Q_REQUIRED_RESULT KMIME_EXPORT bool parseDateTime(const char *&scursor, const char *const send,
0228                                 QDateTime &result, bool isCRLF = false);
0229 
0230 /**
0231  * Extracts and returns the first header that is contained in the given byte array.
0232  * The header will also be removed from the passed-in byte array head.
0233  *
0234  * @since 4.4
0235  */
0236 Q_REQUIRED_RESULT KMIME_EXPORT KMime::Headers::Base *extractFirstHeader(QByteArray &head);
0237 
0238 /**
0239  * Extract the header header and the body from a complete content.
0240  * Internally, it will simply look for the first newline and use that as a
0241  * separator between the header and the body.
0242  *
0243  * @param content the complete mail
0244  * @param header return value for the extracted header
0245  * @param body return value for the extracted body
0246  * @since 4.6
0247  */
0248 KMIME_EXPORT void extractHeaderAndBody(const QByteArray &content,
0249                                        QByteArray &header, QByteArray &body);
0250 
0251 } // namespace HeaderParsing
0252 
0253 } // namespace KMime
0254 
0255 Q_DECLARE_OPERATORS_FOR_FLAGS(KMime::HeaderParsing::ParseTokenFlags)
0256 
0257