1

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)

Ken White
  • 117,855
  • 13
  • 197
  • 405
user1961008
  • 53
  • 1
  • 8
  • 3
    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 Oct 03 '14 at 09:38
  • 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 Oct 03 '14 at 09:43
  • 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 Oct 03 '14 at 10:06
  • 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 Oct 03 '14 at 15:41
  • @xxa Delphi/TurboPascal/FPC strings are (traditionally) one based – David Heffernan Oct 03 '14 at 20:09
  • @DavidHeffernan Granted, but my point was that `for i:= 3 to length(sequence)-4` and `for (int x = 3; x < (sequence.Length - 4); x++)` (both taken from the question) cannot be equivalent as the latter iteration is one shorter. – xxa Oct 03 '14 at 23:31

1 Answers1

1

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.

Community
  • 1
  • 1
David Heffernan
  • 572,264
  • 40
  • 974
  • 1,389
  • Thanks David, I'll check on the encoding types. All I wanted to get out of this question is to know whether I'm converting Pascal into C# correctly since this is the first time I'm dealing with this language. – user1961008 Oct 03 '14 at 10:48
  • David, Ansi doesn't work on C# whereas the Default gives me the same result for the 'check' variable as it did before. However, my assumption is that functions word_to_hex in pascal and ControlByte in C# are not equivalent and there lays the problem. – user1961008 Oct 03 '14 at 11:19
  • `ControlByte` clearly is not equivalent to `word_to_hex`. The former takes a string, the latter a 16 bit unsigned integer, `Word`. In C# that entire `word_to_hex` can be written as: `val.ToString("X4")` where `val` is `ushort`. In Delphi it would be written `IntToHex(val, 4)`. All of the hex conversion code is bogus. I suggest that you read the links at the end of my answer. – David Heffernan Oct 03 '14 at 11:31
  • You're right, the entire procedure was replaced by val.ToString("x4"), however, I don't understand what the last pascal funtion accomplishes and how do I convert it into C#? – user1961008 Oct 03 '14 at 13:01
  • That is `abyte.ToString("x2")`. What more are you looking for here? – David Heffernan Oct 04 '14 at 04:17