Otro problema de portabilidad de Delphi a Java
binary porting (1)
Estoy portando una aplicación antigua escrita en Delphi a Java. Tengo problemas con esta función, que calcula el CRC de un mensaje transmitido.
Aquí está el código original:
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;
Y aquí está mi código de Java:
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)};
Mi función devuelve el código CRC transmitido la mayoría de las veces, pero a veces falla y devuelve los dos últimos bytes del mensaje. Los últimos 3 bytes del mensaje son el código CRC (2 bytes) y el byte 0xff de fin de mensaje.
¿Alguna ayuda?
Gracias, Pedro
Recuerda:
Java byte está firmado . Asi que:
byte test = (byte)255;
System.out.println(test);
producirá: -1
y
byte test = (byte)255;
System.out.println(test == 255);
imprimirá false
, pero
byte test = (byte)255;
System.out.println((test & 255) == 255);
Haré lo que creo que quiere lograr (en este caso, las impresiones son true
).
Para obtener valores sin signo (byte) use (array[index] & 255)
.
Tendrá que enmascarar con 0xff en todas partes, de lo contrario obtendrá números enteros de signo para valores de bytes mayores a 127.
Para comparar también puedes hacer un cast a byte
(ej. if(test == (byte)255)
) pero creo que uno debe apegarse a una sola conversión, por lo que te recomiendo que vayas con el enmascaramiento de & 0xff
.