I am trying to convert below code to Swift:
{
// Set up the variables
double totalUsedMemory = 0.00;
mach_port_t host_port;
mach_msg_type_number_t host_size;
vm_size_t pagesize;
// Get the variable values
host_port = mach_host_self();
host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);
vm_statistics_data_t vm_stat;
// Check for any system errors
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
// Error, failed to get Virtual memory info
return -1;
}
// Memory statistics in bytes
natural_t usedMemory = (natural_t)((vm_stat.active_count +
vm_stat.inactive_count +
vm_stat.wire_count) * pagesize);
natural_t allMemory = [self totalMemory];
return usedMemory;
}
My Swift code is:
{
// Set up the variables
var totalUsedMemory: Double = 0.00
var host_port: mach_port_t
var host_size: mach_msg_type_number_t
var pagesize:vm_size_t
// Get the variable values
host_port = mach_host_self()
host_size = mach_msg_type_number_t(MemoryLayout<vm_statistics_data_t>.stride / MemoryLayout<integer_t>.stride)
// host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);
var vm_stat: vm_statistics_data_t ;
// Check for any system errors
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
// Error, failed to get Virtual memory info
return -1;
}
// Memory statistics in bytes
var usedMemory: Int64 = (Int64)((vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize);
return usedMemory;
}
I am getting these 2 errors:
**Binary operator '&' cannot be applied to operands of type '(host_info_t).Type' (aka 'UnsafeMutablePointer.Type') and 'vm_statistics_data_t' (aka 'vm_statistics')
in this statement
host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size)
And
Binary operator '*' cannot be applied to operands of type 'UInt32' and 'vm_size_t' (aka 'UInt')**
in this statement -
var usedMemory: Int64 = (Int64)((vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize);
Swift is a lot more strict about pointer types than C is, which can make it a real pain to interact with functions like this that expect you to pass pointers to types other than the actual type of the thing you're trying to pass to the function. So I agree with the commenters that you're probably better off leaving this function in (Objective-)C. However, if you absolutely have to convert to Swift, you're probably going to have to do something like this:
// Initialize a blank vm_statistics_data_t
var vm_stat = vm_statistics_data_t()
// Get a raw pointer to vm_stat
let err: kern_return_t = withUnsafeMutableBytes(of: &vm_stat) {
// Bind the raw buffer to Int32, since that's what host_statistics
// seems to want a pointer to.
let boundBuffer = $0.bindMemory(to: Int32.self)
// Call host_statistics, and return its status out of the closure.
return host_statistics(host_port, HOST_VM_INFO, boundBuffer.baseAddress, &host_size)
}
// Now take a look at what we got and compare it against KERN_SUCCESS
if err != KERN_SUCCESS {
// Error, failed to get Virtual memory info
return -1;
}
Related
I have the same code without an array and it just works.
But In this one if i enter amount anything more than 0.001 ether it gives an overflow error.
I tried Other functions called in this one with errored values and they don't give an error.
CheckPairValue() and CheckSellPrice() works.
Code is to check my Wallet's worth in pancakeswap
Idk what's wrong.
Any help is appretiated.
Also Contract is verified on bscscan.
Contract
function GetSellValue(address[] memory TokenAddress, uint[] memory Amount)public view returns(uint256[] memory){
uint[] memory Value = new uint[](TokenAddress.length);
for(uint i = 0; i < TokenAddress.length; i++){
address Pair = CheckPairValue(TokenAddress[i], Amount[i] * 2);
address[] memory path;
if(Pair != PairAddresses[0]){
path = new address[](3);
path[0] = TokenAddress[i];
path[1] = Pair;
path[2] = PairAddresses[0];
}
else
{
path = new address[](2);
path[0] = TokenAddress[i];
path[1] = PairAddresses[0];
}
Value[i] = CheckSellPrice(Amount[i],path);
}
return Value;
}
0.001 ether input works , anything higher doesn't
I still don't know why remix errored like this.
But i've written a js code to call the contract and it works.
I want to access an existing array of UInt64 as if it is an array of Int8. Key requirement is efficiency - I don't want to copy or reallocate the data, just have direct access. I don't want side effects (for example I want to be able to continue to use the uint64Array after this block of code has executed, was reading about rebinding having undefined side effects.)
I tried doing this with Swift 4.2:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.withUnsafeMutableBufferPointer() {
uint64Pointer in
uint64Pointer.withMemoryRebound(to: Int8.self) { // <- Error occurs here.
int8Pointer in
int8Pointer[0] = 1
int8Pointer[1] = 2
int8Pointer[2] = 3
int8Pointer[3] = 4
}
}
However I get a Fatal Error at runtime on the following line:
uint64Pointer.withMemoryRebound(to: Int8.self) {
Is this the right approach? If so, why am I getting the Fatal Error?
I think the problem is that you can't bind to a different type directly as per this note in the docs:
Only use this method to rebind the buffer’s memory to a type with the same size and stride as the currently bound Element type. To bind a region of memory to a type that is a different size, convert the buffer to a raw buffer and use the bindMemory(to:) method.
If bytes is what you're after then the quickest route is:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.withUnsafeMutableBytes { x in
x[0] = 1
x[1] = 2
x[3] = 3
x[4] = 4
}
If you have another type you'd like to use you can do it like this:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.withUnsafeMutableBufferPointer() {
uint64Pointer in
let x = UnsafeMutableRawBufferPointer(uint64Pointer).bindMemory(to: Int32.self)
x[0] = 1
x[1] = 2
x[3] = 3
x[4] = 4
}
Thanks to #brindy for solving this one. Here is an extension implementation that is as clean as I could get it.
The extension:
extension Array {
mutating func bindMutableMemoryTo<T,R>(_ type: T.Type, _ closure: (UnsafeMutableBufferPointer<T>) throws -> R) rethrows -> R {
return try self.withUnsafeMutableBytes() {
return try closure($0.bindMemory(to: type))
}
}
}
Usage:
var uint64Array = [UInt64](repeating: 0, count: 100)
uint64Array.bindMutableMemoryTo(Int8.self) {
int8Pointer in
int8Pointer[0] = 1 // LSB of uint64Array[0]
int8Pointer[1] = 2
int8Pointer[2] = 3
int8Pointer[3] = 4 // MSB of uint64Array[0]
}
I'm trying to create a function that will work for any array-like object in Flash but I'm really struggling to find a way to let the compiler know what I'm doing. I need to use functions like indexOf on the argument, but unless it is cast to the correct data type the compiler doesn't know that method is available. It's frustrating because Vector and Array share pretty much the same interface but there isn't an Interface to reflect that!
At the moment I've got this:
private function deleteFirst(tV:* , tVal:*):void {
trace(tV)
var tIndex:int
if (tV is Array) {
var tArray:Array = tV as Array
tIndex = tArray.indexOf(tVal)
if (tIndex >= 0) tArray.splice(tIndex, 1)
} else if (tV is Vector.<*>) {
var tVObj:Vector.<*> = tV as Vector.<*>
tIndex = tVObj.indexOf(tVal)
if (tIndex >= 0) tVObj.splice(tIndex, 1)
} else if (tV is Vector.<Number>) {
var tVNum:Vector.<Number> = tV as Vector.<Number>
tIndex = tVNum.indexOf(tVal)
if (tIndex >= 0) tVNum.splice(tIndex, 1)
} else if (tV is Vector.<int>) {
var tVInt:Vector.<int> = tV as Vector.<int>
tIndex = tVInt.indexOf(tVal)
if (tIndex >= 0) tVInt.splice(tIndex, 1)
} else if (tV is Vector.<uint>) {
var tVUInt:Vector.<uint> = tV as Vector.<uint>
tIndex = tVUInt.indexOf(tVal)
if (tIndex >= 0) tVUInt.splice(tIndex, 1)
}
trace(tV)
}
It kind of works but it's not exactly elegant! I'm wondering if there's a trick I'm missing. Ideally I'd do this by extending the base class, but I don't think that's possible with Vector.
Thanks
I would be very careful about mixing and matching Vectors and Arrays. The biggest difference between them is that Arrays are sparse, and Vectors are dense.
That said, here is your very compact generic removal function that will work on ANY "set" class that has indexOf and splice...
function deleteFirst( set:Object, elem:Object ) : Boolean
{
if ( ("indexOf" in set) && ("splice" in set) )
{
var idx:int = set.indexOf( elem );
if ( idx >= 0 )
{
set.splice( idx, 1 );
return true;
}
}
return false;
}
You can test the code with this code
var arr:Array = [ 1, 2, 3, 4, 5 ];
var vec:Vector.<int> = new Vector.<int>();
vec.push( 1, 2, 3, 4, 5 );
deleteFirst( arr, 2 ); // will remove 2
deleteFirst( vec, 3 ); // will remove 3
deleteFirst( "aaa4", "4" ); // nothing, cuz String doesn't have splice
trace( arr );
trace( vec );
UPDATE - For #Arron only, I've made the below change. Note that getting exceptions is good. They are informative and help reveal issues with the code path.
function deleteFirst( set:Object, elem:Object ) : Boolean
{
var idx:int = set.indexOf( elem );
if ( idx >= 0 )
{
set.splice( idx, 1 );
return true;
}
return false;
}
There! Now it's even simpler. You get an exception that tells you what's wrong!
This is definitely a short-coming of AS3, I don't think there is any elegant solution.
However, one code simplification you can make:
Since the syntax for indexOf() and splice() is the same for both arrays and vectors, you don't need that big if/else ladder to cast every type. You can simply call indexOf() and splice() on the object without any casting. Of course, you don't get any code-hints in your IDE, but it will work the same as you currently have. Example:
function deleteFirst(arrayOrVector:* , searchValue:*):* {
if (arrayOrVector is Array || arrayOrVector is Vector.<*> || arrayOrVector is Vector.<Number> || arrayOrVector is Vector.<int> || arrayOrVector is Vector.<uint>) {
var index:int = arrayOrVector.indexOf(searchValue)
if (index >= 0)
arrayOrVector.splice(index, 1)
}else
throw new ArgumentError("Argument 'arrayOrVector' must be an array or a vector, but was type " + getQualifiedClassName(arrayOrVector));
return arrayOrVector;
}
You can even skip the whole if/else type check and it would still work, it would just make the code more confusing, and you would get a slightly more confusing error if you called the function with an argument other than array or vector (like "indexOf not found on type Sprite" if you passed a sprite object by accident).
Also it's worth mentioning that, while this doesn't help you with number base type vectors, with other vectors you can sort of use Vector.<*> as a generic vector reference. You can assign a reference using the Vector global function with wildcard (Vector.<*>(myVector)) and it will return a reference to the original vector instead of a new copy as it usually does. If you don't mind returning a copy of number based type vectors instead of always modifying the original vector, you can still take advantage of this to simplify your code:
function deleteFirst(arrayOrVector:* , searchValue:*):* {
if (arrayOrVector is Array) {
var array:Array = arrayOrVector;
var index:int = array.indexOf(searchValue)
if (index >= 0)
array.splice(index, 1)
return array;
}else if(arrayOrVector is Vector.<*> || arrayOrVector is Vector.<Number> || arrayOrVector is Vector.<int> || arrayOrVector is Vector.<uint>) {
var vector:Vector.<*> = Vector.<*>(arrayOrVector);
index = vector.indexOf(searchValue);
if (index >= 0)
vector.splice(index, 1);
return vector;
}
throw new ArgumentError("Argument 'arrayOrVector' must be an array or a vector, but was type " + getQualifiedClassName(arrayOrVector));
}
I'm working on a Ruby native C method: power mod. Here's what I got:
#define TO_BIGNUM(x) (FIXNUM_P(x) ? rb_int2big(FIX2LONG(x)) : x)
#define CONST2BIGNUM(x) (TO_BIGNUM(INT2NUM(x)))
VALUE method_big_power_mod(VALUE self, VALUE base, VALUE exp, VALUE mod){
VALUE res = TO_BIGNUM(INT2NUM(1));
base = TO_BIGNUM(base);
exp = TO_BIGNUM(exp);
mod = TO_BIGNUM(mod);
while (rb_big_cmp(exp, CONST2BIGNUM(0))) {
if (rb_big_modulo(exp, CONST2BIGNUM(2))) {
VALUE mul = rb_big_mul(res, base);
res = rb_big_modulo(mul, mod);
}
base = rb_big_modulo(rb_big_pow(base, CONST2BIGNUM(2)), mod);
exp = rb_big_div(exp, CONST2BIGNUM(2));
}
return res;
}
It segfaults every time. I isolated the problem to rb_big_modulo calls. gdb stacktrace says that it crashes in the bigdivrem method after calling rb_big_modulo. I tried to look through the source of bignum.c, but I can't figure out what's causing the crash. Am I doing something wrong?
There are two problems that are causing the segfault:
1 - The functions rb_big_* sometimes doesn't return a Bignum object, but when you call then the first arg must be a Bignum object. For example:
if (rb_big_modulo(exp, CONST2BIGNUM(2))) {
VALUE mul = rb_big_mul(res, base); // This maybe return a Fixnum
res = rb_big_modulo(mul, mod); // This will cause a segfault :(
}
2 - The function rb_big_pow when you call it with both args Bignum, it will warn you and will return a Float object where you can't convert easily to a Bignum object. So, you should replace the line where you call it by:
VALUE x = TO_BIGNUM(rb_big_pow(base, INT2NUM(2))); // Power by a Fixnum instead a Bignum
base = TO_BIGNUM(rb_big_modulo(x , mod));
The final implementation will be:
#define TO_BIGNUM(x) (FIXNUM_P(x) ? rb_int2big(FIX2LONG(x)) : x)
#define CONST2BIGNUM(x) (TO_BIGNUM(INT2NUM(x)))
VALUE method_big_power_mod(VALUE self, VALUE base, VALUE exp, VALUE mod){
VALUE res = TO_BIGNUM(INT2NUM(1));
base = TO_BIGNUM(base);
exp = TO_BIGNUM(exp);
mod = TO_BIGNUM(mod);
while (rb_big_cmp(exp, CONST2BIGNUM(0))) {
if (rb_big_modulo(exp, CONST2BIGNUM(2))) {
VALUE mul = TO_BIGNUM(rb_big_mul(res, base));
res = TO_BIGNUM(rb_big_modulo(mul, mod));
}
VALUE x = TO_BIGNUM(rb_big_pow(base, INT2NUM(2)));
base = TO_BIGNUM(rb_big_modulo(x , mod));
exp = TO_BIGNUM(rb_big_div(exp, CONST2BIGNUM(2)));
}
return res;
}
I don't know the performance impact with all these conversions. Maybe, you should test when it is a Fixnum or a Bignumand calculate it using the proper function or benchmark both approaches.
When I ran it, I went thought an infinite loop, but I don't know if I call it with the correct values.
What follows is an initializer method. It creates a Movie structure from a file, with an eye to extracting the raw pixels for processing, as per Apple QA1443. This is then wrapped in a QTMovie – sourceMovie = [QTMovie movieWithQuickTimeMovie: ...] – for convenience.
After initializing such an object, the second method is called, and we attempt to use sourceMovie. However, it turns out that any attempt to access sourceMovie here results in EXC_BAD_ACCESS For instance, NSLog(#"%#", sourceMovie) is impossible. The movie appears to have been deallocated, although it is not clear why.
Furthermore, in this second method, the usual methods to obtain a CVPixelBufferRef do not properly function: QTVisualContextIsNewImageAvailable seems always to return NO, and QTVisualContextCopyImageForTime always gives you an imageBuffer pointing at 0x00. (I guess this is not surprising if the QTMovie, Movie or visualContext are somehow being deallocated.)
The question then is, why is sourceMovie inaccessible from the second method? Is it being deallocated as it seems? If so, why?
And now the code, and sorry in advance for the length.
// From the .h, we have the following inst var declarations:
Movie myMovie;
QTMovie *sourceMovie;
QTVisualContextRef visualContext;
CVPixelBufferRef imageBuffer;
pixels_xy sourceSize;
MovieAnalyzer *analyzer;
// And now to the #implementation...
-(id)initWithFileString:(NSString *)file {
if (self = [super init]) {
NSError *e;
// Bit of a hack - get the movie size using temporary QTMovie.
sourceMovie = [QTMovie movieWithFile:file error:&e];
if (e) {
[self release];
NSLog(#"Could not open movie.");
return nil;
}
NSSize movieSize = [[sourceMovie posterImage] size];
CGRect bounds = CGRectMake(0, 0, movieSize.width, movieSize.height);
// Save the size in pixels.
sourceSize.x = (int)movieSize.width, sourceSize.y = (int)movieSize.height;
CFStringRef movieLocation = (CFStringRef) file;
// Get a QT Visual Context, and create a movie inialized to use it for output.
visualContext = NULL;
OSStatus status = CreatePixelBufferContext(k32ARGBPixelFormat, &bounds, &visualContext);
if (noErr != status && NULL == visualContext) {
[self release];
NSLog(#"Problem initializing QT Visual Context.");
return nil;
}
/*** Instantiate the Movie ***/
myMovie = NULL;
Boolean trueValue = true;
QTNewMoviePropertyElement newMovieProperties[3] = {0};
// Setup movie location
newMovieProperties[0].propClass = kQTPropertyClass_DataLocation;
newMovieProperties[0].propID = kQTDataLocationPropertyID_CFStringPosixPath;
newMovieProperties[0].propValueSize = sizeof(CFStringRef);
newMovieProperties[0].propValueAddress = &movieLocation;
// Assign the visual context - could also be NULL
newMovieProperties[1].propClass = kQTPropertyClass_Context;
newMovieProperties[1].propID = kQTContextPropertyID_VisualContext;
newMovieProperties[1].propValueSize = sizeof(visualContext);
newMovieProperties[1].propValueAddress = &visualContext;
// Make the movie active
newMovieProperties[2].propClass = kQTPropertyClass_NewMovieProperty;
newMovieProperties[2].propID = kQTNewMoviePropertyID_Active;
newMovieProperties[2].propValueSize = sizeof(trueValue);
newMovieProperties[2].propValueAddress = &trueValue;
status = NewMovieFromProperties(3, newMovieProperties, 0, NULL, &myMovie);
if (status != noErr || myMovie == NULL) {
NSLog(#"Problem initializing theMovie"); // problem
[self release];
return nil;
}
// Create a new QTMovie with the Movie as its backing object
sourceMovie = [QTMovie movieWithQuickTimeMovie:myMovie disposeWhenDone:NO error:&e];
if (e) {
NSLog(#"Could not initialize QTMovie from Movie.");
[self release];
return nil;
}
[sourceMovie stepForward];
analyzer = [[MovieAnalyzer alloc] initWithColorString:"BGRA" andSourceSize:sourceSize];
}
return self;
}
-(NSImage*) supplyCalibrationImage {
NSLog(#"%x", &sourceMovie);
[sourceMovie stepForward]; // This fails!
....
}
[QTMovie movieWithQuickTimeMovie:disposeWhenDone:error:] is returning an autoreleased movie. If you want it to stick around past that one method, you need to retain it.