binarize 1.4.0 binarize: ^1.4.0 copied to clipboard
Binarize allows for a more streamlined and extendable binary creation experience.
Binarize #
From Wiktionary:
Etymology #
binary + size
Verb #
binarize (third-person singular simple present binarizes, present participle binarizing, simple past and past participle binarized)
- (mathematics) To represent in binary (base 2) notation
- To convert (an image) to only black and white.
- (statistics) To dichotomize a variable.
Binarize is a package that wraps the ByteData functionality into a more streamlined and extendable payload system.
With Binarize you can easily create and read binary data into the correct value types without having to check for the correct byte offset or figure out which ByteData method you need to use.
This is especially useful for when you are implementing a file format specification, like the PSD File Format.
Installation #
Add binarize
as a dependency to your pubspec.yaml file (what?).
Import Binarize:
import 'package:binarize/binarize.dart';
Docs & API #
The API Docs provide information about how to use Binarize.
If you want to see Binarize in practice, check the example. It showcases all the types that Binarize provides.
Usage #
Writing #
The Payload.write
method returns a PayloadWriter
that is used for writing values using
different PayloadTypes:
import 'package:binarize/binarize.dart';
void main() {
final writer = Payload.write()
..set(uint8, 16);
..set(string32, 'Hello World');
}
The binarize
method accepts a PayloadWriter
and converts the values to binary:
void main() {
final writer = Payload.write();
...
// Binarize the writer to a Uint8List.
final bytes = binarize(writer);
...
}
Reading #
The Payload.read
method returns a PayloadReader
that reads a list of bytes. The data from that
list can be retrieved by using different PayloadTypes:
import 'package:binarize/binarize.dart';
void main() {
...
final reader = Payload.read(bytes);
final aUint8 = reader.get(uint8);
final aString = reader.get(string32);
...
}
Note: The order in which the values are written is also the order in which they have to be retrieved.
PayloadType
s #
PayloadType
s are the backbone of Binarize, they do all the heavy lifting of packing and unpacking
bytes. Binarize provides all the basis types that the ByteData class has to offer. But in some
cases a developer might want to create their own PayloadType
. Thankfully Binarize's API allows
for custom PayloadType
s.
Here is an example for a PayloadType
that packs and unpacks the Vector2
class from the
vector_math library:
import 'package:binarize/binarize.dart';
import 'package:vector_math/vector_math.dart';
// Define the PayloadType class, it is private as we only want to have a
// single constant instance for it.
class _Vector2 extends PayloadType<Vector2> {
const _Vector2();
// The byte length, it should return the total byte length it will use for a
// given value. In this case we have two float32 values, each uses 4 bytes
// so our total length is 8.
@override
int length(Vector2 value) => 8;
// Called when the user reads data, the offset is the current read offset
// in the given data.
@override
Vector2 get(ByteData data, int offset) {
return Vector2(
// Read the x value at the current offset.
data.getFloat32(offset),
// Read the y value at the current offset + 4. Float32 has a default
// byte length of 4 so we have to take that into consideration so
// that we don't read the x value again.
data.getFloat32(offset + 4),
);
}
// Called when the user write data, the offset is the current write offset
// in the given byte data.
@override
void set(Vector2 value, ByteData data, int offset) {
// Write the x value at the current offset.
data.setFloat32(offset, value.x);
// Write the y value at the current offset + 4. The 4 is needed as Float32
// have a byte length of 4 so we have to take that into consideration so
// we don't overwrite the x value.
data.setFloat32(offset + 4, value.y);
}
}
// And finally the user-facing variable that users can use to read and write
// with.
const vector2 = _Vector2();
The vector2
can be used like any other PayloadType
:
import 'package:binarize/binarize.dart';
import 'package:vector_math/vector_math.dart';
// Import the newly created vector2 PayloadType.
import './types/vector2.dart';
void main() {
// Write a Vector2.
final writer = Payload.write()..set(vector2, Vector2(100.5, 200));
// Binarize the writer to a Uint8List.
final bytes = binarize(writer);
// Reading our
final reader = Payload.read(bytes);
// The x value will be 100.5 and the y value will be 200.
final aVector2 = reader.get(vector2);
}