Websocket
[VSoRC/.git] / node_modules / websocket / src / bufferutil.cc
1 /*!
2  * BufferUtil originally from:
3  * ws: a node.js websocket client
4  * Copyright(c) 2015 Einar Otto Stangvik <einaros@gmail.com>
5  * MIT Licensed
6  */
7
8 #include <v8.h>
9 #include <node.h>
10 #include <node_version.h>
11 #include <node_buffer.h>
12 #include <node_object_wrap.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <wchar.h>
16 #include <stdio.h>
17 #include "nan.h"
18
19 using namespace v8;
20 using namespace node;
21
22 class BufferUtil : public ObjectWrap
23 {
24 public:
25
26   static void Initialize(v8::Local<v8::Object> target)
27   {
28     Nan::HandleScope scope;
29     Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(New);
30     t->InstanceTemplate()->SetInternalFieldCount(1);
31     Nan::SetMethod(t, "unmask", BufferUtil::Unmask);
32     Nan::SetMethod(t, "mask", BufferUtil::Mask);
33     Nan::SetMethod(t, "merge", BufferUtil::Merge);
34     Nan::Set(target, Nan::New<String>("BufferUtil").ToLocalChecked(), t->GetFunction());
35   }
36
37 protected:
38
39   static NAN_METHOD(New)
40   {
41     Nan::HandleScope scope;
42     BufferUtil* bufferUtil = new BufferUtil();
43     bufferUtil->Wrap(info.This());
44     info.GetReturnValue().Set(info.This());
45   }
46
47   static NAN_METHOD(Merge)
48   {
49     Nan::HandleScope scope;
50     Local<Object> bufferObj = info[0]->ToObject();
51     char* buffer = Buffer::Data(bufferObj);
52     Local<Array> array = Local<Array>::Cast(info[1]);
53     unsigned int arrayLength = array->Length();
54     size_t offset = 0;
55     unsigned int i;
56     for (i = 0; i < arrayLength; ++i) {
57       Local<Object> src = array->Get(i)->ToObject();
58       size_t length = Buffer::Length(src);
59       memcpy(buffer + offset, Buffer::Data(src), length);
60       offset += length;
61     }
62     info.GetReturnValue().Set(Nan::True());
63   }
64
65   static NAN_METHOD(Unmask)
66   {
67     Nan::HandleScope scope;
68     Local<Object> buffer_obj = info[0]->ToObject();
69     size_t length = Buffer::Length(buffer_obj);
70     Local<Object> mask_obj = info[1]->ToObject();
71     unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
72     unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
73     size_t len32 = length / 4;
74     unsigned int i;
75     for (i = 0; i < len32; ++i) *(from + i) ^= *mask;
76     from += i;
77     switch (length % 4) {
78       case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2];
79       case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1];
80       case 1: *((unsigned char*)from  ) = *((unsigned char*)from  ) ^ ((unsigned char*)mask)[0];
81       case 0:;
82     }
83     info.GetReturnValue().Set(Nan::True());
84   }
85
86   static NAN_METHOD(Mask)
87   {
88     Nan::HandleScope scope;
89     Local<Object> buffer_obj = info[0]->ToObject();
90     Local<Object> mask_obj = info[1]->ToObject();
91     unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
92     Local<Object> output_obj = info[2]->ToObject();
93     unsigned int dataOffset = info[3]->Int32Value();
94     unsigned int length = info[4]->Int32Value();
95     unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset);
96     unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
97     unsigned int len32 = length / 4;
98     unsigned int i;
99     for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask;
100     to += i;
101     from += i;
102     switch (length % 4) {
103       case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2);
104       case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1);
105       case 1: *((unsigned char*)to  ) = *((unsigned char*)from  ) ^ *((unsigned char*)mask);
106       case 0:;
107     }
108     info.GetReturnValue().Set(Nan::True());
109   }
110 };
111
112 #if !NODE_VERSION_AT_LEAST(0,10,0)
113 extern "C"
114 #endif
115 void init (Local<Object> target)
116 {
117   Nan::HandleScope scope;
118   BufferUtil::Initialize(target);
119 }
120
121 NODE_MODULE(bufferutil, init)