Permalink
Browse files

Added struct nesting

  • Loading branch information...
1 parent e6c42a4 commit ddba83d68d75cb5c059ab5c55d0654794d585382 @rbranson rbranson committed Nov 15, 2010
Showing with 54 additions and 14 deletions.
  1. +1 −1 README.md
  2. +1 −2 lib/errno.js
  3. +29 −11 lib/struct.js
  4. +23 −0 test/test.js
View
@@ -23,7 +23,7 @@ WARNING: node-ffi assumes you know what you're doing. You can pretty easily crea
# REQUIREMENTS
* Linux, OS X, or Solaris.
-* You will need node.js 0.2.0+
+* You will need node.js 0.2.3+
# NPM INSTALL
View
@@ -21,5 +21,4 @@ var errno = module.exports = function() {
else {
return errnoGlobal.getInt32();
}
-};
-
+};
View
@@ -26,19 +26,31 @@ var Struct = module.exports = function(fields) {
function read(ptr, name) {
var info = struct.struct[name];
var fptr = ptr.seek(info.offset);
- return fptr["get" + FFI.TYPE_TO_POINTER_METHOD_MAP[info.type]]();
+
+ if (FFI.isStructType(info.type)) {
+ return new info.type(fptr);
+ }
+ else {
+ return fptr["get" + FFI.TYPE_TO_POINTER_METHOD_MAP[info.type]]();
+ }
}
function write(ptr, name, val) {
var info = struct.struct[name];
var fptr = ptr.seek(info.offset);
- return fptr["put" + FFI.TYPE_TO_POINTER_METHOD_MAP[info.type]](val);
+
+ if (FFI.isStructType(info.type)) {
+ new info.type(fptr, val);
+ }
+ else {
+ return fptr["put" + FFI.TYPE_TO_POINTER_METHOD_MAP[info.type]](val);
+ }
}
+ // TODO: Allow serialize/deserialize to accept struct instances?
function serialize(ptr, data) {
- for (var i = 0, len = struct.members.length; i < len; i++) {
- var name = struct.members[i];
- write(ptr, name, data[name]);
+ for (var key in data) {
+ write(ptr, key, data[key]);
}
}
@@ -64,30 +76,36 @@ var Struct = module.exports = function(fields) {
throw new Error("Error when constructing Struct: " + name + " field specified twice!");
}
else {
- var sz = FFI.Bindings.TYPE_SIZE_MAP[type],
- offset = struct.size;
+ var stype = FFI.isStructType(type),
+ sz = stype ? type.__structInfo__.size : FFI.Bindings.TYPE_SIZE_MAP[type],
+ offset = struct.size,
+ asz = stype ? type.__structInfo__.alignment : sz;
struct.size += sz;
- struct.alignment = Math.max(struct.alignment, sz);
- struct.size += Math.abs(struct.alignment - sz);
+ struct.alignment = Math.max(struct.alignment, asz);
+ struct.size += struct.size % struct.alignment;
struct.struct[name] = { "name": name, "type": type, "size": sz, "offset": offset };
struct.members.push(name);
}
}
}
- var constructor = function(arg) {
+ var constructor = function(arg, data) {
this.__isStructInstance__ = true;
this.__structInfo__ = struct;
if (arg instanceof FFI.Pointer) {
this.__pointer = arg;
+
+ if (data) {
+ serialize(this.__pointer, data);
+ }
}
else {
this.__pointer = new FFI.Pointer(struct.size);
- if (arg != null) {
+ if (arg) {
serialize(this.__pointer, arg);
}
}
View
@@ -450,6 +450,29 @@ setTimeout(function() {
assert.equal(tv.tv_sec, Math.floor(Date.now() / 1000));
})();
+// Test FFI.Struct nesting
+(function() {
+ var ChildStructType = FFI.Struct([
+ ["int", "a"],
+ ["int", "b"]
+ ]);
+
+ var ParentStructType = FFI.Struct([
+ [ChildStructType, "childA"],
+ [ChildStructType, "childB"]
+ ]);
+
+ var ps = new ParentStructType({
+ "childA": { "a": 100, "b": 200 },
+ "childB": { "a": 300, "b": 400 }
+ });
+
+ assert.equal(100, ps.childA.a);
+ assert.equal(200, ps.childA.b);
+ assert.equal(300, ps.childB.a);
+ assert.equal(400, ps.childB.b);
+})();
+
///////////////////////
util.log("Heap increased by " + ((process.memoryUsage()["rss"] - rss) / 1024) + " KB");

0 comments on commit ddba83d

Please sign in to comment.