Skip to content

Commit

Permalink
[major] Simplify the C++ code and how the functions are exported
Browse files Browse the repository at this point in the history
  • Loading branch information
lpinca committed Feb 3, 2017
1 parent 97d4832 commit 5c43867
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 191 deletions.
88 changes: 62 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,95 @@
[![Linux/macOS Build](https://travis-ci.org/websockets/bufferutil.svg?branch=master)](https://travis-ci.org/websockets/bufferutil)
[![Windows Build](https://ci.appveyor.com/api/projects/status/github/websockets/bufferutil?branch=master&svg=true)](https://ci.appveyor.com/project/lpinca/bufferutil)

Buffer utils is one of the modules that makes `ws` fast. It's optimized for
certain buffer based operations such as merging buffers, generating WebSocket
masks and unmasking.

As the module consists of binary components, it should be used an
`optionalDependency` so when installation fails, it doesn't halt the
installation of your module. There are fallback files available in this
repository. See `fallback.js` for the suggest fallback implementation if
installation fails.
`bufferutil` is what makes `ws` fast. It provides some utilities to efficiently
perform some operations such as masking and unmasking the data payload of
WebSocket frames.

## Installation

```
npm install bufferutil
npm install bufferutil --save-optional
```

The `--save-optional` flag tells npm to save the package in your package.json
under the [`optionalDependencies`](https://docs.npmjs.com/files/package.json#optionaldependencies)
key.

## API

In all examples we assume that you've already required the BufferUtil as
followed:
The module exports 3 different functions.

### `bufferUtil.merge(target, list)`

Merges an array of buffers into a target buffer.

#### Arguments

- `target` - The target buffer.
- `list` - An array containing the `Buffer` instances to merge.

#### Example

```js
'use strict';

var bu = require('bufferutil').BufferUtil;
const bufferUtil = require('bufferutil');
const crypto = require('crypto');

const target = Buffer.allocUnsafe(10);

bufferUtil.merge(target, [crypto.randomBytes(5), crypto.randomBytes(5)]);
```

The module exposes 3 different functions:
#### `bufferUtil.mask(source, mask, output, offset, length)`

Masks a buffer using the given masking-key as specified by the WebSocket
protocol.

#### merge
#### Arguments

Merge multiple buffers in the first supplied buffer argument:
- `source` - The buffer to mask.
- `mask` - A buffer representing the masking-key.
- `output` - The buffer where to store the result.
- `offset` - The offset at which to start writing.
- `length` - The number of bytes to mask.

#### Example

```js
bu.merge(buffer, [buffer1, buffer2]);
'use strict';

const bufferUtil = require('bufferutil');
const crypto = require('crypto');

const source = crypto.randomBytes(10);
const mask = crypto.randomBytes(4);

bufferUtil.mask(source, mask, source, 0, source.length);
```

This merges buffer1 and buffer2 which are in an array into buffer.
#### `bufferUtil.unmask(buffer, mask)`

#### mask
Unmasks a buffer using the given masking-key as specified by the WebSocket
protocol.

Apply a WebSocket mask on the given data.
#### Arguments

- `buffer` - The buffer to unmask.
- `mask` - A buffer representing the masking-key.

#### Example

```js
bu.mask(buffer, mask);
```
'use strict';

#### unmask
const bufferUtil = require('bufferutil');
const crypto = require('crypto');

Remove a WebSocket mask on the given data.;w
const buffer = crypto.randomBytes(10);
const mask = crypto.randomBytes(4);

```js
bu.unmask(buffer, mask);
bufferUtil.unmask(buffer, mask);
```

## License
Expand Down
66 changes: 46 additions & 20 deletions fallback.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,51 @@

'use strict';

exports.BufferUtil = {
merge: function (mergedBuffer, buffers) {
var offset = 0;
for (var i = 0, l = buffers.length; i < l; ++i) {
var buf = buffers[i];
buf.copy(mergedBuffer, offset);
offset += buf.length;
}
},
mask: function (source, mask, output, offset, length) {
for (var i = 0; i < length; i++) {
output[offset + i] = source[i] ^ mask[i & 3];
}
},
unmask: function (data, mask) {
// required until https://github.com/nodejs/node/issues/9006 is resolved
var length = data.length;
for (var i = 0; i < length; i++) {
data[i] ^= mask[i & 3];
}
/**
* Merges an array of buffers into a target buffer.
*
* @param {Buffer} target The target buffer
* @param {Buffer[]} buffers The array of buffers to merge
* @public
*/
const merge = (target, buffers) => {
var offset = 0;
for (var i = 0; i < buffers.length; i++) {
const buf = buffers[i];
buf.copy(target, offset);
offset += buf.length;
}
};

/**
* Masks a buffer using the given mask.
*
* @param {Buffer} source The buffer to mask
* @param {Buffer} mask The mask to use
* @param {Buffer} output The buffer where to store the result
* @param {Number} offset The offset at which to start writing
* @param {Number} length The number of bytes to mask.
* @public
*/
const mask = (source, mask, output, offset, length) => {
for (var i = 0; i < length; i++) {
output[offset + i] = source[i] ^ mask[i & 3];
}
};

/**
* Unmasks a buffer using the given mask.
*
* @param {Buffer} buffer The buffer to unmask
* @param {Buffer} mask The mask to use
* @public
*/
const unmask = (buffer, mask) => {
// Required until https://github.com/nodejs/node/issues/9006 is resolved.
const length = buffer.length;
for (var i = 0; i < length; i++) {
buffer[i] ^= mask[i & 3];
}
};

module.exports = { merge, mask, unmask };

0 comments on commit 5c43867

Please sign in to comment.