How to "remove" Array elements or ge Range from uint8_t Array?

1k views Asked by At

In my Iphone App I've an TCP Connection and want recive data which works ok.

But I need to split an uint8_t Array.

unsigned result;
uint8_t buffer[1024];
len = [inputStream read:buffer maxLength:sizeof(buffer)];
NSString *hexstring = [NSString stringWithFormat:@"%02x%02x%02x%02x",buffer[3],buffer[2],buffer[1],buffer[0]];
                        result = 0;
NSScanner *scanner = [NSScanner scannerWithString:hexstring];
[scanner scanHexInt:&result];
NSLog(@"HexString: %@ Result: %i ",hexstring,result);
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];     

Here I get the first 4 bytes to get the length of the recived package.

Now I want an output for the range of the buffer Array without buffer[1] - buffer[3]

I mean the Range from buffer[4] to buffer[length of packe].

How can I archive that?

2

There are 2 answers

4
Steven Fisher On BEST ANSWER

i think the basic problem here is your use of a uint8_t array. As a C array, you should have a really compelling reason to use it in Objective-C. You don't have a compelling reason, here, and have identified a reason not to use it.

Instead of this:

uint8_t buffer[1024];

Use a NSMutableData built with dataWithCapacity:. Something like this:

NSMutableData *data = [NSMutableData dataWithCapacity:1024];
uint8_t *buffer = [data mutableBytes];

You can manipulate the data, then, with methods against data.

Alternately, you could use memmove (not memcopy) to manipulate your array directly. I don't think it's worth it, though; you can generally assume that Foundation will pick a good algorithm, whereas you're likely to pick the simplest, and you're more likely to introduce a block overrun.

0
ipmcc On

How about:

NSString *output = [[NSString alloc] initWithBytes: buffer + 4 length: len - 4 encoding:NSASCIIStringEncoding];

Pointer arithmetic for the win.

Also, getting a 32 bit unsigned int from 4 bytes by going through NSString is pretty circuitous (not to mention slow). Why not just do this:

uint32_t result = buffer[3] << 24 |  buffer[2] << 16 | buffer[1] << 8 | buffer[0];

I mean, even that is circuitous, but at least it's explicit, and doesn't assume the endianness of the host, and doesn't round trip through a string and an NSScanner.