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