c++ - Ways to interpret groups of bytes in a curl result as other data types -


i'm trying write program query url using curl , retrieve string of bytes. returned data needs interpreted various data types; int followed sequence structures.

the curl write function must have prototype of:

size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata); 

i've seen various examples returned data stored in buffer either characters directly in memory or string object.

if have character array, know can interpret portion of structure code this:

struct mystruct {     //define struct };  char *buffer; //push data buffer char *read_position; read_position = buffer + 5; test = (mystruct *)buffer; 

i have 2 related questions. firstly, there better way of using curl retrieve binary data , pushing structures, rather reading directly memory characters. secondly if reading memory character buffer way go, code above sensible way interpret chunks of memory different data types?

things need consider when interpreting raw structures, on network:

  • the size of data types;
  • the endianness of data types;
  • struct padding.

you should use data types in structure correct size regardless of compiler used. means integers, should use types <cstdint>.

as endianness, need know if data arrive big-endian or little-endian. explicit it:

template< class t > const char * readlittleendian32( const char *buf, t & val ) {     static_assert( sizeof(t) == 4 );     val = t(buf[0]) | t(buf[1]) << 8 | t(buf[2]) << 16 | t(buf[3]) << 24;     return buf + sizeof(t); }  template< class t > const char * readbigendian32( const char *buf, t & val ) {     static_assert( sizeof(t) == 4 );     val = t(buf[0]) << 24 | t(buf[1]) << 16 | t(buf[2]) << 8 | t(buf[3]);     return buf + sizeof(t); }  //etc... 

finally, dealing potential padding differences... i've been naturally tending towards 'deserialise' approach each value read , translated explicitly. structure no different:

struct foo {     uint16_t a;     int16_t  b;     int32_t  c;      const char * read( const char * buf ); };  const char * foo::read( const char * buf ) {     buf = readlittleendian16( buf, );     buf = readlittleendian16( buf, b );     buf = readlittleendian32( buf, c );     return buf; } 

notice templating handles sign , other things in data type, care in end size. remember data types such float , double have inherent endianness , should not translated -- can read verbatim:

const char * readdouble( const char * buf, double & val ) {     val = *(double*)buf;     return buf + sizeof(double); } 

Comments

Popular posts from this blog

c# - Binding a comma separated list to a List<int> in asp.net web api -

Delphi 7 and decode UTF-8 base64 -

html - Is there any way to exclude a single element from the style? (Bootstrap) -