Skip to content

Commit 29e92b6

Browse files
committed
Add "closure" workarounds to all functions and properties of ByteReader to improve its performance with Swift 4.2
1 parent fcd6ed8 commit 29e92b6

1 file changed

Lines changed: 137 additions & 38 deletions

File tree

Sources/ByteReader.swift

Lines changed: 137 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,36 @@ public class ByteReader {
2323
- Note: It generally means that all bytes have been read.
2424
*/
2525
public var isFinished: Bool {
26-
return self.data.endIndex <= self.offset
26+
#if swift(>=4.2)
27+
return { (data: Data, offset: Int) -> Bool in
28+
data.endIndex <= offset
29+
} (self.data, self.offset)
30+
#else
31+
return self.data.endIndex <= self.offset
32+
#endif
33+
2734
}
2835

2936
/// Amount of bytes left to read.
3037
public var bytesLeft: Int {
31-
return self.data.endIndex - self.offset
38+
#if swift(>=4.2)
39+
return { (data: Data, offset: Int) -> Int in
40+
self.data.endIndex - self.offset
41+
} (self.data, self.offset)
42+
#else
43+
return self.data.endIndex - self.offset
44+
#endif
3245
}
3346

3447
/// Amount of bytes that were already read.
3548
public var bytesRead: Int {
36-
return self.offset - self.data.startIndex
49+
#if swift(>=4.2)
50+
return { (data: Data, offset: Int) -> Int in
51+
return offset - data.startIndex
52+
} (self.data, self.offset)
53+
#else
54+
return self.offset - self.data.startIndex
55+
#endif
3756
}
3857

3958
/// Creates an instance for reading bytes from `data`.
@@ -49,9 +68,17 @@ public class ByteReader {
4968
- Precondition: There MUST be enough data left.
5069
*/
5170
public func byte() -> UInt8 {
52-
precondition(self.offset < self.data.endIndex)
53-
defer { self.offset += 1 }
54-
return self.data[self.offset]
71+
#if swift(>=4.2)
72+
return { (data: Data, offset: inout Int) -> UInt8 in
73+
precondition(offset < data.endIndex)
74+
defer { offset += 1 }
75+
return data[offset]
76+
} (self.data, &self.offset)
77+
#else
78+
precondition(self.offset < self.data.endIndex)
79+
defer { self.offset += 1 }
80+
return self.data[self.offset]
81+
#endif
5582
}
5683

5784
/**
@@ -63,8 +90,15 @@ public class ByteReader {
6390
public func bytes(count: Int) -> [UInt8] {
6491
precondition(count >= 0)
6592
precondition(bytesLeft >= count)
66-
defer { self.offset += count }
67-
return self.data[self.offset..<self.offset + count].toArray(type: UInt8.self, count: count)
93+
#if swift(>=4.2)
94+
return { (data: Data, offset: inout Int) -> [UInt8] in
95+
defer { offset += count }
96+
return data[offset..<offset + count].toArray(type: UInt8.self, count: count)
97+
} (self.data, &self.offset)
98+
#else
99+
defer { self.offset += count }
100+
return self.data[self.offset..<self.offset + count].toArray(type: UInt8.self, count: count)
101+
#endif
68102
}
69103

70104
/**
@@ -78,12 +112,23 @@ public class ByteReader {
78112
precondition(bytesLeft >= count)
79113
// TODO: If uintX() could be force inlined or something in the future then probably it would make sense
80114
// to use them for `count` == 2, 4 or 8.
81-
var result = 0
82-
for i in 0..<count {
83-
result += Int(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
84-
self.offset += 1
85-
}
86-
return result
115+
#if swift(>=4.2)
116+
return { (data: Data, offset: inout Int) -> Int in
117+
var result = 0
118+
for i in 0..<count {
119+
result += Int(truncatingIfNeeded: data[offset]) << (8 * i)
120+
offset += 1
121+
}
122+
return result
123+
} (self.data, &self.offset)
124+
#else
125+
var result = 0
126+
for i in 0..<count {
127+
result += Int(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
128+
self.offset += 1
129+
}
130+
return result
131+
#endif
87132
}
88133

89134
/**
@@ -93,8 +138,15 @@ public class ByteReader {
93138
*/
94139
public func uint64() -> UInt64 {
95140
precondition(bytesLeft >= 8)
96-
defer { self.offset += 8 }
97-
return self.data[self.offset..<self.offset + 8].to(type: UInt64.self)
141+
#if swift(>=4.2)
142+
return { (data: Data, offset: inout Int) -> UInt64 in
143+
defer { offset += 8 }
144+
return data[offset..<offset + 8].to(type: UInt64.self)
145+
} (self.data, &self.offset)
146+
#else
147+
defer { self.offset += 8 }
148+
return self.data[self.offset..<self.offset + 8].to(type: UInt64.self)
149+
#endif
98150
}
99151

100152
/**
@@ -109,12 +161,23 @@ public class ByteReader {
109161
public func uint64(fromBytes count: Int) -> UInt64 {
110162
precondition(0...8 ~= count)
111163
precondition(bytesLeft >= count)
112-
var result = 0 as UInt64
113-
for i in 0..<count {
114-
result += UInt64(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
115-
self.offset += 1
116-
}
117-
return result
164+
#if swift(>=4.2)
165+
return { (data: Data, offset: inout Int) -> UInt64 in
166+
var result = 0 as UInt64
167+
for i in 0..<count {
168+
result += UInt64(truncatingIfNeeded: data[offset]) << (8 * i)
169+
offset += 1
170+
}
171+
return result
172+
} (self.data, &self.offset)
173+
#else
174+
var result = 0 as UInt64
175+
for i in 0..<count {
176+
result += UInt64(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
177+
self.offset += 1
178+
}
179+
return result
180+
#endif
118181
}
119182

120183
/**
@@ -124,8 +187,15 @@ public class ByteReader {
124187
*/
125188
public func uint32() -> UInt32 {
126189
precondition(bytesLeft >= 4)
127-
defer { self.offset += 4 }
128-
return self.data[self.offset..<self.offset + 4].to(type: UInt32.self)
190+
#if swift(>=4.2)
191+
return { (data: Data, offset: inout Int) -> UInt32 in
192+
defer { offset += 4 }
193+
return data[offset..<offset + 4].to(type: UInt32.self)
194+
} (self.data, &self.offset)
195+
#else
196+
defer { self.offset += 4 }
197+
return self.data[self.offset..<self.offset + 4].to(type: UInt32.self)
198+
#endif
129199
}
130200

131201
/**
@@ -140,12 +210,23 @@ public class ByteReader {
140210
public func uint32(fromBytes count: Int) -> UInt32 {
141211
precondition(0...4 ~= count)
142212
precondition(bytesLeft >= count)
143-
var result = 0 as UInt32
144-
for i in 0..<count {
145-
result += UInt32(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
146-
self.offset += 1
147-
}
148-
return result
213+
#if swift(>=4.2)
214+
return { (data: Data, offset: inout Int) -> UInt32 in
215+
var result = 0 as UInt32
216+
for i in 0..<count {
217+
result += UInt32(truncatingIfNeeded: data[offset]) << (8 * i)
218+
offset += 1
219+
}
220+
return result
221+
} (self.data, &self.offset)
222+
#else
223+
var result = 0 as UInt32
224+
for i in 0..<count {
225+
result += UInt32(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
226+
self.offset += 1
227+
}
228+
return result
229+
#endif
149230
}
150231

151232
/**
@@ -155,8 +236,15 @@ public class ByteReader {
155236
*/
156237
public func uint16() -> UInt16 {
157238
precondition(bytesLeft >= 2)
158-
defer { self.offset += 2 }
159-
return self.data[self.offset..<self.offset + 2].to(type: UInt16.self)
239+
#if swift(>=4.2)
240+
return { (data: Data, offset: inout Int) -> UInt16 in
241+
defer { offset += 2 }
242+
return data[offset..<offset + 2].to(type: UInt16.self)
243+
} (self.data, &self.offset)
244+
#else
245+
defer { self.offset += 2 }
246+
return self.data[self.offset..<self.offset + 2].to(type: UInt16.self)
247+
#endif
160248
}
161249

162250
/**
@@ -171,12 +259,23 @@ public class ByteReader {
171259
public func uint16(fromBytes count: Int) -> UInt16 {
172260
precondition(0...2 ~= count)
173261
precondition(bytesLeft >= count)
174-
var result = 0 as UInt16
175-
for i in 0..<count {
176-
result += UInt16(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
177-
self.offset += 1
178-
}
179-
return result
262+
#if swift(>=4.2)
263+
return { (data: Data, offset: inout Int) -> UInt16 in
264+
var result = 0 as UInt16
265+
for i in 0..<count {
266+
result += UInt16(truncatingIfNeeded: data[offset]) << (8 * i)
267+
offset += 1
268+
}
269+
return result
270+
} (self.data, &self.offset)
271+
#else
272+
var result = 0 as UInt16
273+
for i in 0..<count {
274+
result += UInt16(truncatingIfNeeded: self.data[self.offset]) << (8 * i)
275+
self.offset += 1
276+
}
277+
return result
278+
#endif
180279
}
181280

182281
}

0 commit comments

Comments
 (0)