1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/*
* adapted from libb64 by CB
*/
/*
cencoder.c - c source to a base64 encoding algorithm implementation
This is part of the libb64 project, and has been placed in the public domain.
For details, see http://sourceforge.net/projects/libb64
*/
#include "libb64.h"
const int CHARS_PER_LINE = 72;
static inline char
base64_encode_value (char value_in)
{
static const char *encoding =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
return value_in > 63 ? '=' : encoding[(int) value_in];
}
void
base64_init_encodestate (base64_encodestate * state_in)
{
state_in->step = step_A;
state_in->result = 0;
state_in->stepcount = 0;
}
size_t
base64_encode_block (const char *plaintext_in, size_t length_in,
char *code_out, base64_encodestate * state_in)
{
/*@unused@ */
const char *plainchar = plaintext_in;
/*@unused@ */
const char *const plaintextend = plaintext_in + length_in;
char *codechar = code_out;
char result;
/*@unused@ */
char fragment;
result = state_in->result;
switch (state_in->step) {
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
while (1) {
case step_A:
if (plainchar == plaintextend) {
state_in->result = result;
state_in->step = step_A;
return (size_t) (codechar - code_out);
}
fragment = *plainchar++;
result = (char) ((fragment & 0x0fc) >> 2);
*codechar++ = base64_encode_value (result);
result = (char) ((fragment & 0x003) << 4);
case step_B:
if (plainchar == plaintextend) {
state_in->result = result;
state_in->step = step_B;
return (size_t) (codechar - code_out);
}
fragment = *plainchar++;
result = (char) (result | ((fragment & 0x0f0) >> 4));
*codechar++ = base64_encode_value (result);
result = (char) ((fragment & 0x00f) << 2);
case step_C:
if (plainchar == plaintextend) {
state_in->result = result;
state_in->step = step_C;
return (size_t) (codechar - code_out);
}
fragment = *plainchar++;
result = (char) (result | ((fragment & 0x0c0) >> 6));
*codechar++ = base64_encode_value (result);
result = (char) ((fragment & 0x03f) >> 0);
*codechar++ = base64_encode_value (result);
++(state_in->stepcount);
/* CB: disable wrapping by default */
#ifdef SC_BASE64_WRAP
if (state_in->stepcount == CHARS_PER_LINE / 4) {
*codechar++ = '\n';
state_in->stepcount = 0;
}
#endif
}
}
/* control should not reach here */
return (size_t) (codechar - code_out);
}
size_t
base64_encode_blockend (char *code_out, base64_encodestate * state_in)
{
char *codechar = code_out;
switch (state_in->step) {
case step_B:
*codechar++ = base64_encode_value (state_in->result);
*codechar++ = '=';
*codechar++ = '=';
break;
case step_C:
*codechar++ = base64_encode_value (state_in->result);
*codechar++ = '=';
break;
case step_A:
break;
}
/* CB: remove final newline by default */
#ifdef SC_BASE64_WRAP
*codechar++ = '\n';
#endif
return (size_t) (codechar - code_out);
}
|