BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlde_quotedprintabledecoder.h
Go to the documentation of this file.
1/// @file bdlde_quotedprintabledecoder.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlde_quotedprintabledecoder.h -*-C++-*-
8#ifndef INCLUDED_BDLDE_QUOTEDPRINTABLEDECODER
9#define INCLUDED_BDLDE_QUOTEDPRINTABLEDECODER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlde_quotedprintabledecoder bdlde_quotedprintabledecoder
15/// @brief Provide automata converting to and from Quoted-Printable encodings.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlde
19/// @{
20/// @addtogroup bdlde_quotedprintabledecoder
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlde_quotedprintabledecoder-purpose"> Purpose</a>
25/// * <a href="#bdlde_quotedprintabledecoder-classes"> Classes </a>
26/// * <a href="#bdlde_quotedprintabledecoder-description"> Description </a>
27/// * <a href="#bdlde_quotedprintabledecoder-quoted-printable-decoding"> Quoted-Printable Decoding </a>
28/// * <a href="#bdlde_quotedprintabledecoder-usage"> Usage </a>
29/// * <a href="#bdlde_quotedprintabledecoder-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#bdlde_quotedprintabledecoder-purpose}
32/// Provide automata converting to and from Quoted-Printable encodings.
33///
34/// # Classes {#bdlde_quotedprintabledecoder-classes}
35///
36/// - bdlde::QuotedPrintableDecoder: automata for Quoted-Printable decoding
37///
38/// @see bdlde_quotedprintableencoder
39///
40/// # Description {#bdlde_quotedprintabledecoder-description}
41/// This component provides a template class (parameterized
42/// separately on both input and output iterators) that can be used to decode
43/// byte sequences of arbitrary length from the Quoted Printable representation
44/// described in Section 6.7 "Quoted-Printable Content Transfer Encoding" of RFC
45/// 2045, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of
46/// Internet Message Bodies."
47///
48/// Each instance of the decoder retains the state of the conversion from one
49/// supplied input to the next, enabling the processing of segmented input --
50/// i.e., processing resumes where it left off with the next invocation on new
51/// input. Instance methods are provided for the decoder to (1) assert the end
52/// of input, (2) determine whether the input so far is currently acceptable,
53/// and (3) indicate whether a non-recoverable error has occurred.
54///
55/// ## Quoted-Printable Decoding {#bdlde_quotedprintabledecoder-quoted-printable-decoding}
56///
57///
58/// (In the following, all rules mentioned refer to those listed in the encoder
59/// section above.)
60///
61/// The decoding process for this encoding scheme involves:
62///
63/// 1. transforming any encoded character triplets back into their original
64/// representation (rule #1 and rule #4).
65/// 2. literally writing out characters that have not been changed (rule #2).
66/// 3. deleting any trailing whitespace at the end of an encoded line (rule #3).
67///
68/// 4. removing the soft line breaks including the `=` prefix (i.e.,
69/// concatenating broken sentences) (rule #5).
70///
71/// The standard imposes a maximum of 76 characters exclusive of CRLF; however,
72/// the decoder implemented in this component will handle lines of arbitrary
73/// length.
74///
75/// The decoder also provides support for 2 error-reporting modes: the strict
76/// mode and the relaxed mode (configurable at construction). A strict-mode
77/// decoder stops decoding at the first offending character encountered, while a
78/// relaxed-mode decoder would continue decoding to the end of the input,
79/// allowing straight pass-through of character sets that cannot be interpreted.
80///
81/// The following kinds of errors can be encountered during decoding, listed in
82/// order of decreasing order of precedence:
83/// @code
84/// E1. BAD_DATA
85/// @endcode
86/// An `=` character is not followed by either two uppercase hexadecimal digits,
87/// or a soft line break -- e.g.,
88/// @code
89/// '=4=' (only one hexadecimal)
90/// '=K3' (K3 is not a hexadecimal number)
91/// '=1f' (lower case f is a literally encoded character)
92/// @endcode
93///
94/// Note that:
95///
96/// 1. In the relaxed error-reporting mode of this implementation, lowercase
97/// hexadecimal digits are treated as valid numerals.
98/// 2. E1 can be caused by a missing or corrupted numeric, a corrupted character
99/// disguised as an `=`, or an accidental insertion of a `=` that does not
100/// belong.
101/// 3. The case where a seemingly valid character is found in place of a missing
102/// numeric cannot be detected, e.g., `=4F` where `F` is actually a literally
103/// encoded character.
104/// 4. An erroneous occurrence of a `=` character preceding 2 seemingly valid
105/// hexadecimal numerics is also undetectable, e.g., `=4F` where `=` was
106/// actually a `t` corrupted during transmission.
107/// @code
108/// E2. BAD_LINEBREAK
109/// @endcode
110/// A '\r' is not followed by a '\n'. In the relaxed mode, each stand-alone
111/// '\r' or '\n' will be copied straight through to the output. For soft line
112/// breaks, whitespace is ignored between the `=` character and the CRLF as they
113/// are to be treated and removed as transport padding.
114/// @code
115/// E3. BAD_LINELENTH
116/// @endcode
117/// An encoded line exceeds the specified maximum line length with missing soft
118/// line breaks. (Because input of flexible line lengths is allowed in this
119/// implementation, this error is not detected or reported.)
120///
121/// In the relaxed-mode, errors of the types E1 and E2 would be copied straight
122/// to output and type E3 ignored. Decoded lines will be broken even when a
123/// bare CRLF is encountered in this mode. Users can still be alerted to the
124/// the unreported errors as offending characters are copied straight through to
125/// the output stream, which can be observed.
126///
127/// The `isError` method is used to detect the above anomalies, while for the
128/// `convert` method, a `numIn` output parameter (indicating the number of input
129/// characters consumed) or possibly the iterator itself (for iterators with
130/// reference-semantics) identifies the offending character.
131///
132/// ## Usage {#bdlde_quotedprintabledecoder-usage}
133///
134///
135/// This section illustrates intended use of this component.
136///
137/// ### Example 1: Basic Usage {#bdlde_quotedprintabledecoder-example-1-basic-usage}
138///
139///
140/// TBD
141/// @}
142/** @} */
143/** @} */
144
145/** @addtogroup bdl
146 * @{
147 */
148/** @addtogroup bdlde
149 * @{
150 */
151/** @addtogroup bdlde_quotedprintabledecoder
152 * @{
153 */
154
155#include <bdlscm_version.h>
156
157#include <bsl_cstring.h>
158#include <bsl_queue.h>
159#include <bsl_vector.h>
160
161
162namespace bdlde {
163
164/// This class implements a mechanism capable of converting data of
165/// arbitrary length from its corresponding Quoted-Printable representation.
166///
167/// See @ref bdlde_quotedprintabledecoder
169
170 // PRIVATE TYPES
171
172 /// Symbolic state values.
173 enum {
174 e_ERROR_STATE = -1, // input is irreparably invalid
175 e_INPUT_STATE = 0, // general input state
176 e_SAW_EQUAL_STATE = 1, // need two hexadecimal values or CR LF
177 e_SAW_WS_STATE = 2, // saw a whitespace
178 e_NEED_HEX_STATE = 3, // need one hexadecimal value
179 e_NEED_SOFT_LF_STATE = 4, // need soft new line
180 e_NEED_HARD_LF_STATE = 5, // need soft new line
181 e_DONE_STATE = 6 // any additional input is an error
182 };
183
184 public:
185
187 // This enumeration type enumerates the input equivalence classes.
188 // Separate enums are given to variants resulting from different modes
189 // of operation to eliminate an extra step of mode checking inside the
190 // main decoding loop.
191
192 // Regular character - copy straight to output
193 e_RC_ = 0, // strict mode
194 e_RC, // relaxed mode
195
196 // Hexadecimal digit - numeral only when preceded by
197 // '='; otherwise a regular character
198 e_HX_, // strict mode
199 e_HX, // relaxed mode
200
201 // '=' - wait for more input
202 e_EQ_, // strict mode
203 e_EQ, // relaxed mode
204
205 // Whitespace - buffer; wait for more input
206 e_WS_, // strict mode
207 e_WS, // relaxed mode
208
209 // Carriage return
210 e_CR_, // strict mode - wait for further input
211 e_CR, // relaxed mode - wait for further input
212
213 // Line Feed Strict mode
214 // ------------
215 e_LC_, // CRLF_MODE - decode to "\r\n" if preceded by
216 // '\r'; report error otherwise
217 e_LL_, // LF_MODE - decode to '\n' if preceded by
218 // '\r' report error otherwise Relaxed mode
219 // ------------
220 e_LC, // CRLF_MODE - decode to "\r\n" if preceded by
221 // '\r'; ignore otherwise
222 e_LL, // LF_MODE - decode to "\n" if preceded by
223 // '\r'; ignore otherwise
224
225 // Unrecognized char - halt and report error
226 e_UC_, // strict mode - Ignore and halt decoding
227 e_UC // relaxed mode - Ignore but continue decoding
228#ifndef BDE_OMIT_INTERNAL_DEPRECATED
245#endif // BDE_OMIT_INTERNAL_DEPRECATED
246 };
247
249 // Configuration governing how line breaks are decoded.
250
251 e_CRLF_MODE, // "\r\n" are decoded to "\r\n".
252 e_LF_MODE // "\r\n" are decoded to "\n".
253#ifndef BDE_OMIT_INTERNAL_DEPRECATED
256#endif // BDE_OMIT_INTERNAL_DEPRECATED
257 };
258
259 // CLASS DATA
260
261 /// Name of component used when reporting errors.
262 static const char s_componentName[];
263
264 /// Default error reporting mode
266
267 /// Default map of `unsigned char` to equivalence class for strict mode
268 static const char *s_defaultEquivClassStrict_p;
269
270 /// Default map of `unsigned char` to equivalence class for CRLF line
271 /// break mode
272 static const char *s_defaultEquivClassCRLF_p;
273
274 /// Character map used for converting an ASCII character to the
275 /// hexadecimal value it is representing.
276 static const unsigned char *const s_decodingMap_p;
277
278 static const int s_defaultMaxLineLength; // Default maximum line length
279 static const char* s_lineBreakModeName[]; // Names of line break mode
280
281 // INSTANCE DATA
282 bool d_unrecognizedIsErrorFlag; // If true, fail on "bad" characters
283 LineBreakMode d_lineBreakMode; // Line break mode
284 int d_state; // TBD doc
285 char d_buffer[90]; // TBD doc
286 int d_bufferLength; // TBD doc
287 char d_hexBuffer; // TBD doc
288 int d_outputLength; // Total number of output characters
289 char *d_equivClass_p; // Map of `unsigned char` to input equivalence class;
290 // dynamically allocated because there is no default
291 // complete configuration.
292
293 private:
294 // NOT IMPLEMENTED
297
298 public:
299 // CLASS METHODS
300
301 /// Return the ASCII string describing the specified `mode` governing
302 /// the decoding of hard linebreaks ("\r\n"). The behavior is undefined
303 /// unless `mode` is either e_CRLF_MODE or e_LF_MODE.
304 static const char* lineBreakModeToAscii(LineBreakMode mode);
305
306 // CREATORS
307
308 /// Create a Quoted-Printable decoder in the initial state, set to the
309 /// strict or relaxed error-reporting mode according to whether the
310 /// specified `detectError` flag is `true` or `false`, respectively, and
311 /// also configured to the specified `lineBreakMode`. The behavior is
312 /// undefined unless `lineBreakMode` is either e_CRLF_MODE or
313 /// e_LF_MODE. Note that the decoder reports errors in the strict
314 /// mode and output offending characters in the relaxed mode. Hard line
315 /// breaks ("\r\n") are decoded to "\r\n" in e_CRLF_MODE (default)
316 /// and to '\n' in e_LF_MODE.
317 explicit
319 bool detectError,
322
323 /// Destroy this object.
325
326 // MANIPULATORS
327
328 /// Append to the buffer addressed by the specified `out` all pending
329 /// output (if there is any) up to the optionally specified `maxNumOut`
330 /// limit (default is negative, meaning no limit) and, when there is no
331 /// pending output and `maxNumOut` is still not reached, begin to
332 /// consume and decode a sequence of input characters starting at the
333 /// specified `begin` position, up to but not including the specified
334 /// `end` position, writing any resulting output in the specified
335 /// `output` buffer up to the (cumulative) `maxNumOut` limit. If
336 /// `maxNumOut` limit is reached, no further input will be consumed.
337 /// Load into the specified `numOut` and `numIn` the number of output
338 /// bytes produced and input bytes consumed, respectively. Return a
339 /// non-negative value on success and a negative value otherwise. A
340 /// successful return status indicates the number of characters that
341 /// would be output if `endConvert` were called with no output limit
342 /// immediately upon exit from this method. These bytes are also
343 /// available for output if this method is called with a sufficiently
344 /// large `maxNumOut`. Note that calling this method after `endConvert`
345 /// has been invoked without an intervening `reset` call will place this
346 /// instance in an error state, and return an error status. Note also
347 /// that it is recommended that after all calls to `convert` are
348 /// finished, the `endConvert` method be called to complete the decoding
349 /// of any unprocessed input characters (e.g., whitespace).
350 int convert(char *out,
351 int *numOut,
352 int *numIn,
353 const char *begin,
354 const char *end,
355 int maxNumOut = -1);
356
357 /// Terminate encoding for this decoder; write any retained output
358 /// (e.g., from a previous call to `convert` with a non-zero `maxNumOut`
359 /// argument) to the specified `out` buffer. Optionally specify the
360 /// `maxNumOut` limit on the number of bytes to output; if `maxNumOut`
361 /// is negative, no limit is imposed. Load into the specified `numOut`
362 /// the number of output bytes produced. Return 0 on success with no
363 /// pending output, the positive number of bytes (if any) that would be
364 /// output if `endConvert` were called with no output limit immediately
365 /// upon exit from this method, and a negative value otherwise. Any
366 /// retained bytes are available on a subsequent call to `endConvert`.
367 /// Once this method is called, no additional input may be supplied
368 /// without an intervening call to `reset`; once this method returns a
369 /// zero status, a subsequent call will place this decoder in the error
370 /// state, and return an error status.
371 int endConvert(char *out, int *numOut, int maxNumOut = -1);
372
373 /// Reset this decoder to its initial state (i.e., as if no input had
374 /// been consumed).
375 void reset();
376
377 // ACCESSORS
378
379 /// Return `true` if the input read so far by this decoder is considered
380 /// syntactically complete and all resulting output has been emitted;
381 /// return `false` otherwise. Note that there must not be any
382 /// unprocessed characters accumulated in the input buffer of this
383 /// decoder.
384 bool isAccepting() const;
385
386 /// Return `true` if this decoder is in the done state (i.e.,
387 /// `endConvert` has been called and any additional input will result in
388 /// an error), and if there is no pending output; return `false`
389 /// otherwise.
390 bool isDone() const;
391
392 /// Return `true` if this decoder has encountered an irrecoverable error
393 /// and `false` otherwise. An irrecoverable error is one for which
394 /// there is no subsequent possibility of achieving an "acceptable"
395 /// result (as defined by the `isAccepting` method).
396 bool isError() const;
397
398 /// Return `true` if this decoder is in the initial state (i.e., as if
399 /// no input had been consumed) and `false` otherwise.
400 bool isInitialState() const;
401
402 /// Return `true` if the input to this decoder is maximal (i.e., the
403 /// input contains an end-of-input sentinel, signaling that no further
404 /// input should be expected). *Always* returns `false` for
405 /// Quoted-Printable decoders since the encoding scheme does not specify
406 /// an end-of-input sentinel.
407 bool isMaximal() const;
408
409 /// Return `true` if this decoder is currently configured to detect an
410 /// error when an unrecognizable encoding is encountered, and `false`
411 /// otherwise.
412 bool isUnrecognizedAnError() const;
413
414 /// Return the line break mode specified for this decoder.
416
417 /// Return the number of output bytes retained by this decoder and not
418 /// emitted because `maxNumOut` has been reached.
419 int numOutputPending() const;
420
421 /// Return the total length of the output emitted by this decoder
422 /// (possibly after several calls to the `convert` or the `input`
423 /// methods) since its initial construction or the latest `reset`.
424 int outputLength() const;
425};
426
427// ============================================================================
428// INLINE DEFINITIONS
429// ============================================================================
430
431// CLASS METHODS
432inline
434 LineBreakMode mode)
435{
436 return s_lineBreakModeName[mode];
437}
438
439// CREATORS
440inline
441QuotedPrintableDecoder::QuotedPrintableDecoder(
442 bool unrecognizedIsErrorFlag,
444: d_unrecognizedIsErrorFlag(unrecognizedIsErrorFlag)
445, d_lineBreakMode(lineBreakMode)
446, d_state(e_INPUT_STATE)
447, d_bufferLength(0)
448, d_outputLength(0)
449{
450 if (unrecognizedIsErrorFlag) {
451 // Strict mode
452 d_equivClass_p = const_cast<char*>(s_defaultEquivClassStrict_p);
453 }
454 else {
455 if (lineBreakMode == e_CRLF_MODE) {
456 d_equivClass_p = const_cast<char*>(s_defaultEquivClassCRLF_p);
457 }
458 else {
459 // First copy the map of equivalence classes for the
460 // e_CRLF_MODE to the strict error-report mode.
461
462 int len = sizeof(*s_defaultEquivClassCRLF_p) * 256;
463 d_equivClass_p = new char[len];
464 bsl::memcpy(d_equivClass_p, s_defaultEquivClassCRLF_p, len);
465 d_equivClass_p['\n'] = e_LL; // output '\n' instead if preceded
466 // by '='.
467 }
468 }
469}
470
471// MANIPULATORS
472inline
474{
475 d_state = e_INPUT_STATE;
476 d_outputLength = 0;
477 d_bufferLength = 0;
478}
479
480// ACCESSORS
481inline
483{
484 return e_INPUT_STATE == d_state || e_DONE_STATE == d_state;
485}
486
487inline
489{
490 return e_DONE_STATE == d_state && 0 == d_bufferLength;
491}
492
493inline
495{
496 return e_ERROR_STATE == d_state;
497}
498
499inline
501{
502 return e_INPUT_STATE == d_state && 0 == d_outputLength;
503}
504
505inline
507{
508 return false;
509}
510
511inline
516
517inline
523
524inline
529
530inline
532{
533 return d_outputLength;
534}
535
536} // close package namespace
537
538
539#endif
540
541// ----------------------------------------------------------------------------
542// Copyright 2015 Bloomberg Finance L.P.
543//
544// Licensed under the Apache License, Version 2.0 (the "License");
545// you may not use this file except in compliance with the License.
546// You may obtain a copy of the License at
547//
548// http://www.apache.org/licenses/LICENSE-2.0
549//
550// Unless required by applicable law or agreed to in writing, software
551// distributed under the License is distributed on an "AS IS" BASIS,
552// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
553// See the License for the specific language governing permissions and
554// limitations under the License.
555// ----------------------------- END-OF-FILE ----------------------------------
556
557/** @} */
558/** @} */
559/** @} */
Definition bdlde_quotedprintabledecoder.h:168
int d_bufferLength
Definition bdlde_quotedprintabledecoder.h:286
static const char s_componentName[]
Name of component used when reporting errors.
Definition bdlde_quotedprintabledecoder.h:262
static const char * s_defaultEquivClassStrict_p
Default map of unsigned char to equivalence class for strict mode.
Definition bdlde_quotedprintabledecoder.h:268
int endConvert(char *out, int *numOut, int maxNumOut=-1)
bool isMaximal() const
Definition bdlde_quotedprintabledecoder.h:506
int convert(char *out, int *numOut, int *numIn, const char *begin, const char *end, int maxNumOut=-1)
static const char * s_defaultEquivClassCRLF_p
Definition bdlde_quotedprintabledecoder.h:272
static const char * lineBreakModeToAscii(LineBreakMode mode)
Definition bdlde_quotedprintabledecoder.h:433
LineBreakMode lineBreakMode() const
Return the line break mode specified for this decoder.
Definition bdlde_quotedprintabledecoder.h:519
int numOutputPending() const
Definition bdlde_quotedprintabledecoder.h:525
char d_hexBuffer
Definition bdlde_quotedprintabledecoder.h:287
bool isInitialState() const
Definition bdlde_quotedprintabledecoder.h:500
LineBreakMode d_lineBreakMode
Definition bdlde_quotedprintabledecoder.h:283
static const int s_defaultMaxLineLength
Definition bdlde_quotedprintabledecoder.h:278
char * d_equivClass_p
Definition bdlde_quotedprintabledecoder.h:289
void reset()
Definition bdlde_quotedprintabledecoder.h:473
int d_state
Definition bdlde_quotedprintabledecoder.h:284
static const unsigned char *const s_decodingMap_p
Definition bdlde_quotedprintabledecoder.h:276
static const bool s_defaultUnrecognizedIsErrorFlag
Default error reporting mode.
Definition bdlde_quotedprintabledecoder.h:265
EquivalenceClasses
Definition bdlde_quotedprintabledecoder.h:186
@ e_UC_
Definition bdlde_quotedprintabledecoder.h:226
@ e_HX_
Definition bdlde_quotedprintabledecoder.h:198
@ BDEDE_CR
Definition bdlde_quotedprintabledecoder.h:238
@ e_RC
Definition bdlde_quotedprintabledecoder.h:194
@ BDEDE_LC_
Definition bdlde_quotedprintabledecoder.h:239
@ e_LC
Definition bdlde_quotedprintabledecoder.h:220
@ BDEDE_WS
Definition bdlde_quotedprintabledecoder.h:236
@ e_CR
Definition bdlde_quotedprintabledecoder.h:211
@ e_WS
Definition bdlde_quotedprintabledecoder.h:207
@ BDEDE_UC
Definition bdlde_quotedprintabledecoder.h:244
@ BDEDE_CR_
Definition bdlde_quotedprintabledecoder.h:237
@ e_WS_
Definition bdlde_quotedprintabledecoder.h:206
@ BDEDE_LL_
Definition bdlde_quotedprintabledecoder.h:240
@ e_CR_
Definition bdlde_quotedprintabledecoder.h:210
@ e_EQ_
Definition bdlde_quotedprintabledecoder.h:202
@ e_LL_
Definition bdlde_quotedprintabledecoder.h:217
@ BDEDE_RC_
Definition bdlde_quotedprintabledecoder.h:229
@ e_HX
Definition bdlde_quotedprintabledecoder.h:199
@ BDEDE_WS_
Definition bdlde_quotedprintabledecoder.h:235
@ BDEDE_LL
Definition bdlde_quotedprintabledecoder.h:242
@ BDEDE_LC
Definition bdlde_quotedprintabledecoder.h:241
@ e_LL
Definition bdlde_quotedprintabledecoder.h:222
@ e_RC_
Definition bdlde_quotedprintabledecoder.h:193
@ BDEDE_UC_
Definition bdlde_quotedprintabledecoder.h:243
@ BDEDE_HX
Definition bdlde_quotedprintabledecoder.h:232
@ BDEDE_HX_
Definition bdlde_quotedprintabledecoder.h:231
@ BDEDE_RC
Definition bdlde_quotedprintabledecoder.h:230
@ e_UC
Definition bdlde_quotedprintabledecoder.h:227
@ BDEDE_EQ
Definition bdlde_quotedprintabledecoder.h:234
@ BDEDE_EQ_
Definition bdlde_quotedprintabledecoder.h:233
@ e_EQ
Definition bdlde_quotedprintabledecoder.h:203
@ e_LC_
Definition bdlde_quotedprintabledecoder.h:215
bool isUnrecognizedAnError() const
Definition bdlde_quotedprintabledecoder.h:512
int d_outputLength
Definition bdlde_quotedprintabledecoder.h:288
~QuotedPrintableDecoder()
Destroy this object.
static const char * s_lineBreakModeName[]
Definition bdlde_quotedprintabledecoder.h:279
bool isError() const
Definition bdlde_quotedprintabledecoder.h:494
bool d_unrecognizedIsErrorFlag
Definition bdlde_quotedprintabledecoder.h:282
int outputLength() const
Definition bdlde_quotedprintabledecoder.h:531
bool isDone() const
Definition bdlde_quotedprintabledecoder.h:488
bool isAccepting() const
Definition bdlde_quotedprintabledecoder.h:482
LineBreakMode
Definition bdlde_quotedprintabledecoder.h:248
@ e_LF_MODE
Definition bdlde_quotedprintabledecoder.h:252
@ BDEDE_CRLF_MODE
Definition bdlde_quotedprintabledecoder.h:254
@ e_CRLF_MODE
Definition bdlde_quotedprintabledecoder.h:251
@ BDEDE_LF_MODE
Definition bdlde_quotedprintabledecoder.h:255
char d_buffer[90]
Definition bdlde_quotedprintabledecoder.h:285
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlde_base64alphabet.h:118