I'm trying to make a file manager for iOS (my code has an exploit built in so it works).
The main code for my application is written in Swift and the code for running the exploit and reading files is written in Objecive-C.
This is the code I'm currently using in Objective-C:
NSString* readFile(NSString* file) {
char* buffer;
long lSize;
char* convertedFileName = [file UTF8String];
char* newFileName = deleteLastChar(convertedFileName); >> removes last / from path
char ch;
FILE *fp=fopen(newFileName, "r");
fseek( fp , 0L , SEEK_END);
lSize = ftell( fp );
rewind( fp );
buffer = calloc( 1, lSize+1 );
if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
if( 1!=fread( buffer , lSize, 1 , fp) )
fclose(fp),free(buffer),fputs("entire read fails",stderr),exit(1);
printf(buffer);
fclose(fp);
return [[NSString alloc] initWithUTF8String:buffer];
}
And this is the code for Swift:
func openFile(file: String) {
let fileContents = readFile(file)
print(fileContents) >> outputs nil
}
This is an example of a file I'm trying to open (plist file):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>canvas_height</key>
<integer>1136</integer>
<key>canvas_width</key>
<integer>640</integer>
</dict>
</plist>
This is what the printf in the Objective-C code returns:
bplist00\322]canvas_height\canvas_width\240\332
(+
And Swift says the string is nil
The file is being read but there is still something wrong. Any ideas on how to fix this or a better way to handle this?
Related
In a project , I have to use an .so file , and the .so need to load a config file that I provide. The problem is that I can not change the code of .so , but the .so load the config file in default path.
When I use rosrun to launch the node , I put the config file in the catkin workspace ,and when I use ./ to launch the node, I put the config file under the same folder with node. My test program is also the result.
My test code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "topic_pub");
ros::NodeHandle nh;
ros::Publisher msg_pub = nh.advertise<rostestdemo::NewMsg>("customize_msg", 20);
ros::Rate loop_rate(10);
rostestdemo::NewMsg msg;
int count = 0;
std::string filename = "hello.txt";
std::ifstream file;
file.open(filename.c_str());
char buf[500] = {0};
file.getline(buf, 500);
while(ros::ok())
{
msg.stamp = ros::Time::now();
msg.data2 = count;
msg.word = buf;
ROS_INFO("stamp.sec = %d", msg.stamp.sec);
ROS_INFO("stamp.nsec = %d", msg.stamp.nsec);
ROS_INFO("data2 = %d", msg.data2);
ROS_INFO("word = %s", msg.word.c_str());
msg_pub.publish(msg);
loop_rate.sleep();
++count;
}
return 0;
}
In addition, I can use absolute path in code or param of launch file to load the file when I use roslaunch to launch the config file. But, when I use default path to load the file, where shuold I put the file when I use roslaunch ?
You are able to search for package paths, so maybe using ros::package::getPath('PKG_NAME') for example, and then you concatenate the config/your_configuration.yaml
For some reason - maybe has to do with a latest Xcode upgrade to version 7.2.1 - my pbxproj's structure got changed, and because of that, when I'm about to merge a PR, it just shows me a one big conflict on the entire file.
The reason, as I see it, is that one of them has this structure (posting the start of the file):
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
009025BEF30C41848E6869F6 /* RolloutDynamic_18.m in Sources */ = {isa = PBXBuildFile; fileRef = E1BF845EAB9E4962853253B5 /* RolloutDynamic_18.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
00AFDB74BD584F1C9BD41B9D /* RolloutDynamic_03.m in Sources */ = {isa = PBXBuildFile; fileRef = 588F21D12977444EAE3C70F5 /* RolloutDynamic_03.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
054D17D506BF45EE98822AB9 /* RolloutDynamic_15.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D47CE8182E4482955DA02E /* RolloutDynamic_15.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
and the other one that structure (start of the file):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>archiveVersion</key>
<string>1</string>
<key>classes</key>
<dict/>
<key>objectVersion</key>
<string>46</string>
<key>objects</key>
<dict>
<key>18011C201B1F865300F52714</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>UserProfileTableViewController.h</string>
<key>sourceTree</key>
<string><group></string>
</dict>
Any idea how can this be solved?
I wan't to turn on/off the call waiting feature of iPhone (that can be found at Settings > Phone > Call Waiting) programmatically.
What I have figured out is that the phone settings calls -setCallWaitingEnabled:specifier: method from PhoneSettingsCallWaitingController class found here. I found it in /System/Library/PreferenceBundles/MobilePhoneSettings.bundle/Call Waiting.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>id</key>
<string>com.apple.preferences.phone.call-waiting</string>
<key>items</key>
<array>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>get</key>
<string>callWaitingEnabled:</string>
<key>label</key>
<string>Call Waiting</string>
<key>set</key>
<string>setCallWaitingEnabled:specifier:</string>
</dict>
</array>
<key>title</key>
<string>Call Waiting</string>
</dict>
</plist>
I loaded the bundle manually and initialized the above class and called the method I said but nothing happens. Here's the code:
NSBundle *b = [NSBundle bundleWithPath:#"/System/Library/PreferenceBundles/MobilePhoneSettings.bundle"];
BOOL success = [b load];
if (success)
{
NSLog(#"\n\n\n\n Bundle load successfull! \n\n\n\n ");
Class PhoneSettingsCallWaitingController = NSClassFromString(#"PhoneSettingsCallWaitingController");
id tc = [[PhoneSettingsCallWaitingController alloc] init];
[tc setCallWaitingEnabled:0 specifier:0];
} else NSLog(#"\n\n\n\n Bundle load failure! \n\n\n\n ");
I don't know if I'm in the correct path. Is there another way to turn on/off the Call Waiting setting?
Declarations for CoreTelephony.framework private APIs
CF_EXTERN_C_BEGIN
CF_EXPORT CFNotificationCenterRef CTTelephonyCenterGetDefault();
CF_EXPORT void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
CF_EXPORT void CTSettingRequest(NSDictionary* dict);
CF_EXPORT void CTSettingSave(NSDictionary* dict);
CF_EXPORT NSString* kCTSettingCallClassVoice;
CF_EXPORT NSString* kCTSettingTypeCallWaiting;
CF_EXPORT NSString* kCTSettingType;
CF_EXPORT NSString* kCTSettingCallClass;
CF_EXPORT NSString* kCTSettingEnabled;
CF_EXTERN_C_END
Setting requests and saves are done asynchronously. Results will be sent to telephony center callback:
void SettingCallback(CFNotificationCallback center, void* observer, NSString* name, const void* objec, NSDictionary* userInfo)
{
if ([name isEqualToString:#"kCTSettingRequestSuccessNotification"])
{
//Setting request results are in 'userInfo' argument
}
else if ([name isEqualToString:#"kCTSettingRequestErrorNotification"])
{
//Setting request error
}
else if ([name isEqualToString:#"kCTSettingSaveSuccessNotification"])
{
//Setting saved
}
else if ([name isEqualToString:#"kCTSettingSaveErrorNotification"])
{
//Setting save error
}
}
...
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, SettingCallback, NULL, NULL, CFNotificationSuspensionBehaviorHold);
Request call waiting setting:
CTSettingRequest(#{#"STSettingTypeUniqueIdentifier" : kCTSettingTypeCallWaiting,
kCTSettingCallClass : kCTSettingCallClassVoice,
kCTSettingType : kCTSettingTypeCallWaiting});
Save call waiting setting (in this case, enabled):
CTSettingSave(#{#"STSettingTypeUniqueIdentifier" : kCTSettingTypeCallWaiting,
kCTSettingCallClass : kCTSettingCallClassVoice,
kCTSettingType : kCTSettingTypeCallWaiting,
kCTSettingEnabled : #YES});
Setting: I'm using Lua from a C/C++ environment.
I have several lua files on disk. Those are read into memory and some more memory-only lua files become available during runtime. Think e.g. of an editor, with additional unsaved lua files.
So, I have a list<identifier, lua_file_content> in memory. Some of these files have require statements in them. When I try to load all these files to a lua instance (currently via lua_dostring) I get attempt to call global require (a nil value).
Is there a possibility to provide a require function, which replaces the old one and just uses the provided in memory files (those files are on the C side)?
Is there another way of allowing require in these files without having the required files on disk?
An example would be to load the lua stdlib from memory only without altering it. (This is actually my test case.)
Instead of replacing require, why not add a function to package.loaders? The code is nearly the same.
int my_loader(lua_State* state) {
// get the module name
const char* name = lua_tostring(state);
// find if you have such module loaded
if (mymodules.find(name) != mymodules.end())
{
luaL_loadbuffer(state, buffer, size, name);
// the chunk is now at the top of the stack
return 1;
}
// didn't find anything
return 0;
}
// When you load the lua state, insert this into package.loaders
http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders
A pretty straightforward C++ function that would mimic require could be: (pseudocode)
int my_require(lua_State* state) {
// get the module name
const char* name = lua_tostring(state);
// find if you have such module loaded
if (mymodules.find(name) != mymodules.end())
luaL_loadbuffer(state, buffer, size, name);
// the chunk is now at the top of the stack
lua_call(state)
return 1;
}
Expose this function to Lua as require and you're good to go.
I'd also like to add that to completely mimic require's behaviour, you'd probably need to take care of package.loaded, to avoid the code to be loaded twice.
There is no package.loaders in lua 5.2
It called package.searchers now.
#include <stdio.h>
#include <string>
#include <lua.hpp>
std::string module_script;
int MyLoader(lua_State *L)
{
const char *name = luaL_checkstring(L, 1); // Module name
// std::string result = SearchScript(name); // Search your database.
std::string result = module_script; // Just for demo.
if( luaL_loadbuffer(L, result.c_str(), result.size(), name) )
{
printf("%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
return 1;
}
void SetLoader(lua_State* L)
{
lua_register(L, "my_loader", MyLoader);
std::string str;
// str += "table.insert(package.loaders, 2, my_loader) \n"; // Older than lua v5.2
str += "table.insert(package.searchers, 2, my_loader) \n";
luaL_dostring(L, str.c_str());
}
void SetModule()
{
std::string str;
str += "print([[It is add.lua]]) \n";
str += "return { func = function() print([[message from add.lua]]) end } \n";
module_script=str;
}
void LoadMainScript(lua_State* L)
{
std::string str;
str += "dev = require [[add]] \n";
str += "print([[It is main.lua]]) \n";
str += "dev.func() \n";
if ( luaL_loadbuffer(L, str.c_str(), str.size(), "main") )
{
printf("%s", lua_tostring(L, -1));
lua_pop(L, 1);
return;
}
}
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
SetModule(L); // Write down module in memory. Lua not load it yet.
SetLoader(L);
LoadMainScript(L);
lua_pcall(L,0,0,0);
lua_close(L);
return 0;
}
I have a rather large plist that I am trying to load data from. Here is an example of the plist, but there are 580 records so I can't put them all here:
<plist version="1.0">
<array>
<dict>
<key>Grave #</key>
<string></string>
<key>Last Name</key>
<string>?</string>
<key>First Name</key>
<string>Ada Lou daughter of</string>
<key>Dates</key>
<string>?-? Unable to read stone</string>
<key>Notes</key>
<string></string>
<key></key>
<string></string>
</dict>
<dict>
<key>Grave #</key>
<string></string>
<key>Last Name</key>
<string>?</string>
<key>First Name</key>
<string>Stone w/ Cherokee syllabry and also in english says: Here we rest</string>
<key>Dates</key>
<string></string>
<key>Notes</key>
<string></string>
<key></key>
<string></string>
</dict>
I have my property in my .h file
#property (nonatomic, strong) NSDictionary *graves;
Synthesized in my .m file:
#synthesize graves;
Here is my code that loads the file in my view did load function:
NSString *file = [[NSBundle mainBundle] pathForResource:#"RossCemeteryList" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:file]) {
NSLog(#"The file exists");
} else {
NSLog(#"The file does not exist");
}
graves = [[NSDictionary alloc] initWithContentsOfFile:file];
NSLog(#"%i", [graves count]);
The NSLog messages says it finds the file, the there are 0 rows in the second NSLog message. I can try to spit out the contents graves using "NSLog (#"%#", graves);" and it returns NULL.
I am a little lost. Any help appreciated.
You are trying to create an NSDictionary object and initialize it from the contents of that plist while that plist actually contains an NSArray as its root object. You need to change your NSDictionary into an NSArray or NSMutableArray.
I don't know if you're still looking for a solution, but this code should allow you to load a plist file and determine the type of its contents:
// load a Property List ("plist") file (fully-qualified path) into a generic object, if
// it's available...
- ( NSObject * ) testLoadPListData: ( NSString * const ) plistPath
{
// load the file data into a raw data object...
NSData * const data = [ NSData dataWithContentsOfFile: plistPath ];
// fields returned from property list creation...
NSPropertyListFormat fmt = 0;
NSError * err = nil;
// load the file data into a serialized property list object...
NSPropertyListSerialization * plist = [ NSPropertyListSerialization propertyListWithData: data
options: NSPropertyListImmutable
format: &fmt
error: &err
];
// if there was an error creating the serialized object...
NSString * const errorText = err ? [ err description ] : nil;
if ( errorText )
{
// log the error string...
NSLog( #"error while reading data from file \"%#\": %#"
, plistPath
, errorText
);
} // end error creating serialized object
#if defined( DEBUG )
//////////////////////////////
// //
// DEBUG PURPOSES ONLY... //
// //
//////////////////////////////
// if this file is in a format that can be readily translated into one of our target data types...
if ( plist )
{
// if this property list file contains a dictionary...
if ( [ plist isKindOfClass: [ NSDictionary class ] ] )
{
// dump the contents of the dictionary to the debug output window...
NSDictionary * const dict = ( NSDictionary * )( plist );
__CCLOG( #"<Dictionary>%#\n</Dictionary>", dict );
} // end is dictionary plist file
// if this property list file contains an array...
else if ( [ plist isKindOfClass: [ NSArray class ] ] )
{
// dump the contents of the array to the debug output window...
NSArray * const arr = ( NSArray * )( plist );
__CCLOG( #"<Array>%#</Array>", arr );
} // end is array plist file
} // end valid file format
#endif // defined( DEBUG )
return plist;
} // end testLoadPListData