Skip to content

Commit b5bc3c9

Browse files
committed
Complete documentation
1 parent 35b16dd commit b5bc3c9

7 files changed

Lines changed: 212 additions & 16 deletions

File tree

Sources/BitReader.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,53 @@
55

66
import Foundation
77

8+
/// A type that contains functions for reading `Data` bit-by-bit and byte-by-byte.
89
public protocol BitReader: class {
910

11+
/// True, if reader's BIT pointer is aligned with the BYTE border.
1012
var isAligned: Bool { get }
1113

14+
/// Creates an instance for reading `data`.
1215
init(data: Data)
1316

17+
/// Reads bit and returns it, advancing by one BIT position.
1418
func bit() -> UInt8
1519

20+
/// Reads `count` bits and returns them as an array of `UInt8`, advancing by `count` BIT positions.
1621
func bits(count: Int) -> [UInt8]
1722

23+
/// Reads `count` bits and returns them as a `Int` number, advancing by `count` BIT positions.
1824
func int(fromBits count: Int) -> Int
1925

20-
// TODO: Describe, that it doesn't check for the end.
26+
/// Aligns reader's BIT pointer to the BYTE border, i.e. moves BIT pointer to the first BIT of the next BYTE.
2127
func align()
2228

2329
// MARK: ByteReader's methods.
24-
// TODO: Describe preconditions.
2530

31+
/// Reads byte and returns it, advancing by one BYTE position.
2632
func byte() -> UInt8
2733

34+
/// Reads `count` bytes and returns them as an array of `UInt8`, advancing by `count` BYTE positions.
2835
func bytes(count: Int) -> [UInt8]
2936

37+
/// Reads 8 bytes and returns them as a `UInt64` number, advancing by 8 BYTE positions.
3038
func uint64() -> UInt64
3139

40+
/// Reads 4 bytes and returns them as a `UInt32` number, advancing by 4 BYTE positions.
3241
func uint32() -> UInt32
3342

43+
/// Reads 2 bytes and returns them as a `UInt16` number, advancing by 2 BYTE positions.
3444
func uint16() -> UInt16
3545

3646
}
3747

3848
extension BitReader {
3949

50+
/**
51+
Reads `count` bits and returns them as an array of `UInt8`, advancing by `count` BIT positions.
52+
53+
- Warning: Doesn't check if there is any data left.
54+
*/
4055
public func bits(count: Int) -> [UInt8] {
4156
guard count > 0
4257
else { return [] }

Sources/BitWriter.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,41 @@
55

66
import Foundation
77

8+
/// A type that contains functions for writing `Data` bit-by-bit (and byte-by-byte).
89
public protocol BitWriter {
910

11+
/// Data which contains writer's output (the last byte in progress is not included).
1012
var data: Data { get }
1113

12-
init()
13-
14+
/// True, if writer's BIT pointer is aligned with the BYTE border.
1415
var isAligned: Bool { get }
1516

17+
/// Creates an instance for writing.
18+
init()
19+
20+
/// Writes `bit`, advancing by one BIT position.
1621
func write(bit: UInt8)
1722

23+
/// Writes `bits`, advancing by `bits.count` BIT positions.
1824
func write(bits: [UInt8])
1925

20-
// TODO: Describe, what will happen if `bitsCount` is smaller than actual amount of `number`'s bits.
21-
// TODO: Describe, that `number` is processed in the same order as `BitWriter`'s.
26+
/// Writes `number`, using and advancing by `bitsCount` BIT positions.
2227
func write(number: Int, bitsCount: Int)
2328

29+
/// Writes `byte`, advancing by one BYTE position.
2430
func append(byte: UInt8)
2531

26-
// TODO: Describe, that it doesn't check if it actually needs to align.
32+
/**
33+
Aligns writer's BIT pointer to the BYTE border, i.e. moves BIT pointer to the first BIT of the next BYTE,
34+
filling all skipped BIT positions with zeros.
35+
*/
2736
func align()
2837

2938
}
3039

3140
extension BitWriter {
3241

42+
/// Writes `bits`, advancing by `bits.count` BIT positions.
3343
public func write(bits: [UInt8]) {
3444
for bit in bits {
3545
self.write(bit: bit)

Sources/ByteReader.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public class ByteReader {
3737
/**
3838
Reads byte and returns it, advancing by one position.
3939

40-
- Warning: Doesn't check for potential out of bounds error, i.e. doesn't check if `isFinished` is true.
40+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
41+
to check if the end is reached.
4142
*/
4243
public func byte() -> UInt8 {
4344
self.offset += 1
@@ -47,8 +48,8 @@ public class ByteReader {
4748
/**
4849
Reads `count` bytes and returns them as an array of `UInt8`, advancing by `count` positions.
4950

50-
- Warning: Doesn't check for potential out of bounds errors, i.e. doesn't check if `isFinished` will be true
51-
at any point during the reading of these bytes.
51+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
52+
to check if the end is reached.
5253
*/
5354
public func bytes(count: Int) -> [UInt8] {
5455
let result = self.data[self.offset..<self.offset + count].toArray(type: UInt8.self, count: count)
@@ -59,8 +60,8 @@ public class ByteReader {
5960
/**
6061
Reads 8 bytes and returns them as a `UInt64` number, advancing by 8 positions.
6162

62-
- Warning: Doesn't check for potential out of bounds errors, i.e. doesn't check if `isFinished` will be true
63-
at any point during the reading of this number.
63+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
64+
to check if the end is reached.
6465
*/
6566
public func uint64() -> UInt64 {
6667
let result = self.data[self.offset..<self.offset + 8].to(type: UInt64.self)
@@ -71,8 +72,8 @@ public class ByteReader {
7172
/**
7273
Reads 4 bytes and returns them as a `UInt32` number, advancing by 4 positions.
7374

74-
- Warning: Doesn't check for potential out of bounds errors, i.e. doesn't check if `isFinished` will be true
75-
at any point during the reading of this number.
75+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
76+
to check if the end is reached.
7677
*/
7778
public func uint32() -> UInt32 {
7879
let result = self.data[self.offset..<self.offset + 4].to(type: UInt32.self)
@@ -83,8 +84,8 @@ public class ByteReader {
8384
/**
8485
Reads 2 bytes and returns them as a `UInt16` number, advancing by 2 positions.
8586

86-
- Warning: Doesn't check for potential out of bounds errors, i.e. doesn't check if `isFinished` will be true
87-
at any point during the reading of this number.
87+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
88+
to check if the end is reached.
8889
*/
8990
public func uint16() -> UInt16 {
9091
let result = self.data[self.offset..<self.offset + 2].to(type: UInt16.self)

Sources/LsbBitReader.swift

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@
55

66
import Foundation
77

8+
/**
9+
A type that contains functions for reading `Data` bit-by-bit and byte-by-byte,
10+
assuming "LSB 0" bit numbering scheme.
11+
*/
812
public final class LsbBitReader: ByteReader, BitReader {
913

1014
private var bitMask: UInt8 = 1
1115

16+
/// True, if reader's BIT pointer is aligned with the BYTE border.
1217
public var isAligned: Bool {
1318
return self.bitMask == 1
1419
}
1520

21+
/**
22+
Reads bit and returns it, advancing by one BIT position.
23+
24+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
25+
to check if the end is reached.
26+
*/
1627
public func bit() -> UInt8 {
1728
let bit: UInt8 = self.data[self.offset] & self.bitMask > 0 ? 1 : 0
1829

@@ -26,6 +37,12 @@ public final class LsbBitReader: ByteReader, BitReader {
2637
return bit
2738
}
2839

40+
/**
41+
Reads `count` bits and returns them as a `Int` number, advancing by `count` BIT positions.
42+
43+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
44+
to check if the end is reached.
45+
*/
2946
public func int(fromBits count: Int) -> Int {
3047
guard count > 0
3148
else { return 0 }
@@ -48,6 +65,13 @@ public final class LsbBitReader: ByteReader, BitReader {
4865
return result
4966
}
5067

68+
/**
69+
Aligns reader's BIT pointer to the BYTE border, i.e. moves BIT pointer to the first BIT of the next BYTE.
70+
71+
- Note: If reader is already aligned, then does nothing.
72+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` AFTER calling this method
73+
to check if the end was reached.
74+
*/
5175
public func align() {
5276
guard self.bitMask != 1
5377
else { return }
@@ -58,26 +82,61 @@ public final class LsbBitReader: ByteReader, BitReader {
5882

5983
// MARK: ByteReader's methods.
6084

85+
/**
86+
Reads byte and returns it, advancing by one BYTE position.
87+
88+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
89+
to check if the end is reached.
90+
- Precondition: Reader MUST be aligned.
91+
*/
6192
public override func byte() -> UInt8 {
6293
precondition(isAligned, "BitReader is not aligned.")
6394
return super.byte()
6495
}
6596

97+
/**
98+
Reads `count` bytes and returns them as an array of `UInt8`, advancing by `count` BYTE positions.
99+
100+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
101+
to check if the end is reached.
102+
- Precondition: Reader MUST be aligned.
103+
*/
66104
public override func bytes(count: Int) -> [UInt8] {
67105
precondition(isAligned, "BitReader is not aligned.")
68106
return super.bytes(count: count)
69107
}
70108

109+
/**
110+
Reads 8 bytes and returns them as a `UInt64` number, advancing by 8 BYTE positions.
111+
112+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
113+
to check if the end is reached.
114+
- Precondition: Reader MUST be aligned.
115+
*/
71116
public override func uint64() -> UInt64 {
72117
precondition(isAligned, "BitReader is not aligned.")
73118
return super.uint64()
74119
}
75120

121+
/**
122+
Reads 4 bytes and returns them as a `UInt32` number, advancing by 4 BYTE positions.
123+
124+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
125+
to check if the end is reached.
126+
- Precondition: Reader MUST be aligned.
127+
*/
76128
public override func uint32() -> UInt32 {
77129
precondition(isAligned, "BitReader is not aligned.")
78130
return super.uint32()
79131
}
80132

133+
/**
134+
Reads 2 bytes and returns them as a `UInt16` number, advancing by 2 BYTE positions.
135+
136+
- Warning: Doesn't check if there is any data left. It is advisable to use `isFinished` BEFORE calling this method
137+
to check if the end is reached.
138+
- Precondition: Reader MUST be aligned.
139+
*/
81140
public override func uint16() -> UInt16 {
82141
precondition(isAligned, "BitReader is not aligned.")
83142
return super.uint16()

Sources/LsbBitWriter.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,27 @@
55

66
import Foundation
77

8+
/**
9+
A type that contains functions for writing `Data` bit-by-bit (and byte-by-byte),
10+
assuming "LSB 0" bit numbering scheme.
11+
*/
812
public final class LsbBitWriter: BitWriter {
913

14+
/// Data which contains writer's output (the last byte in progress is not included).
1015
public private(set) var data: Data = Data()
1116

1217
private var bitMask: UInt8 = 1
1318
private var currentByte: UInt8 = 0
1419

20+
/// True, if writer's BIT pointer is aligned with the BYTE border.
1521
public var isAligned: Bool {
1622
return self.bitMask == 1
1723
}
1824

25+
/// Creates an instance for writing.
1926
public init() { }
2027

28+
/// Writes `bit`, advancing by one BIT position.
2129
public func write(bit: UInt8) {
2230
precondition(bit <= 1, "A bit must be either 0 or 1.")
2331

@@ -32,6 +40,13 @@ public final class LsbBitWriter: BitWriter {
3240
}
3341
}
3442

43+
/**
44+
Writes `number`, using and advancing by `bitsCount` BIT positions.
45+
46+
- Note: If `bitsCount` is smaller than the actual amount of `number`'s bits than the `number` will be truncated to
47+
fit into `bitsCount` amount of bits.
48+
- Note: Bits of `number` are processed using the same bit-numbering scheme as of the writer (i.e. "LSB 0").
49+
*/
3550
public func write(number: Int, bitsCount: Int) {
3651
var mask = 1
3752
for _ in 0..<bitsCount {
@@ -40,11 +55,22 @@ public final class LsbBitWriter: BitWriter {
4055
}
4156
}
4257

58+
/**
59+
Writes `byte`, advancing by one BYTE position.
60+
61+
- Precondition: Writer MUST be aligned.
62+
*/
4363
public func append(byte: UInt8) {
4464
precondition(isAligned, "BitWriter is not aligned.")
4565
self.data.append(byte)
4666
}
4767

68+
/**
69+
Aligns writer's BIT pointer to the BYTE border, i.e. moves BIT pointer to the first BIT of the next BYTE,
70+
filling all skipped BIT positions with zeros.
71+
72+
- Note: If writer is already aligned, then does nothing.
73+
*/
4874
public func align() {
4975
self.data.append(self.currentByte)
5076
self.currentByte = 0

0 commit comments

Comments
 (0)