1
votes

I am trying to convert this pascal code into C# in order to communicate with a peripheral device attached to a comm port. This piece of code should calculate the Control Byte, however I'm not getting the right hex Value therefore I'm wondering if I'm converting the code in the right way. Pascal:

begin
  check := 255;
  for i:= 3 to length(sequence)-4 do
  check := check xor byte(sequence[i]);
end;

C#:

int check = 255;
for (int x = 3; x < (sequence.Length - 4); x++)
{
    check = check ^ (byte)(sequence[x]);
}

Pascal function:

{ *** conversion of number into  string ‘hex’ *** }
function word_to_hex (w: word) : string;
  var
  i : integer;
  s : string;
  b : byte;
  c : char;
begin
  s := ‘’;
  for i:= 0 to 3 do
  begin
    b := (hi(w) shr 4) and 15;
    case b of
    0..9 : c := char(b+$30);
    10..15 : c := char(b+$41-10);
  end;
  s := s + c;
  w := w shl 4;
end;
word_ to_hex := s;
end;

C# Equivalent:

     public string ControlByte(string check)
    {
        string s = "";
        byte b;
        char c = '\0';
        //shift = check >> 4 & 15;
        for (int x = 0; x <= 3; x++)
        {
            b = (byte)((Convert.ToInt32(check) >> 4) & 15);

            if (b >= 0 && b <= 9)
            {
                c = (char)(b + 0x30);
            }
            else if (b >= 10 && b <= 15)
            {
                c = (char)(b + 0x41 - 10);
            }
            s = s + c;
            check = (Convert.ToInt32(check) << 4).ToString();
        }
        return s;
    }

And last pascal:

function byte_to_hex (b:byte) : string;
begin
byte_to_hex := copy(word_to_hex(word(b)),3,2);
end;

which i am not sure how is substringing the result from the function. So please let me know if there is something wrong with the code conversion and whether I need to convert the function result into bytes. I appreciate your help, UF.

Further info EDIT: Initially I send a string sequence containing the command and information that printer is supposed to print. Since every sequence has a unique Control Byte (in Hex) I have to calculate this from the sequence (sequence = "P1;1$l201PrinterPrinterPrinter1B/100.00/100.00/0/\") which is what upper code does according to POSNET=>"cc – control byte, encoded as 2 HEX digits (EXOR of all characters after ESC P to this byte with #255 initial quantity), according to the following algorithm in PASCAL language:(see first code block)".=>1. check number calculated in the above loop which constitutes control byte should be recoded into two HEX characters (ASCII characters from scope: ‘0’..’9’,’A’..’F’,’a’..’f’), utilizing the following byte_to_hex function:(see third code block). =>{* conversion of byte into 2 characters *}(see 5th code block)

1
You don't tell us what the data types are. We've no idea whether the Pascal array like thing is zero or one based. And you don't tell us what input data you use. Nor what output you get. Have you considered doing some debugging? That's a core skill that you should really acquire. Either use your IDE debuggers, or add trace debugging. Work out where the programs diverge from each other. Then fix the problem. Repeat until the programs behave the same way. - David Heffernan
Also, both functions to convert to hex strings are spurious. There are simpler ways to do it, and library functions at least for the Pascal. - David Heffernan
Thanks David for your quick reply. The 'sequence' in the loop is a string '1;1$l201PrinterPrinterPrinter1B/100.00/100.00/0/' whereas 'check' is converted to a string and passed as a parameter to the 'ControlByte' function which returns a Hex value. As far as spurious is concerned, I got the pascal code form a Posnet manual for thermal printers. I hope this information helps in understanding the problem. - user1961008
Assuming the Pascal sequence starts at index 0, for i:= 3 to length(sequence)-4 should translate to for (int x = 3; x <= (sequence.Length - 4); x++) - xxa
@xxa Delphi/TurboPascal/FPC strings are (traditionally) one based - David Heffernan

1 Answers

1
votes

The most obvious problem that I can see is that the Pascal code operates on 1-based 8 bit encoded strings, and the C# code operates on 0-based 16 bit encoded strings. To convert the Pascal/Delphi code that you use to C# you need to address the mis-match. Perhaps like this:

byte[] bytes = Encoding.Default.GetBytes(sequence);
int check = 255;
for (int i = 2; i < bytes.Length-4; i++)
{
    check ^= bytes[i];
}

Now, in order to write this I've had to make quite a few assumptions, because you did not include anywhere near enough code in the question. Here's what I assumed:

  1. The Pascal sequence variable is a 1-based 8 bit ANSI encoded Delphi AnsiString.
  2. The Pascal check variable is a Delphi 32 bit signed Integer.
  3. The C# sequence variable is a C# string.

If any of those assumptions prove to be false, then the code above will be no good. For instance, perhaps the Pascal check is really Byte. In which case I guess the C# code should be:

byte[] bytes = Encoding.Default.GetBytes(sequence);
byte check = 255;
for (int i = 2; i < bytes.Length - 4; i++)
{
    check ^= bytes[i];
}

I hope that this persuades you of the importance of supplying complete information.

That's really all the meat of this question. The rest of the code concerns converting values to hex strings in C# code. That has been covered again and again here on Stack Overflow. For instance:

There are many many more such questions.