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