/*! * ws: a node.js websocket client * Copyright(c) 2011 Einar Otto Stangvik * MIT Licensed */ #include #include #include #include #include #include #include #include using namespace v8; using namespace node; class BufferUtil : public ObjectWrap { public: static void Initialize(v8::Handle target) { HandleScope scope; Local t = FunctionTemplate::New(New); t->InstanceTemplate()->SetInternalFieldCount(1); NODE_SET_METHOD(t->GetFunction(), "unmask", BufferUtil::Unmask); NODE_SET_METHOD(t->GetFunction(), "mask", BufferUtil::Mask); NODE_SET_METHOD(t->GetFunction(), "merge", BufferUtil::Merge); target->Set(String::NewSymbol("BufferUtil"), t->GetFunction()); } protected: static Handle New(const Arguments& args) { HandleScope scope; BufferUtil* bufferUtil = new BufferUtil(); bufferUtil->Wrap(args.This()); return args.This(); } static Handle Merge(const Arguments& args) { HandleScope scope; Local bufferObj = args[0]->ToObject(); char* buffer = Buffer::Data(bufferObj); Local array = Local::Cast(args[1]); unsigned int arrayLength = array->Length(); unsigned int offset = 0; unsigned int i; for (i = 0; i < arrayLength; ++i) { Local src = array->Get(i)->ToObject(); unsigned int length = Buffer::Length(src); memcpy(buffer + offset, Buffer::Data(src), length); offset += length; } return scope.Close(True()); } static Handle Unmask(const Arguments& args) { HandleScope scope; Local buffer_obj = args[0]->ToObject(); unsigned int length = Buffer::Length(buffer_obj); Local mask_obj = args[1]->ToObject(); unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); unsigned int 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:; } return True(); } static Handle Mask(const Arguments& args) { HandleScope scope; Local buffer_obj = args[0]->ToObject(); Local mask_obj = args[1]->ToObject(); unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); Local output_obj = args[2]->ToObject(); unsigned int dataOffset = args[3]->Int32Value(); unsigned int length = args[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:; } return True(); } }; extern "C" void init (Handle target) { HandleScope scope; BufferUtil::Initialize(target); } NODE_MODULE(bufferutil, init)