@@ -28,96 +28,104 @@ import Bionic
28
28
29
29
/// Describes a way to encode and decode an integer as bytes
30
30
///
31
- public protocol BinaryIntegerEncodingStrategy {
32
- /// Read an integer from a buffer. The reader index should be moved accordingly
33
- /// - Returns: The integer
31
+ public protocol NIOBinaryIntegerEncodingStrategy {
32
+ /// Read an integer from a buffer.
33
+ /// If there are not enough bytes to read an integer of this encoding, return nil, and do not move the reader index.
34
+ /// If the the full integer can be read, move the reader index to after the integer, and return the integer.
35
+ /// - Parameters:
36
+ /// - as: The type of integer to be read.
37
+ /// - buffer: The buffer to read from.
38
+ /// - Returns: The integer that was read, or nil if it was not possible to read it.
34
39
func readInteger< IntegerType: FixedWidthInteger > (
35
40
as: IntegerType . Type ,
36
41
from buffer: inout ByteBuffer
37
42
) -> IntegerType ?
38
43
39
- /// Write an integer to a buffer. The writer index should be moved accordingly
44
+ /// Write an integer to a buffer. Move the writer index to after the written integer.
45
+ /// - Parameters:
46
+ /// - integer: The type of the integer to write.
47
+ /// - to: The buffer to write to.
40
48
func writeInteger< IntegerType: FixedWidthInteger > (
41
49
_ integer: IntegerType ,
42
50
to buffer: inout ByteBuffer
43
51
) -> Int
44
52
45
- /// When writing an integer using this strategy, how many bytes we should reserve
46
- /// If the actual bytes used by the write function is more or less than this, it will be necessary to shuffle bytes
47
- /// Therefore, an accurate prediction here will improve performance
48
- var reservedSpaceForInteger : Int { get }
53
+ /// When writing an integer using this strategy, how many bytes we should reserve.
54
+ /// If the actual bytes used by the write function is more or less than this, it will be necessary to shuffle bytes.
55
+ /// Therefore, an accurate prediction here will improve performance.
56
+ var reservedCapacityForInteger : Int { get }
49
57
50
- /// Write an integer to a buffer. The writer index should be moved accordingly
51
- /// This function takes a `reservedSpace ` parameter which is the number of bytes we already reserved for writing this integer
52
- /// If you use write more or less than this many bytes, we wll need to move bytes around to make that possible
53
- /// Therefore, you may decide to encode differently to use more bytes than you actually would need, if it is possible for you to do so
54
- /// That way, you waste the reserved bytes, but improve writing performance
55
- func writeIntegerWithReservedSpace (
58
+ /// Write an integer to a buffer. The writer index should be moved accordingly.
59
+ /// This function takes a `reservedCapacity ` parameter which is the number of bytes we already reserved for writing this integer.
60
+ /// If you use write more or less than this many bytes, we wll need to move bytes around to make that possible.
61
+ /// Therefore, you may decide to encode differently to use more bytes than you actually would need, if it is possible for you to do so.
62
+ /// That way, you waste the reserved bytes, but improve writing performance.
63
+ func writeIntegerWithReservedCapacity (
56
64
_ integer: Int ,
57
- reservedSpace : Int ,
65
+ reservedCapacity : Int ,
58
66
to buffer: inout ByteBuffer
59
67
) -> Int
60
68
}
61
69
62
- extension BinaryIntegerEncodingStrategy {
70
+ extension NIOBinaryIntegerEncodingStrategy {
63
71
@inlinable
64
- public var reservedSpaceForInteger : Int { 1 }
72
+ public var reservedCapacityForInteger : Int { 1 }
65
73
66
74
@inlinable
67
- public func writeIntegerWithReservedSpace < IntegerType: FixedWidthInteger > (
75
+ public func writeIntegerWithReservedCapacity < IntegerType: FixedWidthInteger > (
68
76
_ integer: IntegerType ,
69
- reservedSpace : Int ,
77
+ reservedCapacity : Int ,
70
78
to buffer: inout ByteBuffer
71
79
) -> Int {
72
80
self . writeInteger ( integer, to: & buffer)
73
81
}
74
82
}
75
83
76
84
extension ByteBuffer {
77
- /// Read a binary encoded integer, moving the `readerIndex` appropriately
78
- /// If there are not enough bytes, nil is returned
85
+ /// Read a binary encoded integer, moving the `readerIndex` appropriately.
86
+ /// If there are not enough bytes, nil is returned.
79
87
@inlinable
80
- public mutating func readEncodedInteger< Strategy: BinaryIntegerEncodingStrategy > ( _ strategy: Strategy ) -> Int ? {
88
+ public mutating func readEncodedInteger< Strategy: NIOBinaryIntegerEncodingStrategy > ( _ strategy: Strategy ) -> Int ? {
81
89
strategy. readInteger ( as: Int . self, from: & self )
82
90
}
83
91
84
92
/// Write a binary encoded integer.
85
93
///
86
- /// - Returns: The number of bytes written
94
+ /// - Returns: The number of bytes written.
87
95
@discardableResult
88
96
@inlinable
89
97
public mutating func writeEncodedInteger<
90
98
Integer: FixedWidthInteger ,
91
- Strategy: BinaryIntegerEncodingStrategy
99
+ Strategy: NIOBinaryIntegerEncodingStrategy
92
100
> (
93
101
_ value: Integer ,
94
102
strategy: Strategy
95
103
) -> Int {
96
104
strategy. writeInteger ( value, to: & self )
97
105
}
98
106
99
- /// Prefixes a message written by `writeMessage` with the number of bytes written using `strategy`
107
+ /// Prefixes a message written by `writeMessage` with the number of bytes written using `strategy`.
100
108
///
101
- /// Implementation note : This function works by reserving the number of bytes suggested by ``BinaryIntegerEncodingStrategy.reservedSpace`` before the data
102
- /// It then writes the data, and then goes back to write the length
103
- /// If the reserved capacity turns out to be too little or too much, then the data will be shifted
104
- /// Therefore, this function is most performant if the strategy is able to use the same number of bytes that it reserved
109
+ /// - Note : This function works by reserving the number of bytes suggested by `strategy` before the data.
110
+ /// It then writes the data, and then goes back to write the length.
111
+ /// If the reserved capacity turns out to be too little or too much, then the data will be shifted.
112
+ /// Therefore, this function is most performant if the strategy is able to use the same number of bytes that it reserved.
105
113
///
106
114
/// - Parameters:
107
- /// - strategy: The strategy to use for encoding the length
108
- /// - writeMessage: A closure that takes a buffer, writes a message to it and returns the number of bytes written
109
- /// - Returns: Number of total bytes written. This is the length of the written message + the number of bytes used to write the length before it
115
+ /// - strategy: The strategy to use for encoding the length.
116
+ /// - writeMessage: A closure that takes a buffer, writes a message to it and returns the number of bytes written.
117
+ /// - Returns: Number of total bytes written. This is the length of the written message + the number of bytes used to write the length before it.
110
118
@discardableResult
111
119
@inlinable
112
- public mutating func writeLengthPrefixed< Strategy: BinaryIntegerEncodingStrategy > (
120
+ public mutating func writeLengthPrefixed< Strategy: NIOBinaryIntegerEncodingStrategy > (
113
121
strategy: Strategy ,
114
122
writeMessage: ( inout ByteBuffer ) throws -> Int
115
123
) rethrows -> Int {
116
124
/// The index at which we write the length
117
125
let lengthPrefixIndex = self . writerIndex
118
126
/// The space which we reserve for writing the length
119
- let reservedSpace = strategy. reservedSpaceForInteger
120
- self . writeRepeatingByte ( 0 , count: reservedSpace )
127
+ let reservedCapacity = strategy. reservedCapacityForInteger
128
+ self . writeRepeatingByte ( 0 , count: reservedCapacity )
121
129
122
130
/// The index at which we start writing the message originally. We may later move the message if the reserved space for the length wasn't right
123
131
let originalMessageStartIndex = self . writerIndex
@@ -142,18 +150,18 @@ extension ByteBuffer {
142
150
// We write the length after the message to begin with. We will move it later
143
151
144
152
/// The actual number of bytes used to write the length written. The user may write more or fewer bytes than what we reserved
145
- let actualIntegerLength = strategy. writeIntegerWithReservedSpace (
153
+ let actualIntegerLength = strategy. writeIntegerWithReservedCapacity (
146
154
messageLength,
147
- reservedSpace : reservedSpace ,
155
+ reservedCapacity : reservedCapacity ,
148
156
to: & self
149
157
)
150
158
151
159
switch actualIntegerLength {
152
- case reservedSpace :
160
+ case reservedCapacity :
153
161
// Good, exact match, swap the values and then "delete" the trailing bytes by moving the index back
154
162
self . _moveBytes ( from: originalMessageEndIndex, to: lengthPrefixIndex, size: actualIntegerLength)
155
163
self . moveWriterIndex ( to: originalMessageEndIndex)
156
- case ..< reservedSpace :
164
+ case ..< reservedCapacity :
157
165
// We wrote fewer bytes. We now have to move the length bytes from the end, and
158
166
// _then_ shrink the rest of the buffer onto it.
159
167
self . _moveBytes ( from: originalMessageEndIndex, to: lengthPrefixIndex, size: actualIntegerLength)
@@ -164,10 +172,10 @@ extension ByteBuffer {
164
172
size: messageLength
165
173
)
166
174
self . moveWriterIndex ( to: newMessageStartIndex + messageLength)
167
- case reservedSpace ... :
175
+ case reservedCapacity ... :
168
176
// We wrote more bytes. We now have to create enough space. Once we do, we have the same
169
177
// implementation as the matching case.
170
- let extraSpaceNeeded = actualIntegerLength - reservedSpace
178
+ let extraSpaceNeeded = actualIntegerLength - reservedCapacity
171
179
self . _createSpace ( before: lengthPrefixIndex, requiredSpace: extraSpaceNeeded)
172
180
173
181
// Clean up the indices.
@@ -183,10 +191,10 @@ extension ByteBuffer {
183
191
return totalBytesWritten
184
192
}
185
193
186
- /// Reads a slice which is prefixed with a length. The length will be read using `strategy`, and then that many bytes will be read to create a slice
187
- /// - Returns: The slice, if there are enough bytes to read it fully. In this case, the readerIndex will move to after the slice
188
- /// If there are not enough bytes to read the full slice, the readerIndex will stay unchanged
189
- public mutating func readLengthPrefixedSlice< Strategy: BinaryIntegerEncodingStrategy > (
194
+ /// Reads a slice which is prefixed with a length. The length will be read using `strategy`, and then that many bytes will be read to create a slice.
195
+ /// - Returns: The slice, if there are enough bytes to read it fully. In this case, the readerIndex will move to after the slice.
196
+ /// If there are not enough bytes to read the full slice, the readerIndex will stay unchanged.
197
+ public mutating func readLengthPrefixedSlice< Strategy: NIOBinaryIntegerEncodingStrategy > (
190
198
_ strategy: Strategy
191
199
) -> ByteBuffer ? {
192
200
let originalReaderIndex = self . readerIndex
@@ -202,14 +210,14 @@ extension ByteBuffer {
202
210
// MARK: - Helpers for writing length-prefixed things
203
211
204
212
extension ByteBuffer {
205
- /// Write the length of `buffer` using `strategy`. Then write the buffer
213
+ /// Write the length of `buffer` using `strategy`. Then write the buffer.
206
214
/// - Parameters:
207
- /// - buffer: The buffer to be written
208
- /// - strategy: The encoding strategy to use
209
- /// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the buffer itself
215
+ /// - buffer: The buffer to be written.
216
+ /// - strategy: The encoding strategy to use.
217
+ /// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the buffer itself.
210
218
@discardableResult
211
219
public mutating func writeLengthPrefixedBuffer<
212
- Strategy: BinaryIntegerEncodingStrategy
220
+ Strategy: NIOBinaryIntegerEncodingStrategy
213
221
> (
214
222
_ buffer: ByteBuffer ,
215
223
strategy: Strategy
@@ -220,14 +228,14 @@ extension ByteBuffer {
220
228
return written
221
229
}
222
230
223
- /// Write the length of `string` using `strategy`. Then write the string
231
+ /// Write the length of `string` using `strategy`. Then write the string.
224
232
/// - Parameters:
225
- /// - string: The string to be written
226
- /// - strategy: The encoding strategy to use
227
- /// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the string itself
233
+ /// - string: The string to be written.
234
+ /// - strategy: The encoding strategy to use.
235
+ /// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the string itself.
228
236
@discardableResult
229
237
public mutating func writeLengthPrefixedString<
230
- Strategy: BinaryIntegerEncodingStrategy
238
+ Strategy: NIOBinaryIntegerEncodingStrategy
231
239
> (
232
240
_ string: String ,
233
241
strategy: Strategy
@@ -240,15 +248,15 @@ extension ByteBuffer {
240
248
return written
241
249
}
242
250
243
- /// Write the length of `bytes` using `strategy`. Then write the bytes
251
+ /// Write the length of `bytes` using `strategy`. Then write the bytes.
244
252
/// - Parameters:
245
- /// - bytes: The bytes to be written
246
- /// - strategy: The encoding strategy to use
247
- /// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the bytes themselves
253
+ /// - bytes: The bytes to be written.
254
+ /// - strategy: The encoding strategy to use.
255
+ /// - Returns: The total bytes written. This is the bytes needed to write the length, plus the length of the bytes themselves.
248
256
@inlinable
249
257
public mutating func writeLengthPrefixedBytes<
250
258
Bytes: Sequence ,
251
- Strategy: BinaryIntegerEncodingStrategy
259
+ Strategy: NIOBinaryIntegerEncodingStrategy
252
260
> (
253
261
_ bytes: Bytes ,
254
262
strategy: Strategy
@@ -271,11 +279,11 @@ extension ByteBuffer {
271
279
}
272
280
273
281
extension ByteBuffer {
274
- /// Creates `requiredSpace` bytes of free space immediately before `index`
282
+ /// Creates `requiredSpace` bytes of free space immediately before `index`.
275
283
/// e.g. given [a, b, c, d, e, f, g, h, i, j] and calling this function with (before: 4, requiredSpace: 2) would result in
276
284
/// [a, b, c, d, 0, 0, e, f, g, h, i, j]
277
- /// 2 extra bytes of space were created before index 4 (the letter e)
278
- /// The total bytes written will be equal to `requiredSpace`, and the writer index will be moved accordingly
285
+ /// 2 extra bytes of space were created before index 4 (the letter e).
286
+ /// The total bytes written will be equal to `requiredSpace`, and the writer index will be moved accordingly.
279
287
@usableFromInline
280
288
mutating func _createSpace( before index: Int , requiredSpace: Int ) {
281
289
let bytesToMove = self . writerIndex - index
@@ -294,8 +302,8 @@ extension ByteBuffer {
294
302
}
295
303
}
296
304
297
- /// Move the `size` bytes starting from `source` to `destination`
298
- /// `source` and `destination` must both be within the writable range
305
+ /// Move the `size` bytes starting from `source` to `destination`.
306
+ /// `source` and `destination` must both be within the writable range.
299
307
@usableFromInline
300
308
mutating func _moveBytes( from source: Int , to destination: Int , size: Int ) {
301
309
precondition ( source >= self . readerIndex && destination < self . writerIndex && source >= destination)
0 commit comments