File indexing completed on 2025-04-27 13:04:06
0001 /* -*- c++ -*- 0002 SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 /** 0007 @file 0008 This file is part of the API for handling @ref MIME data and 0009 defines the @ref Base64 and @ref RFC2047B @ref Codec classes. 0010 0011 @brief 0012 Defines the Base64Codec and Rfc2047BEncodingCodec classes. 0013 0014 @authors Marc Mutz \<mutz@kde.org\> 0015 0016 @glossary @anchor Base64 @anchor base64 @b base64: 0017 a binary to text encoding scheme based on @ref RFC1421. 0018 0019 @glossary @anchor RFC1421 @anchor rfc1421 @b RFC @b 1421: 0020 RFC that defines the <a href="http://tools.ietf.org/html/rfc1421"> 0021 Privacy Enhancement for Internet Electronic Mail: Part I: 0022 Message Encryption and Authentication Procedures</a>. 0023 0024 @glossary @anchor RFC2045 @anchor rfc2045 @b RFC @b 2045: 0025 RFC that defines the <a href="http://tools.ietf.org/html/rfc2045"> 0026 MIME Part One: Format of Internet Message Bodies</a>. 0027 0028 @glossary @anchor RFC2047 @anchor rfc2047 @b RFC @b 2047: 0029 RFC that defines the <a href="http://tools.ietf.org/html/rfc2047"> 0030 MIME Part Three: Message Header Extensions for Non-ASCII Text</a>. 0031 0032 @glossary @anchor RFC2047B @anchor rfc2047b @b RFC @b 2047B: 0033 Section 4.1 of @ref RFC2047. 0034 */ 0035 0036 #ifndef KCODECS_BASE64_H 0037 #define KCODECS_BASE64_H 0038 0039 #include "kcodecs.h" 0040 0041 namespace KCodecs 0042 { 0043 /** 0044 @brief 0045 A class representing the @ref codec for @ref Base64 as specified in 0046 @ref RFC2045 0047 */ 0048 class Base64Codec : public Codec 0049 { 0050 public: 0051 /** 0052 Constructs a Base64 codec. 0053 */ 0054 Base64Codec() 0055 : Codec() 0056 { 0057 } 0058 0059 /** 0060 Destroys the codec. 0061 */ 0062 ~Base64Codec() override 0063 { 0064 } 0065 0066 /** 0067 @copydoc 0068 Codec::name() 0069 */ 0070 const char *name() const override 0071 { 0072 return "base64"; 0073 } 0074 0075 /** 0076 @copydoc 0077 Codec::maxEncodedSizeFor() 0078 */ 0079 int maxEncodedSizeFor(int insize, NewlineType newline) const override 0080 { 0081 // first, the total number of 4-char packets will be: 0082 int totalNumPackets = (insize + 2) / 3; 0083 // now, after every 76/4'th packet there needs to be a linebreak: 0084 int numLineBreaks = totalNumPackets / (76 / 4); 0085 // and at the very end, too: 0086 ++numLineBreaks; 0087 // putting it all together, we have: 0088 return 4 * totalNumPackets + (newline == Codec::NewlineCRLF ? 2 : 1) * numLineBreaks; 0089 } 0090 0091 /** 0092 @copydoc 0093 Codec::maxDecodedSizeFor() 0094 */ 0095 int maxDecodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override 0096 { 0097 // assuming all characters are part of the base64 stream (which 0098 // does almost never hold due to required linebreaking; but 0099 // additional non-base64 chars don't affect the output size), each 0100 // 4-tupel of them becomes a 3-tupel in the decoded octet 0101 // stream. So: 0102 int result = ((insize + 3) / 4) * 3; 0103 // but all of them may be \n, so 0104 if (newline == Codec::NewlineCRLF) { 0105 result *= 2; // :-o 0106 } 0107 0108 return result; 0109 } 0110 0111 /** 0112 @copydoc 0113 Codec::makeEncoder() 0114 */ 0115 Encoder *makeEncoder(NewlineType newline = Codec::NewlineLF) const override; 0116 0117 /** 0118 @copydoc 0119 Codec::makeDecoder() 0120 */ 0121 Decoder *makeDecoder(NewlineType newline = Codec::NewlineLF) const override; 0122 }; 0123 0124 /** 0125 @brief 0126 A class representing the @ref codec for the B encoding as specified 0127 in @ref RFC2047B. 0128 */ 0129 class Rfc2047BEncodingCodec : public Base64Codec 0130 { 0131 public: 0132 /** 0133 Constructs a RFC2047B codec. 0134 */ 0135 Rfc2047BEncodingCodec() 0136 : Base64Codec() 0137 { 0138 } 0139 0140 /** 0141 Destroys the codec. 0142 */ 0143 ~Rfc2047BEncodingCodec() override 0144 { 0145 } 0146 0147 /** 0148 @copydoc 0149 Codec::name() 0150 */ 0151 const char *name() const override 0152 { 0153 return "b"; 0154 } 0155 0156 /** 0157 @copydoc 0158 Codec::maxEncodedSizeFor() 0159 */ 0160 int maxEncodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override 0161 { 0162 Q_UNUSED(newline); 0163 // Each (begun) 3-octet triple becomes a 4 char quartet, so: 0164 return ((insize + 2) / 3) * 4; 0165 } 0166 0167 /** 0168 @copydoc 0169 Codec::maxDecodedSizeFor() 0170 */ 0171 int maxDecodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override 0172 { 0173 Q_UNUSED(newline); 0174 // Each 4-char quartet becomes a 3-octet triple, the last one 0175 // possibly even less. So: 0176 return ((insize + 3) / 4) * 3; 0177 } 0178 0179 /** 0180 @copydoc 0181 Codec::makeEncoder() 0182 */ 0183 Encoder *makeEncoder(NewlineType newline = Codec::NewlineLF) const override; 0184 }; 0185 0186 } // namespace KCodecs 0187 0188 #endif // KCODECS_BASE64_H