Boost logo

Boost :

From: René Ferdinand Rivera Morell (grafikrobot_at_[hidden])
Date: 2024-03-21 13:43:43


On Thu, Mar 21, 2024 at 3:35 AM Rainer Deyke via Boost
<boost_at_[hidden]> wrote:
>
> On 19.03.24 19:16, René Ferdinand Rivera Morell via Boost wrote:
> > Yes, but.. I would like a library that handles various types of
> > encoding/decoding with the "same" interface. Encodings that come to
> > mind: base-64, url, html, radix-64, base-16, base-32, custom base-x
> > alphabet table, base-36, base-62, and so on.
>
> Depends on what you mean by "same" interface.

It certainly does. :-)

> I would expect separate
> functions for each encoding with different customization parameters.
> This does not require that the different encodings come from the same
> library; it just requires that they use the same API conventions. For
> example, this is good (in terms of parallelism, not necessarily in terms
> of the specifics of the API):
>
> result = base64_encode(source, base64_options::no_padding);
> result2 = base16_encode(source, base16_options::lower_case);

I wouldn't consider that good. Passable, sure. More..

> This is not so good, because it mixes the options of different
> encodings, resulting in potentially nonsensical combinations:
>
> result = baseX_encode<64>(source, encoding_options::no_padding);
> result2 = baseX_encode<16>(source, encoding_options::lower_case);
>
> // The lower_case option is non-sensical for base 64; can this
> // error be caught at compile time?
> // result3 = baseX_encode<64>(source, encoding_options::lower_case);

It can be caught at compile time. But not with that interface.

> This is just bad, because it sacrifices performance and type safety for
> the dubious flexibility of specifying encoding at runtime:
>
> result = baseX_encode(64, source, encoding_options::no_padding);
> result2 = baseX_encode(16, source, encoding_options::lower_case);

Yeah, as Adrey mentions, making this a runtime choice is sufficiently
rare that it's not worth even thinking about it. I certainly never had
a use for a runtime choice for that. As for a sane interface.. I would
think having encoder/decoder templates (perhaps as functors) is the
way to go. For example:

auto base64enc = boost::thing::base_encoder<64,
boost::thing::encoding_options::no_padding>();
auto encoded = base64enc.encode(data);
auto decoded = base64enc.decode(encoded);

This makes it possible to pass the encoder object to generic code
without worrying about calling some specific base64 or base16
functions. Having the template args also makes it possible to check
valid combinations. It also makes it easier to specialize performant
combinations and still cover everything else with not-so-performant
default implementation.

Note, don't take my saying that I would like more encoding coverage as
a requirement for acceptance of such a hypothetical library. Having a
couple to start would be good enough to be useful and address most API
design issues.

-- 
-- René Ferdinand Rivera Morell
-- Don't Assume Anything  -- No Supone Nada
-- Robot Dreams - http://robot-dreams.net

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk