[M3devel] I know, I know...

Jay K jay.krell at cornell.edu
Thu Aug 23 21:26:58 CEST 2012


How about you just use "bytes" or integers and helper functions like this:  typedef struct _BIT_FIELD {
    UINT8 ByteOffset;
    UINT8 BitOffset;
    UINT8 BitCount;
} BIT_FIELD;
 HRESULT
ExtractBitField(__in const BIT_FIELD* BitField,
                __in const UINT8* Bytes,
                __in size_t Size,
                __out_opt UINT8* Value)
/*++
Extract a bitfield from an array of bytes, as specified
    by a byte offset, a bit offset within the first byte, and a bit count.
The bitfield is presumed to be no more than 8 bits -- however that could be easily fixed.
The bitfield can definitely cross byte boundaries.
--*/
{
    UINT8 const bitCount = BitField->BitCount;
    UINT8 const bitOffset = BitField->BitOffset;
    UINT8 const byteOffset = BitField->ByteOffset;
    UINT8 const FF = (UINT8)~(UINT8)0;
    BOOL8 const twoBytes = ((bitOffset + bitCount) > 8);
    UINT8 const secondBitOffset = (8 - bitOffset);
    UINT8 localValue = { 0 };
    HRESULT error = { 0 };    if (Value)
        *Value = 0;    if ((bitCount > 8) || (bitOffset > 7) || (bitCount == 0))
    {
        error = E_INVALIDARG;
        goto Exit;
    }    if ((byteOffset + twoBytes) >= Size)
    {
        error = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
        goto Exit;
    }    localValue = (Bytes[byteOffset] >> bitOffset);
    if (twoBytes)
    {
        localValue &= ~(FF << secondBitOffset);
        localValue |= (Bytes[byteOffset + 1] << secondBitOffset);
    }
    localValue &= ~(FF << bitCount);
    error = 0;
    if (Value)
        *Value = localValue;
Exit:
    return error;
}
 arrays of bytes are really the only way to control the layout.Look at how GNU binutils works, for example...Bitfields in C don't yield predictable/portable layout either.   - Jay
 > From: hosking at cs.purdue.edu
> Date: Thu, 23 Aug 2012 09:30:57 -0400
> To: dragisha at m3w.org
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] I know, I know...
> 
> PACKED?
> 
> Sent from my iPad
> 
> On Aug 23, 2012, at 3:24 AM, Dragiša Durić <dragisha at m3w.org> wrote:
> 
> > I know this will probably be very dense subject, but. What about:
> > 
> >  TSPacketHeader = <* ENDIAN = BIG*>RECORD
> >    sync: BITS 8 FOR [16_0..16_ff];   (* Always 0x47 *)
> >    tErrInd,                      (* Transport Error Indicator *)
> >    pusi: BITS 1 FOR BOOLEAN;     (* Payload Unit Start Indicator *)
> >    transPrio: BITS 1 FOR [0..1];
> >    pid: BITS 13 FOR PID;
> >    transScramControl: BITS 2 FOR [0..3]; (* 00 means no scrambling *)
> >    afc: BITS 2 FOR [0..3]; (* 01 - no adaptation field, payload only *) 
> >    cc: BITS 4 FOR Nibble;
> >  END;
> > 
> > Meaning: bit data is packed from left to right, and all multi-byte data is packed MSB first.
> > 
> > Right now I am doing this, based on knowledge of my platform (little endian, x86_64), like this:
> > 
> >  TSPacketHeader = RECORD
> >    sync: BITS 8 FOR [16_0..16_ff];   (* Always 0x47 *)
> > 
> >    pidHi: BITS 5 FOR [16_00..16_1f];
> >    transPrio: BITS 1 FOR [0..1];
> >    pusi,
> >    tErrInd: BITS 1 FOR BOOLEAN;
> > 
> >    pidLo: BITS 8 FOR [16_00..16_ff];
> > 
> >    cc: BITS 4 FOR Nibble;
> >    afc: BITS 2 FOR [0..3]; (* 01 - no adaptation field, payload only *) 
> >    transScramControl: BITS 2 FOR [0..3]; (* 00 means no scrambling *)
> >  END;
> > 
> > And please don't tell me "write in C", because then I will just "offload" this problem to C preprocessor and still only hope for the best. Modula-3 is provably very adept to systems programming and I hope it can be more so.
> > 
> > Thanks in advance..
> > --
> > Divided by a common language
> > 
> > Dragiša Durić
> > dragisha at m3w.org
> > 
> > 
> > 
> > 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20120823/1b77f017/attachment-0001.html>


More information about the M3devel mailing list