tags:

views:

1484

answers:

4

type B02 = array [01..02] of byte ;

...

var b : B02;

...

//here i read from tcp socket

socket.ReadBuffer(b, 2);

The question is: how to convert B02 to an integer?

A: 

My integers are often 4 bytes long. Which part do you want to set?

Stephan Eggermont
+6  A: 

You could declare a Word/Smallint at the same memory location, like this:

var
  b : B02;
  myInt: smallint absolute B02;

Then again, is there any particular reason why you don't just create the smallint and pass it to ReadBuffer instead of an array? I don't know exactly what class you're using, but that looks a lot like the way you read from a TStream, and it'll accept variables of any type, along with a size in bytes. Why not just declare your buffer as the integer type you're looking for and cut out the middleman?

Mason Wheeler
+1 for reading my mind. Either solution answers the question unless B02 contains character data.
skamradt
Right. In which case you don't want to use an integer for it anyway.
Mason Wheeler
It could be that the data on the network is stored in network byte order, not the Intel one.
gabr
@gabr: It **should** be in network order, everything else would be disregard for standards.
mghie
@mghie: Well, standards schmandards. If my app is on both end I'll send the data whichever way I want.
gabr
mghie: afaik that goes for the TCP/IP protocol itself, not the content that is transfered using it.
Marco van de Voort
@Marco: No, if there's the slightest chance that either the server or the client is going to run on another platform than the PC it's just common sense for the protocol data too. I'd say it's a standard to either use text formats, or to use network byte order. Have a look at the RFCs for example.
mghie
+1  A: 

If the data is being transmitted in "network" order (highest byte first) and not in "Intel" order (lowest byte first), you can do some byte shufling yourself.

uses
  SysUtils;

var
  b: B02;
  w: word; //two bytes represent a word, not an integer

socket.ReadBuffer(b, 2);
WordRec(w).Hi := b[1];
WordRec(w).Lo := b[2];

Mghie suggested following approach in comments (and I agree with him):

uses Winsock;

var
  w: word;

socket.ReadBuffer(w, 2);
w := ntohs(w);
gabr
+1, but I still don't like the implicit assumption that the processor is little endian. Code should read into a word, call `ntohs()` and cast to a `SmallInt`, then it would work on any processor (when using FPC).
mghie
@mghie: You are totally correct. But I'm still always writing it the Intel-only way. This habbit is hard to break :(
gabr
+1  A: 

You can just cast it:

var
  a: array[01..02] of Byte;
  i: Integer;
begin
  i := PWORD(@a)^;
end;

or if you need to change the byte order:

  i := Swap(PWORD(@a)^);
Remko