Websocket
[VSoRC/.git] / node_modules / websocket / src / bufferutil.cc
diff --git a/node_modules/websocket/src/bufferutil.cc b/node_modules/websocket/src/bufferutil.cc
new file mode 100644 (file)
index 0000000..a53c246
--- /dev/null
@@ -0,0 +1,121 @@
+/*!
+ * BufferUtil originally from:
+ * ws: a node.js websocket client
+ * Copyright(c) 2015 Einar Otto Stangvik <einaros@gmail.com>
+ * MIT Licensed
+ */
+
+#include <v8.h>
+#include <node.h>
+#include <node_version.h>
+#include <node_buffer.h>
+#include <node_object_wrap.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdio.h>
+#include "nan.h"
+
+using namespace v8;
+using namespace node;
+
+class BufferUtil : public ObjectWrap
+{
+public:
+
+  static void Initialize(v8::Local<v8::Object> target)
+  {
+    Nan::HandleScope scope;
+    Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
+    t->InstanceTemplate()->SetInternalFieldCount(1);
+    Nan::SetMethod(t, "unmask", BufferUtil::Unmask);
+    Nan::SetMethod(t, "mask", BufferUtil::Mask);
+    Nan::SetMethod(t, "merge", BufferUtil::Merge);
+    Nan::Set(target, Nan::New<String>("BufferUtil").ToLocalChecked(), t->GetFunction());
+  }
+
+protected:
+
+  static NAN_METHOD(New)
+  {
+    Nan::HandleScope scope;
+    BufferUtil* bufferUtil = new BufferUtil();
+    bufferUtil->Wrap(info.This());
+    info.GetReturnValue().Set(info.This());
+  }
+
+  static NAN_METHOD(Merge)
+  {
+    Nan::HandleScope scope;
+    Local<Object> bufferObj = info[0]->ToObject();
+    char* buffer = Buffer::Data(bufferObj);
+    Local<Array> array = Local<Array>::Cast(info[1]);
+    unsigned int arrayLength = array->Length();
+    size_t offset = 0;
+    unsigned int i;
+    for (i = 0; i < arrayLength; ++i) {
+      Local<Object> src = array->Get(i)->ToObject();
+      size_t length = Buffer::Length(src);
+      memcpy(buffer + offset, Buffer::Data(src), length);
+      offset += length;
+    }
+    info.GetReturnValue().Set(Nan::True());
+  }
+
+  static NAN_METHOD(Unmask)
+  {
+    Nan::HandleScope scope;
+    Local<Object> buffer_obj = info[0]->ToObject();
+    size_t length = Buffer::Length(buffer_obj);
+    Local<Object> mask_obj = info[1]->ToObject();
+    unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
+    unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
+    size_t len32 = length / 4;
+    unsigned int i;
+    for (i = 0; i < len32; ++i) *(from + i) ^= *mask;
+    from += i;
+    switch (length % 4) {
+      case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2];
+      case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1];
+      case 1: *((unsigned char*)from  ) = *((unsigned char*)from  ) ^ ((unsigned char*)mask)[0];
+      case 0:;
+    }
+    info.GetReturnValue().Set(Nan::True());
+  }
+
+  static NAN_METHOD(Mask)
+  {
+    Nan::HandleScope scope;
+    Local<Object> buffer_obj = info[0]->ToObject();
+    Local<Object> mask_obj = info[1]->ToObject();
+    unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
+    Local<Object> output_obj = info[2]->ToObject();
+    unsigned int dataOffset = info[3]->Int32Value();
+    unsigned int length = info[4]->Int32Value();
+    unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset);
+    unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
+    unsigned int len32 = length / 4;
+    unsigned int i;
+    for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask;
+    to += i;
+    from += i;
+    switch (length % 4) {
+      case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2);
+      case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1);
+      case 1: *((unsigned char*)to  ) = *((unsigned char*)from  ) ^ *((unsigned char*)mask);
+      case 0:;
+    }
+    info.GetReturnValue().Set(Nan::True());
+  }
+};
+
+#if !NODE_VERSION_AT_LEAST(0,10,0)
+extern "C"
+#endif
+void init (Local<Object> target)
+{
+  Nan::HandleScope scope;
+  BufferUtil::Initialize(target);
+}
+
+NODE_MODULE(bufferutil, init)