Another Delphi to Java porting issue
binary, delphi, java, porting
Solution
Remember:
Java byte is signed. So:
byte test = (byte)255;
System.out.println(test);
will output: `-1`
and
byte test = (byte)255;
System.out.println(test == 255);
will print `false`, but
byte test = (byte)255;
System.out.println((test & 255) == 255);
will do what I think you want to achieve (in this case prints `true`).
To get unsigned (byte) values use `(array[index] & 255)`.
You will have to do the masking with 0xff everywhere, otherwise you will get sign extended integers for byte values larger than 127.
For compares you can also always do a cast to `byte` (e.g. `if(test == (byte)255)`) but I think one should stick to a single conversion, so I would recommend going with the `& 0xff` masking.
Problem
I'm porting an old application written in Delphi to Java. I'm having some trouble with this function, that calculates the CRC of a transmitted message. Here's the original code: ``` if(ReceivedMessage[slot].Message[1] = $FD) and (ReceivedMessage[slot].MessageLength in [1..16]) and (ReceivedMessage[slot].Message[counter] = $FF) then begin index := 2; ReceivedMessage[slot].DataReady := TRUE; for counter := 1 to ReceivedMessage[slot].MessageLength do begin Inc(index); if ReceivedMessage[slot].Message[index] < $F8 then ReceivedMessage[slot].Data[counter] := ReceivedMessage[slot].Message[index] else if ReceivedMessage[slot].Message[index] = $F8 then begin Inc(index); ReceivedMessage[slot].Data[counter] := ReceivedMessage[slot].Message[index] or $F0; end else ReceivedMessage[slot].DataReady := FALSE; // Invalid data end; if ReceivedMessage[slot].DataReady = TRUE then begin Inc(index); if ReceivedMessage[slot].Message[index] < $F8 then ReceivedMessage[slot].CRC := ReceivedMessage[slot].Message[index] shl 8 else if ReceivedMessage[slot].Message[index] = $F8 then begin Inc(index); ReceivedMessage[slot].CRC := (ReceivedMessage[slot].Message[index] or $F0) shl 8; end; Inc(index); if ReceivedMessage[slot].Message[index] < $F8 then ReceivedMessage[slot].CRC := ReceivedMessage[slot].CRC or ReceivedMessage[slot].Message[index] else if ReceivedMessage[slot].Message[index] = $F8 then begin Inc(index); ReceivedMessage[slot].CRC := ReceivedMessage[slot].CRC or ReceivedMessage[slot].Message[index] or $F0; end; ``` And here's my Java code: ``` if(array[1]==0xFD && (array[2]>0 && array[2]<17) && array[pos]==(byte)0xFF) { index=2; for(int counter=1;counter<splMsg.nbytes+1;counter++) { index++; if(array[index]<0xF8) data[counter]=array[index]; else if(array[index]==0xF8) { index++; data[counter]=(byte)(array[index] | 0xF0); } else return 0xFC; } index++; short crc=0x0000; if(array[index]<0xF8) crc=(short) (array[index]<<8); else if(array[index]==0xF8) { index++; crc=(short)((array[index] | 0xF0) << 8); } index++; if(array[index]<0xF8) crc=(short) (crc | array[index]); else if(array[index]==0xF8) { index++; crc=(short)(crc | array[index] | 0xF0); } msgcrc=new byte[] {(byte)(crc >> 8 & 0xff),(byte)(crc & 0xff)}; ``` My function return the transmitted CRC code most times, but sometimes fails and returns the last two bytes of the message. The last 3 bytes of the message are the CRC code (2 byte) and the end-of-message 0xff byte. Any help? Thanks, Pedro