How to convert char "Q" to 3 bytes in objective c - ios

i am creating data packet in byteArray i want to convert char ch= "Q" to 3 bytes please help how to solve this.

char b[] = {0, 0, 'Q'};
NSData *d = [NSData dataWithBytes:b length:3];
You may need to swap the Q to a different position, depending on the precise byte order which is expected.

Related

Sending int data to BLE device

I have 4 distinct int values that I need to send to a BLE device (connection established OK).
I'll call the int values A,B,C,D for clarity. A and B range between 0-100, C has a range of 0-2000 and D has a range of 0-10000. All values are determined by user input.
I need to send these four values to the BLE device in quick succession, and package each of them differently: A and B (8 bits), C (16 bits) and D (32 bits). I'm unsure as to how to package the values correctly.
Below are three methods I've tried with varying degrees of success.
Convert int to data and send, e.g. for A (8 bit) int:
const unsigned char CHR = (float)A;
float size = sizeof(CHR);
NSData * aData = [NSData dataWithBytes:&CHR length:size];
[p writeValue:aData forCharacteristic:aCHAR type:CBCharacteristicWriteWithResponse];
Convert to string first, e.g. for (16 bit) C:
NSString * cString = [NSString stringWithFormat:#"%i",C];
NSData * cData = [cString dataUsingEncoding:NSUTF16StringEncoding];
[p writeValue:cData forCharacteristic:cCHAR type:CBCharacteristicWriteWithResponse];
Use uint, e.g. for (32 bit) D int:
uint32_t val = D;
float size = sizeof(val);
NSData * dData = [NSData dataWithBytes:(void*)&val length:size];
[p writeValue:valData forCharacteristic:dCHAR type:CBCharacteristicWriteWithResponse];
What am I doing wrong in the above, and how best to convert and send an int value to the device, allowing for the 3 formats required?
You need to know a little more information about the format your device expects:
Are the values signed or unsigned
Is the system little-endian or big-endian
Assuming that you want to use the little-endian format that iOS uses, you can just use dataWithBytes -
unsigned char a = 100
NSData *aData = [NSData dataWithBytes:&a length:sizeof(i)];
UInt16 c = 1000
NSData *cData = [NSData dataWithBytes:&c length:sizeof(c)];
Unit32 d = 10000
NSData *dData = [NSData dataWithBytes:&d length:sizeof(d)];
And then just write the NSData using writeValue:forCharacteristic:type:
If the device wants big-endian data then you will need to manipulate the bytes into the proper order. For this reason it is often easier just to send numeric values as ASCII strings and convert them back to numeric values on the receiving end, but this will depend on whether you have control over the format the device is expecting.

How to convert char(or Byte) with hexadecimal data in it, to an integer(decimal value)

I have
char tem;
Its value is shown as blow:
Printing description of tem:
(char) tem = '\xd1'
which should equals to 209 in decimal.
My question is how can I implement this conversion programmatically? That is I want to get a NSInteger that equals 209 in this case.
Maybe there’s something I’m overlooking here, but given that both char and NSInteger are integral types, can’t you just do
char tem = '\xd1';
NSInteger i = tem;
? Or perhaps, to avoid surprises from sign extension,
NSInteger i = tem & 0xff;
A char variable actually is a 8-bit integer. You don't have to convert it to a NSInteger to get its decimal value. Just explicitly tell the compiler to interpret it as an unsigned 8-bit integer, uint8_t:
char theChar = '\xd1';
NSLog(#"decimal: %d", (uint8_t)theChar); //prints 'decimal: 209'
To convert it to a NSInteger:
NSInteger decimal = (uint8_t)theChar;
If yours char in ANSCII, do this:
char a = '3';//example char
int i = (int)(a - '0');

Checking the length of an array of characters in Objective-C

I'm translating a small Java library for using in an Objective-C application I'm writing.
char[] chars = sentence.toCharArray();
int i = 0;
while (i < chars.length) { ... }
Where sentence is an NSString.
I'd like to translate the above Java code to Objective-C. Here's what I have so far:
// trims sentence off white space
sentence = [sentence stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
const char *chars = [sentence UTF8String];
How do I the above while condition? I'm not sure of how I'm supposed to check the length of the the string after it was converted to a character array.
Your Objective-C string already holds a measure of its length, it's just a matter of retrieving it:
// trims sentence off white space
sentence = [sentence stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSUInteger length = sentence.length;
const char *chars = [sentence UTF8String];
But I would like to remember that even if you didn't know the length, you could use the C strlen function:
// trims sentence off white space
sentence = [sentence stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
const char *chars = [sentence UTF8String];
size_t length = strlen(chars);
Even there is already an accepted answer I want to warn of using strlen(), even in this case it might be without any problem. There are a differences between NSString and C-Strings.
A. -length (NSString) and strlen() has different semantics:
NSString is not(!) \0-terminated, but length based. It can store \0 characters. It is very easy to get different length, if there is a \0 character in the string instance:
NSString *sentence = #"Amin\0Negm";
NSLog( #"length %ld", [sentence length]); // 9
const char *chars = [sentence cStringUsingEncoding:NSUTF8StringEncoding];
size_t length= strlen(chars);
NSLog(#"strlen %ld", (long)length); // 4
length 9
strlen 4
But -UTF8String and even the used -cStringUsingEnocding: (both NSString) copy out the whole string stored in the string instance. (I think in case of -cStringUsingEncoding it is misleading, because standard string functions like strlen() always uses the first \0 as the termination of strings.)
B. In UTF8 a character can have multibytes. A char in C is one byte. (With byte not in the meaning of 8 bits, but smallest addressable unit.)
NSString *sentence = #"Αmin Negm";
NSLog( #"length %ld", [sentence length]);
const char *chars = [sentence UTF8String];
size_t length= strlen(chars);
NSLog(#"strlen %ld", (long)length);
length 9
strlen 10
WTF happened here? The "A" of Amin is no latin capital letter A but a greek capital letter Alpha. In UTF8 this takes two bytes and for pure C's strlen there are two characters!
NSLog(#"%x-%x %x-%x", 'A', 'm', (unsigned char)*chars, (unsigned char)*(chars+1) );
41-6d ce-91
The first two numbers are the codes for 'A', 'm', the second two numbers are the UTF8 code for greek capital letter Alpha (CE 91).
I do not think, that it is a good idea to simply change from NSString to char * without good reason and a complete understanding of the problems. If you do not expect such characters, use NSASCIIStringEncoding. If you expect such characters check your code again and again … or read C.
C. C supports wide characters. This is similiar to Mac OS' unichar, but typed wchar_t. There are string functions for wchar_t in wchar.h.
NSString *sentence = #"Αmin Negm";
NSLog( #"length %ld", [sentence length]);
wchar_t wchars[128]; // take care of the size
wchar_t *wchar = wchars;
for (NSUInteger index = 0; index < [sentence length]; index++)
{
*wchar++ = [sentence characterAtIndex:index];
}
*wchar = '\0';
NSLog(#"widestrlen %ld", wcslen(wchars));
length 9
widestrlen 9
D. Obviously you want to iterate through the string. The common pattern in pure C is not to use an index and to compare it to the length and definitly not to to strlen() in every loop, because it produces high costs. (C strings are not length based so the whole string has to be scanned over and over.) You simply increment the pointer to the next char:
char letter;
while ( (letter = *chars++) ) {…}
or
do
{
// *chars points to the actual char
} while (*char++);
int lenght = sizeof(chars) / sizeof(char)
might work, but it will (inte the best case) return same thing as
sentence.lenght
in worst case 0 because the whole pointer / sizeof thing i don't remember now

Appending binary string to NSMutableData

How would I go about appending this binary string
111000111000111111000111000111
to an NSMutableData object that contains a png
(NSMutableData *dataForPNGFile = UIImagePNGRepresentation(p.Image);)
You'd need to parse the string into an NSData, then append that.
I'm not aware of anything built in, so e.g.
NSMutableData *data = [NSMutableData dataWithLength(string.length+7)/8];
uint8_t *mutableBytes = (uint8_t *)data.mutableBytes;
for(NSUinteger index = 0; index < string.length; index++)
{
unichar character = [string characterAtIndex:index];
mutableBytes[index >> 3] <<= 1;
if(character == '1') mutableBytes[index >> 3] |= 1;
}
if(string.length&7)
mutableBytes[string.length >> 3] <<= (7 - (string.length&7));
So assumptions are that your source string is only 1s and 0s, that it's written from most significant to least significant digit and that it's byte rather than word oriented.
Also, UIImagePNGRepresentation returns immutable data so you'll need to take a mutable copy of that.
Look at the NSMuteableData method appendBytes:length:
You will have to convert your bits to bytes as #Tommy says.

Converting integer from 0 to 255 ( 1 byte ) into NSDATA

I need exactly 1 byte for some kind of socket based application and i cant find a way to create it.
unsigned char mydata = 3;
[NSMutableData dataWithBytes:&mydata length:sizeof(mydata)];
NSData reference, unsigned char is used to save 1 byte.

Resources