Bug 771928 - OS.File pointer arithmetics. r=froydnj

This commit is contained in:
David Rajchenbach-Teller 2012-08-16 22:05:30 -04:00
parent 8d5c2b19dd
commit f3ff2d0747

View File

@ -118,8 +118,10 @@
*/
get in_ptr() {
delete this.in_ptr;
let ptr_t = new PtrType("[in] " + this.name + "*",
this.implementation.ptr);
let ptr_t = new PtrType(
"[in] " + this.name + "*",
this.implementation.ptr,
this);
Object.defineProperty(this, "in_ptr",
{
get: function() {
@ -134,8 +136,10 @@
*/
get out_ptr() {
delete this.out_ptr;
let ptr_t = new PtrType("[out] " + this.name + "*",
this.implementation.ptr);
let ptr_t = new PtrType(
"[out] " + this.name + "*",
this.implementation.ptr,
this);
Object.defineProperty(this, "out_ptr",
{
get: function() {
@ -154,8 +158,10 @@
*/
get inout_ptr() {
delete this.inout_ptr;
let ptr_t = new PtrType("[inout] " + this.name + "*",
this.implementation.ptr);
let ptr_t = new PtrType(
"[inout] " + this.name + "*",
this.implementation.ptr,
this);
Object.defineProperty(this, "inout_ptr",
{
get: function() {
@ -193,7 +199,17 @@
*/
cast: function cast(value) {
return ctypes.cast(value, this.implementation);
}
},
/**
* Return the number of bytes in a value of |this| type.
*
* This may not be defined, e.g. for |void_t|, array types
* without length, etc.
*/
get size() {
return this.implementation.size;
}
};
@ -202,9 +218,19 @@
*
* @param {string} name The name of this type.
* @param {CType} implementation The type of this pointer.
* @param {Type} targetType The target type.
*/
function PtrType(name, implementation) {
function PtrType(name, implementation, targetType) {
Type.call(this, name, implementation);
if (targetType == null || !targetType instanceof Type) {
throw new TypeError("targetType must be an instance of Type");
}
/**
* The type of values targeted by this pointer type.
*/
Object.defineProperty(this, "targetType", {
value: targetType
});
}
PtrType.prototype = Object.create(Type.prototype);
@ -371,7 +397,8 @@
*/
Types.voidptr_t =
new PtrType("void*",
ctypes.voidptr_t);
ctypes.voidptr_t,
Types.void_t);
// void* is a special case as we can cast any pointer to/from it
// so we have to shortcut |in_ptr|/|out_ptr|/|inout_ptr| and
@ -765,7 +792,50 @@
exports.OS.Shared.Utils = {};
let Strings = exports.OS.Shared.Utils.Strings = {};
let Pointers = exports.OS.Shared.Utils.Pointers = {};
// A bogus array type used to perform pointer arithmetics
let gOffsetByType;
/**
* Advance a pointer by a number of items.
*
* This method implements adding an integer to a pointer in C.
*
* Example:
* // ptr is a uint16_t*,
* offsetBy(ptr, 3)
* // returns a uint16_t* with the address ptr + 3 * 2 bytes
*
* @param {C pointer} pointer The start pointer.
* @param {number} length The number of items to advance. Must not be
* negative.
*
* @return {C pointer} |pointer| advanced by |length| items
*/
exports.OS.Shared.offsetBy =
function offsetBy(pointer, length) {
if (length === undefined || length < 0) {
throw new TypeError("offsetBy expects a positive number");
}
if (!("isNull" in pointer)) {
throw new TypeError("offsetBy expects a pointer");
}
if (length == 0) {
return pointer;
}
let type = pointer.constructor;
let size = type.targetType.size;
if (size == 0 || size == null) {
throw new TypeError("offsetBy cannot be applied to a pointer without size");
}
let bytes = length * size;
if (!gOffsetByType || gOffsetByType.size <= bytes) {
gOffsetByType = ctypes.uint8_t.array(bytes * 2);
}
let addr = ctypes.cast(pointer, gOffsetByType.ptr).
contents.addressOfElement(bytes);
return ctypes.cast(addr, type);
};
/**
* Import a wide string (e.g. a |jschar.ptr|) as a string.
@ -824,9 +894,6 @@
return Strings.importWString(decoded);
};
exports.OS.Shared.Utils = { Strings: Strings };
/**
* Specific tools that don't really fit anywhere.
*/