00001
00002
00003
00004
00005
00006
00007
00008 #include <b64/cencode.h>
00009
00010 const int CHARS_PER_LINE = 72;
00011
00012 void base64_init_encodestate(base64_encodestate* state_in)
00013 {
00014 state_in->step = step_A;
00015 state_in->result = 0;
00016 state_in->stepcount = 0;
00017 }
00018
00019 char base64_encode_value(char value_in)
00020 {
00021 static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00022 if (value_in > 63) return '=';
00023 return encoding[(int)value_in];
00024 }
00025
00026 int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
00027 {
00028 const char* plainchar = plaintext_in;
00029 const char* const plaintextend = plaintext_in + length_in;
00030 char* codechar = code_out;
00031 char result;
00032 char fragment;
00033
00034 result = state_in->result;
00035
00036 switch (state_in->step)
00037 {
00038 while (1)
00039 {
00040 case step_A:
00041 if (plainchar == plaintextend)
00042 {
00043 state_in->result = result;
00044 state_in->step = step_A;
00045 return codechar - code_out;
00046 }
00047 fragment = *plainchar++;
00048 result = (fragment & 0x0fc) >> 2;
00049 *codechar++ = base64_encode_value(result);
00050 result = (fragment & 0x003) << 4;
00051 case step_B:
00052 if (plainchar == plaintextend)
00053 {
00054 state_in->result = result;
00055 state_in->step = step_B;
00056 return codechar - code_out;
00057 }
00058 fragment = *plainchar++;
00059 result |= (fragment & 0x0f0) >> 4;
00060 *codechar++ = base64_encode_value(result);
00061 result = (fragment & 0x00f) << 2;
00062 case step_C:
00063 if (plainchar == plaintextend)
00064 {
00065 state_in->result = result;
00066 state_in->step = step_C;
00067 return codechar - code_out;
00068 }
00069 fragment = *plainchar++;
00070 result |= (fragment & 0x0c0) >> 6;
00071 *codechar++ = base64_encode_value(result);
00072 result = (fragment & 0x03f) >> 0;
00073 *codechar++ = base64_encode_value(result);
00074
00075 ++(state_in->stepcount);
00076 if (state_in->stepcount == CHARS_PER_LINE/4)
00077 {
00078 *codechar++ = '\n';
00079 state_in->stepcount = 0;
00080 }
00081 }
00082 }
00083
00084 return codechar - code_out;
00085 }
00086
00087 int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
00088 {
00089 char* codechar = code_out;
00090
00091 switch (state_in->step)
00092 {
00093 case step_B:
00094 *codechar++ = base64_encode_value(state_in->result);
00095 *codechar++ = '=';
00096 *codechar++ = '=';
00097 break;
00098 case step_C:
00099 *codechar++ = base64_encode_value(state_in->result);
00100 *codechar++ = '=';
00101 break;
00102 case step_A:
00103 break;
00104 }
00105 *codechar++ = '\n';
00106
00107 return codechar - code_out;
00108 }
00109