0
# Packet I/O System
1
2
Immutable byte packets and builders for structured data handling with automatic memory management and efficient serialization.
3
4
## Capabilities
5
6
### ByteReadPacket Class
7
8
Immutable read-only byte packet that extends the Input class for sequential reading operations.
9
10
```kotlin { .api }
11
/**
12
* Immutable read-only byte packet for sequential data reading.
13
* Thread-safe for concurrent reading after creation.
14
*/
15
class ByteReadPacket : Input {
16
/** Total bytes remaining to be read */
17
val remaining: Long
18
19
/** True when no more bytes are available for reading */
20
val endOfInput: Boolean
21
22
/**
23
* Create a concurrent-safe copy of this packet.
24
* Both copies can be read independently without affecting each other.
25
* @return new ByteReadPacket with same content
26
*/
27
fun copy(): ByteReadPacket
28
29
companion object {
30
/** Empty packet singleton with no content */
31
val Empty: ByteReadPacket
32
}
33
}
34
```
35
36
**Usage Examples:**
37
38
```kotlin
39
import io.ktor.utils.io.core.*
40
41
// Create packet from byte array
42
val packet = ByteReadPacket(byteArrayOf(1, 2, 3, 4, 5))
43
44
// Read data sequentially
45
val firstByte = packet.readByte()
46
val remaining = packet.remaining // 4 bytes left
47
48
// Create independent copies
49
val copy1 = packet.copy()
50
val copy2 = packet.copy()
51
// Both copies can be read independently
52
53
// Check if packet is empty
54
if (!packet.endOfInput) {
55
val nextByte = packet.readByte()
56
}
57
```
58
59
### BytePacketBuilder Class
60
61
Mutable builder for creating byte packets with fluent API and automatic memory management.
62
63
```kotlin { .api }
64
/**
65
* Builder for creating byte packets with fluent API.
66
* Extends Output and implements Appendable for versatile content creation.
67
*/
68
class BytePacketBuilder : Output, Appendable {
69
/** Current size of the packet being built in bytes */
70
val size: Int
71
72
/** True if no bytes have been written yet */
73
val isEmpty: Boolean
74
75
/** True if any bytes have been written */
76
val isNotEmpty: Boolean
77
78
/**
79
* Build the packet and reset this builder for reuse.
80
* @return new immutable ByteReadPacket with current content
81
*/
82
fun build(): ByteReadPacket
83
84
/**
85
* Append a single UTF-8 character to the packet.
86
* @param value character to append
87
* @return this builder for method chaining
88
*/
89
override fun append(value: Char): BytePacketBuilder
90
91
/**
92
* Append a character sequence as UTF-8 text.
93
* @param value text to append (null values are ignored)
94
* @return this builder for method chaining
95
*/
96
override fun append(value: CharSequence?): BytePacketBuilder
97
98
/**
99
* Write a single byte to the packet.
100
* @param v byte value to write
101
*/
102
override fun writeByte(v: Byte)
103
104
/**
105
* Write a 16-bit short value in big-endian byte order.
106
* @param v short value to write
107
*/
108
fun writeShort(v: Short)
109
110
/**
111
* Write a 32-bit int value in big-endian byte order.
112
* @param v int value to write
113
*/
114
fun writeInt(v: Int)
115
116
/**
117
* Write a 64-bit long value in big-endian byte order.
118
* @param v long value to write
119
*/
120
fun writeLong(v: Long)
121
122
/**
123
* Write a 32-bit float value in big-endian byte order.
124
* @param v float value to write
125
*/
126
fun writeFloat(v: Float)
127
128
/**
129
* Write a 64-bit double value in big-endian byte order.
130
* @param v double value to write
131
*/
132
fun writeDouble(v: Double)
133
134
/**
135
* Write an entire byte array to the packet.
136
* @param src source byte array
137
* @param offset starting position in source array
138
* @param length number of bytes to write
139
*/
140
fun writeFully(src: ByteArray, offset: Int, length: Int)
141
142
/**
143
* Write all bytes from another packet.
144
* The source packet will be consumed (closed) after writing.
145
* @param packet source packet to write
146
*/
147
override fun writePacket(packet: ByteReadPacket)
148
149
/**
150
* Write a UTF-8 string to the packet.
151
* @param text string to write
152
*/
153
fun writeText(text: String)
154
155
/**
156
* Write a UTF-8 string followed by a line separator.
157
* @param text string to write
158
*/
159
fun writeTextLine(text: String)
160
}
161
```
162
163
**Usage Examples:**
164
165
```kotlin
166
import io.ktor.utils.io.core.*
167
168
// Build a packet with mixed data types
169
val builder = BytePacketBuilder()
170
builder.writeByte(0x42)
171
builder.writeInt(12345)
172
builder.writeText("Hello")
173
builder.append(' ')
174
builder.append("World")
175
176
val packet = builder.build()
177
178
// Or use fluent chaining
179
val chainedPacket = BytePacketBuilder()
180
.append("User: ")
181
.append("Alice")
182
.build()
183
184
// Check builder state
185
println("Size: ${builder.size} bytes")
186
println("Is empty: ${builder.isEmpty}")
187
```
188
189
### buildPacket Function
190
191
DSL function for creating packets with a builder block.
192
193
```kotlin { .api }
194
/**
195
* Create a byte packet using a builder block.
196
* Provides a clean DSL for packet construction.
197
* @param block builder operations to perform
198
* @return new immutable ByteReadPacket
199
*/
200
inline fun buildPacket(block: BytePacketBuilder.() -> Unit): ByteReadPacket
201
```
202
203
**Usage Examples:**
204
205
```kotlin
206
import io.ktor.utils.io.core.*
207
208
// Build packet with DSL
209
val packet = buildPacket {
210
writeByte(0xFF.toByte())
211
writeInt(42)
212
writeText("Hello World")
213
writeFloat(3.14f)
214
}
215
216
// Build a structured data packet
217
val userPacket = buildPacket {
218
writeInt(1001) // User ID
219
writeText("Alice") // Username
220
writeByte(25) // Age
221
writeDouble(175.5) // Height
222
}
223
224
// Read the packet back
225
val userId = userPacket.readInt()
226
val username = userPacket.readText()
227
val age = userPacket.readByte()
228
val height = userPacket.readDouble()
229
```
230
231
### Packet Factory Functions
232
233
Factory functions for creating packets from various data sources.
234
235
```kotlin { .api }
236
/**
237
* Create a ByteReadPacket from a byte array.
238
* @param array source data
239
* @param offset starting position in array
240
* @param length number of bytes to use
241
* @return new packet containing the specified data
242
*/
243
fun ByteReadPacket(array: ByteArray, offset: Int, length: Int): ByteReadPacket
244
245
/**
246
* Create a ByteReadPacket from entire byte array.
247
* @param array source data
248
* @return new packet containing all array data
249
*/
250
fun ByteReadPacket(array: ByteArray): ByteReadPacket
251
```
252
253
### Input Class (Deprecated Base)
254
255
Abstract base class for reading byte sequences with chunked buffer management.
256
257
```kotlin { .api }
258
/**
259
* Abstract base class for sequential byte reading operations.
260
* @deprecated Direct usage discouraged, use ByteReadPacket instead
261
*/
262
@Deprecated("Use ByteReadPacket and related APIs instead")
263
abstract class Input : Closeable {
264
/** True when no more bytes are available for reading */
265
val endOfInput: Boolean
266
267
/** Total bytes remaining to be read */
268
val remaining: Long
269
270
/**
271
* Read a single byte.
272
* @return byte value
273
* @throws EOFException if no more bytes available
274
*/
275
fun readByte(): Byte
276
277
/**
278
* Read a 16-bit short value in big-endian byte order.
279
* @return short value
280
*/
281
fun readShort(): Short
282
283
/**
284
* Read a 32-bit int value in big-endian byte order.
285
* @return int value
286
*/
287
fun readInt(): Int
288
289
/**
290
* Read a 64-bit long value in big-endian byte order.
291
* @return long value
292
*/
293
fun readLong(): Long
294
295
/**
296
* Read a 32-bit float value in big-endian byte order.
297
* @return float value
298
*/
299
fun readFloat(): Float
300
301
/**
302
* Read a 64-bit double value in big-endian byte order.
303
* @return double value
304
*/
305
fun readDouble(): Double
306
307
/**
308
* Read bytes into a destination array.
309
* @param dst destination array
310
* @param offset starting position in destination
311
* @param length maximum bytes to read
312
* @return actual bytes read
313
*/
314
fun readAvailable(dst: ByteArray, offset: Int, length: Int): Int
315
316
/**
317
* Read exactly the specified number of bytes.
318
* @param dst destination array
319
* @param offset starting position in destination
320
* @param length exact bytes to read
321
* @throws EOFException if not enough bytes available
322
*/
323
fun readFully(dst: ByteArray, offset: Int, length: Int)
324
325
/**
326
* Discard up to n bytes from input.
327
* @param n maximum bytes to discard
328
* @return actual bytes discarded
329
*/
330
fun discard(n: Int): Int
331
332
/**
333
* Discard exactly n bytes from input.
334
* @param n exact bytes to discard
335
* @throws EOFException if not enough bytes available
336
*/
337
fun discardExact(n: Int)
338
339
/**
340
* Peek at the next byte without consuming it.
341
* @return next byte value or -1 if no more bytes
342
*/
343
fun tryPeek(): Int
344
345
/**
346
* Read UTF-8 text with character limits.
347
* @param min minimum characters to read
348
* @param max maximum characters to read
349
* @return decoded string
350
*/
351
fun readText(min: Int = 0, max: Int = Int.MAX_VALUE): String
352
353
/**
354
* Read exactly the specified number of UTF-8 characters.
355
* @param exactCharacters exact number of characters
356
* @return decoded string
357
*/
358
fun readTextExact(exactCharacters: Int): String
359
}
360
```
361
362
### Output Class (Deprecated Base)
363
364
Abstract base class for writing byte sequences.
365
366
```kotlin { .api }
367
/**
368
* Abstract base class for sequential byte writing operations.
369
* @deprecated Direct usage discouraged, use BytePacketBuilder instead
370
*/
371
@Deprecated("Use BytePacketBuilder and related APIs instead")
372
abstract class Output : Appendable, Closeable {
373
/**
374
* Write a single byte.
375
* @param v byte value to write
376
*/
377
abstract fun writeByte(v: Byte)
378
379
/**
380
* Write bytes from a source array.
381
* @param src source array
382
* @param offset starting position in source
383
* @param length number of bytes to write
384
*/
385
fun writeFully(src: ByteArray, offset: Int, length: Int)
386
387
/**
388
* Write all bytes from a packet.
389
* @param packet source packet to write
390
*/
391
abstract fun writePacket(packet: ByteReadPacket)
392
393
/**
394
* Flush any pending writes immediately.
395
*/
396
abstract fun flush()
397
398
/**
399
* Append a character as UTF-8.
400
* @param value character to append
401
* @return this output for chaining
402
*/
403
override fun append(value: Char): Appendable
404
405
/**
406
* Append a character sequence as UTF-8.
407
* @param value sequence to append
408
* @return this output for chaining
409
*/
410
override fun append(value: CharSequence?): Appendable
411
}
412
```
413
414
### Constants and Configuration
415
416
```kotlin { .api }
417
/**
418
* Platform-specific maximum size for single copy operations.
419
* Used internally for optimizing bulk operations.
420
*/
421
expect val PACKET_MAX_COPY_SIZE: Int
422
```
423
424
**Advanced Usage Examples:**
425
426
```kotlin
427
import io.ktor.utils.io.core.*
428
import io.ktor.utils.io.pool.*
429
430
// Using object pool for builders
431
val pool = ObjectPool.NoPool<BytePacketBuilder>()
432
433
pool.useInstance { builder ->
434
builder.writeInt(42)
435
builder.writeText("Pooled packet")
436
val packet = builder.build()
437
438
// Use packet...
439
val value = packet.readInt()
440
val text = packet.readText()
441
}
442
443
// Creating packets from different sources
444
val emptyPacket = ByteReadPacket.Empty
445
val arrayPacket = ByteReadPacket(byteArrayOf(1, 2, 3))
446
val partialPacket = ByteReadPacket(byteArrayOf(1, 2, 3, 4, 5), offset = 1, length = 3)
447
448
// Chaining packet operations
449
val finalPacket = buildPacket {
450
// Add header
451
writeInt(0x12345678) // Magic number
452
writeShort(1) // Version
453
454
// Add payload
455
val payload = buildPacket {
456
writeText("Nested packet content")
457
writeDouble(System.currentTimeMillis().toDouble())
458
}
459
writePacket(payload)
460
461
// Add footer
462
writeInt(size) // Content size
463
}
464
```