CMS 3D CMS Logo

Classes | Macros | Functions
base64.h File Reference
#include <cstddef>

Go to the source code of this file.

Classes

struct  base64_decode_context
 

Macros

#define base64_decode(in, inlen, out, outlen)   base64_decode_ctx(NULL, in, inlen, out, outlen)
 
#define base64_decode_alloc(in, inlen, out, outlen)   base64_decode_alloc_ctx(NULL, in, inlen, out, outlen)
 
#define BASE64_LENGTH(inlen)   ((((inlen) + 2) / 3) * 4)
 

Functions

bool base64_decode_alloc_ctx (struct base64_decode_context *ctx, const char *in, size_t inlen, char **out, size_t *outlen)
 
bool base64_decode_ctx (struct base64_decode_context *ctx, const char *in, size_t inlen, char *out, size_t *outlen)
 
void base64_decode_ctx_init (struct base64_decode_context *ctx)
 
void base64_encode (const char *in, size_t inlen, char *out, size_t outlen)
 
size_t base64_encode_alloc (const char *in, size_t inlen, char **out)
 
bool isbase64 (char ch)
 

Macro Definition Documentation

◆ base64_decode

#define base64_decode (   in,
  inlen,
  out,
  outlen 
)    base64_decode_ctx(NULL, in, inlen, out, outlen)

Definition at line 52 of file base64.h.

◆ base64_decode_alloc

#define base64_decode_alloc (   in,
  inlen,
  out,
  outlen 
)    base64_decode_alloc_ctx(NULL, in, inlen, out, outlen)

Definition at line 54 of file base64.h.

◆ BASE64_LENGTH

#define BASE64_LENGTH (   inlen)    ((((inlen) + 2) / 3) * 4)

Definition at line 31 of file base64.h.

Function Documentation

◆ base64_decode_alloc_ctx()

bool base64_decode_alloc_ctx ( struct base64_decode_context ctx,
const char *  in,
size_t  inlen,
char **  out,
size_t *  outlen 
)

Definition at line 452 of file base64.cc.

453  {
454  /* This may allocate a few bytes too many, depending on input,
455  but it's not worth the extra CPU time to compute the exact size.
456  The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
457  input ends with "=" and minus another 1 if the input ends with "==".
458  Dividing before multiplying avoids the possibility of overflow. */
459  size_t needlen = 3 * (inlen / 4) + 3;
460 
461  *out = static_cast<char *>(malloc(needlen));
462  if (!*out)
463  return true;
464 
465  if (!base64_decode_ctx(ctx, in, inlen, *out, &needlen)) {
466  free(*out);
467  *out = nullptr;
468  return false;
469  }
470 
471  if (outlen)
472  *outlen = needlen;
473 
474  return true;
475 }

References base64_decode_ctx(), recoMuon::in, and MillePedeFileConverter_cfg::out.

◆ base64_decode_ctx()

bool base64_decode_ctx ( struct base64_decode_context ctx,
const char *  in,
size_t  inlen,
char *  out,
size_t *  outlen 
)

Definition at line 372 of file base64.cc.

372  {
373  size_t outleft = *outlen;
374  bool ignore_newlines = ctx != nullptr;
375  bool flush_ctx = false;
376  unsigned int ctx_i = 0;
377 
378  if (ignore_newlines) {
379  ctx_i = ctx->i;
380  flush_ctx = inlen == 0;
381  }
382 
383  while (true) {
384  size_t outleft_save = outleft;
385  if (ctx_i == 0 && !flush_ctx) {
386  while (true) {
387  /* Save a copy of outleft, in case we need to re-parse this
388  block of four bytes. */
389  outleft_save = outleft;
390  if (!decode_4(in, inlen, &out, &outleft))
391  break;
392 
393  in += 4;
394  inlen -= 4;
395  }
396  }
397 
398  if (inlen == 0 && !flush_ctx)
399  break;
400 
401  /* Handle the common case of 72-byte wrapped lines.
402  This also handles any other multiple-of-4-byte wrapping. */
403  if (inlen && *in == '\n' && ignore_newlines) {
404  ++in;
405  --inlen;
406  continue;
407  }
408 
409  /* Restore OUT and OUTLEFT. */
410  out -= outleft_save - outleft;
411  outleft = outleft_save;
412 
413  {
414  char const *in_end = in + inlen;
415  char const *non_nl;
416 
417  if (ignore_newlines)
418  non_nl = get_4(ctx, &in, in_end, &inlen);
419  else
420  non_nl = in; /* Might have nl in this case. */
421 
422  /* If the input is empty or consists solely of newlines (0 non-newlines),
423  then we're done. Likewise if there are fewer than 4 bytes when not
424  flushing context and not treating newlines as garbage. */
425  if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines)) {
426  inlen = 0;
427  break;
428  }
429  if (!decode_4(non_nl, inlen, &out, &outleft))
430  break;
431 
432  inlen = in_end - in;
433  }
434  }
435 
436  *outlen -= outleft;
437 
438  return inlen == 0;
439 }

References decode_4(), get_4(), base64_decode_context::i, recoMuon::in, and MillePedeFileConverter_cfg::out.

Referenced by base64_decode_alloc_ctx().

◆ base64_decode_ctx_init()

void base64_decode_ctx_init ( struct base64_decode_context ctx)

Definition at line 246 of file base64.cc.

246 { ctx->i = 0; }

References base64_decode_context::i.

◆ base64_encode()

void base64_encode ( const char *  in,
size_t  inlen,
char *  out,
size_t  outlen 
)

Definition at line 65 of file base64.cc.

65  {
66  static const char *b64str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
67 
68  while (inlen && outlen) {
69  *out++ = b64str[(to_uchar(in[0]) >> 2) & 0x3f];
70  if (!--outlen)
71  break;
72  *out++ = b64str[((to_uchar(in[0]) << 4) + (--inlen ? to_uchar(in[1]) >> 4 : 0)) & 0x3f];
73  if (!--outlen)
74  break;
75  *out++ = (inlen ? b64str[((to_uchar(in[1]) << 2) + (--inlen ? to_uchar(in[2]) >> 6 : 0)) & 0x3f] : '=');
76  if (!--outlen)
77  break;
78  *out++ = inlen ? b64str[to_uchar(in[2]) & 0x3f] : '=';
79  if (!--outlen)
80  break;
81  if (inlen)
82  inlen--;
83  if (inlen)
84  in += 3;
85  }
86 
87  if (outlen)
88  *out = '\0';
89 }

References b64str, recoMuon::in, MillePedeFileConverter_cfg::out, and to_uchar().

Referenced by base64_encode_alloc().

◆ base64_encode_alloc()

size_t base64_encode_alloc ( const char *  in,
size_t  inlen,
char **  out 
)

Definition at line 100 of file base64.cc.

100  {
101  size_t outlen = 1 + BASE64_LENGTH(inlen);
102 
103  /* Check for overflow in outlen computation.
104  *
105  * If there is no overflow, outlen >= inlen.
106  *
107  * If the operation (inlen + 2) overflows then it yields at most +1, so
108  * outlen is 0.
109  *
110  * If the multiplication overflows, we lose at least half of the
111  * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
112  * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
113  * (inlen > 4).
114  */
115  if (inlen > outlen) {
116  *out = nullptr;
117  return 0;
118  }
119 
120  *out = static_cast<char *>(malloc(outlen));
121  if (!*out)
122  return outlen;
123 
124  base64_encode(in, inlen, *out, outlen);
125 
126  return outlen - 1;
127 }

References base64_encode(), BASE64_LENGTH, recoMuon::in, and MillePedeFileConverter_cfg::out.

Referenced by cond::auth::Cipher::b64encrypt().

◆ isbase64()

bool isbase64 ( char  ch)

Definition at line 243 of file base64.cc.

243 { return uchar_in_range(to_uchar(ch)) && 0 <= b64[to_uchar(ch)]; }

References b64, to_uchar(), and uchar_in_range.

Referenced by decode_4().

b64
static const signed char b64[0x100]
Definition: base64.cc:208
base64_encode
void base64_encode(const char *in, size_t inlen, char *out, size_t outlen)
Definition: base64.cc:65
BASE64_LENGTH
#define BASE64_LENGTH(inlen)
Definition: base64.h:31
to_uchar
static unsigned char to_uchar(char ch)
Definition: base64.cc:59
decode_4
static bool decode_4(char const *in, size_t inlen, char **outp, size_t *outleft)
Definition: base64.cc:302
recoMuon::in
Definition: RecoMuonEnumerators.h:6
base64_decode_ctx
bool base64_decode_ctx(struct base64_decode_context *ctx, const char *in, size_t inlen, char *out, size_t *outlen)
Definition: base64.cc:372
base64_decode_context::i
unsigned int i
Definition: base64.h:34
get_4
static char * get_4(struct base64_decode_context *ctx, char const **in, char const *in_end, size_t *n_non_newline)
Definition: base64.cc:255
MillePedeFileConverter_cfg.out
out
Definition: MillePedeFileConverter_cfg.py:31
b64str
static const char * b64str
Definition: DecodingKey.cc:18
uchar_in_range
#define uchar_in_range(c)
Definition: base64.cc:237