1 #ifndef C4_FORMAT_BASE64_HPP_
2 #define C4_FORMAT_BASE64_HPP_
10 #include "c4/blob.hpp"
12 #ifndef C4_BASE64_HPP_
61 template<
class>
struct sfinae_true : std::true_type{};
62 template<
class T,
class A0>
static auto test_resize(
int) -> sfinae_true<decltype(std::declval<T>().resize(std::declval<A0>()))>;
63 template<
class,
class A0>
static auto test_resize(int64_t) -> std::false_type;
66 template<
class T,
class Arg=
size_t>
67 struct has_resize : decltype(detail::test_resize<typename std::remove_cv<typename std::remove_reference<typename std::remove_pointer<T>::type>::type>::type, Arg>(0)){};
69 template<
typename CharOrConstChar>
70 struct base64_wrapper_
72 blob_<CharOrConstChar> data;
73 size_t *required_size;
74 base64_wrapper_(blob_<CharOrConstChar> blob,
size_t *len_=
nullptr) noexcept
80 template<
class Container,
typename CharOrConstChar>
81 struct base64_container_wrapper_
83 using value_type =
typename Container::value_type;
85 size_t *required_size;
86 base64_container_wrapper_(Container *c,
size_t *len_=
nullptr) noexcept
90 blob_<CharOrConstChar> data() const noexcept
92 size_t sz = container->size();
93 CharOrConstChar *first = sz ?
reinterpret_cast<CharOrConstChar*
>(&(*container)[0]) :
nullptr;
94 return blob_<CharOrConstChar>(first,
sizeof(value_type) * sz);
109 template<
class Container>
112 template<
class Container>
141 C4_ALWAYS_INLINE
auto base64(T * arg,
size_t sz,
size_t *reqsize=
nullptr)
142 ->
typename std::conditional<std::is_const<typename std::remove_reference<typename std::remove_pointer<T>::type>::type>::value,
146 using U =
typename std::remove_reference<typename std::remove_pointer<T>::type>::type;
147 using ret_type =
typename std::conditional<std::is_const<U>::value,
150 using blob_type =
typename std::conditional<std::is_const<U>::value,
153 return ret_type(blob_type(arg, sz), reqsize);
159 C4_ALWAYS_INLINE
auto cbase64(T
const& arg,
size_t *reqsize=
nullptr)
160 ->
typename std::enable_if< ! detail::has_resize<T>::value, const_base64_wrapper>::type
166 C4_ALWAYS_INLINE
auto base64(T & arg,
size_t *reqsize=
nullptr)
167 ->
typename std::enable_if< ! detail::has_resize<T>::value,
168 typename std::conditional<std::is_const<typename std::remove_reference<typename std::remove_pointer<T>::type>::type>::value,
172 using U =
typename std::remove_reference<typename std::remove_pointer<T>::type>::type;
173 using ret_type =
typename std::conditional<std::is_const<U>::value,
176 using blob_type =
typename std::conditional<std::is_const<U>::value,
179 return ret_type(blob_type(arg), reqsize);
185 C4_ALWAYS_INLINE
auto cbase64(T
const& arg,
size_t *reqsize=
nullptr)
186 ->
typename std::enable_if<detail::has_resize<T>::value, const_base64_container_wrapper<T>>::type
188 return const_base64_container_wrapper<T>(&arg, reqsize);
195 C4_ALWAYS_INLINE
auto base64(T & arg,
size_t *reqsize=
nullptr)
196 ->
typename std::enable_if<detail::has_resize<T>::value,
197 typename std::conditional<std::is_const<typename std::remove_reference<typename std::remove_pointer<T>::type>::type>::value,
198 const_base64_container_wrapper<T>,
199 base64_container_wrapper<T>>::type>::type
201 using ret_type =
typename std::conditional<std::is_const<typename std::remove_reference<typename std::remove_pointer<T>::type>::type>::value,
202 const_base64_container_wrapper<T>,
203 base64_container_wrapper<T>>::type;
204 return ret_type(&arg, reqsize);
224 *b.required_size = reqsize;
237 template<
typename CharOrConstChar>
238 inline size_t to_chars(
substr buf, fmt::detail::base64_wrapper_<CharOrConstChar>
const& b)
242 *b.required_size = reqsize;
247 template<
class Container,
typename CharOrConstChar>
248 size_t to_chars(
substr buf, fmt::detail::base64_container_wrapper_<Container, CharOrConstChar>
const& b)
250 cblob data = b.data();
253 *b.required_size = reqsize;
264 blob data = b.data();
265 size_t required_size = 0;
268 *b.required_size = required_size;
271 else if(!ok && ((required_size < data.len) || (required_size % elm_sz)))
273 size_t num_elms = required_size / elm_sz;
274 b.container->resize(num_elms);
275 if(required_size > data.len)
280 *b.required_size = required_size;
detail::base64_wrapper_< byte > base64_wrapper
a tag type to mark a payload to be decoded as base64
encoding/decoding for base64.
C * str
a restricted pointer to the first character of the substring
bool from_chars(csubstr buf, uint8_t *v) noexcept
size_t len
the length of the substring
detail::base64_container_wrapper_< const Container, cbyte > const_base64_container_wrapper
a tag type to mark a payload as base64-encoded
detail::base64_wrapper_< cbyte > const_base64_wrapper
a tag type to mark a payload to be encoded as base64
size_t base64_encode(char *encoded, size_t encoded_sz, void const *data, size_t data_sz)
base64-encode binary data.
const_base64_wrapper base64(csubstr s, size_t *reqsize=nullptr)
a tag function to mark a csubstr payload to be encoded in base64 format
bool base64_decode(char const *encoded, size_t encoded_sz, void *data, size_t data_sz, size_t *data_sz_required)
decode the base64 encoding in the given buffer.
detail::base64_container_wrapper_< Container, byte > base64_container_wrapper
a tag type to mark a payload to be encoded as base64
const_base64_wrapper cbase64(csubstr s, size_t *reqsize=nullptr)
a tag function to mark a csubstr payload to be encoded in base64 format
size_t to_chars(substr buf, uint8_t v) noexcept