...

Source file src/golang.conradwood.net/go-easyops/utils/shifter.go

Documentation: golang.conradwood.net/go-easyops/utils

     1  package utils
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // serialise/deserialise a bunch of variables
     8  type Shifter struct {
     9  	values         map[int]*Value
    10  	buf            []byte
    11  	consumed_bytes int
    12  	err            error
    13  }
    14  type Value struct {
    15  	Integer int
    16  }
    17  
    18  /*
    19  A "Shifter" shifts bytes from a larger number into an array and unshifts it again
    20  */
    21  func NewShifter(buf []byte) *Shifter {
    22  	res := &Shifter{
    23  		buf:            buf,
    24  		consumed_bytes: 0,
    25  	}
    26  	return res
    27  }
    28  
    29  // next byte is length, followed by uint8s
    30  func (sh *Shifter) Array8() []byte {
    31  	l := int(sh.Unshift_uint8())
    32  	res := make([]byte, l)
    33  	for i := 0; i < l; i++ {
    34  		res[i] = sh.Unshift_uint8()
    35  	}
    36  	return res
    37  }
    38  
    39  func (sh *Shifter) Unshift_uint16() uint32 {
    40  	res := uint32(0)
    41  	for i := 0; i < 2; i++ {
    42  		b := uint32(sh.Unshift_uint8())
    43  		b = b << (8 * i)
    44  		res = res | b
    45  	}
    46  	return res
    47  }
    48  
    49  // LSB first, MSB last. e.g. 0xAABBCCDD will be shifted into a byte array like so: []byte{0xDD,0xCC,0xBB,0xAA}
    50  func (sh *Shifter) Unshift_uint32() uint32 {
    51  	res := uint32(0)
    52  	for i := 0; i < 4; i++ {
    53  		b := uint32(sh.Unshift_uint8())
    54  		b = b << (8 * i)
    55  		res = res | b
    56  	}
    57  	return res
    58  }
    59  func (sh *Shifter) Unshift_uint64() uint64 {
    60  	res := uint64(0)
    61  	for i := 0; i < 8; i++ {
    62  		b := uint64(sh.Unshift_uint8())
    63  		b = b << (8 * i)
    64  		res = res | b
    65  	}
    66  	return res
    67  }
    68  func (sh *Shifter) Unshift_uint8() uint8 {
    69  	if len(sh.buf) <= sh.consumed_bytes {
    70  		sh.consumed_bytes++
    71  		sh.err = fmt.Errorf("Read beyond length (length=%d, read=%d)", len(sh.buf), sh.consumed_bytes)
    72  		return 0
    73  	}
    74  	res := sh.buf[sh.consumed_bytes]
    75  	sh.consumed_bytes++
    76  	return res
    77  }
    78  
    79  // modify the underlying byte array to set a uint32 at a particular address
    80  func (sh *Shifter) SetUint32(pos int, b uint32) {
    81  	if pos+4 >= len(sh.buf) {
    82  		sh.err = fmt.Errorf("Write beyond length (length=%d, write=%d)", len(sh.buf), pos)
    83  		return
    84  	}
    85  	sh.buf[pos] = byte(0xFF & b)
    86  	sh.buf[pos+1] = byte(0xFF & (b >> 8))
    87  	sh.buf[pos+2] = byte(0xFF & (b >> 16))
    88  	sh.buf[pos+3] = byte(0xFF & (b >> 24))
    89  }
    90  
    91  // return ALL bytes
    92  func (sh *Shifter) Bytes() []byte {
    93  	return sh.buf
    94  }
    95  
    96  // return remaining bytes
    97  func (sh *Shifter) RemainingBytes() []byte {
    98  	return sh.buf[sh.consumed_bytes:]
    99  }
   100  func (sh *Shifter) Error() error {
   101  	return sh.err
   102  }
   103  

View as plain text