base64.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /* Based on code from Dave Winer (http://www.scripting.com/midas/base64/) */
  2. #include "precomp_wasabi_bfc.h"
  3. #include "base64.h"
  4. char Base64::encodingTable [64] = {
  5. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
  6. 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
  7. 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
  8. 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
  9. };
  10. int Base64::encode(MemBlock<char> &htext, MemBlock<char> &h64, int linelength) {
  11. /*
  12. encode the handle. some funny stuff about linelength -- it only makes
  13. sense to make it a multiple of 4. if it's not a multiple of 4, we make it
  14. so (by only checking it every 4 characters.
  15. further, if it's 0, we don't add any line breaks at all.
  16. */
  17. unsigned long ixtext;
  18. unsigned long lentext;
  19. unsigned long origsize;
  20. long ctremaining;
  21. unsigned char inbuf [3] = {0}, outbuf [4] = {0};
  22. short i;
  23. short charsonline = 0, ctcopy;
  24. ixtext = 0;
  25. lentext = htext.getSize();
  26. while (1) {
  27. ctremaining = lentext - ixtext;
  28. if (ctremaining <= 0)
  29. break;
  30. for (i = 0; i < 3; i++) {
  31. unsigned long ix = ixtext + i;
  32. if (ix < lentext)
  33. inbuf [i] = *htext.getMemory(ix);
  34. else
  35. inbuf [i] = 0;
  36. }
  37. outbuf [0] = (inbuf [0] & 0xFC) >> 2;
  38. outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
  39. outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
  40. outbuf [3] = inbuf [2] & 0x3F;
  41. origsize = h64.getSize();
  42. h64.setSize(origsize + 4);
  43. ctcopy = 4;
  44. switch (ctremaining) {
  45. case 1:
  46. ctcopy = 2;
  47. break;
  48. case 2:
  49. ctcopy = 3;
  50. break;
  51. }
  52. for (i = 0; i < ctcopy; i++)
  53. *h64.getMemory(origsize + i) = encodingTable[outbuf[i]];
  54. for (i = ctcopy; i < 4; i++)
  55. *h64.getMemory(origsize + i) = '=';
  56. ixtext += 3;
  57. charsonline += 4;
  58. if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/
  59. if (charsonline >= linelength) {
  60. charsonline = 0;
  61. origsize = h64.getSize();
  62. h64.setSize(origsize + 1);
  63. *h64.getMemory() = '\n';
  64. }
  65. }
  66. }
  67. return 1;
  68. }
  69. int Base64::encode(MemBlock<char> &htext, MemBlock<wchar_t> &h64, int linelength) {
  70. /*
  71. encode the handle. some funny stuff about linelength -- it only makes
  72. sense to make it a multiple of 4. if it's not a multiple of 4, we make it
  73. so (by only checking it every 4 characters.
  74. further, if it's 0, we don't add any line breaks at all.
  75. */
  76. unsigned long ixtext;
  77. unsigned long lentext;
  78. unsigned long origsize;
  79. long ctremaining;
  80. unsigned char inbuf [3] = {0}, outbuf [4] = {0};
  81. short i;
  82. short charsonline = 0, ctcopy;
  83. ixtext = 0;
  84. lentext = htext.getSize();
  85. while (1) {
  86. ctremaining = lentext - ixtext;
  87. if (ctremaining <= 0)
  88. break;
  89. for (i = 0; i < 3; i++) {
  90. unsigned long ix = ixtext + i;
  91. if (ix < lentext)
  92. inbuf [i] = *htext.getMemory(ix);
  93. else
  94. inbuf [i] = 0;
  95. }
  96. outbuf [0] = (inbuf [0] & 0xFC) >> 2;
  97. outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
  98. outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
  99. outbuf [3] = inbuf [2] & 0x3F;
  100. origsize = h64.getSize();
  101. h64.setSize(origsize + 4);
  102. ctcopy = 4;
  103. switch (ctremaining) {
  104. case 1:
  105. ctcopy = 2;
  106. break;
  107. case 2:
  108. ctcopy = 3;
  109. break;
  110. }
  111. for (i = 0; i < ctcopy; i++)
  112. *h64.getMemory(origsize + i) = encodingTable[outbuf[i]];
  113. for (i = ctcopy; i < 4; i++)
  114. *h64.getMemory(origsize + i) = '=';
  115. ixtext += 3;
  116. charsonline += 4;
  117. if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/
  118. if (charsonline >= linelength) {
  119. charsonline = 0;
  120. origsize = h64.getSize();
  121. h64.setSize(origsize + 1);
  122. *h64.getMemory() = '\n';
  123. }
  124. }
  125. }
  126. return 1;
  127. }
  128. int Base64::decode(MemBlock<char> &h64, MemBlock<char> &htext) {
  129. unsigned long ixtext;
  130. unsigned long lentext;
  131. unsigned long origsize;
  132. unsigned char ch;
  133. unsigned char inbuf [4] = {0}, outbuf [4] = {0};
  134. short i, ixinbuf;
  135. boolean flignore;
  136. boolean flendtext = false;
  137. ixtext = 0;
  138. lentext = h64.getSize();
  139. ixinbuf = 0;
  140. while (true) {
  141. if (ixtext >= lentext)
  142. break;
  143. ch = *h64.getMemory(ixtext++);
  144. flignore = 0;
  145. if ((ch >= 'A') && (ch <= 'Z'))
  146. ch = ch - 'A';
  147. else if ((ch >= 'a') && (ch <= 'z'))
  148. ch = ch - 'a' + 26;
  149. else if ((ch >= '0') && (ch <= '9'))
  150. ch = ch - '0' + 52;
  151. else if (ch == '+')
  152. ch = 62;
  153. else if (ch == '=') /*no op -- can't ignore this one*/
  154. flendtext = true;
  155. else if (ch == '/')
  156. ch = 63;
  157. else
  158. flignore = true;
  159. if (!flignore) {
  160. short ctcharsinbuf = 3;
  161. boolean flbreak = false;
  162. if (flendtext) {
  163. if (ixinbuf == 0)
  164. break;
  165. if ((ixinbuf == 1) || (ixinbuf == 2))
  166. ctcharsinbuf = 1;
  167. else
  168. ctcharsinbuf = 2;
  169. ixinbuf = 3;
  170. flbreak = 1;
  171. }
  172. inbuf [ixinbuf++] = ch;
  173. if (ixinbuf == 4) {
  174. ixinbuf = 0;
  175. outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4);
  176. outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2);
  177. outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F);
  178. origsize = htext.getSize();
  179. htext.setSize(origsize + ctcharsinbuf);
  180. for (i = 0; i < ctcharsinbuf; i++)
  181. *htext.getMemory(origsize + i) = outbuf[i];
  182. }
  183. if (flbreak)
  184. break;
  185. }
  186. }
  187. return 1;
  188. }
  189. int Base64::decode(MemBlock<wchar_t> &h64, MemBlock<char> &htext) {
  190. unsigned long ixtext;
  191. unsigned long lentext;
  192. unsigned long origsize;
  193. unsigned char ch;
  194. unsigned char inbuf [4] = {0}, outbuf [4] = {0};
  195. short i, ixinbuf;
  196. boolean flignore;
  197. boolean flendtext = false;
  198. ixtext = 0;
  199. lentext = h64.getSize();
  200. ixinbuf = 0;
  201. while (true) {
  202. if (ixtext >= lentext)
  203. break;
  204. ch = (unsigned char)*h64.getMemory(ixtext++);
  205. flignore = 0;
  206. if ((ch >= 'A') && (ch <= 'Z'))
  207. ch = ch - 'A';
  208. else if ((ch >= 'a') && (ch <= 'z'))
  209. ch = ch - 'a' + 26;
  210. else if ((ch >= '0') && (ch <= '9'))
  211. ch = ch - '0' + 52;
  212. else if (ch == '+')
  213. ch = 62;
  214. else if (ch == '=') /*no op -- can't ignore this one*/
  215. flendtext = true;
  216. else if (ch == '/')
  217. ch = 63;
  218. else
  219. flignore = true;
  220. if (!flignore) {
  221. short ctcharsinbuf = 3;
  222. boolean flbreak = false;
  223. if (flendtext) {
  224. if (ixinbuf == 0)
  225. break;
  226. if ((ixinbuf == 1) || (ixinbuf == 2))
  227. ctcharsinbuf = 1;
  228. else
  229. ctcharsinbuf = 2;
  230. ixinbuf = 3;
  231. flbreak = 1;
  232. }
  233. inbuf [ixinbuf++] = ch;
  234. if (ixinbuf == 4) {
  235. ixinbuf = 0;
  236. outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4);
  237. outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2);
  238. outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F);
  239. origsize = htext.getSize();
  240. htext.setSize(origsize + ctcharsinbuf);
  241. for (i = 0; i < ctcharsinbuf; i++)
  242. *htext.getMemory(origsize + i) = outbuf[i];
  243. }
  244. if (flbreak)
  245. break;
  246. }
  247. }
  248. return 1;
  249. }