2 * BufferUtil originally from:
3 * ws: a node.js websocket client
4 * Copyright(c) 2015 Einar Otto Stangvik <einaros@gmail.com>
10 #include <node_version.h>
11 #include <node_buffer.h>
12 #include <node_object_wrap.h>
22 class BufferUtil : public ObjectWrap
26 static void Initialize(v8::Local<v8::Object> target)
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());
39 static NAN_METHOD(New)
41 Nan::HandleScope scope;
42 BufferUtil* bufferUtil = new BufferUtil();
43 bufferUtil->Wrap(info.This());
44 info.GetReturnValue().Set(info.This());
47 static NAN_METHOD(Merge)
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();
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);
62 info.GetReturnValue().Set(Nan::True());
65 static NAN_METHOD(Unmask)
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;
75 for (i = 0; i < len32; ++i) *(from + i) ^= *mask;
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];
83 info.GetReturnValue().Set(Nan::True());
86 static NAN_METHOD(Mask)
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;
99 for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask;
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);
108 info.GetReturnValue().Set(Nan::True());
112 #if !NODE_VERSION_AT_LEAST(0,10,0)
115 void init (Local<Object> target)
117 Nan::HandleScope scope;
118 BufferUtil::Initialize(target);
121 NODE_MODULE(bufferutil, init)