On Thu, Mar 21, 2024 at 3:35 AM Rainer Deyke via Boost
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