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

rs-buffer

v0.7.0

Published

Readable/writable buffer designed for a video game

Downloads

18

Readme

rs-buffer

Readable/writable byte buffer designed for a video game

Installation

You can install this from npm:

npm install rs-buffer

Usage

Writable fixed

import { FixedWritableByteBuffer } from "rs-buffer";

const buf = new FixedWritableByteBuffer(7); // create a writable byte buffer with 7 bytes

buf.pushShort(0x1234); // push 0x1234
buf.pushInt(0x4321ABCD, Transformation.NONE, DataOrder.LITTLE_ENDIAN); // push 0x4321ABCD in little endian order
buf.pushByte(0xFF); // push 0xFF

buf.buffer; // get the underlying byte buffer to do with as you please

// values here will be:
// [ 0x12, 0x34, 0xCD, 0xAB, 0x21, 0x43, 0xFF ]

Writable variable

You can also have a variable-sized buffer but this is just backed by an array and is slower.

import { VariableWritableByteBuffer } from "rs-buffer";

const buf = new VariableWritableByteBuffer(); // create a variable-sized writable byte buffer

buf.pushInt(0x4321ABCD); // push 0x4321ABCD
buf.pushInt(0x4321ABCD); // push 0x4321ABCD
buf.pushInt(0x4321ABCD); // push 0x4321ABCD

buf.buffer; // convert array to byte buffer

// values here will be:
// [ 0x43, 0x21, 0xAB, 0xCD, 0x43, 0x21, 0xAB, 0xCD, 0x43, 0x21, 0xAB, 0xCD ]

Readable

import { ReadableByteBuffer } from "rs-buffer";

const buf = new ReadableByteBuffer(buffer); // pass in the Buffer instance you want to actually read from

buf.readInt(); // get an int from the buffer
buf.readByte(); // get a byte from the buffer

buf.readByte(true, Transformation.ADD); // read a signed byte with "add" type transformation

buf.readInt(true, Transformation.NONE, DataOrder.LITTLE_ENDIAN); // read a signed int in little-endian order, without transforming it

Transformations

There are a number of "transformations" that can be made when writing an item to the buffer. The transformation is always made to the least significant bit.

The transformations are as follows:

  • add (called A in some other implementations): Add 128 to the LSB
  • subtract (called S in some other implementations): Subtract the LSB from 128
  • negate (called C in some other implementations): Multiply the LSB with -1

The transformation is always from the point of view of the write. If you read a byte with the add transformation, the buffer will subtract 128 from the LSB in order to return to the original (written) value. Do not be misled into thinking that the buffer will perform the original (write) transformation again.

These transformations have other names in other implementations. add is commonly called A, subtract is commonly called S and negate is commonly called C.

For comparisons sake, here is some code you may find in another implementation of this buffer, followed by an example using this buffer.

// others
buffer.putLEShortA(0xC3D8);
buffer.putByteS(0xF1);
buffer.putByteC(0xD5);
buffer.putInt(0x67D401B2);

// this
buffer.pushShort(0xC3D8, DataOrder.LITTLE_ENDIAN, Transformation.ADD);
buffer.pushByte(0xF1, Transformation.SUBTRACT);
buffer.pushByte(0xD5, Transformation.NEGATE);
buffer.pushInt(0x67D401B2);

Data Order

You can either use big- or little-endian data orders when interacting with the buffer.

For example, take a value 0x12345678. In big-endian order (the default), that will be written as [ 0x12, 0x34, 0x56, 0x78 ], because it starts with the MSB. In little-endian order, however, it will start at the LSB and be written as [ 0x78, 0x56, 0x34, 0x12 ].

Mixed

The only exception to this is the pushInt method which takes a boolean parameter mixed. This will then split the integer into four octets, order them as above based on their endianness, and then switches the first two with the last two.

Again, take the value 0x12345678. When written using mixed big-endianness, it will be split into the four octets as detailed above, giving us [ 0x56, 0x78, 0x12, 0x34 ]. In the same fashion, when written using mixed little-endianness, the output would be [ 0x34, 0x12, 0x78, 0x56 ]

Pushing bits

You can push bits into a writable byte buffer:

buf.pushBits(4, 0b1111).pushBits(4, 0b0000); // values will be 0b11110000

The first time you call pushBits on the buffer, some context is set up to allow for chaining. You can store this context in a variable to keep pushing bits into the same section:

const context = buf.pushBits(4, 0b1111);
context.pushBits(2, 0b00);
context.pushBits(2, 0b10);
// values will be 0b11110010

Performing any byte-level operations will render that context invalid. There are currently no safety guards around that, so make sure that you don't do this:

/* BAD! Do not do this. */

const context = buf.pushBits(4, 0b1111);
buf.pushByte(0xFF);
context.pushBits(4, 0b1111);

/* BAD! Do not do this. */