core text - getting nsstring from ctrunref - ios

I have the following code to get a run:
CFArrayRef runs = CTLineGetGlyphRuns(line);
for(int j = 0; j < CFArrayGetCount(runs); j++)
//for(id runObj in (__bridge NSArray*)CTLineGetGlyphRuns(line))
{
CTRunRef run = CFArrayGetValueAtIndex(runs, j);
}
What I need to do is to get the actual string of characters that contains this run. If I get the glyphs then these are not actual characters, is there any way to for example get an nsstring containing the actual text given a ctrun?
Thanks

CTRunRef run = (CTRunRef)runObj;
CFRange runRange = CTRunGetStringRange(run);
[[_attributedString attributedSubstringFromRange:NSMakeRange(runRange.location, runRange.length)] string]

No there is no way to get back the attributed string that was used in creation of a CTRun. Your program already ought to know this information, since it created the CTFrame, CTLine or CTRun from an attributed string.

Related

How to generate random messages from strings

I've google and i can't find the exact closest thing to the function i'm seeking.
So this is the idea of the generating message on the iOS apps.
This just randomly generate random number depend on the length
// Generates alpha-numeric-random string
- (NSString *)genRandStringLength:(int)len {
static NSString *letters = #"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
for (int i=0; i<len; i++) {
[randomString appendFormat: #"%C", [letters characterAtIndex: arc4random() % [letters length]]];
}
return randomString;
}
What i'm seeking is for the apps to generate random messages store in the array list depending on the settled time.
This is how i want it to work
static NSString *letters = #"Hello all","You're awesome","This is awkward","Are you sleeping?";
I need help to generate random messages in the string of arrays . Thank you in advance
This is not a way of doing this certain task. you have to make one array with most of word instad of punting single string with all alphabet character And create random sentence. This is logical and programmatic task xcode not generate random word it self. you have to do some logical stuff your self.
Here i found one github example code please check Bellow you got idea how does you can achieve this task. Hope you getting some idea with this example.
https://github.com/dav/Objective-C-Lorem-Ipsum-Generator

Will this unicode encryption fail?

I'm not needing any serious security, I just need to stop 11 year olds with plist editors from editing their number of coins in my game with ease.
I created a function that takes a string, for each unicode value of a character it raises this unicode value by 220 plus 14 times the character number that it is in the string.
Obviously this will fail (I think) if the string was like a million characters long because eventually you run out of unicode characters, but for all intents and purposes, this will only be used on strings of 20 characters and less.
Are there any unicode characters in this range that will not be stored to a plist or will be ignored by Apple's underlying code when I save the plist so that when I retrieve it and decrypt the character will be gone and I can't decrypt it?
+(NSString*)encryptString:(NSString*)theString {
NSMutableString *encryptedFinal = [[NSMutableString alloc] init];
for (int i = 0; i < theString.length; i++) {
unichar uniCharacter = [theString characterAtIndex:i];
uniCharacter += +220+(14*i);
[encryptedFinal appendFormat:#"%C", uniCharacter];
}
return encryptedFinal;
}
+(NSString*)decryptString:(NSString*)theString {
NSMutableString *decryptedFinal = [[NSMutableString alloc] init];
for (int i = 0; i < theString.length; i++) {
unichar uniCharacter = [theString characterAtIndex:i];
uniCharacter += +220+(14*i);
[decryptedFinal appendFormat:#"%C", uniCharacter];
}
return decryptedFinal;
}
It works for a range of a string of length 20 characters or less if you are encrypting one of the first 26+26+10+30 characters in the unicode index at any given point along the 20 character line. It probably works higher, I just didn't test it any higher.
This is the code I created to test it, all unicode characters were stored in an NSString and stayed valid for counting later.
int i = 0;
NSMutableString *encryptedFinal = [[NSMutableString alloc] init];
NSString *theString = #"a";
int j = 26+26+10+30;//letters + capital letters + numbers + 30 extra things like ?><.\]!#$
int f = 0;
int z = 0;
while (f < j) {
while (i < 220+220+(14*20)) {
unichar uniCharacter = [theString characterAtIndex:0];
uniCharacter += +f;
uniCharacter += +220+(14*i);
[encryptedFinal appendFormat:#"%C", uniCharacter];
i++;
}
z += i;
f++;
i = 0;
}
NSLog(#"%#", encryptedFinal);
NSLog(#"%i == %i?", z, encryptedFinal.length);
There are two thing that you can do:
Save the number of coins using NSData rather than using
NSNumber. Then use
NSData+AES
to encrypt it. You can even encrypt your entire .plist file to
ensure that no other fields are changed.
Security through obscurity. Just save the number of coins as an important sounding field. e.g.:Security Token Number. You can also create a bogus number of coins field whose value is ignored. Or maybe save the same value in both the fields and flag the user for cheating if the two values don't match.

how to include index number in a class name

I am making a program where I need to loop through an array with a list of letters. I want the letters to be shown on their specific label. I have therefore created an outlet of each (about 38) and given them the name "alif01", "alif02", etc.
for (int i = 0; i < [arabicLetters count]; i++) {
int num = i;
NSString *letterString = [arabicLetters objectAtIndex:i];
NSLog(#"alif0%d is %#", num, letterString);
alif0**[i]**.text = arabicLetters[i];
}
is it possible to use the index [i] instead of writing it all manually?
You should not have 38 IBOutlet properties for this. You should have an array (possibly an IBOutletCollection) so that you can loop over the array / index into the array.
While technically you can create a key name and use KVC valueForKey: (appending strings / string format), the array approach is a much better solution.
Indeed, as you already have a loop, you would be better served by creating the labels in the loop directly, then you know you have the correct number. This is particularly beneficial later, when you change the contents of arabicLetters (though that sounds like it isn't a concern in this particular case).
Try with below code:
for (int i = 0; i < [arabicLetters count]; i++) {
NSString *letterString = [arabicLetters objectAtIndex:i];
NSString *propertyName = [NSString stringWithFormat:#"alif0%d.text",i];
[self setValue:letterString forKeyPath:propertyName];
}

Objective C parsing hiccup

Please bear with me. I am new to C altogether, let alone Objective C. I am trying to do something that should be simple however its not working. I am scanning a string of numbers that also contains symbols. As the mini function runs through the input string it appends numbers to a new string until it comes across an operator (I'm writing a calculator in my own way as a learning exercise.) Right now I am just doing the beginning part and scanning the string and appending character. Here is my code:
char userInput[99];
NSMutableString *number = nil;
int i;
printf( "Please enter math: " );
scanf( "%s", userInput );
fpurge( stdin );
NSString *InputString = [NSString stringWithUTF8String:userInput];
for (i=0; i < [InputString length]; i++) {
char current = [InputString characterAtIndex:i];
if (isalnum(current)) {
[number appendString:[NSString stringWithCharacters:&current length:1]];
NSLog(#"%# ", number);
}
}
For the life of me I can not seem to figure out why it keeps printing 2012-05-02 19:23:20.935 CALC[1447:403] (null) instead of the number value for each number it comes across. So for example if there are 5 numbers in the entered string it will print that 5 times.
You never initialized number--so when you call -appendString: on it, you're only appending to nil, and the result is just nil back. Try this for your second line:
NSMutableString *number = [NSMutableString string];
Now number is an empty string object, which is very different from being nil, which is no object at all.

Find Character String In Binary Data

I have a binary file I've loaded using an NSData object. Is there a way to locate a sequence of characters, 'abcd' for example, within that binary data and return the offset without converting the entire file to a string? Seems like it should be a simple answer, but I'm not sure how to do it. Any ideas?
I'm doing this on iOS 3 so I don't have -rangeOfData:options:range: available.
I'm going to award this one to Sixteen Otto for suggesting strstr. I went and found the source code for the C function strstr and rewrote it to work on a fixed length Byte array--which incidentally is different from a char array as it is not null terminated. Here is the code I ended up with:
- (Byte*)offsetOfBytes:(Byte*)bytes inBuffer:(const Byte*)buffer ofLength:(int)len;
{
Byte *cp = bytes;
Byte *s1, *s2;
if ( !*buffer )
return bytes;
int i = 0;
for (i=0; i < len; ++i)
{
s1 = cp;
s2 = (Byte*)buffer;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return cp;
cp++;
}
return NULL;
}
This returns a pointer to the first occurrence of bytes, the thing I'm looking for, in buffer, the byte array that should contain bytes.
I call it like this:
// data is the NSData object
const Byte *bytes = [data bytes];
Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]];
Convert your substring to an NSData object, and search for those bytes in the larger NSData using rangeOfData:options:range:. Make sure that the string encodings match!
On iPhone, where that isn't available, you may have to do this yourself. The C function strstr() will give you a pointer to the first occurrence of a pattern within the buffer (as long as neither contain nulls!), but not the index. Here's a function that should do the job (but no promises, since I haven't tried actually running it...):
- (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack
{
const void* needleBytes = [needle bytes];
const void* haystackBytes = [haystack bytes];
// walk the length of the buffer, looking for a byte that matches the start
// of the pattern; we can skip (|needle|-1) bytes at the end, since we can't
// have a match that's shorter than needle itself
for (NSUInteger i=0; i < [haystack length]-[needle length]+1; i++)
{
// walk needle's bytes while they still match the bytes of haystack
// starting at i; if we walk off the end of needle, we found a match
NSUInteger j=0;
while (j < [needle length] && needleBytes[j] == haystackBytes[i+j])
{
j++;
}
if (j == [needle length])
{
return i;
}
}
return NSNotFound;
}
This runs in something like O(nm), where n is the buffer length, and m is the size of the substring. It's written to work with NSData for two reasons: 1) that's what you seem to have in hand, and 2) those objects already encapsulate both the actual bytes, and the length of the buffer.
If you're using Snow Leopard, a convenient way is the new -rangeOfData:options:range: method in NSData that returns the range of the first occurrence of a piece of data. Otherwise, you can access the NSData's contents yourself using its -bytes method to perform your own search.
I had the same problem.
I solved it doing the other way round, compared to the suggestions.
first, I reformat the data (assume your NSData is stored in var rawFile) with:
NSString *ascii = [[NSString alloc] initWithData:rawFile encoding:NSAsciiStringEncoding];
Now, you can easily do string searches like 'abcd' or whatever you want using the NSScanner class and passing the ascii string to the scanner. Maybe this is not really efficient, but it works until the -rangeOfData method will be available for iPhone also.

Resources