Boost logo

Boost :

From: Pavol Droba (droba_at_[hidden])
Date: 2002-11-24 12:58:19


On Sun, Nov 24, 2002 at 04:59:45PM +0100, Terje Sletteb? wrote:
> >From: "Pavol Droba" <droba_at_[hidden]>
>
> > On Sun, Nov 24, 2002 at 01:26:05PM +0100, Terje Sletteb? wrote:
> > > >From: "Pavol Droba" <droba_at_[hidden]>
> > >
> > > > I have developed a simple cast function which I found very useful.
> Here it
> > > is:
> > > >
> > > > template< typename T >
> > > > inline T offset_cast( void* p, unsigned int offset=0 )
> > > > {
> > > > return reinterpret_cast< T >( static_cast<unsigned char*>(
> p )+offset );
> > > > }
> > > >
> > > > template< typename T >
> > > > inline T offset_cast( const void* p, unsigned int offset=0 )
> > > > {
> > > > return reinterpret_cast< T >( static_cast<const unsigned char*>(
> > > p )+offset );
> > > > }
> > > >
> > > > Its purposes is to simplify a mapping of C-like structure onto binary
> > > data. Here is
> > > > the example: Assume thath you have a network packet in raw format, and
> you
> > > want
> > > > to read IP-header information. You could do following:
> > > >
> > > > ip_header* ip=offset_cast<ip_header>( packet, ip_header_offset );
> > > >
> > > > instead of ugly pointer arithmetic.
> > >
> > > Uhm, I think pointer arithmetic could be preferrable to casts,
> particularly
> > > reinterpret_cast, as pointer arithmetic is at least not
> > > implementation-dependent, unlike the reinterpret_cast.
> >
> > I don't see you point here. I'm not sure why whould be reinterpret_cast
> > implemetation dependent and pointer aritmetic not?
>
> Pointer arithmetic, in itself, isn't implementation-dependent. You said that
> your example was an alternative to pointer arithmetic. However, is it
> possible to do the above with pointer arithmetic, only, and no casts? In
> other words, what is the alternative you compare to? [Addition: I see you
> reply to this below here]
>
> > > Also, I find nothing ugly about pointer arithmetic - in fact, STL is
> based
> > > on it, except that it's abstracted as "iterators". int array[10];
> > > std::for_each(array,array+10,f) is pointer arithmetic. Do you find that
> > > ugly, as well?
> >
> > I'm sorry, you are right, ugly is not a good term here. However the
> purpose
> > of the offset cast is not to avoid pointer arithemtic at all cost.
> > Ist purpose is to simplify mapping of structures over memory buffers.
> >
> > Problem here is to shift a pointer n-bytes forward. You can do it
> > with pointer arithmetic, but still you have to cast the pointer to
> something
> > what have size of 1 otherwise you will not shift it n-bytes but
> n*sizeof(type).
> >
> > So offset_cast handles this for you. It is merely a shorcut, which could
> be
> > very handy if you are working with raw data.
>
> Ok, I understand the purpose of it, now. The purpose is to encapsulate the
> pointer arithmetic and casts, into a component. However, as also Dave
> pointed out, it's implementation-dependent whether it would work or not. It
> depends on things like alignment, and any padding in the class you try to
> extract (such as ip_header, above here). As I understand, it's only safe as
> long as the data was the original type to begin with, rather than a plain
> char buffer.

You are right that I have forgotten to mention prerequisities. I have used
offset_cast for analysis of raw network packets. A packet is just a plain
char buffer and you need to analyze it part by part from general parts like
ethernet header to protocol specific parts like tcp header or icmp message body.
offset_cast worked very well for me.

The prerequisite I haven't mentioned is that if you wan to use a structure to
map to such a buffer, it has to have 1 byte aligmnent. Most of the compilers
allow this kind of specification with pragmas.

Reinterpret-cast could be avoided like this:

template< typename T >
inline T* offset_cast( void* p, unsigned int offset=0 )
{
         return static_cast<T*>(
                static_cast< void* >( static_cast<unsigned char*> p )+offset )
        );
}

This would alse restrict the usage of the template to pointer a return value.

>From my experience, such an analysis of unstructured data is not so uncommon.
offset_cast in the form I have proposed is probably too dangerous for general
use. It is possible to provide the same functionality with copy-in, copy-out
semantics. Although it would need more complex framework.

So my question is if such a framework would be usable enough to be considered
for boots.

Regards,

Pavol


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk