Re: typecasting



Malcolm McLean wrote, On 29/04/07 10:29:

"aki" <akhileshrawat007@xxxxxxxxx> wrote in message news:1177838206.040139.210090@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Hi all,

i am receiving a buffer from network...
there are n number of options in buffer type char*
each option contain thr fields of fixed size.
1)type
2)length
3)value

example->

struct authProt
{
uint8_t type;
uint8_t length;
uint16_t authprot;

};

have created a char array of pointers to point to all these n
options.
char *options[n];
then how to decode each field of an option.

all comments are welcome....

option string

"10 15 1001"

Unless, as is quite likely IMHO from the way the OP described it, it is coming in as binary not text. The OP has not been explicit, so it is possibly your interpretation of the requirement is correct and mine wrong.

to decode

int type;
int len;
int ap;

sscanf(options[n], "%d %d %d", &type, &len, &ap);

Then in your structure

struct authProt auth;

auth.type = (unit8_t) type;
auth.length = (uint8_t) length;
auth.authprot = (uint16_t) ap;

The casting above is completely pointless.

You could use strtol instead of sscanf. Strictly you should use a long for ap if it can go over 32767, and you need error checking in sccanf.
You only need the special fixed types in the actual structure. Elsewhere you can manipulate the information with plain types, and often these will be better. For instance if legal types go from 1-100, and someone feeds 123456789012345678901234567890 to the function, a conversion to integer is much more likely to pick up the error than a conversion to an 8 bit value, handy if you have "good enough" error checking.

With scanf it still invokes undefined behaviour if the number is out of range, so it is still difficult to get error checking with sscanf, so I think strtoul/strtol would still be better.

If, as I suspect, the data is coming in as binary, then you can do things like:

#define TYPE_OFFSET 0
#define LENGTH_OFFSET 1
#define AUTH_PROT 2

mess.type = buff[TYPE_OFFSET];
mess.len = buff[LENGTH_OFFSET];
mess.auth = buff[AUTH_PROT] << 8 + buff[AUTH_PROT+1];

Adjust for the endianness of the incoming data (you do not need to worry about the endianness of the receiving machine doing it this way). You might want to write either small functions or macros to wrap up the extraction of 16 bit unsigned integers, 32 bit unsigned integers etc.

char is not guaranteed to be 8 bits (although the chances of the OPs system not using 8 bits bytes is slim), but I'm assuming here that even if it is not the octets of the network data are being put in to separate bytes on the receiving system which is why I used 8 rather than CHAR_BIT.
--
Flash Gordon
.



Relevant Pages

  • typecasting
    ... i am receiving a buffer from network... ... there are n number of options in buffer type char* ... each option contain thr fields of fixed size. ...
    (comp.lang.c)
  • Re: CAsyncSocket and Send
    ... The sending side sends an 'f' char immediately before a file is sent. ... > Are you using TCP/IP or UDP? ... > Are you making sure that, if you are handling strings, that you insert a terminating NUL ... >>in C and the receiving side is MFC. ...
    (microsoft.public.vc.mfc)
  • Re: Clarification required about select vs wake_up race condition
    ... Our char driverdoes a ... In our poll(), ... it looks like it can set the state of the receiving ... any) or just getting back (iow, the task doesn't lose a cpu). ...
    (Linux-Kernel)
  • Re: Async Pro for serial communications
    ... in the loop, that pump responds. ... (psIdle, psXmitting, psWaitingResp, psReceiving); ... psReceiving:Log receiving timeout; ... If char signals beginning of message from pump ...
    (borland.public.delphi.thirdpartytools.general)
  • Re: Read/Write socket Problem
    ... > receiving at the byte level. ... I am always writing 3 bytes from client, reading 3 bytes from server, ... char givenNo; ...
    (comp.unix.programmer)