-2

How do we change following code in Swift?:

typedef union
{
    uint32_t raw;
    struct
    {
        uint32_t type : 2;
        uint32_t offset : 16;
        uint32_t count : 12;
        uint32_t baseaddrse : 2;
    };
} header_t;
timrau
  • 22,578
  • 4
  • 51
  • 64
user3284302
  • 129
  • 1
  • 8

1 Answers1

0

Here's a brute force translation. The property raw holds the value, and the computed properties type, offset, count, and baseaddrse read and write the sub fields.

The utility functions readbits() and writebits() take care of packing and unpacking the values.

All of the ugliness is hidden in the structure itself. Using it is straightforward, just as in C. You can set a raw value, and then read out the individual fields, or you can set the values of the fields and then read out the raw value.

struct Header_T {
    var raw: UInt32 = 0
    
    func readbits(start: Int, end: Int ) -> UInt32 {
        let nbits = start - end + 1
        let mask = UInt32.max >> (32 - nbits)
        return (raw >> end) & mask
    }
    
    mutating func writebits(value: UInt32, start: Int, end: Int) {
        let nbits = start - end + 1
        let mask = UInt32.max >> (32 - nbits)
        let imask = UInt32.max ^ (mask << end)
        raw = (raw & imask) | ((value & mask) << end)
    }
    
    var type: UInt32 {
        get { readbits(start: 31, end: 30) }
        set(newType) { writebits(value: newType, start: 31, end: 30) }
    }
    
    var offset: UInt32 {
        get { readbits(start: 29, end: 14) }
        set(newOffset) { writebits(value: newOffset, start: 29, end: 14) }
    }
                                
    var count: UInt32 {
        get { readbits(start: 13, end: 2) }
        set(newCount) { writebits(value: newCount, start: 13, end: 2) }
    }
    
    var baseaddrse: UInt32 {
        get { readbits(start: 1, end: 0) }
        set(newAddr) { writebits(value: newAddr, start: 1, end: 0) }
    }
}

Tests

var foo = Header_T()
foo.type = 3
foo.offset = 0
foo.count = 4095
foo.baseaddrse = 0

print(String(foo.raw, radix: 2))
11000000000000000011111111111100
foo.type = 2
foo.offset = 65535
foo.count = 0
foo.baseaddrse = 3

print(String(foo.raw, radix: 2))
 10111111111111111100000000000011
foo.raw = 0b11_1111111111111110_111111111110_01
// Expect 3, 65534, 4094, 1
print(foo.type)
print(foo.offset)
print(foo.count)
print(foo.baseaddrse)
3
65534
4094
1
vacawama
  • 150,663
  • 30
  • 266
  • 294