mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-27 10:50:35 +00:00
Bug 771928 - OS.File pointer arithmetics. r=froydnj
This commit is contained in:
parent
8d5c2b19dd
commit
f3ff2d0747
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user