Hi Paul. Check out Data::ParseBinary. I developed it for similar tasks.
Shmuel. On Sep 24, 2014 1:56 PM, "Paul "LeoNerd" Evans" <leon...@leonerd.org.uk> wrote: > [[ background ]] > > I've been doing a lot of hardware IO work lately, which involves lots > of talking to hardware devices, where there are byte-wide registers > that store little bitfields, sometimes of individual and unrelated bits > packed together. To make this easier I tend to write myself lots of > pairs of functions to pack/unpack the fields in one of these bytes; for > instance: > > use constant { > MASK_RX_RD => 1<<6, > MASK_TX_DS => 1<<5, > MASK_MAX_RT => 1<<4, > EN_CRC => 1<<3, > CRCO => 1<<2, > PWR_UP => 1<<1, > PRIM_RX => 1<<0, > }; > > sub unpack_CONFIG > { > my ( $config ) = @_; > return > MASK_RX_RD => !!( $config & MASK_RX_RD ), > MASK_TX_DS => !!( $config & MASK_TX_DS ), > MASK_MAX_RT => !!( $config & MASK_MAX_RT ), > EN_CRC => !!( $config & EN_CRC ), > CRCO => $CRCOs[!!( $config & CRCO )], > PWR_UP => !!( $config & PWR_UP ), > PRIM_RX => !!( $config & PRIM_RX ); > } > > sub pack_CONFIG > { > my %config = @_; > return > ( $config{MASK_RX_RD} ? MASK_RX_RD : 0 ) | > ( $config{MASK_TX_DS} ? MASK_TX_DS : 0 ) | > ( $config{MASK_MAX_RT} ? MASK_MAX_RT : 0 ) | > ( $config{EN_CRC} ? EN_CRC : 0 ) | > ( ( _idx_of $config{CRCO}, @CRCOs ) > // croak "Unsupported 'CRCO'" ) * CRCO | > ( $config{PWR_UP} ? PWR_UP : 0 ) | > ( $config{PRIM_RX} ? PRIM_RX : 0 ) ); > } > > This convenient pair of functions bidirectionally converts bytes into > key/value lists. As well as containing 6 simple boolean values, there's > also an enumerated field, represented by the values in the array > @CRCOs. These functions convert those too. > > I'm getting tired of writing these pairs of functions. Hey, this is > Perl write? :) I should get Perl to write them for me. > > [[ TL;DR - I propose the following ]] > > I'd like instead to write something like: > > use bitfield; > > bitfield CONFIG => > MASK_RX_DS => boolfield(6), > MASK_TX_DS => boolfield(5), > MASK_MAX_RT => boolfield(4), > EN_CRC => boolfield(3), > CRCO => enumfield(2, qw( values here )), > PWR_UP => boolfield(1), > PRIM_RX => boolfield(0); > > The operation here is that 'bitfield' is automatically exporting a > function called 'bitfield', along with the various *field() functions > that create field definitions. boolfield() declares a single true/false > boolean bit position, enumfield() declares a range of bits that give > an enumeration. I guess also would be required intfield() to use a > range of bits as an integer, and finally most likely customfield() > taking a pair of conversion CODE refs or somesuch. > > What does anyone think to that? > > -- > Paul "LeoNerd" Evans > > leon...@leonerd.org.uk > http://www.leonerd.org.uk/ | https://metacpan.org/author/PEVANS >