2 * ws: a node.js websocket client
3 * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
9 #include <node_buffer.h>
10 #include <node_object_wrap.h>
20 class BufferUtil : public ObjectWrap
24 static void Initialize(v8::Handle<v8::Object> target)
27 Local<FunctionTemplate> t = NanNew<FunctionTemplate>(New);
28 t->InstanceTemplate()->SetInternalFieldCount(1);
29 NODE_SET_METHOD(t, "unmask", BufferUtil::Unmask);
30 NODE_SET_METHOD(t, "mask", BufferUtil::Mask);
31 NODE_SET_METHOD(t, "merge", BufferUtil::Merge);
32 target->Set(NanSymbol("BufferUtil"), t->GetFunction());
37 static NAN_METHOD(New)
40 BufferUtil* bufferUtil = new BufferUtil();
41 bufferUtil->Wrap(args.This());
42 NanReturnValue(args.This());
45 static NAN_METHOD(Merge)
48 Local<Object> bufferObj = args[0]->ToObject();
49 char* buffer = Buffer::Data(bufferObj);
50 Local<Array> array = Local<Array>::Cast(args[1]);
51 unsigned int arrayLength = array->Length();
54 for (i = 0; i < arrayLength; ++i) {
55 Local<Object> src = array->Get(i)->ToObject();
56 size_t length = Buffer::Length(src);
57 memcpy(buffer + offset, Buffer::Data(src), length);
60 NanReturnValue(NanTrue());
63 static NAN_METHOD(Unmask)
66 Local<Object> buffer_obj = args[0]->ToObject();
67 size_t length = Buffer::Length(buffer_obj);
68 Local<Object> mask_obj = args[1]->ToObject();
69 unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
70 unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
71 size_t len32 = length / 4;
73 for (i = 0; i < len32; ++i) *(from + i) ^= *mask;
76 case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2];
77 case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1];
78 case 1: *((unsigned char*)from ) = *((unsigned char*)from ) ^ ((unsigned char*)mask)[0];
81 NanReturnValue(NanTrue());
84 static NAN_METHOD(Mask)
87 Local<Object> buffer_obj = args[0]->ToObject();
88 Local<Object> mask_obj = args[1]->ToObject();
89 unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
90 Local<Object> output_obj = args[2]->ToObject();
91 unsigned int dataOffset = args[3]->Int32Value();
92 unsigned int length = args[4]->Int32Value();
93 unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset);
94 unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
95 unsigned int len32 = length / 4;
97 for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask;
100 switch (length % 4) {
101 case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2);
102 case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1);
103 case 1: *((unsigned char*)to ) = *((unsigned char*)from ) ^ *((unsigned char*)mask);
106 NanReturnValue(NanTrue());
110 extern "C" void init (Handle<Object> target)
113 BufferUtil::Initialize(target);
116 NODE_MODULE(bufferutil, init)