# mbr-buffer

> Extendable utilities for simple NodeJS buffer manipulations

Latest version **1.4.2** (published 2023-03-11) · ISC license · 0 weekly downloads

## Install

```sh
npm install mbr-buffer
pnpm add mbr-buffer
yarn add mbr-buffer
bun add mbr-buffer
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.4.2 |
| Published | 2023-03-11 |
| First published | 2019-04-29 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 21.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | MadBrozzeR |
| Maintainers | madbrozzer |
| Keywords | buffer, reader, writer |

## Links

- npm: https://www.npmjs.com/package/mbr-buffer
- Repository: https://github.com/MadBrozzeR/buffer
- Homepage: https://github.com/MadBrozzeR/buffer#readme
- Issues: https://github.com/MadBrozzeR/buffer/issues
- npm.io page: https://npm.io/package/mbr-buffer

## Alternatives

- [flatbuffers](https://npm.io/package/flatbuffers.md) — 6.0M weekly downloads
- [jwt-simple](https://npm.io/package/jwt-simple.md) — 259.5K weekly downloads
- [@exodus/patch-broken-hermes-typed-arrays](https://npm.io/package/@exodus/patch-broken-hermes-typed-arrays.md) — 28.5K weekly downloads
- [@native-to-anchor/buffer-layout](https://npm.io/package/@native-to-anchor/buffer-layout.md) — 12.2K weekly downloads
- [binary-parser-encoder](https://npm.io/package/binary-parser-encoder.md) — 5.3K weekly downloads

## Recent versions

- 1.4.2 (latest) — 2023-03-11
- 1.4.1 — 2020-04-19
- 1.4.0 — 2020-04-19
- 1.3.0 — 2019-08-19
- 1.2.2 — 2019-07-12
- 1.2.1 — 2019-07-05
- 1.2.0 — 2019-05-07
- 1.1.0 — 2019-05-03
- 1.0.1 — 2019-05-03
- 1.0.0 — 2019-05-03
- 0.0.1 — 2019-04-29

## README

# mbr-buffer
Reading and writing Buffer operations

My projects always have restrictions to not to use third party packages.
Only the ones included in default NodeJS and my own other projects.
This approach helps to make them really lightweight and fast.

## Reader
Utility to read from buffer. Instance has internal cursor which moves on each read operation or on demand.
You are always free to extend it by methods reqired by your project.
```
const reader = new Reader(buffer);
```
### reader.append
`reader.append(buffer)`

Append new data chunk to existing one without index being reset.

*buffer* - new data chunk to be appended.

Returns current Reader instance.

### reader.goTo
`reader.goTo(index)`

Move cursor so certain position.

*index* - position to go to.

Returns current Reader instance.

### reader.isEndReached
`reader.isEndReached()`

Check if cursor reached the end of storing data.

Returns `true` if end has been reached or `false` otherwise.

### reader.last
`reader.last(value, encoding = reader.encoding)`

Get index of last occurrence of `value`.

*value* - value to search. Can be either string or buffer, or one-byte number (0 - 255).

*encoding* - encoding of string value type. If value is not of string type, then argument is ignored.

Returns index as number type.

### reader.next
`reader.next(value, encoding = reader.encoding)`

Get index of next (after current cursor position) occurrence of `value`.

*value* - value to search. Can be either string or buffer, or one-byte number (0 - 255).

*encoding* - encoding of string value type. If value is not of string type, then argument is ignored.

Returns index as number type.

### reader.read
`reader.read(length = 1, encoding = reader.encoding)`

Read string from `length` bytes starting from current cursor position.

### reader.readInt
`reader.readInt(length = 1, littleEndian = false, unsigned = false)`

Read integer from `length` bytes starting from current cursor position.

*length* - byte count to read from.

*littleEndian* - is integer written in little-endian byte direction. Big-endian otherwise.

*unsigned* - is integer is unsigned.

Returns number.

### reader.readIntBE, .readIntLE, .readUIntBE, readUIntLE
```
reade.readIntBE(length = 1);  // Signed in big-endian byte direction
reade.readIntLE(length = 1);  // Signed in little-endian byte direction
reade.readUIntBE(length = 1); // Unsigned in big-endian byte direction
reade.readUIntLE(length = 1); // Unsigned in little-endian byte direction
```

Read signed or unsigned integer in desired byte direction from `length` bytes starting from current cursor position.

*length* - byte count to read from.

Returns number.

### reader.shft
`reader.shift(count)`

Move cursor by `count` of bytes, but return previous index value, unlike `.skip` method.

*count* - count of bytes to move cursor by.

Returns previous cursor position index as number type.

### reader.skip
`reader.skip(count = 1)`

Skip `count` of bytes and place cursor at new position.

*count* - count of bytes to be skipped.

Returns current Reader instance.

### reader.slice
`reader.slice(length)`

Read length bytes from current cursor position into new buffer. Note that both buffers share the same place in memory
so if one buffer has been modified then other one is modified as well.

*length* - byte count to read.

Returns new buffer object.

### reader.until
`reader.until(value, encoding = reader.encoding)`

Get byte count from current cursor position to next occurrence of `value`.

*value* - value to search. Can be either string or buffer, or one-byte number (0 - 255).

*encoding* - encoding of string value type. If value is not of string type, then argument is ignored.

Returns length as number.

### Reader.extend (static method)
`Reader.extend([constructor], methods)`

Create new constructor as an extension of Reader.

*constructor* - new constructor to extend Reader. Default one will be created if argument is omitted.

*methods* - methods to be appended to new prototype.

Returns new constructor function.

Example:

```
// Extend base class with two new methods: `readStrNull` which reads string
// from current cursor position until firs 0x00 byte and `readBase64` that
// returns `length` of bytes as base64.
const ExtendedReader1 = Reader.extend({
  readStrNull: function () {
    return this.read(this.until(0));
  },
  readBase64: function (length) {
    return this.slice(length).toString('base64');
  }
});

// Extend base class with custom constructor and `readAndAppendPrefix` method.
const ExtendedReader2 = Reader.extend(function (buffer, prefix) {
    Reader.call(this, buffer);
    this.prefix = prefix;
}, {
    readAndAppendPrefix: function (length) {
        return this.prefix + this.read(length);
    }
});
```

## Writer

Set of functions to write into new buffer. Unlike Reader, Writer is not a constructor.

### Writer.Group
`Writer.Group([elements]);`

Create group of elements or nested groups. Explicitly stores it's offset and size, which can be obtained by
`Writer.IndexOf` and `Writer.SizeOf`. Or by `group.IndexOf` and `group.SizeOf` which are essentially the same.

It is still possible to use arrays instead of Groups, but in that case you won't have direct access to size and offset.
You can use first element for offset and manually calculate size of all nested elements.

*elements* - array of child elements or nested groups.

Own methods:

`group.SizeOf(length = 1, {unsigned = false, littleEndian = false});`

Create reference to group size. Alias for `Writer.SizeOf`.

`group.IndexOf(length = 1, {unsigned = false, littleEndian = false});`

Create reference to group offset. Alias for `Writer.IndexOf`.

### Writer.Integer
`Writer.Integer(value, length = 1, {unsigned = false, littleEndian = false});`

Create integer element.

*value* - value to write.

*length* - byte length in new buffer.

*props.unsigned* - integer is unsigned.

*props.littleEndian* - integer in little-endian format.

### Writer.Float
`Writer.Float(value, {littleEndian = false});`

Create floating point element.

*value* - float value to write.

*props.littleEndian* - number in little-endian format.

### Writer.Double
`Writer.Double(value, {littleEndian = false});`

Create double precision element.

*value* - value to write.

*props.littleEndian* - number in little-endian format.

### Writer.String
`Writer.String(value, length = value.length, {encoding = 'utf8'});`

Create string element.

*value* - value to write.

*length* - byte length in new buffer.

*props.encoding* - text encoding.

#### Writer.Fill
`Writer.Fill(value = 0, length = 1);`

Fill `length` bytes with given `value`s.

*value* - value to write into each byte.

*length* - count of bytes to be filled.

### Writer.Buffer
`Writer.Buffer(value, length = value.length);`

Create buffer element.

*value* - value to write.

*length* - byte length in new buffer.

### Writer.Flags
`Writer.Flags([values], length = 1);`

Create flags.

*values* - array of values as bits.

*length* - byte length in new buffer.

### Writer.IndexOf
`Writer.IndexOf(value, length = 1, {unsigned = false, littleEndian = false});`

Create reference to element's offset.

*value* - element (or group) to reference.

*length* - byte length in new buffer.

*props.unsigned* - integer is unsigned.

*props.littleEndian* - integer in little-endian format.

### Writer.SizeOf
`Writer.SizeOf(value, length = 1, {unsigned = false, littleEndian = false});`

Create reference to element's size.

*value* - element (or group) to reference.

*length* - byte length in new buffer.

*props.unsigned* - integer is unsigned.

*props.littleEndian* - integer in little-endian format.

### Writer.make
`Writer.make([elements]);`

Create buffer from elements. Array may consist of elements or other arrays. Nesting is supported.
If element is not an instance of Array, Writer.Group or any extension of Writer.Element (BufferElement)
then it will be ignored. So it is possible to use ternary operator to decide wether you need to include
element in array (Group) or not:
```
[
    ...
    someCase ? Writer.String('Yes!') : null,
    !!orSomeOtherCase && Writer.String('A-ha!')
    ...
]
```

*elements* - elements to convert into buffer.

### Writer.Element.extend
`Writer.Element.extend(constructor, valueOf);`

Way to create your own elements for your project.

*constructor* - constructor function to be extended.

*valueOf* - function that explains how to compile your value into result buffer.

Proper example:

```
const CustomElement = Writer.Element.extend(function (value, length, params) {
  // Call default constructor to set value and reserved buffer length.
  Writer.Element.call(this, value, length);

  // Set all desired custom parameters.
  this.params = params.
}, function () {
  // Make buffer you need.
  const buffer = Buffer.alloc(this.length);

  // Return an appropriate object.
  return Writer.Element.valueOf.call(this, buffer);
}).generator();

const customElement = CustomElement('value', 10);
```

Calling to `.generator()` method at the end is not required, but it's a good way to avoid using
`new` keyword before your custom element constructor. Otherwise element should be created like so:

```
const customElement = new CustomElement('value', 10);
```

---
_Source: https://npm.io/package/mbr-buffer · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
