capnproto 0.2.0 capnproto: ^0.2.0 copied to clipboard
Cap'n Proto is an extremely efficient protocol for sharing data and capabilities.
import 'dart:io';
import 'dart:typed_data';
import 'package:capnproto/capnproto.dart';
void main(List<String> args) {
// Read the compiled example message:
final compiledFile = File('example/message.bin');
print(compiledFile.absolute.path);
final data = compiledFile.readAsBytesSync();
final message = Message.fromBuffer(data.buffer);
// And decode it:
final testStruct = message.getRoot(TestStruct.from);
print(testStruct);
}
// For every struct in your Cap'n Proto definitions, create a class like this:
class TestStruct {
// Create a constructor like the following:
const TestStruct(this.segmentView, this.dataSectionLengthInWords);
// Create a static method called `from`, which delegated to the above
// constructor. (We use this because tear-offs don't work for named
// constructors.)
// ignore: prefer_constructors_over_static_methods
static TestStruct from(
SegmentView segmentView,
int dataSectionLengthInWords,
) =>
TestStruct(segmentView, dataSectionLengthInWords);
final SegmentView segmentView;
final int dataSectionLengthInWords;
// Write a getter for each member. They delegate to getters on `segmentView`
// (a view of the underlying buffer).
//
// The offsets are generated by Cap'n Proto if you execute the following
// command:
//
// > capnp compile -ocapnp main.capnp > main-compiled.capnp
//
// (Where `main.capnp` is your source file and `main-compiled.capnp` gets
// generated.)
//
// You then fill in the offsets for every getter as follows:
//
// * anything for `Void`
// * bits for `Bool`
// E.g., the generated line for the field `boolean` looks like:
// boolean @1 :Bool; # bits[0, 1)
// ^ You want this number.
// * bytes for other primitives (i.e., numbers)
// E.g., the generated line for the field `int8` looks like:
// int8 @3 :Int8; # bits[8, 16)
// ^ You want this number, divided by eight (or
// `CapnpConstants.bitsPerByte`).
// Hence: ``
// * `dataSectionLengthInWords + <pointerIndex>` for nested structs and lists.
// E.g., the generated line for the field `float32List` looks like:
// float32List @13 :List(Float32); # ptr[2]
// ^ You want this number.
// Hence: `segmentView.getFloat32List(dataSectionLengthInWords + 2)`
//
// For inner structs and lists of structs, you also have to pass in a
// `StructFactory`, which is used to actually instantiate those structs. This
// is why we wrote the static function `from` above.
void get unit => segmentView.getVoid(0);
bool get boolean => segmentView.getBool(0);
UnmodifiableBoolListView get booleanList =>
segmentView.getBoolList(dataSectionLengthInWords + 0);
int get int8 => segmentView.getInt8(8 ~/ CapnpConstants.bitsPerByte);
int get int16 => segmentView.getInt16(16 ~/ CapnpConstants.bitsPerByte);
int get int32 => segmentView.getInt32(32 ~/ CapnpConstants.bitsPerByte);
int get int64 => segmentView.getInt64(64 ~/ CapnpConstants.bitsPerByte);
int get uint8 => segmentView.getUInt8(128 ~/ CapnpConstants.bitsPerByte);
int get uint16 => segmentView.getUInt16(144 ~/ CapnpConstants.bitsPerByte);
UnmodifiableUint16ListView get uint16List =>
segmentView.getUInt16List(dataSectionLengthInWords + 1);
int get uint32 => segmentView.getUInt32(160 ~/ CapnpConstants.bitsPerByte);
int get uint64 => segmentView.getUInt64(192 ~/ CapnpConstants.bitsPerByte);
double get float32 =>
segmentView.getFloat32(256 ~/ CapnpConstants.bitsPerByte);
UnmodifiableFloat32ListView get float32List =>
segmentView.getFloat32List(dataSectionLengthInWords + 2);
double get float64 =>
segmentView.getFloat64(320 ~/ CapnpConstants.bitsPerByte);
String get text => segmentView.getText(dataSectionLengthInWords + 3);
UnmodifiableUint8ListView get data =>
segmentView.getData(dataSectionLengthInWords + 4);
Foo get foo => segmentView.getStruct(dataSectionLengthInWords + 5, Foo.from);
UnmodifiableCompositeListView<Foo> get fooList =>
segmentView.getCompositeList(dataSectionLengthInWords + 6, Foo.from);
// This is optional:
@override
String toString() =>
'TestStruct(unit: <void>, boolean: $boolean, booleanList: $booleanList, int8: $int8, int16: $int16, int32: $int32, int64: $int64, uint8: $uint8, uint16: $uint16, uint16List: $uint16List, uint32: $uint32, uint64: $uint64, float32: $float32, float32List: $float32List, float64: $float64, text: $text, data: $data, foo: $foo, fooList: $fooList';
}
class Foo {
const Foo(this.segmentView, this.dataSectionLengthInWords);
// ignore: prefer_constructors_over_static_methods
static Foo from(SegmentView segmentView, int dataSectionLengthInWords) =>
Foo(segmentView, dataSectionLengthInWords);
final SegmentView segmentView;
final int dataSectionLengthInWords;
int get bar => segmentView.getUInt8(0);
@override
String toString() => 'Foo(bar: $bar)';
}
// ignore_for_file: avoid_print