File indexing completed on 2024-12-08 03:38:25

0001 /*
0002     SPDX-FileCopyrightText: 2000-2001 Dawit Alemayehu <adawit@kde.org>
0003     SPDX-FileCopyrightText: 2001 Rik Hemsley (rikkus) <rik@kde.org>
0004     SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 
0008     The quoted-printable codec as described in RFC 2045, section 6.7. is by
0009     Rik Hemsley (C) 2001.
0010 */
0011 
0012 #ifndef KCODECS_H
0013 #define KCODECS_H
0014 
0015 #include <kcodecs_export.h>
0016 
0017 #include <QString>
0018 
0019 #include <memory>
0020 
0021 class QByteArray;
0022 class QIODevice;
0023 
0024 /**
0025  * A wrapper class for the most commonly used encoding and
0026  * decoding algorithms.  Currently there is support for encoding
0027  * and decoding input using base64, uu and the quoted-printable
0028  * specifications.
0029  *
0030  * \b Usage:
0031  *
0032  * \code
0033  * QByteArray input = "Aladdin:open sesame";
0034  * QByteArray result = KCodecs::base64Encode(input);
0035  * cout << "Result: " << result.data() << endl;
0036  * \endcode
0037  *
0038  * <pre>
0039  * Output should be
0040  * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ==
0041  * </pre>
0042  *
0043  * The above example makes use of the convenience functions
0044  * (ones that accept/return null-terminated strings) to encode/decode
0045  * a string.  If what you need is to encode or decode binary data, then
0046  * it is highly recommended that you use the functions that take an input
0047  * and output QByteArray as arguments.  These functions are specifically
0048  * tailored for encoding and decoding binary data.
0049  *
0050  * @short A collection of commonly used encoding and decoding algorithms.
0051  * @author Dawit Alemayehu <adawit@kde.org>
0052  * @author Rik Hemsley <rik@kde.org>
0053  */
0054 namespace KCodecs
0055 {
0056 /**
0057  * Encodes the given data using the quoted-printable algorithm.
0058  *
0059  * @param in      data to be encoded.
0060  * @param useCRLF if true the input data is expected to have
0061  *                CRLF line breaks and the output will have CRLF line
0062  *                breaks, too.
0063  * @return        quoted-printable encoded string.
0064  */
0065 KCODECS_EXPORT QByteArray quotedPrintableEncode(QByteArrayView in, bool useCRLF = true);
0066 
0067 /**
0068  * Encodes the given data using the quoted-printable algorithm.
0069  *
0070  * Use this function if you want the result of the encoding
0071  * to be placed in another array which cuts down the number
0072  * of copy operation that have to be performed in the process.
0073  * This is also the preferred method for encoding binary data.
0074  *
0075  * NOTE: the output array is first reset and then resized
0076  * appropriately before use, hence, all data stored in the
0077  * output array will be lost.
0078  *
0079  * @param in      data to be encoded.
0080  * @param out     encoded data.
0081  * @param useCRLF if true the input data is expected to have
0082  *                CRLF line breaks and the output will have CRLF line
0083  *                breaks, too.
0084  */
0085 KCODECS_EXPORT void quotedPrintableEncode(QByteArrayView in, QByteArray &out, bool useCRLF);
0086 
0087 /**
0088  * Decodes a quoted-printable encoded data.
0089  *
0090  * Accepts data with CRLF or standard unix line breaks.
0091  *
0092  * @param in  data to be decoded.
0093  * @return    decoded string.
0094  * @since 5.5
0095  */
0096 KCODECS_EXPORT QByteArray quotedPrintableDecode(QByteArrayView in);
0097 
0098 /**
0099  * Decodes a quoted-printable encoded data.
0100  *
0101  * Accepts data with CRLF or standard unix line breaks.
0102  * Use this function if you want the result of the decoding
0103  * to be placed in another array which cuts down the number
0104  * of copy operation that have to be performed in the process.
0105  * This is also the preferred method for decoding an encoded
0106  * binary data.
0107  *
0108  * NOTE: the output array is first reset and then resized
0109  * appropriately before use, hence, all data stored in the
0110  * output array will be lost.
0111  *
0112  * @param in   data to be decoded.
0113  * @param out  decoded data.
0114  */
0115 KCODECS_EXPORT void quotedPrintableDecode(QByteArrayView in, QByteArray &out);
0116 
0117 /**
0118  * Decodes the given data using the uudecode algorithm.
0119  *
0120  * Any 'begin' and 'end' lines like those generated by
0121  * the utilities in unix and unix-like OS will be
0122  * automatically ignored.
0123  *
0124  * @param in   data to be decoded.
0125  * @return     decoded string.
0126  */
0127 KCODECS_EXPORT QByteArray uudecode(QByteArrayView in);
0128 
0129 /**
0130  * Decodes the given data using the uudecode algorithm.
0131  *
0132  * Use this function if you want the result of the decoding
0133  * to be placed in another array which cuts down the number
0134  * of copy operation that have to be performed in the process.
0135  * This is the preferred method for decoding binary data.
0136  *
0137  * Any 'begin' and 'end' lines like those generated by
0138  * the utilities in unix and unix-like OS will be
0139  * automatically ignored.
0140  *
0141  * NOTE: the output array is first reset and then resized
0142  * appropriately before use, hence, all data stored in the
0143  * output array will be lost.
0144  *
0145  * @param in   data to be decoded.
0146  * @param out  uudecoded data.
0147  */
0148 KCODECS_EXPORT void uudecode(QByteArrayView in, QByteArray &out);
0149 
0150 /**
0151  * Encodes the given data using the base64 algorithm.
0152  *
0153  * The boolean argument determines if the encoded data is
0154  * going to be restricted to 76 characters or less per line
0155  * as specified by RFC 2045.  If @p insertLFs is true, then
0156  * there will be 76 characters or less per line.
0157  *
0158  * @param in         data to be encoded.
0159  * @param insertLFs  limit the number of characters per line.
0160  *
0161  * @return           base64 encoded string.
0162  * @since 5.5
0163  */
0164 KCODECS_EXPORT QByteArray base64Encode(QByteArrayView in);
0165 
0166 /**
0167  * Encodes the given data using the base64 algorithm.
0168  *
0169  * Use this function if you want the result of the encoding
0170  * to be placed in another array which cuts down the number
0171  * of copy operation that have to be performed in the process.
0172  * This is also the preferred method for encoding binary data.
0173  *
0174  * The boolean argument determines if the encoded data is going
0175  * to be restricted to 76 characters or less per line as specified
0176  * by RFC 2045.  If @p insertLFs is true, then there will be 76
0177  * characters or less per line.
0178  *
0179  * NOTE: the output array is first reset and then resized
0180  * appropriately before use, hence, all data stored in the
0181  * output array will be lost.
0182  *
0183  * @param in        data to be encoded.
0184  * @param out       encoded data.
0185  * @param insertLFs limit the number of characters per line.
0186  */
0187 KCODECS_EXPORT void base64Encode(QByteArrayView in, QByteArray &out, bool insertLFs = false);
0188 
0189 /**
0190  * Decodes the given data that was encoded using the
0191  * base64 algorithm.
0192  *
0193  * @param in   data to be decoded.
0194  * @return     decoded string.
0195  */
0196 KCODECS_EXPORT QByteArray base64Decode(QByteArrayView in);
0197 
0198 /**
0199  * Decodes the given data that was encoded with the base64
0200  * algorithm.
0201  *
0202  * Use this function if you want the result of the decoding
0203  * to be placed in another array which cuts down the number
0204  * of copy operation that have to be performed in the process.
0205  * This is also the preferred method for decoding an encoded
0206  * binary data.
0207  *
0208  * NOTE: the output array is first reset and then resized
0209  * appropriately before use, hence, all data stored in the
0210  * output array will be lost.
0211  *
0212  * @param in   data to be decoded.
0213  * @param out  decoded data.
0214  */
0215 KCODECS_EXPORT void base64Decode(QByteArrayView in, QByteArray &out);
0216 
0217 /**
0218  * Decodes string @p text according to RFC2047,
0219  * i.e., the construct =?charset?[qb]?encoded?=
0220  *
0221  * @param text source string
0222  * @returns the decoded string
0223  */
0224 KCODECS_EXPORT QString decodeRFC2047String(QStringView text);
0225 
0226 /**
0227  * Charset options for RFC2047 encoder
0228  * @since 5.5
0229  */
0230 enum CharsetOption {
0231     NoOption = 0, /// No special option
0232     ForceDefaultCharset = 1, /// Force use of the default charset
0233 };
0234 
0235 /**
0236  * Decodes string @p src according to RFC2047, i.e. the construct
0237  *  =?charset?[qb]?encoded?=
0238  *
0239  * @param src       source string.
0240  * @param usedCS    the name of any detected charset or, in case of multiple
0241  *                  different ones, "UTF-8" as that of a super charset is
0242  *                  returned here
0243  * @param defaultCS the charset to use in case the detected
0244  *                  one isn't known to us.
0245  * @param option    options for the encoder
0246  *
0247  * @return the decoded string.
0248  * @since 5.5
0249  */
0250 KCODECS_EXPORT QString decodeRFC2047String(QByteArrayView src, QByteArray *usedCS, const QByteArray &defaultCS = QByteArray(), CharsetOption option = NoOption);
0251 
0252 /**
0253  * Encodes string @p src according to RFC2047 using charset @p charset.
0254  *
0255  * This function also makes commas, quotes and other characters part of the encoded name, for example
0256  * the string "Jöhn Döe" <john@example.com"> would be encoded as <encoded word for "Jöhn Döe"> <john@example.com>,
0257  * i.e. the opening and closing quote mark would be part of the encoded word.
0258  * Therefore don't use this function for input strings that contain semantically meaningful characters,
0259  * like the quoting marks in this example.
0260  *
0261  * @param src           source string.
0262  * @param charset       charset to use. If it can't encode the string, UTF-8 will be used instead.
0263  * @return the encoded string.
0264  * @since 5.5
0265  */
0266 KCODECS_EXPORT QByteArray encodeRFC2047String(QStringView src, const QByteArray &charset);
0267 
0268 /**
0269  * Decodes the given data that was encoded using the
0270  * base45 codec.
0271  *
0272  * @param in   data to be decoded.
0273  * @return     decoded string.
0274  * @since 5.84
0275  * @see https://datatracker.ietf.org/doc/draft-faltstrom-base45/
0276  */
0277 KCODECS_EXPORT QByteArray base45Decode(QByteArrayView in);
0278 
0279 class Encoder;
0280 class EncoderPrivate;
0281 class Decoder;
0282 class DecoderPrivate;
0283 
0284 /**
0285   @class KCodecs::Codec kcodecs.h KCodecs
0286 
0287   @glossary @anchor MIME @anchor mime @b MIME:
0288   <b>Multipurpose Internet Mail Extensions</b> or @acronym MIME is an
0289   Internet Standard that extends the format of e-mail to support text in
0290   character sets other than US-ASCII, non-text attachments, multi-part message
0291   bodies, and header information in non-ASCII character sets. Virtually all
0292   human-written Internet e-mail and a fairly large proportion of automated
0293   e-mail is transmitted via @acronym SMTP in MIME format. Internet e-mail is
0294   so closely associated with the SMTP and MIME standards that it is sometimes
0295   called SMTP/MIME e-mail. The content types defined by MIME standards are
0296   also of growing importance outside of e-mail, such as in communication
0297   protocols like @acronym HTTP for the World Wide Web. MIME is also a
0298   fundamental component of communication protocols such as  HTTP, which
0299   requires that data be transmitted in the context of e-mail-like messages,
0300   even though the data may not actually be e-mail.
0301 
0302   @glossary @anchor codec @anchor codecs @anchor Codec @anchor Codecs @b codec:
0303   a program capable of performing encoding and decoding on a digital data
0304   stream. Codecs encode data for storage or encryption and decode it for
0305   viewing or editing.
0306 
0307   @glossary @anchor CRLF @b CRLF: a "Carriage Return (0x0D)" followed by a
0308   "Line Feed (0x0A)", two ASCII control characters used to represent a
0309   newline on some operating systems, notably DOS and Microsoft Windows.
0310 
0311   @glossary @anchor LF @b LF: a "Line Feed (0x0A)" ASCII control character used
0312   to represent a newline on some operating systems, notably Unix, Unix-like,
0313   and Linux.
0314 
0315   @brief An abstract base class of @ref codecs for common mail transfer encodings.
0316 
0317   Provides an abstract base class of @ref codecs like base64 and quoted-printable.
0318   Implemented as a singleton.
0319 
0320   @authors Marc Mutz \<mutz@kde.org\>
0321   @since 5.5
0322 */
0323 class KCODECS_EXPORT Codec
0324 {
0325 public:
0326     enum NewlineType {
0327         NewlineLF,
0328         NewlineCRLF,
0329     };
0330 
0331     /**
0332       Returns a codec associated with the specified @p name.
0333 
0334       @param name is a valid codec name.
0335     */
0336     static Codec *codecForName(QByteArrayView name);
0337 
0338     /**
0339       Computes the maximum size, in characters, needed for the encoding.
0340 
0341       @param insize is the number of input characters to be encoded.
0342       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0343 
0344       @return the maximum number of characters in the encoding.
0345     */
0346     virtual qsizetype maxEncodedSizeFor(qsizetype insize, NewlineType newline = NewlineLF) const = 0;
0347 
0348     /**
0349       Computes the maximum size, in characters, needed for the deccoding.
0350 
0351       @param insize is the number of input characters to be decoded.
0352       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0353 
0354       @return the maximum number of characters in the decoding.
0355     */
0356     virtual qsizetype maxDecodedSizeFor(qsizetype insize, NewlineType newline = NewlineLF) const = 0;
0357 
0358     /**
0359       Creates the encoder for the codec.
0360 
0361       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0362 
0363       @return a pointer to an instance of the codec's encoder.
0364     */
0365     virtual Encoder *makeEncoder(NewlineType newline = NewlineLF) const = 0;
0366 
0367     /**
0368       Creates the decoder for the codec.
0369 
0370       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0371 
0372       @return a pointer to an instance of the codec's decoder.
0373     */
0374     virtual Decoder *makeDecoder(NewlineType newline = NewlineLF) const = 0;
0375 
0376     /**
0377       Convenience wrapper that can be used for small chunks of data
0378       when you can provide a large enough buffer. The default
0379       implementation creates an Encoder and uses it.
0380 
0381       Encodes a chunk of bytes starting at @p scursor and extending to
0382       @p send into the buffer described by @p dcursor and @p dend.
0383 
0384       This function doesn't support chaining of blocks. The returned
0385       block cannot be added to, but you don't need to finalize it, too.
0386 
0387       Example usage (@p in contains the input data):
0388       <pre>
0389       KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
0390       if (!codec) {
0391           qFatal() << "no base64 codec found!?";
0392       }
0393       QByteArray out(in.size() * 1.4); // crude maximal size of b64 encoding
0394       QByteArray::Iterator iit = in.begin();
0395       QByteArray::Iterator oit = out.begin();
0396       if (!codec->encode(iit, in.end(), oit, out.end())) {
0397           qDebug() << "output buffer too small";
0398           return;
0399       }
0400       qDebug() << "Size of encoded data:" << oit - out.begin();
0401       </pre>
0402 
0403       @param scursor is a pointer to the start of the input buffer.
0404       @param send is a pointer to the end of the input buffer.
0405       @param dcursor is a pointer to the start of the output buffer.
0406       @param dend is a pointer to the end of the output buffer.
0407       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0408 
0409       @return false if the encoded data didn't fit into the output buffer;
0410       true otherwise.
0411     */
0412     virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const;
0413 
0414     /**
0415       Convenience wrapper that can be used for small chunks of data
0416       when you can provide a large enough buffer. The default
0417       implementation creates a Decoder and uses it.
0418 
0419       Decodes a chunk of bytes starting at @p scursor and extending to
0420       @p send into the buffer described by @p dcursor and @p dend.
0421 
0422       This function doesn't support chaining of blocks. The returned
0423       block cannot be added to, but you don't need to finalize it, too.
0424 
0425       Example usage (@p in contains the input data):
0426       <pre>
0427       KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
0428       if (!codec) {
0429           qFatal() << "no base64 codec found!?";
0430       }
0431       QByteArray out(in.size()); // good guess for any encoding...
0432       QByteArray::Iterator iit = in.begin();
0433       QByteArray::Iterator oit = out.begin();
0434       if (!codec->decode(iit, in.end(), oit, out.end())) {
0435           qDebug() << "output buffer too small";
0436           return;
0437       }
0438       qDebug() << "Size of decoded data:" << oit - out.begin();
0439       </pre>
0440 
0441       @param scursor is a pointer to the start of the input buffer.
0442       @param send is a pointer to the end of the input buffer.
0443       @param dcursor is a pointer to the start of the output buffer.
0444       @param dend is a pointer to the end of the output buffer.
0445       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0446 
0447       @return false if the decoded data didn't fit into the output buffer;
0448       true otherwise.
0449     */
0450     virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const;
0451 
0452     /**
0453       Even more convenient, but also a bit slower and more memory
0454       intensive, since it allocates storage for the worst case and then
0455       shrinks the result QByteArray to the actual size again.
0456 
0457       For use with small @p src.
0458 
0459       @param src is the data to encode.
0460       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0461     */
0462     QByteArray encode(QByteArrayView src, NewlineType newline = NewlineLF) const;
0463 
0464     /**
0465       Even more convenient, but also a bit slower and more memory
0466       intensive, since it allocates storage for the worst case and then
0467       shrinks the result QByteArray to the actual size again.
0468 
0469       For use with small @p src.
0470 
0471       @param src is the data to decode.
0472       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0473     */
0474     QByteArray decode(QByteArrayView src, NewlineType newline = NewlineLF) const;
0475 
0476     /**
0477       Returns the name of the encoding. Guaranteed to be lowercase.
0478     */
0479     virtual const char *name() const = 0;
0480 
0481     /**
0482       Destroys the codec.
0483     */
0484     virtual ~Codec()
0485     {
0486     }
0487 
0488 protected:
0489     /**
0490       Constructs the codec.
0491     */
0492     Codec()
0493     {
0494     }
0495 };
0496 
0497 /**
0498   @class KCodecs::Decoder kcodecs.h KCodecs
0499 
0500   @brief Stateful CTE decoder class
0501 
0502   Stateful decoder class, modelled after QTextDecoder.
0503 
0504   @section Overview
0505 
0506   KCodecs decoders are designed to be able to process encoded data in
0507   chunks of arbitrary size and to work with output buffers of also
0508   arbitrary size. They maintain any state necessary to go on where
0509   the previous call left off.
0510 
0511   The class consists of only two methods of interest: see decode,
0512   which decodes an input block and finalize, which flushes any
0513   remaining data to the output stream.
0514 
0515   Typically, you will create a decoder instance, call decode as
0516   often as necessary, then call finalize (most often a single
0517   call suffices, but it might be that during that call the output
0518   buffer is filled, so you should be prepared to call finalize
0519   as often as necessary, i.e. until it returns @p true).
0520 
0521   @section Return Values
0522 
0523   Both methods return @p true to indicate that they've finished their
0524   job. For decode, a return value of @p true means that the
0525   current input block has been finished (@p false most often means
0526   that the output buffer is full, but that isn't required
0527   behavior. The decode call is free to return at arbitrary
0528   times during processing).
0529 
0530   For finalize, a return value of @p true means that all data
0531   implicitly or explicitly stored in the decoder instance has been
0532   flushed to the output buffer. A @p false return value should be
0533   interpreted as "check if the output buffer is full and call me
0534   again", just as with decode.
0535 
0536   @section Usage Pattern
0537 
0538   Since the decoder maintains state, you can only use it once. After
0539   a sequence of input blocks has been processed, you finalize
0540   the output and then delete the decoder instance. If you want to
0541   process another input block sequence, you create a new instance.
0542 
0543   Typical usage (@p in contains the (base64-encoded) input data),
0544   taking into account all the conventions detailed above:
0545 
0546   <pre>
0547   KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
0548   if (!codec) {
0549       qFatal() << "No codec found for base64!";
0550   }
0551   KCodecs::Decoder *dec = codec->makeDecoder();
0552   Q_ASSERT(dec); // should not happen
0553   QByteArray out(256); // small buffer is enough ;-)
0554   QByteArray::Iterator iit = in.begin();
0555   QByteArray::Iterator oit = out.begin();
0556   // decode the chunk
0557   while (!dec->decode(iit, in.end(), oit, out.end()))
0558     if (oit == out.end()) { // output buffer full, process contents
0559       do_something_with(out);
0560       oit = out.begin();
0561     }
0562   // repeat while loop for each input block
0563   // ...
0564   // finish (flush remaining data from decoder):
0565   while (!dec->finish(oit, out.end()))
0566     if (oit == out.end()) { // output buffer full, process contents
0567       do_something_with(out);
0568       oit = out.begin();
0569     }
0570   // now process last chunk:
0571   out.resize(oit - out.begin());
0572   do_something_with(out);
0573   // _delete_ the decoder, but not the codec:
0574   delete dec;
0575   </pre>
0576 
0577   @since 5.5
0578 */
0579 class KCODECS_EXPORT Decoder
0580 {
0581 protected:
0582     friend class Codec;
0583     friend class DecoderPrivate;
0584 
0585     /**
0586       Protected constructor. Use KCodecs::Codec::makeDecoder to create an
0587       instance.
0588 
0589       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0590     */
0591     Decoder(Codec::NewlineType newline = Codec::NewlineLF);
0592 
0593 public:
0594     /**
0595       Destroys the decoder.
0596     */
0597     virtual ~Decoder();
0598 
0599     /**
0600       Decodes a chunk of data, maintaining state information between
0601       calls. See class decumentation for calling conventions.
0602 
0603       @param scursor is a pointer to the start of the input buffer.
0604       @param send is a pointer to the end of the input buffer.
0605       @param dcursor is a pointer to the start of the output buffer.
0606       @param dend is a pointer to the end of the output buffer.
0607     */
0608     virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0;
0609 
0610     /**
0611       Call this method to finalize the output stream. Writes all
0612       remaining data and resets the decoder. See KCodecs::Codec for
0613       calling conventions.
0614 
0615       @param dcursor is a pointer to the start of the output buffer.
0616       @param dend is a pointer to the end of the output buffer.
0617     */
0618     virtual bool finish(char *&dcursor, const char *const dend) = 0;
0619 
0620 protected:
0621     //@cond PRIVATE
0622     std::unique_ptr<DecoderPrivate> const d;
0623     //@endcond
0624 };
0625 
0626 /**
0627   @class KCodecs::Encoder kcodecs.h KCodecs
0628 
0629   @brief Stateful encoder class.
0630 
0631   Stateful encoder class, modeled after QTextEncoder.
0632 
0633   @since 5.5
0634 */
0635 class KCODECS_EXPORT Encoder
0636 {
0637 protected:
0638     friend class Codec;
0639     friend class EncoderPrivate;
0640 
0641     /**
0642       Protected constructor. Use KCodecs::Codec::makeEncoder if you want one.
0643 
0644       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0645     */
0646     explicit Encoder(Codec::NewlineType newline = Codec::NewlineLF);
0647 
0648 public:
0649     /**
0650       Destroys the encoder.
0651     */
0652     virtual ~Encoder();
0653 
0654     /**
0655       Encodes a chunk of data, maintaining state information between
0656       calls. See KCodecs::Codec for calling conventions.
0657 
0658       @param scursor is a pointer to the start of the input buffer.
0659       @param send is a pointer to the end of the input buffer.
0660       @param dcursor is a pointer to the start of the output buffer.
0661       @param dend is a pointer to the end of the output buffer.
0662     */
0663     virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0;
0664 
0665     /**
0666       Call this method to finalize the output stream. Writes all remaining
0667       data and resets the encoder. See KCodecs::Codec for calling conventions.
0668 
0669       @param dcursor is a pointer to the start of the output buffer.
0670       @param dend is a pointer to the end of the output buffer.
0671     */
0672     virtual bool finish(char *&dcursor, const char *const dend) = 0;
0673 
0674 protected:
0675     /**
0676       The maximum number of characters permitted in the output buffer.
0677     */
0678     enum {
0679         maxBufferedChars = 8, /**< Eight */
0680     };
0681 
0682     /**
0683       Writes character @p ch to the output stream or the output buffer,
0684       depending on whether or not the output stream has space left.
0685 
0686       @param ch is the character to write.
0687       @param dcursor is a pointer to the start of the output buffer.
0688       @param dend is a pointer to the end of the output buffer.
0689 
0690       @return true if written to the output stream; else false if buffered.
0691     */
0692     bool write(char ch, char *&dcursor, const char *const dend);
0693 
0694     /**
0695       Writes characters from the output buffer to the output stream.
0696       Implementations of encode and finish should call this
0697       at the very beginning and for each iteration of the while loop.
0698 
0699       @param dcursor is a pointer to the start of the output buffer.
0700       @param dend is a pointer to the end of the output buffer.
0701 
0702       @return true if all chars could be written, false otherwise
0703     */
0704     bool flushOutputBuffer(char *&dcursor, const char *const dend);
0705 
0706     /**
0707       Convenience function. Outputs @ref LF or @ref CRLF, based on the
0708       state of mWithCRLF.
0709 
0710       @param dcursor is a pointer to the start of the output buffer.
0711       @param dend is a pointer to the end of the output buffer.
0712     */
0713     bool writeCRLF(char *&dcursor, const char *const dend);
0714 
0715 protected:
0716     //@cond PRIVATE
0717     std::unique_ptr<EncoderPrivate> const d;
0718     //@endcond
0719 };
0720 
0721 } // namespace KCodecs
0722 
0723 #endif // KCODECS_H