arnaucube
arnaucube/comunicationLeapPublic Self-hosted repository
comunicationLeap/node_modules/ws/src/bufferutil.cc
node_modules/ws/src/bufferutil.ccRaw
  1/*!
  2 * ws: a node.js websocket client
  3 * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com>
  4 * MIT Licensed
  5 */
  6
  7#include <v8.h>
  8#include <node.h>
  9#include <node_buffer.h>
 10#include <node_object_wrap.h>
 11#include <stdlib.h>
 12#include <string.h>
 13#include <wchar.h>
 14#include <stdio.h>
 15#include "nan.h"
 16
 17using namespace v8;
 18using namespace node;
 19
 20class BufferUtil : public ObjectWrap
 21{
 22public:
 23
 24  static void Initialize(v8::Handle<v8::Object> target)
 25  {
 26    NanScope();
 27    Local<FunctionTemplate> t = FunctionTemplate::New(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(String::NewSymbol("BufferUtil"), t->GetFunction());
 33  }
 34
 35protected:
 36
 37  static NAN_METHOD(New)
 38  {
 39    NanScope();
 40    BufferUtil* bufferUtil = new BufferUtil();
 41    bufferUtil->Wrap(args.This());
 42    NanReturnValue(args.This());
 43  }
 44
 45  static NAN_METHOD(Merge)
 46  {
 47    NanScope();
 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();
 52    size_t offset = 0;
 53    unsigned int i;
 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);
 58      offset += length;
 59    }
 60    NanReturnValue(True());
 61  }
 62
 63  static NAN_METHOD(Unmask)
 64  {
 65    NanScope();
 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;
 72    unsigned int i;
 73    for (i = 0; i < len32; ++i) *(from + i) ^= *mask;
 74    from += i;
 75    switch (length % 4) {
 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];
 79      case 0:;
 80    }
 81    NanReturnValue(True());
 82  }
 83
 84  static NAN_METHOD(Mask)
 85  {
 86    NanScope();
 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;
 96    unsigned int i;
 97    for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask;
 98    to += i;
 99    from += i;
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);
104      case 0:;
105    }
106    NanReturnValue(True());
107  }
108};
109
110extern "C" void init (Handle<Object> target)
111{
112  NanScope();
113  BufferUtil::Initialize(target);
114}
115
116NODE_MODULE(bufferutil, init)
117