From 84ab75184c0b5490af07703529a4b5d743ec3124 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Thu, 17 Sep 2020 14:21:17 +0200 Subject: [PATCH] Set individual bytes in a uint32 using MSB 0 indexing --- quic/bits.nim | 24 ++++++++++++++++++++++++ tests/quic/testBits.nim | 16 ++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/quic/bits.nim b/quic/bits.nim index 83b6f6a..6011418 100644 --- a/quic/bits.nim +++ b/quic/bits.nim @@ -4,17 +4,29 @@ type Bit* = range[0'u8..1'u8] Bits* = distinct byte BitIndex = BitsRange[byte] + Bytes* = distinct uint32 + ByteIndex* = range[0..sizeof(uint32)-1] proc lsb(index: BitIndex): BitsRange[byte] = ### Converts a bit index from MSB 0 to LSB 0 BitsRange[byte].high - BitsRange[byte](index) +proc lsb(index: ByteIndex): ByteIndex = + ## Converts a byte index from MSB 0 to LSB 0 + ByteIndex.high - index + proc `[]`*(bits: Bits, index: BitIndex): Bit = ## Returns the bit at the specified index. ## Uses MSB 0 bit numbering, so an `index` ## of 0 indicates the most significant bit. testBit[byte](bits.byte, index.lsb).Bit +proc `[]`*(bytes: Bytes, index: ByteIndex): byte = + ## Returns the byte at the specified index. + ## Uses MSB 0 byte numbering, so an `index` + ## of 0 indicates the most significant byte. + byte(uint32(bytes) shr (index.lsb * 8)) + proc `[]=`*(bits: var Bits, index: BitIndex, value: Bit) = ## Sets the bit at the specified index. ## Uses MSB 0 bit numbering, so an `index` @@ -23,8 +35,20 @@ proc `[]=`*(bits: var Bits, index: BitIndex, value: Bit) = of 0: clearBit[byte](bits.byte, index.lsb) of 1: setBit[byte](bits.byte, index.lsb) +proc `[]=`*(bytes: var Bytes, index: ByteIndex, value: byte) = + ## Sets the byte at the specified index. + ## Uses MSB 0 byte numbering, so an `index` + ## of 0 indicates the most significant byte. + bytes = Bytes(uint32(bytes) or (uint32(value) shl (index.lsb * 8))) + proc bits*(value: byte): Bits = Bits(value) proc bits*(value: var byte): var Bits = Bits(value) + +proc bytes*(value: uint32): Bytes = + Bytes(value) + +proc bytes*(value: var uint32): var Bytes = + Bytes(value) diff --git a/tests/quic/testBits.nim b/tests/quic/testBits.nim index 978b4c4..3564fc0 100644 --- a/tests/quic/testBits.nim +++ b/tests/quic/testBits.nim @@ -27,3 +27,19 @@ suite "bits": value.bits[3] = 0 value.bits[7] = 0 check value == 0b01101110'u8 + +suite "bytes": + + test "can index bytes": + let value = 0xAABBCCDD'u32 + check value.bytes[0] == 0xAA + check value.bytes[1] == 0xBB + check value.bytes[2] == 0xCC + check value.bytes[3] == 0xDD + + test "can set bytes": + var value = 0x00000000'u32 + value.bytes[0] = 0xAA + value.bytes[2] = 0xCC + value.bytes[3] = 0xDD + check value == 0xAA00CCDD'u32