8#ifndef INCLUDED_BDLDE_BASE64ENCODER
9#define INCLUDED_BDLDE_BASE64ENCODER
474#include <bdlscm_version.h>
483#include <bsl_cstddef.h>
484#include <bsl_limits.h>
521 const int d_maxLineLength;
526 const char *
const d_alphabet_p;
529 const bool d_isPadded;
543 bsl::size_t lengthWithoutCrlfs(
const EncoderOptions&
options,
544 bsl::size_t inputLength);
554 template <
class OUTPUT_ITERATOR>
555 void append(OUTPUT_ITERATOR *out,
char character,
int maxLength);
564 template <
class OUTPUT_ITERATOR>
565 void encode(OUTPUT_ITERATOR *out,
int maxLength);
568 void setState(State newState);
577 bool isResidualOutput(
int numBytes)
const;
592 bsl::size_t inputLength);
605 "use overload with 'options'")
634 bsl::
size_t inputLength);
735 template <class OUTPUT_ITERATOR, class INPUT_ITERATOR>
736 int convert(OUTPUT_ITERATOR out,
737 INPUT_ITERATOR begin,
739 template <class OUTPUT_ITERATOR, class INPUT_ITERATOR>
740 int convert(OUTPUT_ITERATOR out,
743 INPUT_ITERATOR begin,
759 template <class OUTPUT_ITERATOR>
761 template <class OUTPUT_ITERATOR>
762 int endConvert(OUTPUT_ITERATOR out,
int *numOut,
int maxNumOut = -1);
823 bsl::
size_t inputLength)
825 static const bsl::size_t maxSize_t = bsl::numeric_limits<
829 if (0 == inputLength) {
833 const bsl::size_t numTripletsRoundedDown = (inputLength + 2) / 3 - 1;
834 const bsl::size_t numResidual = inputLength - numTripletsRoundedDown * 3;
842 BSLS_ASSERT(numTripletsRoundedDown <= (maxSize_t - pad) / 4);
844 return numTripletsRoundedDown * 4 + pad;
848template <
class OUTPUT_ITERATOR>
849void Base64Encoder::append(OUTPUT_ITERATOR *out,
855 if (d_maxLineLength && d_lineLength >= d_maxLineLength) {
856 if (d_lineLength == d_maxLineLength) {
861 if (d_outputLength == maxLength) {
869 if (d_outputLength == maxLength) {
879template <
class OUTPUT_ITERATOR>
880void Base64Encoder::encode(OUTPUT_ITERATOR *out,
int maxLength)
884 if (d_maxLineLength && d_lineLength >= d_maxLineLength) {
885 if (d_lineLength == d_maxLineLength) {
890 if (d_outputLength == maxLength) {
898 if (d_outputLength == maxLength) {
903 **out = d_alphabet_p[(d_stack >> d_bitsInStack) & 0x3f];
910void Base64Encoder::setState(State newState)
917bool Base64Encoder::isResidualOutput(
int numBytes)
const
922 if (d_maxLineLength) {
923 const int lineSize = d_maxLineLength + 2;
924 const int linesSoFar = numBytes / lineSize;
925 const int bytesSinceLastCrlf = numBytes - linesSoFar * lineSize;
926 const int partialCrlf = d_maxLineLength < bytesSinceLastCrlf;
927 const int nonCrlfBytes = linesSoFar * d_maxLineLength +
928 bytesSinceLastCrlf - partialCrlf;
930 return 0 != nonCrlfBytes % 4;
933 return 0 != numBytes % 4;
938Base64Encoder::State Base64Encoder::state()
const
946 bsl::size_t inputLength)
948 static const bsl::size_t maxSize_t = bsl::numeric_limits<
952 if (0 == inputLength) {
956 const bsl::size_t length = lengthWithoutCrlfs(
options, inputLength);
965 return length + 2 * numCrlfs;
991 bsl::size_t inputLength)
1020template <
class OUTPUT_ITERATOR,
class INPUT_ITERATOR>
1022 INPUT_ITERATOR begin,
1028 return convert(out, &dummyNumOut, &dummyNumIn, begin, end, -1);
1031template <
class OUTPUT_ITERATOR,
class INPUT_ITERATOR>
1035 INPUT_ITERATOR begin,
1041 numOut = &dummyNumOut;
1045 numIn = &dummyNumIn;
1048 if (e_ERROR_STATE == state() || e_DONE_STATE == state()) {
1049 setState(e_ERROR_STATE);
1055 const int initialLength = d_outputLength;
1056 const int maxLength = d_outputLength + maxNumOut;
1060 while (6 <= d_bitsInStack && d_outputLength != maxLength) {
1061 encode(&out, maxLength);
1068 while (4 >= d_bitsInStack && begin != end) {
1069 const unsigned char byte =
static_cast<unsigned char>(*begin);
1074 d_stack = (d_stack << 8) |
byte;
1077 if (d_outputLength != maxLength) {
1078 encode(&out, maxLength);
1079 if (6 <= d_bitsInStack && d_outputLength != maxLength) {
1080 encode(&out, maxLength);
1086 *numOut = d_outputLength - initialLength;
1091template <
class OUTPUT_ITERATOR>
1099template <
class OUTPUT_ITERATOR>
1106 if (e_ERROR_STATE == state() ||
isDone()) {
1107 setState(e_ERROR_STATE);
1112 const int initialLength = d_outputLength;
1113 const int maxLength = d_outputLength + maxNumOut;
1117 const int residualBits = d_bitsInStack % 6;
1119 const int shift = 6 - residualBits;
1120 d_stack = d_stack << shift;
1121 d_bitsInStack += shift;
1128 while (6 <= d_bitsInStack && d_outputLength != maxLength) {
1129 encode(&out, maxLength);
1134 if (0 == d_bitsInStack) {
1136 if (!d_isPadded || !isResidualOutput(d_outputLength)) {
1137 setState(e_DONE_STATE);
1142 if (d_outputLength == maxLength) {
1146 append(&out,
'=', maxLength);
1150 *numOut = d_outputLength - initialLength;
1158 setState(e_INITIAL_STATE);
1175 return e_ERROR_STATE != state();
1181 return e_DONE_STATE == state()
1183 && (!d_isPadded || !isResidualOutput(d_outputLength));
1189 return e_ERROR_STATE == state();
1195 return 0 == d_outputLength && e_INITIAL_STATE == state();
1207 return d_maxLineLength;
1222 return d_outputLength;
Definition bdlde_base64encoderoptions.h:310
static Base64EncoderOptions custom(int maxLineLength, Base64Alphabet::Enum alphabet, bool padded)
Definition bdlde_base64encoderoptions.h:485
bool isPadded() const
Return the value of the isPadded attribute.
Definition bdlde_base64encoderoptions.h:545
int maxLineLength() const
Return the value of the maxLineLength attribute.
Definition bdlde_base64encoderoptions.h:551
static Base64EncoderOptions mime()
Definition bdlde_base64encoderoptions.h:494
Definition bdlde_base64encoder.h:497
void resetState()
Definition bdlde_base64encoder.h:1156
static const Alphabet e_URL
Definition bdlde_base64encoder.h:508
int maxLineLength
Definition bdlde_base64encoder.h:625
static bsl::size_t encodedLength(const EncoderOptions &options, bsl::size_t inputLength)
Definition bdlde_base64encoder.h:945
static bsl::size_t encodedLines(const EncoderOptions &options, bsl::size_t inputLength)
Definition bdlde_base64encoder.h:990
int outputLength() const
Definition bdlde_base64encoder.h:1220
bool isInitialState() const
Definition bdlde_base64encoder.h:1193
static const Alphabet e_BASIC
Definition bdlde_base64encoder.h:507
int convert(OUTPUT_ITERATOR out, INPUT_ITERATOR begin, INPUT_ITERATOR end)
Definition bdlde_base64encoder.h:1021
bool isPadded() const
Definition bdlde_base64encoder.h:1199
int endConvert(OUTPUT_ITERATOR out)
Definition bdlde_base64encoder.h:1092
bool isError() const
Definition bdlde_base64encoder.h:1187
bool isAcceptable() const
Definition bdlde_base64encoder.h:1173
bool isDone() const
Definition bdlde_base64encoder.h:1179
EncoderOptions options() const
Definition bdlde_base64encoder.h:1211
Alphabet alphabet
Definition bdlde_base64encoder.h:707
BSLS_DEPRECATE_FEATURE("bdl", "encodedLength", "use overload with 'options'") static int encodedLength(int inputLength)
Base64Alphabet::Enum Alphabet
Definition bdlde_base64encoder.h:504
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:387
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlde_base64alphabet.h:118
Definition bdlat_valuetypefunctions.h:939
Enum
Definition bdlde_base64alphabet.h:137
@ e_URL
Definition bdlde_base64alphabet.h:139
@ e_BASIC
Definition bdlde_base64alphabet.h:138