npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mbr-buffer

v1.4.2

Published

Extendable utilities for simple NodeJS buffer manipulations

Downloads

14

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 values.

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);