Use RapidJson in Cocos2dx, it crash in Accept(writer) in IOS - ios

I use Cocos2dx 3.9; and use rapidjson to convert CCDictionary to string; I find it will crash in value->Accept(wirter) in Real machine; but work will in Simulator.
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value->Accept(writer);

It's my error, I use:
rapidjson::Value *value = KSCCJsonRapid::jsonValueFromDictionary(dic);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value->Accept(writer);
std::string jsonString = buffer.GetString();
but in
static rapidjson::Value* jsonValueFromDictionary(cocos2d::CCDictionary *dic, rapidjson::Document *document = NULL);
, I create a new document, and delete it; in Real machine, the memory is limit; so the value is invalid.
it can be corrected by :
rapidjson::Document *document = new Document();
rapidjson::Value *value = KSCCJsonRapid::jsonValueFromDictionary(dic, document);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
value->Accept(writer);
std::string jsonString = buffer.GetString();
delete value;
delete document;

Related

How to Expose Objective-C Pointer Method WithResultBuffer in IOS Binding

I'm trying to Invoke Objective-C Method
-(nabto_status_t)nabtoRpcInvoke:(NSString *)url withResultBuffer:(char
**)jsonResponse;
I used Objective-Sharpie Tool to generate the follow Method
[Export("nabtoRpcInvoke:withResultBuffer:")]
unsafe nabto_status_t RpcInvoke(string url, ref byte jsonResponse);
Please help expose me it correctly so i can get the JsonResponse String which i can use in IOS app.
I Made these changes to Generated Method
[Export("nabtoRpcInvoke:withResultBuffer:")]
unsafe nabto_status_t RpcInvoke(string url, ref IntPtr
jsonResponse);
and then I got the JsonResonse as follow.
IntPtr buff=new IntPtr() ;
status = Client.RpcInvoke(URL, ref buff);
byte[] newArray = new byte[buff.ToInt32() + 1];
for (int m = 0; m < buff.ToInt32(); m++)
{
byte b = Marshal.ReadByte(buff,m);
newArray[m] = b;
}
var JsonResponse = System.Text.Encoding.UTF8.GetString(newArray);

Are there new device identifiers in iOS 10?

Has anyone found a new way to uniquely identify a device in iOS 10? I haven't seen any documentation mentioning changes in that area and I wanted to ask before I surrendered to identifier for vendor.
If you're submitting to the store, the only real identifier you have left is the Advertising Identifier for the AdSupport framework.
If you want to go down the rabbit hole a little further and potentially go into some unsafe API territory, you could hook into IOKit and try to get the battery identifier on the device. This is taken from Anthony Agatiello gist of UIDevice extensions:
- (NSString *)batteryID {
void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY);
NSParameterAssert(IOKit);
mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
NSParameterAssert(kIOMasterPortDefault);
CFMutableDictionaryRef (*IOServiceNameMatching)(const char *name) = dlsym(IOKit, "IOServiceNameMatching");
NSParameterAssert(IOServiceNameMatching);
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
NSParameterAssert(IOServiceGetMatchingService);
kern_return_t (*IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, UInt32 options) = dlsym(IOKit, "IORegistryEntryCreateCFProperties");
NSParameterAssert(IORegistryEntryCreateCFProperties);
kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
NSParameterAssert(IOObjectRelease);
CFMutableDictionaryRef properties = NULL;
mach_port_t service = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceNameMatching("charger"));
IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0);
IOObjectRelease(service);
service = 0;
NSDictionary *dictionary = (__bridge NSDictionary *)properties;
NSData *batteryIDData = [dictionary objectForKey:#"battery-id"];
CFRelease(properties);
properties = NULL;
dlclose(IOKit);
return [NSString stringWithUTF8String:[batteryIDData bytes]];
}
This still works on iOS 10.

iOS Core Foundation Memory Leak in External Library

I'm currently trying to write an application using an open-source, external library. I have the source code available to it, and can build myself a fresh copy whenever needed.
Anyway, while profiling my application - I noticed that some memory was leaking in the library. It's small - 128b a shot - but still, I'd prefer not to have memory leaks to begin with.
Here's the code. The modified code that I wrote is on top (that leaks), and the original code is on bottom (that leaks).
CFURLRef getURLFromPath(const char * path) {
//modified code to hopefully clean up after myself
CFStringRef cfTotalPath = CFStringCreateWithCString (NULL, path, kCFStringEncodingUTF8);
CFURLRef cURL = CFURLCreateWithFileSystemPath(NULL, cfTotalPath, kCFURLPOSIXPathStyle, false);
CFRelease(cfTotalPath);
return cURL;
//original code
/*CFStringRef cfTotalPath = CFStringCreateWithCString (kCFAllocatorDefault,
path, kCFStringEncodingUTF8);
return CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfTotalPath,
kCFURLPOSIXPathStyle, false);*/
}
I'm relatively new to iOS programming; I'm debugging on an actual device, and I know that sometimes Instruments gives false-positives when it comes to leaks.
This is infuriating, because this one block of code is the last step in the stack trace for my leaks... and I honestly do not know how to fix it.
EDIT: From what I've read, Apple doesn't mind the occasional memory leak here and there; I'll continue programming, because this process only happens once per music file in my application - analyzing a track for the BPM (it gets saved once analyzed).
Edit2: Here's the referring code. I've added all of the CFRelease(fileURL), but it still leaks:
uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) {
if (s->samplerate == 0 || s->channels == 0) return AUBIO_FAIL;
AudioStreamBasicDescription clientFormat;
memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription));
clientFormat.mFormatID = kAudioFormatLinearPCM;
clientFormat.mSampleRate = (Float64)(s->samplerate);
clientFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
clientFormat.mChannelsPerFrame = s->channels;
clientFormat.mBitsPerChannel = sizeof(short) * 8;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame / 8;
clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame;
clientFormat.mReserved = 0;
AudioFileTypeID fileType = kAudioFileWAVEType;
CFURLRef fileURL = getURLFromPath(s->path);
bool overwrite = true;
OSStatus err = noErr;
err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL,
overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile);
if (err) {
char_t errorstr[20];
AUBIO_ERR("sink_apple_audio: error when trying to create %s with "
"ExtAudioFileCreateWithURL (%s)\n", s->path,
getPrintableOSStatusError(errorstr, err));
goto beach;
}
if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) {
AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, "
"out of memory? \n", s->path);
goto beach;
}
//added release code
CFRelease(fileURL);
return AUBIO_OK;
beach:
//added release code
CFRelease(fileURL);
return AUBIO_FAIL;
}
EDIT3: Here's a screenshot
EDIT4: The original solution actually works, XCode refused to load the new version of my framework even though I kept recompiling it. So, I had to purge all references of the framework - including scrubbing the Build info pages - and re-add the "fixed" version.
You are leaking the returned CFURLRef created with CFURLCreateWithFileSystemPath.
You should rename the function from getURLFromPath to createURLFromPath to indicate that ownership of the returned CFURLRef is being passed on to the caller. Then any code that calls the method is responsible for releasing the CFURLRef when done with it.

Data corrupt after converting byte[] to NSData

I have .Net web service response containing a byte[] entry, among other fields.
The data is a PDF file.
I extract the Dictionary from the received data with:
[NSJSONSerialization JSONObjectWithData]
Hereafter I use the following code to convert the byte[] to NSData.
I then save the result to disk (see last line).
When opening the resulting PDF file, I get the following error:
"failed to find PDF header: `%PDF' not found."
NSArray *byteArray = [rootDictionary objectForKey:#"file"];
unsigned c = byteArray.count;
uint8_t *bytes = malloc(sizeof(*bytes) * c);
unsigned i;
for (i = 0; i < c; i++)
{
NSString *str = [byteArray objectAtIndex:i];
int byte = [str intValue];
bytes[i] = (uint8_t)byte;
}
NSData* data = [NSData dataWithBytes:(const void *)byteArray length:sizeof(unsigned char)*c];
//Save to disk using svc class.
NSString *localPath = [svc saveReport:data ToFile:[rootDictionary objectForKey:#"name"]];
I also tried converting the byte[] to a base64 NSString (on the service side) and then back to NSData in my app, which worked (**mostly) but I was told that it's sloppy code.
** When pulling multiple PDF asynchronously at the same time, some of these reports received as base64 strings were also corrupted.
PS. Please let me know if I must supply the code from my svc class as well, but I don't think the problem is there.
Edit:
I created a new web service method which takes a byte[] as input, then modified my iOS app to send the byteArray variable back to the service, where it get's saved to a file.
The resulting PDF file is a valid file readable by Adobe. Meaning there is no corruption during transfer.
Thank you!
O.k, finally sorted this out after fine-tooth-combing my code (as inspired by snadeep.gvn from http://www.raywenderlich.com/forums/viewtopic.php?f=2&p=38590#p38590).
I made a stupid mistake, which I overlooked 100+ times.
This line of code:
NSData* data = [NSData dataWithBytes:(const void *)byteArray length:sizeof(unsigned char)*c];
Should change to:
NSData* data = [NSData dataWithBytes:(const void *)bytes length:sizeof(unsigned char)*c];
Good times, now I can finally get some sleep :-)

Save BIO into char* (from SMIME_write_CMS)

I want to save (pipe/copy) a BIO into a char array.
When I know the size it works, but otherwise not.
For example, I can store the content of my char* into a BIO using this
const unsigned char* data = ...
myBio = BIO_new_mem_buf((void*)data, strlen(data));
But when I try to use SMIME_write_CMS which takes a BIO (what I've created before) for the output it doesn't work.
const int SIZE = 50000;
unsigned char *temp = malloc(SIZE);
memset(temp, 0, SIZE);
out = BIO_new_mem_buf((void*)temp, SIZE);
if (!out) {
NSLog(#"Couldn't create new file!");
assert(false);
}
int finished = SMIME_write_CMS(out, cms, in, flags);
if (!finished) {
NSLog(#"SMIME write CMS didn't succeed!");
assert(false);
}
printf("cms encrypted: %s\n", temp);
NSLog(#"All succeeded!");
The OpenSSL reference uses a direct file output with the BIO.
This works but I can't use BIO_new_file() in objective-c... :-/
out = BIO_new_file("smencr.txt", "w");
if (!out)
goto err;
/* Write out S/MIME message */
if (!SMIME_write_CMS(out, cms, in, flags))
goto err;
Do you guys have any suggestion?
I would suggest trying to use SIZE-1, that way you are guaranteed that it is NULL terminated. Otherwise, it is possible that it is just over running the buffer.
out = BIO_new_mem_buf((void*)temp, SIZE-1);
Let me know if that helps.
Edit:
When using BIO_new_mem_buf() it is a read only buffer, so you cannot write to it. If you want to write to memory use:
BIO *bio = BIO_new(BIO_s_mem());

Resources