Basic usage

This section demonstrates the library’s most common usage.

It is sufficient for users wanting to encode and decode data with no particular constraints.

Encoding & decoding

Each codec exposes encode and decode functions.

Input parameters

Codecs share a common set of contraints on encode/decode input parameters. They can be one of the following:

  1. a meta::input_range (e.g. std::string, std::vector<unsigned char>)

  2. a pair of meta::input_iterator and meta::sentinel_for

  3. a char const[]

#include <mgs/base64.hpp>

#include <list>
#include <string>

using namespace mgs;

int main() {
  // 1. range
  std::string decoded_str("decoded text");
  std::string encoded_str("ZGVjb2RlZCB0ZXh0");
  std::list<char> encoded_list(encoded_str.begin(), encoded_str.end());
  std::list<char> decoded_list(decoded_str.begin(), decoded_str.end());

  auto encoded = base64::encode(decoded_str);
  auto decoded = base64::decode(encoded_list);
  // decltype(encoded) -> std::string
  // decltype(decoded) -> std::vector<unsigned char>

  // 2. iterator/sentinel pair
  encoded = base64::encode(decoded_list.begin(), decoded_list.end());
  decoded = base64::decode(encoded_list.begin(), encoded_list.end());

  // 3. char const[]
  encoded = base64::encode("decoded text");
}

Warning

Passing a char const[] to encode/decode will discard any input after the first encountered null terminator ('\0').

If you want to avoid this behavior, use the iterator/sentinel overload (2).

Return types

Each codec defines two default return types. One for encode, one for decode.

Both can be overriden:

#include <mgs/base64.hpp>

#include <list>
#include <vector>

using namespace mgs;

int main() {
  auto encoded = base64::encode("decoded text");
  auto decoded = base64::decode(encoded);

  // decltype(encoded) -> std::string
  // decltype(decoded) -> std::vector<unsigned char>

  auto encoded_vec = base64::encode<std::vector<char>>("decoded text");
  auto decoded_list = base64::decode<std::list<unsigned char>>(encoded_vec);
}

Currently all codecs use std::string as the default encoded output type, and std::vector<unsigned char> as the default decoded output type.

Tip

You can find the list of supported return types here.

If a type you wish to use is not supported by default, take a look here.

Laziness

encode and decode are overloaded functions, and thus cannot easily be used with STL algorithms (e.g. std::transform).

You can use their lazy counterparts (i.e. lazy_encode/lazy_decode) which return a function object than can be called with the same arguments as encode/decode.

#include <mgs/base64.hpp>

#include <algorithm>
#include <vector>

using namespace mgs;

int main() {
  std::vector<std::string> vec{"Hello", "world", "!"};
  std::vector<std::string> encoded_vec;

  std::transform(vec.begin(), vec.end(),
                 std::back_inserter(encoded_vec),
                 base64::lazy_encode());
}

Error handling

As of now, mgs reports errors with exceptions.

Every exception resides in the namespace mgs::errors.

Class

Derived from

Description

errors::exception

std::runtime_error

Base class for all exceptions

errors::decode_error

errors::exception

Base class for decoding exceptions

errors::invalid_input

errors::decode_error

Thrown on invalid encoded input

errors::unexpected_eof

errors::decode_error

Thrown when more input was expected

Note

I am well aware that using exceptions will put off users who disable them. I would like to support this use-case in future versions. Do not hesitate to give your feedback/ideas!

Predicting encoded/decoded size

Codecs also provide two methods to predict the to-be-transformed size:

#include <mgs/base64.hpp>

#include <cassert>

using namespace mgs;

int main() {
  auto const encoded_size = base64::encoded_size(42);
  auto const decoded_size = base64::max_decoded_size(encoded_size);
  assert(decoded_size == 42);

  // base64 is always padded to a multiple of 4 bytes
  auto const invalid_decoded_size = base64::max_decoded_size(3);
  assert(invalid_decoded_size == -1);
}