I want to zero-out the contents of an UnsafeMutablePointer in Swift.
In C you usually have something like this:
void freeSecure(void *buffer, uint64_t size) {
// Create volatile pointer to make sure that the code won't be optimized away
volatile uint8_t *ptr = buffer;
for (uint64_t i = 0; i < size; i++) ptr[i] = 0x00;
free(buffer);
}
How can I achieve the same thing in Swift?
// Is extension of `UnsafeMutablePointer`
public func KC_dealloc(allocated: Int) {
if num == 0 {
self.destroy()
self.dealloc(allocated)
return
}
let byteCount = sizeof(Memory) * allocated
let ptr = UnsafeMutablePointer<UInt8>(self) // volatile???
for var i = 0; i < byteCount; i++ {
ptr[i] = 0x00
}
self.destroy()
self.dealloc(allocated)
}
Okay, I asked the same question in the Apple-developer-forum and some guy there pointed me to the memset_s-function which does what I want.
So my Swift-code should look like this:
// Is extension of `UnsafeMutablePointer`
public func KC_dealloc(allocated: Int) {
if num == 0 {
self.destroy()
self.dealloc(allocated)
return
}
let byteCount = sizeof(Memory) * allocated
let ptr = UnsafeMutablePointer<UInt8>(self) // volatile???
memset_s(ptr, byteCount, 0x00, byteCount) // Defined in C11
self.destroy()
self.dealloc(allocated)
}
Related
I am creating a character customization system. I have 2 shirts with their own 2 textures.
When I switch shirts the all of the textures are applying two both renderers instead of their own.
Any help would be appreciated. Here is my script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharCustomizationOne : MonoBehaviour
{
public GameObject[] characters;
public GameObject[] maleHairs;
public GameObject[] maleShirts;
public GameObject[] malePants;
public GameObject[] femaleHairs;
public GameObject[] femaleShirts;
public GameObject[] femalePants;
public Texture[] charTexturesM;
public Texture[] charTexturesF;
public Texture[] shirtTextureM;
public Texture[] shirtTextureF;
public Texture[] pantTextureM;
public Texture[] pantTextureF;
private int currentCharacters;
private int currentMaleHair;
private int currentMaleShirts;
private int currentMalePants;
private int currentFemaleHair;
private int currentFemaleShirt;
private int currentFemalePant;
private int currentCharTextureM;
private int currentCharTextureF;
private int currentShirtTextureM;
private int currentShirtTextureF;
private int currentPantTextureM;
private int currentPantTextureF;
public Renderer rendererM;
public Renderer rendererF;
public Renderer[] rendererShirtM = new Renderer[2];
public Renderer[] rendererShirtF = new Renderer[2];
public Renderer[] rendererPantM = new Renderer[2];
public Renderer[] rendererPantF = new Renderer[2];
public void Update() {
//Gender Loop
for (int i = 0; i < characters.Length; i++)
{
if (i == currentCharacters)
{
characters[i].SetActive(true);
}
else
{
characters[i].SetActive(false);
}
}
//Hair Loop
if (currentCharacters == 0)
{
for (int i = 0; i < maleHairs.Length; i++)
{
if (i == currentMaleHair)
{
femaleHairs[i].SetActive(false);
maleHairs[i].SetActive(true);
}
else
{
femaleHairs[i].SetActive(false);
maleHairs[i].SetActive(false);
}
}
}
else
{
for (int i = 0; i < femaleHairs.Length; i++)
{
if (i == currentFemaleHair)
{
maleHairs[i].SetActive(false);
femaleHairs[i].SetActive(true);
}
else
{
maleHairs[i].SetActive(false);
femaleHairs[i].SetActive(false);
}
}
}
// Shirt Loop
if (currentCharacters == 0)
{
for (int i = 0; i < maleShirts.Length; i++)
{
if (i == currentMaleShirts)
{
femaleShirts[i].SetActive(false);
maleShirts[i].SetActive(true);
}
else
{
femaleShirts[i].SetActive(false);
maleShirts[i].SetActive(false);
}
}
}
else
{
for (int i = 0; i < femaleShirts.Length; i++)
{
if (i == currentFemaleShirt)
{
maleShirts[i].SetActive(false);
femaleShirts[i].SetActive(true);
}
else
{
maleShirts[i].SetActive(false);
femaleShirts[i].SetActive(false);
}
}
}
// Pants Loop
if (currentCharacters == 0)
{
for (int i = 0; i < malePants.Length; i++)
{
if (i == currentMalePants)
{
femalePants[i].SetActive(false);
malePants[i].SetActive(true);
}
else
{
femalePants[i].SetActive(false);
malePants[i].SetActive(false);
}
}
}
else
{
for (int i = 0; i < femalePants.Length; i++)
{
if (i == currentFemalePant)
{
malePants[i].SetActive(false);
femalePants[i].SetActive(true);
}
else
{
malePants[i].SetActive(false);
femalePants[i].SetActive(false);
}
}
}
//CharTexture Loop
if (currentCharacters == 0)
{
for (int i = 0; i < charTexturesM.Length; i++)
{
if (i == currentCharTextureM)
{
rendererM.sharedMaterial.mainTexture = charTexturesM[i];
}
}
}
else
{
for (int i = 0; i < charTexturesF.Length; i++)
{
if (i == currentCharTextureF)
{
rendererF.sharedMaterial.mainTexture = charTexturesF[i];
}
}
}
//Shirt Texture Loop
if (currentCharacters == 0)
{
for (int i = 0; i < maleShirts.Length; i++)
{
for (int j = 0; j < shirtTextureM.Length; j++)
{
if (j == currentShirtTextureM)
{
rendererShirtM[i].sharedMaterial.mainTexture = shirtTextureM[j];
}
}
}
}
else
{
for (int i = 0; i < femaleShirts.Length; i++)
{
for (int j = 0; j < shirtTextureF.Length; j++)
{
if (j == currentShirtTextureF)
{
rendererShirtF[i].sharedMaterial.mainTexture = shirtTextureF[j];
}
}
}
}
//Pant Texture Loop
if (currentCharacters == 0)
{
for (int i = 0; i < malePants.Length; i++)
{
for (int j = 0; j < pantTextureM.Length; j++)
{
if (j == currentPantTextureM)
{
rendererPantM[i].sharedMaterial.mainTexture = pantTextureM[j];
}
}
}
}
else
{
for (int i = 0; i < femalePants.Length; i++)
{
for (int j = 0; j < pantTextureF.Length; j++)
{
if (j == currentPantTextureF)
{
rendererPantF[i].sharedMaterial.mainTexture = pantTextureF[j];
}
}
}
}
}
//Switching Characters
public void SwitchCharacters() {
Debug.Log("Method Called!");
if (currentCharacters == characters.Length - 1)
{
currentCharacters = 0;
}
else
{
currentCharacters++;
}
}
//Switching Hairs
public void SwitchHairs() {
Debug.Log("MaleHairsCalled");
if (currentMaleHair == maleHairs.Length - 1)
{
currentMaleHair = 0;
}
else
{
currentMaleHair++;
}
if (currentFemaleHair == femaleHairs.Length - 1)
{
currentFemaleHair= 0;
}
else
{
currentFemaleHair++;
}
}
//Switching Shirts
public void SwitchShirts()
{
Debug.Log("MaleShirtCalled");
if (currentMaleShirts == maleShirts.Length - 1)
{
currentMaleShirts = 0;
}
else
{
currentMaleShirts++;
}
if (currentFemaleShirt == femaleShirts.Length - 1)
{
currentFemaleShirt = 0;
}
else
{
currentFemaleShirt++;
}
}
//Switching Pants
public void SwitchPants() {
Debug.Log("MalePantsCalled");
if (currentMalePants == malePants.Length - 1)
{
currentMalePants = 0;
}
else
{
currentMalePants++;
}
if (currentFemalePant == femalePants.Length - 1)
{
currentFemalePant = 0;
}
else
{
currentFemalePant++;
}
}
//Switching Character Textures
public void SwitchCharTexture()
{
Debug.Log("Char Texture Method Was Called!");
if (currentCharTextureM == charTexturesM.Length - 1)
{
currentCharTextureM = 0;
}
else
{
currentCharTextureM++;
}
if (currentCharTextureF == charTexturesF.Length - 1)
{
currentCharTextureF = 0;
}
else
{
currentCharTextureF++;
}
}
public void SwitchShirtTexture()
{
Debug.Log("Shirt Texture Method Was Called!");
if (currentShirtTextureM == shirtTextureM.Length - 1)
{
currentShirtTextureM = 0;
}
else
{
currentShirtTextureM++;
}
if (currentShirtTextureF == shirtTextureF.Length - 1)
{
currentShirtTextureF = 0;
}
else
{
currentShirtTextureF++;
}
}
public void SwitchPantTexture()
{
Debug.Log("Pant Texture Method Was Called!");
if (currentPantTextureM == pantTextureM.Length - 1)
{
currentPantTextureM = 0;
}
else
{
currentPantTextureM++;
}
if (currentPantTextureF == pantTextureF.Length - 1)
{
currentPantTextureF = 0;
}
else
{
currentPantTextureF++;
}
}
//End of Class
}
instead of Renderer.sharedMaterial
Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.
It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.
rather use Renderer.material
Modifying material will change the material for this object only.
If the material is used by any other renderers, this will clone the shared material and start using it from now on.
Also check your loops .. some things seems odd there e.g.
for (int j = 0; j < someTextureArray.Length; j++)
{
if (j == currentTextureIndex)
{
someRenderer[i].material.mainTexture = someTextureArray[j];
}
}
seems just to be a very complex way of simply writing
someRenderer[i].material.mainTexture = someTextureArray[currentTextureIndex];
For all your switch methods: note that the easiest solution for wrap around a positive counter for indices in an array you can simply do
currentIndex = (currentIndex + 1) % accordingArray.Length;
this is the code in OC
It is not easy for me to convert it to swift, especially the calculate of check sum part
If anyone knows how to write, please let me know. Thank you.
OC Code:
MessageToOnboard {
unsigned char header[2];
ushort length;
uint8_t msgID;
uint missionID;
ushort wayPointID;
double lon;
double lat;
float height;
unsigned char wayPointAction;
// unsigned long reserve;
unsigned char checkSum;
}
MessageToOnboard message;
message.header[0] = 'Q';
message.header[1] = 'Z';
message.msgID = 0x21;
message.missionID = 12;
message.wayPointID = 10;
message.lon = 34.2323242;
message.lat = 68.2121221;
message.height = 30;
message.wayPointAction = '2';
message.length = sizeof(message) -5;
uint8_t *msgBIn = (uint8_t *)&message;
int iLength = sizeof(message);
uint8_t icheckSum = 0;
for (int i = 0 ; i < iLength - 3; i++)
{
icheckSum += *(msgBIn+2+i);
}
message.checkSum = icheckSum;
NSData *data = [[NSData alloc] initWithBytes:&message length:sizeof(message)];
Swift Code:
I tried this, but it is not right, I don't know how to use pointer to calculate the sum bytes of struct in swift
let msgBIn = withUnsafePointer(to: &message) {$0}
print(msgBIn.pointee)
let iLength: Int = MemoryLayout<MessageToOnboard>.size
let icheckSum: UInt8 = 0
for i in 0..<iLength - 1 {
let pointer = msgBIn.advanced(by: 2 + i)
icheckSum += UInt8(pointer)
}
finally, solved this problem
Message is a Struct
func sumByte(msg: inout Message) -> UInt8 {
let pointer = withUnsafePointer(to: msg) {UnsafeRawPointer($0)}
var sum: UInt8 = 0;
for i in 0..<(MemoryLayout<Message>.size) {
let nextP = pointer.advanced(by: i)
sum += nextP.load(as: UInt8.self)
}
return sum;
}
I'm working to convert to Swift this code which helps get me get audio data for visualizations. The code I'm working with in Obj C, which works well, is:
while (reader.status == AVAssetReaderStatusReading) {
AVAssetReaderTrackOutput *trackOutput = (AVAssetReaderTrackOutput *)[reader.outputs objectAtIndex:0];
self.sampleBufferRef = [trackOutput copyNextSampleBuffer];
if (self.sampleBufferRef) {
CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(self.sampleBufferRef);
size_t bufferLength = CMBlockBufferGetDataLength(blockBufferRef);
void *data = malloc(bufferLength);
CMBlockBufferCopyDataBytes(blockBufferRef, 0, bufferLength, data);
SInt16 *samples = (SInt16 *)data;
int sampleCount = bufferLength / bytesPerInputSample;
for (int i=0; i<sampleCount; i+=100) {
Float32 sample = (Float32) *samples++;
sample = decibel(sample);
sample = minMaxX(sample,noiseFloor,0);
tally += sample;
for (int j=1; j<channelCount; j++)
samples++;
tallyCount++;
if (tallyCount == downsampleFactor) {
sample = tally / tallyCount;
maximum = maximum > sample ? maximum : sample;
[fullSongData appendBytes:&sample length:sizeof(sample)];//tried dividing the sample by 2
tally = 0;
tallyCount = 0;
outSamples++;
}
}
CMSampleBufferInvalidate(self.sampleBufferRef);
CFRelease(self.sampleBufferRef);
free(data);
}
}
In Swift, I'm trying to write is this part:
while (reader.status == AVAssetReaderStatus.Reading) {
var trackOutput = reader.outputs[0] as! AVAssetReaderTrackOutput
self.sampleBufferRef = trackOutput.copyNextSampleBuffer()
if (self.sampleBufferRef != nil) {
let blockBufferRef = CMSampleBufferGetDataBuffer(self.sampleBufferRef)
let bufferLength = CMBlockBufferGetDataLength(blockBufferRef)
var data = NSMutableData(length: bufferLength)
CMBlockBufferCopyDataBytes(blockBufferRef, 0, bufferLength, data!.mutableBytes)
var samples = UnsafeMutablePointer<Int16>(data!.mutableBytes)
var sampleCount = Int32(bufferLength)/bytesPerInputSample
for var i = 0; i < Int(sampleCount); i++ {
var sampleValue = CGFloat(samples[i]) etc. etc.
However, when I println() sampleValue is just comes out (Opaque Value) in the console. I can't figure out how to actually read the sampleValue.
I'm new at trying to read audio data for visualization purposes. Any help on getting a buffer of audio data to work with would be helpful. Thank you.
Use stride?
let bytesPerInputSample = 4 // assumption ;)
var samplePtr = data.mutableBytes
for _ in stride(from: 0, to: data.length, by: bytesPerInputSample) {
let currentSample = Data(bytes: samplePtr, count: bytesPerInputSample)
// do whatever is needed with current sample
//...
// increase ptr by size of sample
samplePtr = samplePtr + bytesPerInputSample
}
I code to send a touch event to my app by GSEvent,get mach_port_t by GSCopyPurpleSystemEventPort().
the sending function was launched after the ApplicationDidFinishLaunch:option have completed.the app is UIControlView app.
code as follow:
void handleMouseEventAtPoint(CGPoint point, int buttons)
{
// NOTE: Must store button state for comparision, port for
// mouse dragging and button up
static int buttons_;
static mach_port_t port_;
int diff = buttons_ ^ buttons;
bool twas = ((buttons_ & 0x1) != 0);
bool tis = ((buttons & 0x1) != 0);
buttons_ = buttons;
// Round point values to prevent subpixel coordinates
point.x = roundf(point.x);
point.y = roundf(point.y);
// Check for mouse button events
mach_port_t purple;
if ((diff & 0x10) != 0) {
// Simulate Headset button press
struct GSEventRecord record;
memset(&record, 0, sizeof(record));
record.type = (buttons & 0x4) != 0 ?
kGSEventHeadsetButtonDown :
kGSEventHeadsetButtonUp;
record.timestamp = GSCurrentEventTimestamp();
FixRecord(&record);
GSSendSystemEvent(&record);
}
if ((diff & buttonThree) != 0) {
// Simulate Home button press
struct GSEventRecord record;
memset(&record, 0, sizeof(record));
record.type = (buttons & buttonThree) != 0 ?
kGSEventMenuButtonDown :
kGSEventMenuButtonUp;
record.timestamp = GSCurrentEventTimestamp();
FixRecord(&record);
GSSendSystemEvent(&record);
}
if ((diff & buttonTwo) != 0)
{
// Simulate Sleep/Wake button press
struct GSEventRecord record;
memset(&record, 0, sizeof(record));
record.type = (buttons & buttonTwo) != 0 ?
kGSEventLockButtonDown :
kGSEventLockButtonUp;
record.timestamp = GSCurrentEventTimestamp();
FixRecord(&record);
GSSendSystemEvent(&record);
}
if (twas != tis || tis) {
// Main (left button) state changed, or was dragged
struct {
struct GSEventRecord record;
struct
{
struct GSEventRecordInfo info;
struct GSPathInfo path;
} data;
} event;
memset(&event, 0, sizeof(event));
event.record.type = kGSEventHand;
event.record.windowLocation = point;
event.record.timestamp = GSCurrentEventTimestamp();
event.record.infoSize = sizeof(event.data);
event.data.info.handInfo.type = twas == tis ?
kGSHandInfoTypeTouchDragged :
tis ?
kGSHandInfoTypeTouchDown :
kGSHandInfoTypeTouchUp;
event.data.info.handInfo._0x44 = 0x1;
event.data.info.handInfo._0x48 = tis ? 0x1 : 0x0;
event.data.info.pathPositions = 1;
event.data.path.pathIndex = 0x01;
event.data.path.pathIdentity = 0x02;
event.data.path.pathProximity = tis ? 0x03 : 0x00;
event.data.path.pathLocation = event.record.windowLocation;
if (twas != tis && tis)
{
// Button down and was not down before
port_ = 0;
CAWindowServer *server;
server = [CAWindowServer serverIfRunning];
char svrptrstr [255];
sprintf(svrptrstr, "%p", server);
NSLog(#"One!");
if (server = [CAWindowServer serverIfRunning])
//if (true)
{
NSLog(#"Two!");
//NSArray *displays([server displays]);
NSArray *displays = [server displays];
if (displays != nil && [displays count] != 0)
{
NSLog(#"Three!");
//CAWindowServer *display;
if (CAWindowServerDisplay *display = [displays objectAtIndex:0])
{
NSLog(#"Four!");
port_ = [display clientPortAtPosition:point];
}
}
}
if (port_ == 0)
{
// Is SpringBoard
if (purple == 0)
{
purple = GSGetPurpleSystemEventPort();
port_ = purple;
}
}
}
FixRecord(&event.record);
GSSendEvent(&event.record, port_);
NSLog(#"Event sent!");
//GSSendSystemEvent(&event.record);
//GSSendEvent(&event.record, purple);
}
if (purple != 0 && PurpleAllocated)
{
mach_port_deallocate(mach_task_self(), purple);
NSLog(#"Deallocated mach_port!");
}
}
but the app launch on the jailbreak ipad2(iOS5.01),there is no any click result,if click event was done,the debug.log would be there.
who can tell me what i have miss?
I've seen this code somewhere else (I think it was on an app that translated mouse clicks to iPhone/iPad taps). The problem here is not the code or the port, but the event structure you are sending. This is the GSevent structure for iOS 3.0, not for iOS 5.0. It has changed, not only in structure but in values and tags. I suggest receiving UIEvents, translating them into GSEvents and looking at their content.
im writing a game to find the differences between 2 images. i created a subclass of CCSprite, Spot. firstly i tried to create small images and add itself according to it's position, but later i found the position is hard to determine, since it's hard to avoid offset of 1 or 2 pixels.
then i tried to make the Spot the same size as the image, with the other part transparent. but I still need to find out the 'hotspot' of finger tap. but when i use CGRectContainsPoint([self boundingBox], touchLocation), it's actually the whole image.
so is there any other way to do this? like content.size or self.size, and make a CGRect out of it's non-transparent part?
Thank you.
I figured it out now. here is my code: (it's actually quite simple
-(void) findRect:(NSString*) fn {
//the origin of mTex is top left
//the origin of CGRect is top left, in the coordinate system inside the image
int topLeftX = 0;
int topLeftY = 0;
for (int i = 0; i < image_width; i += 10) {
for (int j = 0; j < image_height; j += 10) {
if (([mTex pixelAt:ccp(i, j)].a & 0xFF) != 0) {
topLeftX = i;
topLeftY = j;
goto outer;
}
}
}
outer:;
int topRightX = 0;
for (int i = topLeftX; i < image_width; i += 10) {
if (([mTex pixelAt:ccp(i, topLeftY)].a & 0xFF) == 0) {
topRightX = i;
break;
}
}
if (topRightX == 0) {
topRightX = image_width - 1;
}
int bottomLeftY = 0;
for (int i = topLeftY; i < image_height; i += 10) {
if (([mTex pixelAt:ccp(topLeftX, i)].a & 0xFF) == 0) {
bottomLeftY = i;
break;
}
}
if (bottomLeftY == 0) {
bottomLeftY = image_height - 1;
}
areaRect = CGRectMake(topLeftX, topLeftY, topRightX - topLeftX, bottomLeftY - topLeftY);
}