cencode.c 2.6 KB

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