Open mezoni opened 9 years ago
Thanks. This is the first time I have ever dealt with C, I always used C++ (but I even then only have written maybe 60 lines). If you see anything else I am doing wrong, please let me know :)
I begun work on binary marshalling
.
For the purpose: "much less doing wrong" with unmarshalling binary data into Dart classes (structs).
Cool :)
This protoptype already works:
import "package:binary_types/binary_types.dart";
import "package:binary_marshalling/annotations.dart";
import "package:binary_marshalling/binary_marshalling.dart";
final BinaryUnmarshaller _unmarshaller = new BinaryUnmarshaller();
void main() {
var types = new BinaryTypes();
var helper = new BinaryTypeHelper(types);
helper.declare(_header);
final data = types["FOO"].alloc(const []);
final string = helper.allocString("Hello");
var index = 0;
for (var c in "Hey!".codeUnits) {
data["ca"][index++].value = c;
}
data["ca"][index++].value = 0;
data["cp"].value = string;
data["self"].value = data;
var count = 3;
final strings = types["char*"].array(count + 1).alloc(const []);
final heap = [];
for (var i = 0; i < count; i++) {
var object = helper.allocString("String $i");
// For preventing a deallocation (auto freeing)
heap.add(object);
strings[i].value = object;
}
for (var i = 0; i < 3; i++) {
data["cb"][i].value = 41;
}
data["strings"].value = strings;
// Now we have filled "struct foo"
// Unmarshall it to "Foo"
// JUST ONE LINE OF CODE!
Foo foo = _unmarshaller.unmarshall(data, Foo);
print("ca : ${foo.ca}");
print("cb : ${foo.cb}");
print("cp : ${foo.cp}");
print("i : ${foo.i}");
print("self : ${foo.self}");
print("strings: ${foo.strings}");
}
const String _header = '''
typedef struct foo {
// For string
char ca[10];
// For bytes
char cb[10];
struct foo *self;
int i;
char *cp;
// Ptr to null terminated array of strings
char **strings;
} FOO;
''';
class Foo {
String ca;
@NullTerminated()
List<int> cb;
String cp;
@NullTerminated()
List<String> strings;
int i = 0;
Foo self;
}
Make it available (publish)? Next will be a wrapper for binary structs.
Results:
ca : Hey!
cb : [41, 41, 41, null, null, null, null, null, null, null]
cp : Hello
i : 0
self : Instance of 'Foo'
strings: [String 0, String 1, String 2]
Slightly improved. An integer and a float values in C does not have a NULL value and they filled (rest of array elements) with an appropriate values (false, 0, 0.0).
const String _header = '''
typedef struct foo {
_Bool ba[3];
// For string
char ca[10];
// For bytes
char cb[10];
struct foo *self;
int i;
char *cp;
// Ptr to null terminated array of strings
char **strings;
} FOO;
''';
class Foo {
List<bool> ba;
String ca;
List<int> cb;
String cp;
@NullTerminated()
List<String> strings;
int i = 0;
Foo self;
}
ba : [false, false, false]
ca : Hey!
cb : [41, 41, 41, 0, 0, 0, 0, 0, 0, 0]
cp : Hello
i : 0
self : Instance of 'Foo'
strings: [String 0, String 1, String 2]
P.S.
Your opinion plays a role for me.
I like it a lot :)
@mezoni btw, I am moving all my syscall stuff into another package.
What is a puprose of
dynamic readValue(data)
? In C langauge impossible to determine is data string or not.char *str
are string or not?char *bytes
are string or not?Aslo this may not work.
This should work
I ask because once I planned add the support of
binary wrappers
andbinary readers
.Eg.
With
binary readers
plain old Dart object (PODO)Foo
can be filled (hydrated) from thetypedef struct foo Foo
without a requirements to implementing additional fillers.Of course, with a reflection but not so slow (because information about the requested (to read) runtime types (PODO) are cached).
Binary wrappers allows work slightly easier with C structs (binary data).