I am receiving some numerical data from a Java client via socket connection on C++ server. When I receive 4 byte int type data, what I need is just using ntohl() function or reverse the bit order to convert to c++ int type. However, I'am having trouble trying to convert long data type from Java. No matter what I tried, I could not recover the correct value. I used LONG64, ULONG64 and int64_t as well, and none of them worked.
For example, when I send long s = 1 from Java, on C++ side I did:
int64_t size;
recv(client, (char *)&size, sizeof int64_t, 0);
if I do
size = ntohl(size)
Then size will become 0 whatever the original long value is in Java !
If I don't do ntohl() conversion, then size = 72057594037927936 for s = 1
I have hardly found any useful information on this topic and I would appreciate any suggestion.
The value 72057594037927936 is 0x0100000000000000 in Hex. As you may have guessed, that's simply backwards byte ordering, the 1 is in front instead of back.
ntohl() is 32-bit, so it is throwing out those top four bytes (the first 8 hex digits), giving you zero. You could possibly use htonll instead, but that isn't quite right. The best thing is to reverse the order of the bytes yourself.
int64_t size;
recv(client, (char *)&size, sizeof int64_t, 0);
char *start = (char *)&size, *end = start + sizeof(size);
std::reverse(start, end);
There are a ton of ways of reversing the bytes, and a ton of ways of dealing with little/big endian problems in general.
Related
I'm trying to read a 31 bit long Integer from an InputStream in java and i can't figure a way out for doing this. I receive four byte from the InputStream and the first bit of the first byte is a reserved bit which is always unset (0x0) and the rest is 31 bit long integer.Here is a visualization of what i described :
+-+-------------+---------------+-------------------------------+
|R| 31 bit long Integer |
+-+-------------------------------------------------------------+
I would appreciate it if you could help me come up with a solution. Thanks!
I'm trying to read a 31 bit long Integer from an InputStream
That is impossible.
The minimum size of thing you can read is a byte, which is 8 bits; all things you can read from them are a multiple of 8.
and the first bit of the first byte is a reversed byte which is always onset (0x0)
This sentence doesn't make any sense. The first 'bit of a byte' cannot be a 'reversed byte'. Given that bits are a 1-dimensional concept, there is no such thing as a 'reversed bit', and 'onset', if it means anything, means '1' and not '0', and bits are not as a rule communicated in '0x' syntax, which is hexadecimal.
I conclude you must be confused about the API.
However, to be a bit more helpful: If you have 4 bytes of data that contains a 31-bit-length integer, then:
You need to know if it is 'big endian' or 'little endian'. It will be someplace in the docs; usually protocols are big endian.
That first bit can trivially be stripped away or isolated, which should help.
Assuming big endian:
try (InputStream raw = socket.getInputStream();
DataInputStream data = new DataInputStream(raw)) {
int v = data.readInt();
boolean isolatedBit = (v >>> 31) != 0;
v = v & 0x7FFFFFFF;
}
DataInputStream has the readInt() call that takes care of business.
isolatedBit will be 0 if that 'R' bit is unset, and '1' if it is iset.
Even if this R thing is set, that last line will ensure that the value of v has that bit unset. As a consequence, the number will be between 0 and 2^31-1 (thus, always positive).
NB: After some corrections to the original question, this is much simpler:
Given that the reserved bit is always unset, you can just call int v = data.readInt(), that's the only thing in the try block that would then be required. Had the 'reserved bit' always been a 1 - you would need that & 0x7FFFFFFF to get rid of it.
This is my very first post on Stackoverflow so please go easy on me :)
I am looking for a more processor-efficient way of performing byte array conversions to primitive types in Java.
The byte array contains a data stream which is made up of many different primitive types. For the purpose of this question, let's just assume that is contains INT's and for brevity, ignore endian.
In C, I can extract an INT very efficiently via pointers: IE
int *value;
unsigned char data[MAX_LEN_DATA];
value = (int *)&data[10];
To perform the same in Java, is it true that I need to compute the value. IE, something like:
int value;
byte[] data;
value = (data[10]<<24) | (data[11]<<16) | (data[12]<<8) | data[13];
Is there a more processor-efficient method such as the C example or does Java utilise CPU barrel shifting (Intel & AMD in my case) in which case, my question becomes superfluous ... but maybe useful for others :)
My android program need to receive int values from arduino analog sensor via usb and print them on real time graph, i receive byte[] from call back function.
i tried many ways to convert from byte[] to string or int include new String new Integer BigInteger parseInt and some code method that i find in other topics, but nothing work i receive only half of the correct values, other values to much bugger or smaller.
The byte[] length changed from 1 to 4 , their is some empty bytes, it look like this(log):
How i can to convert it to correct values? where the problem?
In ideal i need receive int values between 230 to 300 from sensor.
It seems that your sensor is using text protocol. If I convert your bytes to ASCII chars, it will be:
..
10-LF
50-2
53-5
56-8
..
13-CR
10-LF
50-2
53-5
..
54-6
13-CR
10-LF
etc.
Interpreted as
258
256
so, I thing the best solution is to accumulate received bytes as chars and when CRLF is reveived, read whole string (with stripped CRLF) as int - probably via parseInt.
Arduino code segment?
Guessing badly : int is a 16 bit value byte is 8 bits.
Int_8 is -128 to 127 . uint8_t 0-255 not supported by java as far as i know but you can use the char type unsigned 16 bit(need to cast it).
I have a objective-c code.
but I want to convert to java code.
I know objective-c's NSData equals java's byte[].
but I don't know about the equivalent of rest of the keywords.
Objective-C CODE
NSData * updatedValue = characteristic.value;
uint8_t* dataPointer = (uint8_t*)[updatedValue bytes];
uint8_t flags = dataPointer[0]; dataPointer++;
int32_t tempData = (int32_t)CFSwapInt32LittleToHost(*(uint32_t*)dataPointer); dataPointer += 4;
int8_t exponent = (int8_t)(tempData >> 24);
int32_t mantissa = (int32_t)(tempData & 0x00FFFFFF);
if( tempData == 0x007FFFFF )
{
NSLog(#"Invalid temperature value received");
return;
}
float tempValue = (float)(mantissa*pow(10, exponent));
self.tempString = [NSString stringWithFormat:#"%.1f", tempValue];
Please help me
You could try
Objective c to Java converter
Incase if you need your java code to be converted to Objective C
Java to Objective c converter
Reference
Do not attempt convert it to Java, determine what it does and write it in Java.
A little educated guesswork based on your knowledge of programming should get you a long way to understanding the code. This is a great advantage of programming languages over natural languages, understand programming and you can usually make a good educated guess at the meaning of a fragment of code even if you don't know the language. In natural languages the same simply does not hold, knowing, say, French is little help in reading Hindi!
So let's see, uint8_t is probably a type, what type could it be? Well int sounds a lot like integer, 8 is probably the size of the integer in bits - it occurs in the second line which also contains the word bytes, and the u probably means unsigned. So guess that uint8_t is an unsigned 8-bit integer. Now look at the other type-like words, do they make sense in the same way?
So what is the code doing? Well you've figure out that NSData * is "like" byte[], so what would the code set flags to? The first byte in the array maybe? How about tempData? Well there is a 32 in the types here, and that is four bytes.
Having got tempData what do the code do? Some manipulation which results in tempValue which is a float. Maybe float is a 32-bit floating point number? Which is of course what it is in Java.
However here you're going to hit a wall. If you look up how a 32-bit floating-point number is represented in IEEE 754 - the most common way to represent floating point numbers - you will discover that it is stored in binary with the mantissa being a faction (see Wikipedia).
Now look at the code, pow(10, exponent) looks a lot like 10 to the power, not 2 to the power. And does the mantissa look like its being treated as a fraction?
So whatever for those 4 bytes you've guessed are being converted into a float it looks like either (a) they are not a typical 32-bit float or (b) the Objective-C code is wrong...
So back to the first point - determine what this code is meant to do and then write it directly in Java, don't try to convert it.
HTH
I have a problem with converting raw-bytes values into java types. I am receiving bytes by a datagram socket as a bytes array. I know exactly which bytes means what, but I don't know how to convert them appropriately (I mean I know offsets, but don't know if what I think I received is correct ;)).
For example, I want to convert 16 bit unsigned short into java int type. I found some examples in the web, the one is:
public int getUShort(byte[] bytes, int offset) {
int b0 = bytes[offset] & oxFF;
int b1 = bytes[offset + 1] & oxFF;
return (b1 << 8) + (b0 << 0);
Another one is the same but the last line is:
return (b0 << 8) + b1;
Of course it gives different results. Which one is correct? Can you please give me also a valid example how to do the same but for an unsigned long?
Thank you in advance!
I had to do some work similar to this a while back and I found that the best way to do this sort of work is to use ByteBuffer and its conversions to DoubleBuffer, LongBuffer, etc. You can convert an array of bytes into a ByteBuffer by calling
ByteBuffer myBuffer = ByteBuffer.wrap(myRawArray);
From there, you can get a view of the bytes as a list of ints by calling
IntBuffer myIntBuffer = myBuffer.asIntBuffer();
and you can then convert the bytes by calling
int nextInt = myIntBuffer.get();
These classes also have lots of support for bulk get operations, so if you know for a fact that you're receiving a whole bunch of data of the same type over the network you can do the conversions very quickly.
An alternative approach would be, if at all possible, to use some sort of Java-based serialization to send the data over the network. This allows you to do the conversions much more easily using the stream writer classes. Of course, this might not be available, especially if you're communicating with a non-Java server, but it might be worth exploring.
You can use DataInputStream or ByteBuffer to read the various types. You can use signed types as unsigned values for most operations just the same. I have written a simple class to illustrate how you can use the signed types as if they were unsigned Unsigned
ByteBuffer b = ByteBuffer.wrap(bytes);
short s = b.getShort();
long l = b.getLong();
Really late on this one.
Both are correct based on the endianess of the data. See here: http://en.wikipedia.org/wiki/Endianness
return (b1 << 8) + b0;//little endian
return (b0 << 8) + b1;//big endian