Dealing with bitfield in Swift

日本語の同記事は[こちら](http://qiita.com/codelynx/items/4923adf9eef9d4b05dab)

# Bitfield in C
You know that Swift does not support bitfield feature.  In many cases, you even don't have to deal with that anyway, on the other hand, you don't know when have to deal with that one day.  In programming language C, you may write code to deal with RGBA bit value as follows.

```RGB_t.c
struct RGB_t {
  unsigned int red : 4;
  unsigned int greeb : 4;
  unsigned int blue : 4
  unsigned int alpha : 4
};

struct RGB_t color;
color.red = 0xf
color.green = 0x0
color.blue = 0x8
color.alpha = 0xf
```

# ZBitField

I would like to introduce [ZBitField](https://github.com/codelynx/ZBitField) for you.  Please take a look at sample code before move on to the details.  Here is an example of setting bit values into bitfield.

```.swift
var bitfield = ZBitField([("red", 4), ("green", 4), ("blue", 4), ("alpha", 4)]!
bitfield["red"] = 0xf
bitfield["green"] = 0x0
bitfield["blue"] = 0x8
bitfield["alpha"] = 0xf
let data = bitfield.data // NSData
```

Here is an example of extracting bit values from NSData via bitfield.

```.swift
var data = .... // NSData
var bitfield = ZBitField([("red", 4), ("green", 4), ("blue", 4), ("alpha", 4)]!
bitfield.data = data
let r = bitfield["red"]
let g = bitfield["green"]
let b = bitfield["blue"]
let a = bitfield["alpha"]
```

It may not be a big deal if a format is not so complex, you just write some code to shift some bits.  However, if need to deal with complex bit format, ZBitfield would be the one for you.  It allows you to access bit values in-and-out by name, and your code should look cleaner.

# Defining Bit Format

Actual bits are defined from MSB (Most Significant Bit).  Usually total amount of bits are multiple of 8, but not required, extra bits will be padded for you.  Name and bit size should be defined as an array of `(String, Int)` tuple.  Name should be unique, and bit size should be between 1 to 64.  Here is an example of how to define TCP header.


```
+---------------+---------------+---------------+---------------+
| Source Port                   | Destination Port              |
| . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . |
| Acknowledgement Number                                        |
| . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . |
|Offset | Reserved  |U|A|R|P|S|F| Window                        |
| . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . |
| Checksum                      | Urgent Pointer                |
| . . . . . . . | . . . . . . . | . . . . . . . | . . . . . . . |
+---------------+---------------+---------------+---------------+
```

Here is an example of the definition.  TCP header is just an living example of bit fields, and it's accuracy is irrelevant to this topic. :-)

```.swift
[
	("SourcePort", 16), ("DestinationPort", 16), ("SequenceNumber", 32), ("AckNumber", 32), 
	("DataOffset", 4), ("Reserved", 6), 
	("URG", 1), ("ACK", 1), ("PSH", 1), ("RST", 1), ("SYN", 1), ("FIN", 1),
	("Window", 16), ("Checksum", 16), ("UrgentPointer", 16)
]
```

# ZBitField API

### init

```.swift
init?(_ spec: [(String, Int)]) 
```

It defines bit fields' bit format, name and bit size are given in the form of array of tuples.  If there are some problems of definition, it returns nil.

#### length

```.swift
let length: UInt
```
Returns the number of length in bytes.

#### data

```.swift
var data: NSData { get set }
```

You may get or set actual bytes array (`NSData`).

#### subscript

```.swift
subscript(key: String) -> UInt { get set }
```

You may read or write bit field by name.  Be careful, name is case sensitive.

# Github

You may get the code from Github. It's MIT license.

https://github.com/codelynx/ZBitField


# Environment

Swift version at this moment.

```.console
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
```