123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #include <stdint.h>
- #include <stddef.h>
- #ifdef _OPENMP
- #include <omp.h>
- #endif
- #include "../include/libbase64.h"
- #include "tables/tables.h"
- #include "codecs.h"
- #include "env.h"
- // These static function pointers are initialized once when the library is
- // first used, and remain in use for the remaining lifetime of the program.
- // The idea being that CPU features don't change at runtime.
- static struct codec codec = { NULL, NULL };
- void
- base64_stream_encode_init (struct base64_state *state, int flags)
- {
- // If any of the codec flags are set, redo choice:
- if (codec.enc == NULL || flags & 0xFF) {
- codec_choose(&codec, flags);
- }
- state->eof = 0;
- state->bytes = 0;
- state->carry = 0;
- state->flags = flags;
- }
- void
- base64_stream_encode
- ( struct base64_state *state
- , const char *src
- , size_t srclen
- , char *out
- , size_t *outlen
- )
- {
- codec.enc(state, src, srclen, out, outlen);
- }
- void
- base64_stream_encode_final
- ( struct base64_state *state
- , char *out
- , size_t *outlen
- )
- {
- uint8_t *o = (uint8_t *)out;
- if (state->bytes == 1) {
- *o++ = base64_table_enc_6bit[state->carry];
- *o++ = '=';
- *o++ = '=';
- *outlen = 3;
- return;
- }
- if (state->bytes == 2) {
- *o++ = base64_table_enc_6bit[state->carry];
- *o++ = '=';
- *outlen = 2;
- return;
- }
- *outlen = 0;
- }
- void
- base64_stream_decode_init (struct base64_state *state, int flags)
- {
- // If any of the codec flags are set, redo choice:
- if (codec.dec == NULL || flags & 0xFFFF) {
- codec_choose(&codec, flags);
- }
- state->eof = 0;
- state->bytes = 0;
- state->carry = 0;
- state->flags = flags;
- }
- int
- base64_stream_decode
- ( struct base64_state *state
- , const char *src
- , size_t srclen
- , char *out
- , size_t *outlen
- )
- {
- return codec.dec(state, src, srclen, out, outlen);
- }
- #ifdef _OPENMP
- // Due to the overhead of initializing OpenMP and creating a team of
- // threads, we require the data length to be larger than a threshold:
- #define OMP_THRESHOLD 20000
- // Conditionally include OpenMP-accelerated codec implementations:
- #include "lib_openmp.c"
- #endif
- void
- base64_encode
- ( const char *src
- , size_t srclen
- , char *out
- , size_t *outlen
- , int flags
- )
- {
- size_t s;
- size_t t;
- struct base64_state state;
- #ifdef _OPENMP
- if (srclen >= OMP_THRESHOLD) {
- base64_encode_openmp(src, srclen, out, outlen, flags);
- return;
- }
- #endif
- // Init the stream reader:
- base64_stream_encode_init(&state, flags);
- // Feed the whole string to the stream reader:
- base64_stream_encode(&state, src, srclen, out, &s);
- // Finalize the stream by writing trailer if any:
- base64_stream_encode_final(&state, out + s, &t);
- // Final output length is stream length plus tail:
- *outlen = s + t;
- }
- int
- base64_decode
- ( const char *src
- , size_t srclen
- , char *out
- , size_t *outlen
- , int flags
- )
- {
- int ret;
- struct base64_state state;
- #ifdef _OPENMP
- if (srclen >= OMP_THRESHOLD) {
- return base64_decode_openmp(src, srclen, out, outlen, flags);
- }
- #endif
- // Init the stream reader:
- base64_stream_decode_init(&state, flags);
- // Feed the whole string to the stream reader:
- ret = base64_stream_decode(&state, src, srclen, out, outlen);
- // If when decoding a whole block, we're still waiting for input then fail:
- if (ret && (state.bytes == 0)) {
- return ret;
- }
- return 0;
- }
|