bufferutil.cc 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*!
  2. * bufferutil: WebSocket buffer utils
  3. * Copyright(c) 2015 Einar Otto Stangvik <einaros@gmail.com>
  4. * MIT Licensed
  5. */
  6. #include <nan.h>
  7. NAN_METHOD(mask) {
  8. char* from = node::Buffer::Data(info[0]);
  9. char* mask = node::Buffer::Data(info[1]);
  10. char* to = node::Buffer::Data(info[2]) + info[3]->Int32Value();
  11. size_t length = info[4]->Int32Value();
  12. size_t index = 0;
  13. //
  14. // Alignment preamble.
  15. //
  16. while (index < length && (reinterpret_cast<size_t>(from) & 0x07)) {
  17. *to++ = *from++ ^ mask[index % 4];
  18. index++;
  19. }
  20. length -= index;
  21. if (!length) return;
  22. //
  23. // Realign mask and convert to 64 bit.
  24. //
  25. char maskAlignedArray[8];
  26. for (size_t i = 0; i < 8; i++, index++) {
  27. maskAlignedArray[i] = mask[index % 4];
  28. }
  29. //
  30. // Apply 64 bit mask in 8 byte chunks.
  31. //
  32. size_t loop = length / 8;
  33. uint64_t* pMask8 = reinterpret_cast<uint64_t*>(maskAlignedArray);
  34. while (loop--) {
  35. uint64_t* pFrom8 = reinterpret_cast<uint64_t*>(from);
  36. uint64_t* pTo8 = reinterpret_cast<uint64_t*>(to);
  37. *pTo8 = *pFrom8 ^ *pMask8;
  38. from += 8;
  39. to += 8;
  40. }
  41. //
  42. // Apply mask to remaining data.
  43. //
  44. char* pmaskAlignedArray = maskAlignedArray;
  45. length &= 0x7;
  46. while (length--) {
  47. *to++ = *from++ ^ *pmaskAlignedArray++;
  48. }
  49. }
  50. NAN_METHOD(unmask) {
  51. char* from = node::Buffer::Data(info[0]);
  52. size_t length = node::Buffer::Length(info[0]);
  53. char* mask = node::Buffer::Data(info[1]);
  54. size_t index = 0;
  55. //
  56. // Alignment preamble.
  57. //
  58. while (index < length && (reinterpret_cast<size_t>(from) & 0x07)) {
  59. *from++ ^= mask[index % 4];
  60. index++;
  61. }
  62. length -= index;
  63. if (!length) return;
  64. //
  65. // Realign mask and convert to 64 bit.
  66. //
  67. char maskAlignedArray[8];
  68. for (size_t i = 0; i < 8; i++, index++) {
  69. maskAlignedArray[i] = mask[index % 4];
  70. }
  71. //
  72. // Apply 64 bit mask in 8 byte chunks.
  73. //
  74. size_t loop = length / 8;
  75. uint64_t* pMask8 = reinterpret_cast<uint64_t*>(maskAlignedArray);
  76. while (loop--) {
  77. uint64_t* pSource8 = reinterpret_cast<uint64_t*>(from);
  78. *pSource8 ^= *pMask8;
  79. from += 8;
  80. }
  81. //
  82. // Apply mask to remaining data.
  83. //
  84. char* pmaskAlignedArray = maskAlignedArray;
  85. length &= 0x7;
  86. while (length--) {
  87. *from++ ^= *pmaskAlignedArray++;
  88. }
  89. }
  90. NAN_MODULE_INIT(init) {
  91. NAN_EXPORT(target, mask);
  92. NAN_EXPORT(target, unmask);
  93. }
  94. NODE_MODULE(bufferutil, init)