-
Notifications
You must be signed in to change notification settings - Fork 1
Home
BufferPlus has very similar API to node.js Buffer
, all the common methods likes alloc(), allocUnsafe(), from(), read/write<Number|String|>()...etc are supported. So the programer is quite easy to master with this library without steep learning curve.
- size: <Integer> The desired size of the new
BufferPlus
instance. - Returns: <BufferPlus>
Create a new non-zero-filled
BufferPlus
object. withsize
, or create a 64 bytesBufferPlus
object issize
is not specified.
It is a alias method of
BufferPlus.allocUnsafe(size)
- buffer: <Buffer> or <BufferPlus> instance
Create a reference of
buffer
. The newBufferPlus
instance shares the same allocated memory of originalBuffer
orBufferPlus
instance.
The behavior is the same as
BufferPlus.from(buffer)
Allocates a new BufferPlus
object of size bytes. If fill is undefined, the Buffer will be zero-filled.
Same behavior as node.js Buffer.alloc except it returns a
BufferPlus
object.
Allocates a new non-zero-filled BufferPlus
object of size bytes.
Same behavior as node.js Buffer.allocUnsafe except it returns a
BufferPlus
object.
Returns the actual byte length of a string.
Same behavior as node.js Buffer.byteLength
- buf1:
Buffer
orBufferPlus
instances - buf2:
Buffer
orBufferPlus
instance - Returns: <integer>
Compares buf1 to buf2 typically for the purpose of sorting arrays of Buffer
or BufferPlus
instances.
Same behavior as node.js Buffer.compare except it accepts both
Buffer
andBufferPlus
instances.
- list: <Array> of
Buffer
orBufferPlus
instances - totalLength: Total length of list when concatenated
- Returns: new <BufferPlus> instance
Returns a new Buffer which is the result of concatenating all the Buffer instances in the list together.
Same behavior as node.js Buffer.concat expect it accepts list of
Buffer
orBufferPlus
instances.
Create a new BufferPlus
instance or create a view of ArrayBuffer
or a refernce of Buffer
or BufferPlus
.
Same behavior as node.js Buffer.from when the argument types are
String
,Array
andArrayBuffer
.
But it create a reference when the argument types are
Buffer
orBufferPlus
without copying the underlying memory, which means the newBufferPlus
instance will share the same allocated memory of originalBuffer
orBufferPlus
instance.
The API is same as BufferPlus.from(...)
, but always create a new allocated memory and copy data from original, even the argument types are Buffer
, ArrayBuffer
or BufferPlus
.
BufferPlus
Extenstion Method.
- obj: <Object>
- Returns: <boolean>
Returns true
if obj
is a Buffer
, false otherwise.
Same behavior as node.js Buffer.isBuffer
Returns true
if obj
is a BufferPlus
, false otherwise.
BufferPlus
Extenstion Method.
Returns true
if encoding contains a supported character encoding, or false
otherwise.
Same behavior as node.js Buffer.isEncoding
- str: <String> String content to be calculated.
- encoding: <String> The encoding of string. Default:
buffer.encoding
. - Returns: <Integer>
Calculate the byte length of str
with packed string format.
- buf: <Buffer> Buffer content to be calculated.
- Returns: <Integer>
Calculates the byte length of buf
with packed buffer format.
- name: <String> Schema name
- Returns: <boolean>
Checks if schema defintion exists, returns true
if schema defintion exists, false otherwise.
- name: <String> Schema name
- Returns: <BufferSchema> | <undefined>
Get Schema instance by schema name, returns undefined
if schema doesn't exist.
Added in: v1.3.0
- Returns: <Object>
Retreives all schema instances, the return value is an object contains schema name as key, and
BufferSchema
instance as value.
- name: <String> Schema name
- schemaDef: <Object> Schema defintion
- Returns: <BufferSchema> | <undefined>
Create schema with schema name and schema definition, returns BufferSchema
instance if success, undefined
otherwise.
- name: <String> Schema name
- obj: <Object> The object that wants to encode
- Returns <Number> Byte length of encoded data
Get the encoded data length of obj
, the obj
is the object that wants to encode.
The length of the data that is being tracked in the internal Buffer
.
The length will be zero when a new empty BufferPlus
instance created from create(size)
, alloc(...)
or allocUnsafe(...)
.
And the length will be the length
of the input argument when it's created from create(buffer)
, from(...)
, or clone(...)
.
Example:
// buf1.length === 0, buf1.position === 0, buf1.size === 1024
const buf1 = BufferPlus.create(1024);
// buf2.length === 6, buf1.position === 0, buf1.size === 6
const buf2 = BufferPlus.from('string', 'ascii');
// buf3.length === 6, buf3.position === 0, buf3.size === 6
const buf3 = BufferPlus.clone(buf2);
// buf2.length === 128, buf1.position === 0, buf1.size === 128
const buf4 = BufferPlus.from(Buffer.alloc(128));
It's not the real byte size of the internal
Buffer
. If you want to get the real size of internalBuffer
, please readbuffer.size
property.
The current position that is read from or write to.
The position
are be confused with length
someteims because they have the same value in some cases.
The most significant difference between position
and length
is:
-
position
is the offset we read or write data, like a cursor, NOT the byte length we already wrote. -
length
presents the length of buffer that we already wrote data into it.
Example:
const user = BufferPlus.create();
// user.length === 0, user.position === 0 after created
// write a user ID
user.writeUInt32LE(1000);
// user.length === 4, user.position === 4 after writeUInt32LE
const cloneUser = BufferPlus.clone(user);
// cloneUser.length === 4, cloneUser.position === 0
The remaining bytes in buffer, equals to buffer.length - buffer.position
The byte length of the internal Buffer
- position: <Integer> The position want to move to.
Move to the position, the position
must be the value between 0 to buffer.length.
- offset: <Integer> The bytes want to skip.
Skip offset
bytes , equals to buffer.moveTo(buffer.position + offset)
.
The target position must between 0 to buffer.length.
- offset: <Integer> The bytes want to skip.
Rewind back
offset
bytes, it is opposite tobuffer.skip(offset)
, equals tobuffer.moveTo(buffer.position - offset)
.
The target position must between 0 to buffer.length.
The various of read/write number methods are simliar to native node.js Buffer
APIs, but without the offset
argument.
All read/write methods share the same API style.
buffer.read<NumericType>()
buffer.write<NumericType>(value[, insertOffset])
Which value
is the numeric value want to write, and the optional insertOffset
argument is used to insert the value
to the specific position.
The read methods return corresponding type of value.
The write methods return <BufferPlus>
instance for chainable operations.
Note when using insertOffset
argument to insert value
, it does not override data at the given position. It will move the exist data from the insertOffset
position to (insertOffset
+ byteLength
), which byteLength
is the byte size of numeric value, then write numeric value to the insertOffset
position.
It means it will execute in-buffer copying operation when we want to insert data, and might affects performance if operating a large buffer.
Supported Read Methods
- readInt8()
- readInt16BE()
- readInt16LE()
- readInt32BE()
- readInt32LE()
- readInt64BE()
- readInt64LE()
- readUInt8()
- readUInt16BE()
- readUInt16LE()
- readUInt32BE()
- readUInt32LE()
- readUInt64BE()
- readUInt64LE()
- readFloatBE()
- readFloatLE()
- readDoubleBE()
- readDoubleLE()
Supported Write Methods
- writeInt8(value[, insertOffset])
- writeInt16BE(value[, insertOffset])
- writeInt16LE(value[, insertOffset])
- writeInt32BE(value[, insertOffset])
- writeInt32LE(value[, insertOffset])
- writeInt64BE(value[, insertOffset])
- writeInt64LE(value[, insertOffset])
- writeUInt8(value[, insertOffset])
- writeUInt16BE(value[, insertOffset])
- writeUInt16LE(value[, insertOffset])
- writeUInt32BE(value[, insertOffset])
- writeUInt32LE(value[, insertOffset])
- writeUInt64BE(value[, insertOffset])
- writeUInt64LE(value[, insertOffset])
- writeFloatBE(value[, insertOffset])
- writeFloatLE(value[, insertOffset])
- writeDoubleBE(value[, insertOffset])
- writeDoubleLE(value[, insertOffset])
Javascript <Number> object can only can only safely represent numbers between -(2^53 - 1) to 2^53 - 1, This library will convert <Number> object to/from 64-bit signed/unsigned integers. But if the 64-bit interger store on the buffer is larger than the range of <Number> object, the result will not correct.
Variant Integet(Varint) is a special integer encoding method which introduced in Protocol Buffer
It's useful to store length of dynamic data, which the length is variable.
Varints are a method of serializing integers using one or more bytes. Smaller numbers take a smaller number of bytes.
Each byte in a varint, except the last byte, has the most significant bit (msb) set – this indicates that there are further bytes to come. The lower 7 bits of each byte are used to store the two's complement representation of the number in groups of 7 bits, least significant group first.
In general speaking, Varint use 7 bits of each byte to store number, each byte store 7 bit instead of 8-bit.
The bytes to value mapping of un-signed VARUINT will be:
- 1 byte: 0 to 127
- 2 bytes: 128 to 16,383
- 3 bytes: 16,384 to 2,097,151
- 4 bytes: 2,097,152 to 268,435,455
- ... etc.
The bytes to value mapping of signed VARUINT will be:
- 1 byte: -64 to 63
- 2 bytes: -8,192 to 8,191
- 3 bytes: -1,048,576 to 1,048,575
- 4 bytes: -134,217,728 to 134,217,727
- ... etc.
Read signed variant integer
Read un-signed variant integer
Write signed variant integer
Write un-signed variant integer
Provides readString
/writeString
methods for raw string operations.
And provides convenient packed readPackedString
/writePackedString
methods which contains string length information itself.
Examples:
/*** Packed string opertion example ***/
const assert = require('assert');
const buf = BufferPlus.create();
buf.setEncoding('utf8');
const str = 'this is string';
const len = BufferPlus.byteLengthPackedString(str);
// write string to buffer
buf.writePackedString(str);
// move to begining position
buf.moveTo(0);
// fetch the string we wrote
const result = buf.readPackedString();
// compare result & str
assert.strictEqual(str, result);
/*** Raw string opertion example ***/
const assert = require('assert');
const buf = BufferPlus.create();
buf.setEncoding('utf8');
const str = 'this is string';
const len = BufferPlus.byteLength(str);
// write string to buffer
buf.writeString(str, len);
// move to begining position
buf.moveTo(0);
// fetch the string we wrote
const result = buf.readString(len);
// compare result & str
assert.strictEqual(str, result);
<String> The default string encoding of this buffer, defaults to 'utf8'
- encoding: <String> The encoding of string.
Set the default string encoding to encoding
.
- length: <Integer> Number of bytes to read. Default: buffer.length - buffer.position
- encoding: <String> The encoding of string. Default: 'utf8'.
- Returns: <String>
Read string according to the specified character encoding in encoding
.
- str: <String> String to write to
BufferPlus
. - insertOffset: <Integer> Insert the
str
to the specific position. - encoding: <String> The encoding of string. Default:
buffer.encoding
. - Returns: Current <BufferPlus> instance.
Write string to BufferPlus
.
- encoding: <String> The encoding of string. Default:
buffer.encoding
. - Returns: <String>
The convenient way to read string with packed format, which is <Varint> + <String>.
The <Varint> presents the length of string, and the <String> value presents the content of string.
- str: <String> String to write to buffer.
- insertOffset: <Integer> Insert the
str
to the specific position. - encoding: <String> The encoding of string. Default:
buffer.encoding
. - Returns: Current <BufferPlus> instance.
The convenient way to write string to BufferPlus
with packed format.
The data structure of this method is: <Varint> + <String>.
The <Varint> presents the length of str
, and the <String> value presents the content of str
.
Provides readBuffer
/writeBuffer
methods for raw buffer operations.
And provides convenient packed readPackedBuffer
/writePackedBuffer
methods which contains buffer length information itself.
Examples:
/*** Packed buffer opertion example ***/
const assert = require('assert');
const buf = BufferPlus.create();
const buf1 = Buffer.from([0x74, 0xc3, 0xa9, 0x75, 0x76]);
const len = BufferPlus.byteLengthPackedBuffer(buf1);
// write string to buffer
buf.writePackedBuffer(buf1);
// move to begining position
buf.moveTo(0);
// fetch the string we wrote
const result = buf.writePackedBuffer();
// compare result & str
assert.strictEqual(buf1, result);
/*** Raw buffer opertion example ***/
const assert = require('assert');
const buf = BufferPlus.create();
const buf1 = Buffer.from([0x74, 0xc3, 0xa9, 0x75, 0x76]);
const len = BufferPlus.byteLength(buf1);
// write string to buffer
buf.writeBuffer(buf1);
// move to begining position
buf.moveTo(0);
// fetch the string we wrote
const result = buf.readBuffer(len);
// compare result & str
assert.strictEqual(buf1, result);
- length: <Integer> Number of bytes to read. Default: buffer.length - buffer.position
- Returns: <Buffer>
Read & returns a node.js <Buffer>
- buf: <Buffer>
buf
to write toBufferPlus
. - insertOffset: <Integer> Insert the
buf
to the specific position. - Returns: Current <BufferPlus> instance.
Write buf
to BufferPlus
.
The convenient way to read <Buffer>
with packed format, which is <Varint> + <Buffer>.
The <Varint> presents the length of <Buffer>
, and the <Buffer> value presents the content of <Buffer>
.
- buf: <Buffer>
buf
to write toBufferPlus
. - insertOffset: <Integer> Insert the
buf
to the specific position. - Returns: Current <BufferPlus> instance.
The convenient way to write buf
to BufferPlus
with packed format.
The data structure of this method is: <Varint> + <Buffer>.
The <Varint> presents the length of buf
, and the <Buffer> value presents the content of buf
.
Provides readArray
/writeArray
methods for array manipulation.
/*** Array Operation Example ***/
const assert = require('assert');
const items = ['str1', 'str2', 'str3'];
const bp = BufferPlus.create();
bp.writeArray(items, 'string');
bp.moveTo(0);
const result = bp.readArray('string');
assert.strictEqual(items, result);
- dataType: <String> Data type want to read, possible values are built-in ta types, custom types or schema name.
- Returns: <Array>
Returns array of items which wrote by buffer.writeArray
method.
- items: <Array> Items with type of
dataType
want to write - dataType: <String> Data type want to read, possible values are built-in ta types, custom types or schema name.
- insertOffset: <Integer> Insert the
items
to the specific position. - Returns: Current <BufferPlus> instance
Write items
with data type of dataType
into BufferPlus
.
- name: <String> custom. type name
- Returns: <boolean>
Returns if custom type of name
exists.
- name: <String> custom. type name
- readFunc <Function> Read function for custom. type
- writeFunc <Function> Write function for custom. type
- sizeFunc <Function> Size function for custom. type
Add a custom. type, it a convenience helper to define custom. type of data and wraps read/write/byteLength opertaions.
This method will dynamic add three methods in BufferPlus:
-
BufferPlus.read<name>()
: read custom. type from current position -
BufferPlus.write<name>(value)
writevalue
with custom. type to current position -
BufferPlus.byteLength<name>()
get byte length of custom. type in current position
The type ofreadFunc
is function(buffer)
.
The type ofwriteFunc
is function(buffer, value)
.
The type ofsizeFunc
is function(value)
and return byte length of custom. type.
For Example, we add a custom. type named "Header", which contains three properties: type
, message
and items
BufferPlus.addCustomType('Header',
(buffer) => { // readFunc
const header = {}
header.type = buffer.readUInt8();
const msgLen = buffer.readVarUInt();
header.message = buffer.readString(msgLen);
header.origins = buffer.readArray('uint32le');
return header;
},
(buffer, value) => { // writeFunc
buffer.writeUInt8(value.type);
buffer.writeVarUInt(value.message.length);
buffer.writeArray(value.items, 'uint32le');
},
(value) => { // sizeFunc
return 1 + BufferPlus.byteLengthVarUInt(value.message.length)
+ BufferPlus.byteLengthArray(value.items, 'uint32le');
},
);
const header = {
type: 1,
mesage: 'header message',
origins: [1000, 2000, 3000],
};
bp = BufferPlus.create(128);
// write header into buffer
bp.writeHeader(header);
bp.moveTo(0);
// read 'Header' from buffer
const readHeader = bp.readHeader();
// read byte length of 'Header' custom. type
const headerLen = bp.byteLengthHeader(header);
Schema related methods provide read(decode) from schema and write(encode) with schema.
- name: <String> Schema name
- Returns: <Object> Decoded result
Read and decode data in buffer by schema name
, and returns decoded result.
- name: <String> Schema name
- data: <Object> The object want to encode
Encode data
by schema name
and write encoded result into buffer, the optional insertOffset
argument is used to insert the value
to the specific position.
- name: <String> Field name
- dataType: <String> | <BufferSchema> Data type of field
- Returns: <BufferSchema> | <undefined> Current
BufferSchema
instance for chainable operations.
Add field(property) to schema with field name and data type, the dataType
argument can be the supported data types like string
, uint32le
, floatbe
...etc, or it can be a BufferSchema
object which represents another schema instance that needs to be added to current schema as nested schema.
- name: <String> field name
- dataType: <String> | <BufferSchema> data type of array field
- Returns: <BufferSchema> | <undefined> Current
BufferSchema
instance for chainable operations.
Add field(property) as array fields to schema with field name and data type, the new field will be treadted as array.
The dataType
argument can be the supported data types like string
, uint32le
, floatbe
...etc, or it can be a BufferSchema
object which represents another schema instance that needs to be added to current schema as nested schema.
For example:
const messageSchema = BufferPlus.createSchema('Message', {
type: 'object',
properties: {
id: {type: 'uint32le'},
name: {type: 'string'},
},
order: ['name'],
});
const headerSchema = BufferPlus.createSchema('Header');
// the Header schema will be added a messages field, which contains list of 'Message' objects
headerSchema.addArrayField('messages', messageSchema);
Build schema with schema definitions that added previously.
It's internal method which almost not need to call from outside because all schema related methods will rebuild schema automitcally.
- obj: <Object> The object that wants to encode
- Returns <Number> Byte length of encoded data
Get the encoded data length of obj
, the obj
is the object that wants to encode.
- buffer: <BufferPlus>
BufferPlus
instance to decode - Returns: <Object> Decoded result
Read and decode data from buffer
, and returns decoded result.
- buffer: <BufferPlus>
BufferPlus
instance thatdata
encode to - data: <Object> The object want to encode
Encode data
and write encoded result into buffer
.
- encoding: <String> The encoding of string.
Set schema default string encoding to encoding
.
-
BufferPlus Class Methods
- BufferPlus.create([size])
- BufferPlus.create(buffer)
- BufferPlus.alloc(size[, fill[, encoding]])
- BufferPlus.allocUnsafe(size)
- BufferPlus.byteLength(string[, encoding])
- BufferPlus.compare(buf1, buf2)
- BufferPlus.concat(list[, totalLength])
- BufferPlus.from(...)
- BufferPlus.clone(...)
- BufferPlus.isBuffer(obj)
- BufferPlus.isBufferPlus(obj)
- BufferPlus.isEncoding(encoding)
- BufferPlus.byteLengthPackedString(str[, encoding])
- BufferPlus.byteLengthPackedBuffer(buf)
- BufferPlus.hasSchema(name)
- BufferPlus.getSchema(name)
- BufferPlus.getAllSchemas
- BufferPlus.createSchema(name, schmeaDef)
- BufferPlus.byteLengthSchema(name, obj)
- BufferSchema Prototype Methods
- Array Operations
- BufferSchema Prototype Methods