how to get char array-element in 2-dimensional array - objective-c
I have 2-dimensional array like below.
unsigned char myArray[][48] = {
{0xfc,0x94,0x88,0x48,0x5f,0xa4,0x9a,0xfb,0x6e,0xf8,0xcd,0x01,0x47,0x64,0x03,0xd0,0x1f,0xb8,0xa3,0x85,0x84,0xa9,0x4a,0xc4,0x9e,0xea,0x26,0x09,0x62,0x96,0x91,0xa6},
{0xa9,0xc5,0x9a,0xb3,0x09,0x38,0x15,0xb3,0x22,0xb3,0x07,0x21,0x3e,0x39,0x35,0xc6,0x69,0x6e,0xf3,0x64,0xb0,0x0a,0x4c,0xcb,0x77,0xff,0x76,0x3c,0x37,0xf3,0x99,0x96},
{0x24,0x4d,0xc0,0x45,0xe0,0x50,0x1f,0x72,0x0f,0xb0,0xcc,0xb9,0xc6,0x72,0xa9,0x5a,0xf3,0x5a,0xd9,0xe2,0xc3,0x44,0xd9,0x25,0xf3,0x12,0x6a,0x0c,0x37,0x6a,0x3f,0xb6},
{0xd3,0x91,0x98,0xfd,0xcd,0x6e,0x01,0x44,0xfc,0xf7,0x5d,0x08,0xab,0xbc,0x43,0xab,0xd3,0x4a,0xd9,0x07,0xa7,0x8e,0xda,0xba,0xb5,0x8a,0x27,0xe1,0xc6,0x7a,0xfe,0xee},
{0x5f,0x08,0xcc,0x01,0x17,0xde,0xbb,0x99,0x19,0xf3,0x0d,0xd7,0x08,0x5f,0xcd,0xe3,0xe0,0x24,0x54,0xee,0x16,0x68,0xe1,0x64,0x41,0x58,0x09,0xd8,0xf7,0x93,0x8f,0xf1,0xf0,0x00,0xd7,0xd4,0x5b,0x6b,0x8d,0x1e,0x18,0x06,0x1f,0x70,0x6a,0x40,0x86,0x38}
};
When I get myArray[0], it's not 36 bytes as we see; instead, it is 48. How can I get 36 bytes as we see in the array without specifying its size, 36, while getting it.
{0xfc,0x94,0x88,0x48,0x5f,0xa4,0x9a,0xfb,0x6e,0xf8,0xcd,0x01,0x47,0x64,0x3,0xd0,0x1f,0xb8,0xa3,0x85,0x84,0xa9,0x4a,0xc4,0x9e,0xea,0x26,0x09,0x62,0x96,0x91,0xa6}
NSData *row1 = [NSData dataWithBytes:url[0]
length:(sizeof(myArray[0])/sizeof(unsigned char))];
There's only 32 bytes in the first 4 rows.
Since the values not provided are initialized to 0, you could search for the last non-zero backward, like:
unsigned char* data = myArray[n];
size_t len = sizeof(myArray[n]);
for (; len > 0; -- len)
if (data[len-1] != 0)
break;
NSData* row = [NSData dataWithBytes:data length:len];
This assumes there are no 0 at the end of your provided 32-byte sequence. If not, you have to provide an additional array recording the number of bytes each row.
NSData *row1 = [NSData dataWithBytes:myArray[0] length:36];
^_^
Related
Troubles with casting bytes from NSInputStream?
I have openssl server and Objective-C client. I send message like this uint32_t testD = 161; err = SSL_write(ssl_, &testD, sizeof(uint32_t)); and read it by NSInputStream like case NSStreamEventHasBytesAvailable: { uint8_t buffer[4]; int len; while ([inStream hasBytesAvailable]) { len = [inStream read:buffer maxLength:sizeof(buffer)]; if (len > 0) { NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; NSData *theData = [[NSData alloc] initWithBytes:buffer length:len]; if (nil != output) { char buff; [theData getBytes:&buff length:1]; uint32_t temp = (uint32_t)buffer; } ... So, in output I have "¡", it's 161-th ASCII symbol, in buff I have '\xa1' and in temp very big number, but actually I need 161 in temp. I read that '\xa1' it's also 161, but I can't cast this to uint32_t. What is the problem? ANSWER: The problem was in casting. This works fine for me: unsigned char buff; int temp = buff; or char buff; int b = (unsigned char) buff;
No encoding is used by SSL_write(), and \xa1 == 161 is a mathematical identity, not the result of any encoding process. As you're successfully recovering \xa1, clearly no decoding is used by NSInputStream either. It seems to me that you're casting the address of the buffer rather than its contents, which is why you get a high value that varies with compilation. In addition you are possibly over-running the data by reading whatever is available and then only consuming four bytes of it: less in fact because you're incorrectly testing len >= 1 rather than len >= 4. You should: Use a buffer of exactly four bytes. No need to allocate it dynamically: you can declare it as a local array. Read until you have read four bytes. This requires a loop. Change the casting syntax (don't ask me how, I'm no Objective-C expert, but the code that recovers buff looks like a good start), so that you get the content of the buffer instead of the address. After that you may then have endian issues. Nothing to do with encoding.
What encoding is used in SSL_write and NSInputStream? There is no encoding. Its bytes in and bytes out. I think you are looking for network byte order/endianess. Network byte order is big endian. So your code would become: uint32_t testD = 161; uint32_t be = htonl(testD); err = SSL_write(ssl_, &be, sizeof(be)); Here's the description of htonl from the htonl(3) man pages: The htonl() function converts the unsigned integer hostlong from host byte order to network byte order. To convert back, you would use ntohl. I'm not sure if Cocoa/CocoaTouch offers a replacement for htonl and ntohl. So you might have to use them in your iPhone projects, too. See, for example, Using ntohl and htonl problems on iPhone.
We can get a single byte value like this: unsigned char buff; int temp = buff; Or char buff; int b = (unsigned char) buff;
How do I set the bits in a byte?
I need to store a series of 1s and 0s of arbitrary length. I had planned to use ints, but then it occurred to me that really all I need is a bitstream. NSMutableData seems like just the thing. Except all I see anyone talking about is how to set bytes on it, or store jpegs or strings in it. I need to get way more granular than that. Given a series of 1s and 0s such as: 110010101011110110, how do I make it into an NSData object--and how do I get it out? NSData's appendBytes:length: and mutableBytes are all at the byte level, and I need to start lower. Storing those 1s and 0s as bytes doesn't make sense, when the bytes themselves are made of sets of 1s and 0s. I'm having trouble finding anything telling me how to set bits. Here's some faux code: NSString *sequence = #"01001010000010"; //(or int sequence, or whatever) for (...){//iterate through whatever it is--this isn't what I need help with if ([sequence intOrCharOrWhateverAtIndex: index] == 0) { //do something to set a bit -- this is what I need help with } else { //set the bit the other way -- again, this is what I need help with } } NSData *data = [NSData something]; //wrap it up and save it -- help here too
Do you literally have 1s and 0s? Like... ASCII numerals? I would use NSString to store that. If by 1s and 0s you mean a bunch of bits, then just divide the number of bits by 8 to get the number of bytes and make an NSData of the bytes. (Editing to add untested code to convert a bitstream to a buffer) //Assuming the presence of an array of 1s and 0s stored as some numeric type, called bits, and the number of bits in the array stored in a variable called bitsLength NSMutableData *buffer = [NSMutableData data]; for (int i = 0; i < bitsLength; i += 8) { char byte = 0; for (int bit = 0; bit < 8 && i + bit < bitsLength; bit++) { if (bits[i + bit] > 0) { byte += (1 << bit); } } [buffer appendBytes:&byte length:1]; }
I got this answer from: Convert Binary to Decimal in Objective C Basically, I think the question could be phrased, "how do I parse a string representation of a binary number into a primitive number type". The magic is all in strtol. NSString* b = #"01001010000010"; long v = strtol([b UTF8String], NULL, 2); long data[1]; data[0] = v; NSData* d = [NSData dataWithBytes:data length:sizeof(data)]; [d writeToFile:#"test.txt" atomically:YES]; Using this idea, you could split your string into 64 character chunks and convert them to longs.
Best way to release memory allocated using malloc
I have function to convert an integer into byte array (for iPhone). To add dynamicity I have allocate the array using malloc. But I think this will leak memory. What's best way to manage this memory, + (unsigned char *) intToByteArray:(int)num{ unsigned char * arr = (unsigned char *) malloc(sizeof(num) * sizeof(unsigned char)); for (int i = sizeof(num) - 1 ; i >= 0; i --) { arr[i] = num & 0xFF; num = num >> 8; } return arr; } When calling, int x = 500; unsigned char * bytes = [Util intToByteArray:x]; I want to avoid the call free(bytes) since, the calling function do not know or explicitly knows, the memory is allocated and not freed.
A few things: The char type (and signed char and unsigned char) all have a size of 1 by definition, so sizeof(unsigned char) is unnecessary. It looks like you just want to get the byte representation of an int object, if this is the case, it is not necessary to allocate more space for it, simply take the address of the int and cast it to a pointer to unsigned char *. If the byte order is wrong you can use the NSSwapInt function to swap the order of the bytes in the int and then take the address and cast to unsigned char *. For example: int someInt = 0x12345678; unsigned char *bytes = (unsigned char *) &someInt; This cast is legal and reading from bytes is legal up until sizeof(int) bytes are read. This is accessing the “object representation”. If you insist on using malloc, then you simply need to pass the buffer to free when you are done, as in: free(bytes); The name of your method does not imply the correct ownership of the returned buffer. If your method returns something that the caller is responsible for freeing, it is conventional to name the method using new, copy, or sometimes create. A more suitable name would be copyBytesFromInt: or something similar. Otherwise you could have the method accept a pre-allocated buffer and call the method getBytes:fromInt:, for example: + (void) getBytes:(unsigned char *) bytes fromInt:(int) num { for (int i = sizeof(num) - 1 ; i >= 0; i --) { bytes[i] = num & 0xFF; num = num >> 8; } } You could wrap your bytes into a NSData instance: NSData *data = [NSData dataWithBytesNoCopy:bytes length:sizeof(num) freeWhenDone:YES]; Make sure your method follows the usual object ownership rules.
Just call free(bytes); when you are done with the bytes (either at the end of method or in dealloc of the class) since you want to avoid the free call, you could wrap your byte[] in a NSData object: NSData *d = [NSData dataWithBytesNoCopy:bytes length:num freeWhenDone:YES];
The conventional way of handling this is for the caller to pass in an allocated byte buffer. That way the caller is responsible for freeing it. Something like: int x = 500; char *buffer = malloc(x * sizeof(char)); [Util int:x toByteArray:buffer]; … free(buffer); I would also consider creating an NSData to hold the bytes, this would take care of memory management for you, while still allowing you to alter the byte buffer: + (NSData *) intToByteArray:(int)num { unsigned char * arr = (unsigned char *) malloc(sizeof(num) * sizeof(unsigned char)); for (int i = sizeof(num) - 1 ; i >= 0; i --) { arr[i] = num & 0xFF; num = num >> 8; } return [NSData dataWithBytesNoCopy:arr length:num freeWhenDone:YES]; }
BLOB to byte array conversion in objective C
I have a table filed in which the value is stored as BLOB type . I need to get that as a binary array so that I can get different values from different byte positions in the BLOB. Any Help is appreciated.
// Get the start and length of the blob. // (remember column indexes are 0-based when fetching the value // but 1-base when binding - yeah cheers!) uint8_t *data = (uint8_t *)sqlite3_column_blob(stmt, columnIndex); size_t length = (size_t)sqlite3_column_bytes(stmt, columnIndex); // And now you can access the data unsigned sum = 0; for (size_t i = 0; i < length; i++) sum += data[i];
Objective C - Parse NSData
I have the following data inside an NSData object: <00000000 6f2d840e 31504159 2e535953 2e444446 3031a51b 8801015f 2d02656e 9f110101 bf0c0cc5 0affff3f 00000003 ffff03> I'm having issues parsing this data. This data contains information which is marked by tags Tag 1 is from byte value 0x84 to 0xa5 Tag 2 is from byte value 0xa5 to 0x88 Tag 3 is from byte value 0x88 to 0x5f0x2d Tag 4 is from byte value 0x5f0x2d to 0x9f0x11 How would I go about to get those values from the NSData object? Regards, EZFrag
Use -[NSData bytes] to get a pointer to the contents. Then use pointer arithmetic to iterate over the bytes until you find what you are looking for. Since you want to go byte by byte, you should probably cast the pointer returned by bytes to uint8_t*. Then, pointer[0] points to the first byte, pointer[1] to the second, and so on.
I managed a nice solution, deciding to actually use the graymatter -(int)getIndexOfSubDataInData:(NSData*)haystack forData:(NSData*)needle{ int dataCounter = 0; NSRange dataRange = NSMakeRange(dataCounter, [needle length]); NSData* compareData = [haystack subdataWithRange:dataRange]; while (![compareData isEqualToData:needle]) { dataCounter++; dataRange = NSMakeRange(dataCounter, [needle length]); compareData = [haystack subdataWithRange:dataRange]; } return dataCounter; } -(NSData*)getSubDataInData:(NSData*)targetData fromTag:(NSData*)fromTag toTag:(NSData*)toTag{ int startIndex = [self getIndexOfSubDataInData:targetData forData:fromTag] + [fromTag length]; int endIndex = [self getIndexOfSubDataInData:targetData forData:toTag]; int dataLength = endIndex - startIndex; NSRange dataRange = NSMakeRange(startIndex, dataLength); return [targetData subdataWithRange:dataRange]; } //here is how I use the code NSData* langTagStart=[[NSData alloc] initWithBytes:"\x5F\x2D" length:2]; NSData* langTagEnd=[[NSData alloc] initWithBytes:"\x9F\x11" length:2]; NSData* languageData = [self getSubDataInData:[response bytes] fromTag:langTagStart toTag:langTagEnd]; Thanks for your suggestions. Regards, EZFrag