[32] | 1 | #include "stdafx.h" |
---|
| 2 | |
---|
| 3 | #include "encode.h" |
---|
| 4 | |
---|
| 5 | const int CHARS_PER_LINE = 950; |
---|
| 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 | |
---|