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/cencode.h"
9 
base64_init_encodestate(base64_encodestate * state_in)10 void base64_init_encodestate(base64_encodestate* state_in)
11 {
12 	state_in->step = step_A;
13 	state_in->result = 0;
14 	state_in->stepcount = 0;
15 }
16 
base64_encode_value(char value_in)17 char base64_encode_value(char value_in)
18 {
19 	static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
20 	if (value_in > 63) return '=';
21 	return encoding[(int)value_in];
22 }
23 
base64_encode_block(const char * plaintext_in,int length_in,char * code_out,base64_encodestate * state_in)24 int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
25 {
26 	const char* plainchar = plaintext_in;
27 	const char* const plaintextend = plaintext_in + length_in;
28 	char* codechar = code_out;
29 	char result;
30 	char fragment;
31 
32 	result = state_in->result;
33 
34 	switch (state_in->step)
35 	{
36 		while (1)
37 		{
38 	case step_A:
39 			if (plainchar == plaintextend)
40 			{
41 				state_in->result = result;
42 				state_in->step = step_A;
43 				return (int)(codechar - code_out);
44 			}
45 			fragment = *plainchar++;
46 			result = (fragment & 0x0fc) >> 2;
47 			*codechar++ = base64_encode_value(result);
48 			result = (fragment & 0x003) << 4;
49 			/* fall through */
50 
51 	case step_B:
52 			if (plainchar == plaintextend)
53 			{
54 				state_in->result = result;
55 				state_in->step = step_B;
56 				return (int)(codechar - code_out);
57 			}
58 			fragment = *plainchar++;
59 			result |= (fragment & 0x0f0) >> 4;
60 			*codechar++ = base64_encode_value(result);
61 			result = (fragment & 0x00f) << 2;
62 			/* fall through */
63 
64 	case step_C:
65 			if (plainchar == plaintextend)
66 			{
67 				state_in->result = result;
68 				state_in->step = step_C;
69 				return (int)(codechar - code_out);
70 			}
71 			fragment = *plainchar++;
72 			result |= (fragment & 0x0c0) >> 6;
73 			*codechar++ = base64_encode_value(result);
74 			result  = (fragment & 0x03f) >> 0;
75 			*codechar++ = base64_encode_value(result);
76 
77 			++(state_in->stepcount);
78 		}
79 	}
80 	/* control should not reach here */
81 	return (int)(codechar - code_out);
82 }
83 
base64_encode_blockend(char * code_out,base64_encodestate * state_in)84 int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
85 {
86 	char* codechar = code_out;
87 
88 	switch (state_in->step)
89 	{
90 	case step_B:
91 		*codechar++ = base64_encode_value(state_in->result);
92 		*codechar++ = '=';
93 		*codechar++ = '=';
94 		break;
95 	case step_C:
96 		*codechar++ = base64_encode_value(state_in->result);
97 		*codechar++ = '=';
98 		break;
99 	case step_A:
100 		break;
101 	}
102 	*codechar++ = '\n';
103 
104 	return (int)(codechar - code_out);
105 }
106 
107