cencode.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. #ifdef _MSC_VER
  9. #pragma warning(push)
  10. #pragma warning(disable : 4244)
  11. #endif // _MSC_VER
  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. char base64_encode_value(char value_in)
  19. {
  20. static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  21. if (value_in > 63) return '=';
  22. return encoding[(int)value_in];
  23. }
  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. result = state_in->result;
  32. switch (state_in->step)
  33. {
  34. while (1)
  35. {
  36. case step_A:
  37. if (plainchar == plaintextend)
  38. {
  39. state_in->result = result;
  40. state_in->step = step_A;
  41. return (int)(codechar - code_out);
  42. }
  43. fragment = *plainchar++;
  44. result = (fragment & 0x0fc) >> 2;
  45. *codechar++ = base64_encode_value(result);
  46. result = (fragment & 0x003) << 4;
  47. case step_B:
  48. if (plainchar == plaintextend)
  49. {
  50. state_in->result = result;
  51. state_in->step = step_B;
  52. return (int)(codechar - code_out);
  53. }
  54. fragment = *plainchar++;
  55. result |= (fragment & 0x0f0) >> 4;
  56. *codechar++ = base64_encode_value(result);
  57. result = (fragment & 0x00f) << 2;
  58. case step_C:
  59. if (plainchar == plaintextend)
  60. {
  61. state_in->result = result;
  62. state_in->step = step_C;
  63. return (int)(codechar - code_out);
  64. }
  65. fragment = *plainchar++;
  66. result |= (fragment & 0x0c0) >> 6;
  67. *codechar++ = base64_encode_value(result);
  68. result = (fragment & 0x03f) >> 0;
  69. *codechar++ = base64_encode_value(result);
  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 (int)(codechar - code_out);
  80. }
  81. int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
  82. {
  83. char* codechar = code_out;
  84. switch (state_in->step)
  85. {
  86. case step_B:
  87. *codechar++ = base64_encode_value(state_in->result);
  88. *codechar++ = '=';
  89. *codechar++ = '=';
  90. break;
  91. case step_C:
  92. *codechar++ = base64_encode_value(state_in->result);
  93. *codechar++ = '=';
  94. break;
  95. case step_A:
  96. break;
  97. }
  98. *codechar++ = '\n';
  99. return (int)(codechar - code_out);
  100. }
  101. #ifdef _MSC_VER
  102. #pragma warning(pop)
  103. #endif // _MSC_VER