2

I have java code:

Long long_value = 1;
ByteBuffer.allocate( 8).putLong( long_value).array();

I have result arrays of bytes: 0, 0, 0, 0, 0, 0, 0, 1 (in this order).

Please how correct port this code to Objective C?

2
  • Do you want to store the values in NSArray, a plain C array, NSData? Please provide more background on what you're trying to accomplish. Commented Mar 19, 2014 at 13:57
  • @sbooth, I need array of chars (bytes) with length 8 in result. Commented Mar 19, 2014 at 14:06

2 Answers 2

5

Preamble

You say "in this order". When a multi-byte value is stored in memory the bytes can be stored big-endian - the most significant byte first, or little endian - the least significant byte first. For example the 2-byte hex value 0x1234 is stored as 0x12, 0x34 big-endian and 0x34, 0x12 little-endian. The endian order depends on the computer architecture in use, for example the Intel x86 is little-endian.

ByteBuffer is a Java class which stores values as byte according to its own endian flag, independent of the underlying hardware's endian order. The default setting of ByteBuffer is big-endian. In your sample you do not set this flag and the array you show is in big endian order.

Apple provides the functions described in Byte Order Utilities Reference for manipulating endian order. The function you need is CFSwapInt64HostToBig which takes a 64-bit signed or unsigned int in whatever endian order the host uses and returns an integer with the bytes arranged in big-endian order - the numeric value of the result is effectively meaningless at this point, it is an ordered collection of 8 bytes.

You also say you want 8 bytes, but a long may not be 8 bytes long - that depends on the hardware architecture, language and compiler. For example for OS X they are 8 bytes when compiling for 64-bit. There are two ways to address this, you can use the sizeof standard function which returns the number of bytes in a value or a type, you pass it a variable or a type name; or you can use the pre-defined sized types when you need a particular number of bytes, for example SInt64 is the pre-defined 8-byte signed integer type.

Finally you say you want an "array", but what kind of array? Objective-C/Cocoa has two: C language value arrays, and Objective-C object arrays NSArray and its mutable sibling NSMutableArray.

C language arrays: in C the name of an array variable is of type "pointer to element type", e.g. for the declaration float values[8] the type of values is float *. This means that pointers can be used as arrays, but they are not the same thing - a pointer variable holds a pointer to memory but does not allocate memory to point to, an array declaration allocates memory for its elements.

C Array

How to get a C "array" of bytes in big-endian order:

SInt64 long_value = 0x123456789ABCDEF;              // use SInt64 rather than long
UInt64 BE_value = CFSwapInt64HostToBig(long_value); // use UInt64 as this value may not make numeric sense any more
UInt8 *BE_ptr = (UInt8 *)&BE_value;                 // UInt8 is a byte, take the address of BE_value

// BE_ptr is now a pointer to the 8 bytes of memory occupied by BE_value
// it can be treated as an array
// print it out to demo
for (int ix = 0; ix < 8; ix++)
{
    NSLog(@"%d: %2x", ix, BE_ptr[ix]);
}

This will print out 12, 34 etc.

Objective-C array

You can build this on the above. You cannot store a byte directly in an Objective-C object, you must wrap it up as an object using NSNumber, and @() is a shorthand to do that:

SInt64 long_value = CFSwapInt64HostToBig(0x123456789ABCDEF);
UInt8 *BE_ptr = (UInt8 *)& long_value;

NSMutableArray *BE_array = [NSMutableArray arrayWithCapacity:8]; // create an object array
for (int ix = 0; ix < sizeof(long); ix++)
{
    [BE_array addObject:@(BE_ptr[ix])]; // @(...) creates an NSNumber
}
NSLog(@"array: %@", BE_array);

This will print out the array (in decimal).

HTH

Sign up to request clarification or add additional context in comments.

Comments

0

You could use a char pointer (chars are the same size as a byte, usually).

unsigned char *p = (unsigned char *)&myLong;

char byte1 = p[0];
char byte2 = p[1];
//etc...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.