PageRenderTime 61ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/base64.cc

http://github.com/brainfucker/node-base64
C++ | 221 lines | 182 code | 29 blank | 10 comment | 38 complexity | a42a0597ec10435cdba714b6a67814c8 MD5 | raw file
  1. /**
  2. * nodejs(http://github.com/ry/node/) library for base64 encoding(decoding)
  3. *
  4. * @package base64
  5. * @link http://github.com/brainfucker/node-base64
  6. * @autor Oleg Illarionov <oleg@emby.ru>
  7. * @version 1.0
  8. */
  9. #include <v8.h>
  10. #include <node.h>
  11. #include <node_buffer.h>
  12. #include <iostream>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. using namespace v8;
  16. using namespace node;
  17. static const char base64_table[] = {
  18. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  19. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  20. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  21. 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  22. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
  23. };
  24. static const char base64_pad = '=';
  25. static const short base64_reverse_table[256] = {
  26. -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2,
  27. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  28. -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
  29. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
  30. -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  31. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
  32. -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  33. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
  34. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  35. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  36. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  37. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  38. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  39. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  40. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
  41. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
  42. };
  43. char* base64_encode(const unsigned char *str, int length, int *ret_length) /* {{{ */
  44. {
  45. const unsigned char *current = str;
  46. char *p;
  47. char *result;
  48. if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
  49. if (ret_length != NULL) {
  50. *ret_length = 0;
  51. }
  52. return NULL;
  53. }
  54. result = (char *)malloc((((length + 2) / 3) * 4)*(sizeof(char))+(1));
  55. if (result == NULL) {
  56. fprintf(stderr, "out of memory!\n");
  57. exit(1);
  58. }
  59. p = result;
  60. while (length > 2) {
  61. *p++ = base64_table[current[0] >> 2];
  62. *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
  63. *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
  64. *p++ = base64_table[current[2] & 0x3f];
  65. current += 3;
  66. length -= 3;
  67. }
  68. if (length != 0) {
  69. *p++ = base64_table[current[0] >> 2];
  70. if (length > 1) {
  71. *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
  72. *p++ = base64_table[(current[1] & 0x0f) << 2];
  73. *p++ = base64_pad;
  74. } else {
  75. *p++ = base64_table[(current[0] & 0x03) << 4];
  76. *p++ = base64_pad;
  77. *p++ = base64_pad;
  78. }
  79. }
  80. if (ret_length != NULL) {
  81. *ret_length = (int)(p - result);
  82. }
  83. *p = '\0';
  84. return result;
  85. }
  86. char *base64_decode(const unsigned char *str, int length, int *ret_length)
  87. {
  88. const unsigned char *current = str;
  89. int ch, i = 0, j = 0, k;
  90. char *result;
  91. result = (char *)malloc(length+1);
  92. if (result == NULL) {
  93. fprintf(stderr, "out of memory!\n");
  94. exit(1);
  95. }
  96. while ((ch = *current++) != '\0' && length-- > 0) {
  97. if (ch == base64_pad) {
  98. if (*current != '=' && (i % 4) == 1) {
  99. free(result);
  100. return NULL;
  101. }
  102. continue;
  103. }
  104. ch = base64_reverse_table[ch];
  105. if ((1 && ch < 0) || ch == -1) {
  106. continue;
  107. } else if (ch == -2) {
  108. free(result);
  109. return NULL;
  110. }
  111. switch(i % 4) {
  112. case 0:
  113. result[j] = ch << 2;
  114. break;
  115. case 1:
  116. result[j++] |= ch >> 4;
  117. result[j] = (ch & 0x0f) << 4;
  118. break;
  119. case 2:
  120. result[j++] |= ch >>2;
  121. result[j] = (ch & 0x03) << 6;
  122. break;
  123. case 3:
  124. result[j++] |= ch;
  125. break;
  126. }
  127. i++;
  128. }
  129. k = j;
  130. if (ch == base64_pad) {
  131. switch(i % 4) {
  132. case 1:
  133. free(result);
  134. return NULL;
  135. case 2:
  136. k++;
  137. case 3:
  138. result[k] = 0;
  139. }
  140. }
  141. if(ret_length) {
  142. *ret_length = j;
  143. }
  144. result[j] = '\0';
  145. return result;
  146. }
  147. Handle<Value>
  148. base64_encode_binding(const Arguments& args)
  149. {
  150. HandleScope scope;
  151. int len;
  152. Local<String> ret;
  153. if (Buffer::HasInstance(args[0])) {
  154. //Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args[0]->ToObject());
  155. Handle<Object> buffer = args[0]->ToObject();
  156. char *str = base64_encode((unsigned char*)Buffer::Data(buffer), Buffer::Length(buffer),&len);
  157. ret = String::New(str, len);
  158. delete str;
  159. } else {
  160. String::Utf8Value data(args[0]->ToString());
  161. char* str = base64_encode((unsigned char*)*data,data.length(),&len);
  162. ret = String::New(str,len);
  163. delete str;
  164. }
  165. return scope.Close(ret);
  166. }
  167. Handle<Value>
  168. base64_decode_binding(const Arguments& args)
  169. {
  170. HandleScope scope;
  171. Local<String> ret;
  172. int len;
  173. if (Buffer::HasInstance(args[0])) {
  174. //Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args[0]->ToObject());
  175. Handle<Object> buffer = args[0]->ToObject();
  176. char *str = base64_decode((unsigned char*)Buffer::Data(buffer), Buffer::Length(buffer),&len);
  177. ret = String::New(str, len);
  178. delete str;
  179. } else {
  180. String::Utf8Value data(args[0]->ToString());
  181. char* str=base64_decode((unsigned char*)*data,data.length(),&len);
  182. ret = String::New(str,len);
  183. delete str;
  184. }
  185. return scope.Close(ret);
  186. }
  187. extern "C" void init (Handle<Object> target)
  188. {
  189. HandleScope scope;
  190. target->Set(String::New("encode"), FunctionTemplate::New(base64_encode_binding)->GetFunction());
  191. target->Set(String::New("decode"), FunctionTemplate::New(base64_decode_binding)->GetFunction());
  192. }