or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffer.mdbytestring.mdfilesystem.mdhashing.mdindex.mdjvm-extensions.mdsources-sinks.md

sources-sinks.mddocs/

0

# Source and Sink Streaming

1

2

Source and Sink are Okio's streaming I/O abstractions. Sources supply bytes while Sinks receive bytes. Their buffered variants provide convenient methods for reading and writing common data types with automatic buffering for efficiency.

3

4

## Capabilities

5

6

### Source Interface

7

8

Basic interface for reading streams of bytes.

9

10

```kotlin { .api }

11

/**

12

* Supplies a stream of bytes

13

* Similar to InputStream but simpler and more efficient

14

*/

15

interface Source : Closeable {

16

/**

17

* Reads bytes from this source into the sink buffer

18

* @param sink Buffer to read bytes into

19

* @param byteCount Number of bytes to attempt to read

20

* @return Number of bytes actually read, or -1 if exhausted

21

* @throws IOException if an I/O error occurs

22

*/

23

@Throws(IOException::class)

24

fun read(sink: Buffer, byteCount: Long): Long

25

26

/**

27

* Returns the timeout policy for this source

28

* @return The timeout instance controlling read operations

29

*/

30

fun timeout(): Timeout

31

32

/**

33

* Closes this source and releases resources

34

* @throws IOException if an error occurs during closing

35

*/

36

@Throws(IOException::class)

37

override fun close()

38

}

39

```

40

41

### Sink Interface

42

43

Basic interface for writing streams of bytes.

44

45

```kotlin { .api }

46

/**

47

* Receives a stream of bytes

48

* Similar to OutputStream but simpler and more efficient

49

*/

50

interface Sink : Closeable {

51

/**

52

* Writes bytes from the source buffer to this sink

53

* @param source Buffer containing bytes to write

54

* @param byteCount Number of bytes to write

55

* @throws IOException if an I/O error occurs

56

*/

57

@Throws(IOException::class)

58

fun write(source: Buffer, byteCount: Long)

59

60

/**

61

* Flushes any buffered bytes to the underlying sink

62

* @throws IOException if an I/O error occurs

63

*/

64

@Throws(IOException::class)

65

fun flush()

66

67

/**

68

* Returns the timeout policy for this sink

69

* @return The timeout instance controlling write operations

70

*/

71

fun timeout(): Timeout

72

73

/**

74

* Closes this sink and releases resources

75

* @throws IOException if an error occurs during closing

76

*/

77

@Throws(IOException::class)

78

override fun close()

79

}

80

```

81

82

### BufferedSource Interface

83

84

Source with internal buffering for efficient reading operations.

85

86

```kotlin { .api }

87

/**

88

* Source with an internal buffer for efficient reading

89

* Provides convenient methods for reading common data types

90

*/

91

interface BufferedSource : Source {

92

/**

93

* Internal buffer used for buffering operations

94

*/

95

val buffer: Buffer

96

97

/**

98

* Checks if this source is exhausted (no more bytes available)

99

* @return true if no more bytes can be read

100

* @throws IOException if an I/O error occurs

101

*/

102

@Throws(IOException::class)

103

fun exhausted(): Boolean

104

105

/**

106

* Ensures at least byteCount bytes are buffered

107

* @param byteCount Minimum number of bytes to buffer

108

* @throws EOFException if insufficient bytes are available

109

* @throws IOException if an I/O error occurs

110

*/

111

@Throws(IOException::class)

112

fun require(byteCount: Long)

113

114

/**

115

* Attempts to buffer at least byteCount bytes

116

* @param byteCount Number of bytes to attempt to buffer

117

* @return true if the requested bytes are available

118

* @throws IOException if an I/O error occurs

119

*/

120

@Throws(IOException::class)

121

fun request(byteCount: Long): Boolean

122

123

/**

124

* Reads and removes a single byte

125

* @return Byte value

126

* @throws EOFException if source is exhausted

127

* @throws IOException if an I/O error occurs

128

*/

129

@Throws(IOException::class)

130

fun readByte(): Byte

131

132

/**

133

* Reads and removes a 16-bit integer in big-endian format

134

* @return Short value

135

* @throws EOFException if insufficient bytes available

136

* @throws IOException if an I/O error occurs

137

*/

138

@Throws(IOException::class)

139

fun readShort(): Short

140

141

/**

142

* Reads and removes a 16-bit integer in little-endian format

143

* @return Short value

144

* @throws EOFException if insufficient bytes available

145

* @throws IOException if an I/O error occurs

146

*/

147

@Throws(IOException::class)

148

fun readShortLe(): Short

149

150

/**

151

* Reads and removes a 32-bit integer in big-endian format

152

* @return Int value

153

* @throws EOFException if insufficient bytes available

154

* @throws IOException if an I/O error occurs

155

*/

156

@Throws(IOException::class)

157

fun readInt(): Int

158

159

/**

160

* Reads and removes a 32-bit integer in little-endian format

161

* @return Int value

162

* @throws EOFException if insufficient bytes available

163

* @throws IOException if an I/O error occurs

164

*/

165

@Throws(IOException::class)

166

fun readIntLe(): Int

167

168

/**

169

* Reads and removes a 64-bit integer in big-endian format

170

* @return Long value

171

* @throws EOFException if insufficient bytes available

172

* @throws IOException if an I/O error occurs

173

*/

174

@Throws(IOException::class)

175

fun readLong(): Long

176

177

/**

178

* Reads and removes a 64-bit integer in little-endian format

179

* @return Long value

180

* @throws EOFException if insufficient bytes available

181

* @throws IOException if an I/O error occurs

182

*/

183

@Throws(IOException::class)

184

fun readLongLe(): Long

185

186

/**

187

* Reads all remaining bytes as UTF-8 string

188

* @return String representation of remaining bytes

189

* @throws IOException if an I/O error occurs

190

*/

191

@Throws(IOException::class)

192

fun readUtf8(): String

193

194

/**

195

* Reads and removes the specified number of UTF-8 bytes

196

* @param byteCount Number of bytes to read

197

* @return String representation of the bytes

198

* @throws EOFException if insufficient bytes available

199

* @throws IOException if an I/O error occurs

200

*/

201

@Throws(IOException::class)

202

fun readUtf8(byteCount: Long): String

203

204

/**

205

* Reads a UTF-8 line, ending with \n or \r\n

206

* @return String line without line terminator, or null if exhausted

207

* @throws IOException if an I/O error occurs

208

*/

209

@Throws(IOException::class)

210

fun readUtf8Line(): String?

211

212

/**

213

* Reads a UTF-8 line, requiring a line terminator

214

* @param limit Maximum line length to prevent excessive memory usage

215

* @return String line without line terminator

216

* @throws EOFException if no line terminator found within limit

217

* @throws IOException if an I/O error occurs

218

*/

219

@Throws(IOException::class)

220

fun readUtf8LineStrict(limit: Long = Long.MAX_VALUE): String

221

222

/**

223

* Skips the specified number of bytes

224

* @param byteCount Number of bytes to skip

225

* @throws EOFException if insufficient bytes to skip

226

* @throws IOException if an I/O error occurs

227

*/

228

@Throws(IOException::class)

229

fun skip(byteCount: Long)

230

231

/**

232

* Reads all remaining bytes as ByteString

233

* @return ByteString containing all remaining bytes

234

* @throws IOException if an I/O error occurs

235

*/

236

@Throws(IOException::class)

237

fun readByteString(): ByteString

238

239

/**

240

* Reads the specified number of bytes as ByteString

241

* @param byteCount Number of bytes to read

242

* @return ByteString containing the specified bytes

243

* @throws EOFException if insufficient bytes available

244

* @throws IOException if an I/O error occurs

245

*/

246

@Throws(IOException::class)

247

fun readByteString(byteCount: Long): ByteString

248

249

/**

250

* Selects from the given options, consuming the selected option from this source

251

* @param options Options containing ByteStrings to match against

252

* @return Index of the selected option, or -1 if none match

253

* @throws IOException if an I/O error occurs

254

*/

255

@Throws(IOException::class)

256

fun select(options: Options): Int

257

258

/**

259

* Selects from the given typed options, consuming the selected option from this source

260

* @param options TypedOptions containing values to match against

261

* @return The selected value, or null if none match

262

* @throws IOException if an I/O error occurs

263

*/

264

@Throws(IOException::class)

265

fun <T : Any> select(options: TypedOptions<T>): T?

266

267

/**

268

* Reads all remaining bytes into a byte array

269

* @return Byte array containing all remaining bytes

270

* @throws IOException if an I/O error occurs

271

*/

272

@Throws(IOException::class)

273

fun readByteArray(): ByteArray

274

275

/**

276

* Reads the specified number of bytes into a byte array

277

* @param byteCount Number of bytes to read

278

* @return Byte array containing the specified bytes

279

* @throws EOFException if insufficient bytes available

280

* @throws IOException if an I/O error occurs

281

*/

282

@Throws(IOException::class)

283

fun readByteArray(byteCount: Long): ByteArray

284

285

/**

286

* Creates a new source that reads a subset of bytes from this source

287

* Does not consume bytes from this source until the returned source is read

288

* @return New BufferedSource for peeking ahead

289

*/

290

fun peek(): BufferedSource

291

}

292

```

293

294

### BufferedSink Interface

295

296

Sink with internal buffering for efficient writing operations.

297

298

```kotlin { .api }

299

/**

300

* Sink with an internal buffer for efficient writing

301

* Provides convenient methods for writing common data types

302

*/

303

interface BufferedSink : Sink {

304

/**

305

* Internal buffer used for buffering operations

306

*/

307

val buffer: Buffer

308

309

/**

310

* Writes a ByteString to this sink

311

* @param byteString ByteString to write

312

* @return This sink for method chaining

313

* @throws IOException if an I/O error occurs

314

*/

315

@Throws(IOException::class)

316

fun write(byteString: ByteString): BufferedSink

317

318

/**

319

* Writes a portion of a ByteString to this sink

320

* @param byteString ByteString to write from

321

* @param offset Starting position in ByteString

322

* @param byteCount Number of bytes to write

323

* @return This sink for method chaining

324

* @throws IOException if an I/O error occurs

325

*/

326

@Throws(IOException::class)

327

fun write(byteString: ByteString, offset: Int, byteCount: Int): BufferedSink

328

329

/**

330

* Writes a byte array to this sink

331

* @param source Byte array to write

332

* @return This sink for method chaining

333

* @throws IOException if an I/O error occurs

334

*/

335

@Throws(IOException::class)

336

fun write(source: ByteArray): BufferedSink

337

338

/**

339

* Writes a portion of a byte array to this sink

340

* @param source Byte array to write from

341

* @param offset Starting position in array

342

* @param byteCount Number of bytes to write

343

* @return This sink for method chaining

344

* @throws IOException if an I/O error occurs

345

*/

346

@Throws(IOException::class)

347

fun write(source: ByteArray, offset: Int, byteCount: Int): BufferedSink

348

349

/**

350

* Writes all bytes from a source to this sink

351

* @param source Source to read all bytes from

352

* @return Number of bytes written

353

* @throws IOException if an I/O error occurs

354

*/

355

@Throws(IOException::class)

356

fun writeAll(source: Source): Long

357

358

/**

359

* Writes bytes from a source to this sink

360

* @param source Source to read bytes from

361

* @param byteCount Number of bytes to write

362

* @return This sink for method chaining

363

* @throws IOException if an I/O error occurs

364

*/

365

@Throws(IOException::class)

366

fun write(source: Source, byteCount: Long): BufferedSink

367

368

/**

369

* Writes a single byte

370

* @param b Byte value to write

371

* @return This sink for method chaining

372

* @throws IOException if an I/O error occurs

373

*/

374

@Throws(IOException::class)

375

fun writeByte(b: Int): BufferedSink

376

377

/**

378

* Writes a 16-bit integer in big-endian format

379

* @param s Short value to write

380

* @return This sink for method chaining

381

* @throws IOException if an I/O error occurs

382

*/

383

@Throws(IOException::class)

384

fun writeShort(s: Int): BufferedSink

385

386

/**

387

* Writes a 16-bit integer in little-endian format

388

* @param s Short value to write

389

* @return This sink for method chaining

390

* @throws IOException if an I/O error occurs

391

*/

392

@Throws(IOException::class)

393

fun writeShortLe(s: Int): BufferedSink

394

395

/**

396

* Writes a 32-bit integer in big-endian format

397

* @param i Int value to write

398

* @return This sink for method chaining

399

* @throws IOException if an I/O error occurs

400

*/

401

@Throws(IOException::class)

402

fun writeInt(i: Int): BufferedSink

403

404

/**

405

* Writes a 32-bit integer in little-endian format

406

* @param i Int value to write

407

* @return This sink for method chaining

408

* @throws IOException if an I/O error occurs

409

*/

410

@Throws(IOException::class)

411

fun writeIntLe(i: Int): BufferedSink

412

413

/**

414

* Writes a 64-bit integer in big-endian format

415

* @param v Long value to write

416

* @return This sink for method chaining

417

* @throws IOException if an I/O error occurs

418

*/

419

@Throws(IOException::class)

420

fun writeLong(v: Long): BufferedSink

421

422

/**

423

* Writes a 64-bit integer in little-endian format

424

* @param v Long value to write

425

* @return This sink for method chaining

426

* @throws IOException if an I/O error occurs

427

*/

428

@Throws(IOException::class)

429

fun writeLongLe(v: Long): BufferedSink

430

431

/**

432

* Writes a string as UTF-8 bytes

433

* @param string String to write

434

* @return This sink for method chaining

435

* @throws IOException if an I/O error occurs

436

*/

437

@Throws(IOException::class)

438

fun writeUtf8(string: String): BufferedSink

439

440

/**

441

* Writes a portion of a string as UTF-8 bytes

442

* @param string String to write from

443

* @param beginIndex Starting character index

444

* @param endIndex Ending character index

445

* @return This sink for method chaining

446

* @throws IOException if an I/O error occurs

447

*/

448

@Throws(IOException::class)

449

fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): BufferedSink

450

451

/**

452

* Writes a UTF-8 code point

453

* @param codePoint Unicode code point to write

454

* @return This sink for method chaining

455

* @throws IOException if an I/O error occurs

456

*/

457

@Throws(IOException::class)

458

fun writeUtf8CodePoint(codePoint: Int): BufferedSink

459

460

/**

461

* Writes a long as decimal ASCII digits

462

* @param v Long value to write as decimal

463

* @return This sink for method chaining

464

* @throws IOException if an I/O error occurs

465

*/

466

@Throws(IOException::class)

467

fun writeDecimalLong(v: Long): BufferedSink

468

469

/**

470

* Writes a long as hexadecimal ASCII digits

471

* @param v Long value to write as hexadecimal

472

* @return This sink for method chaining

473

* @throws IOException if an I/O error occurs

474

*/

475

@Throws(IOException::class)

476

fun writeHexadecimalUnsignedLong(v: Long): BufferedSink

477

478

/**

479

* Emits buffered bytes to the underlying sink

480

* @return This sink for method chaining

481

* @throws IOException if an I/O error occurs

482

*/

483

@Throws(IOException::class)

484

fun emit(): BufferedSink

485

486

/**

487

* Emits complete segments to the underlying sink

488

* @return This sink for method chaining

489

* @throws IOException if an I/O error occurs

490

*/

491

@Throws(IOException::class)

492

fun emitCompleteSegments(): BufferedSink

493

}

494

```

495

496

### Options for Selection

497

498

Classes for efficient byte string selection from buffered sources.

499

500

```kotlin { .api }

501

/**

502

* An indexed set of byte strings for efficient selection

503

* Used with BufferedSource.select() for pattern matching

504

*/

505

class Options private constructor() : AbstractList<ByteString>, RandomAccess {

506

override val size: Int

507

override fun get(index: Int): ByteString

508

509

companion object {

510

/**

511

* Creates Options from a list of ByteStrings

512

* @param byteStrings ByteStrings to select from

513

* @return Options instance for selection

514

*/

515

fun of(vararg byteStrings: ByteString): Options

516

}

517

}

518

519

/**

520

* A typed set of values that may be selected from buffered sources

521

* Maps ByteString patterns to typed values

522

*/

523

class TypedOptions<T : Any> private constructor() : AbstractList<T>, RandomAccess {

524

override val size: Int

525

override fun get(index: Int): T

526

527

companion object {

528

/**

529

* Creates TypedOptions from values and an encoding function

530

* @param values Collection of values to select from

531

* @param encode Function to convert values to ByteStrings

532

* @return TypedOptions instance for typed selection

533

*/

534

inline fun <T : Any> of(

535

values: Iterable<T>,

536

encode: (T) -> ByteString

537

): TypedOptions<T>

538

}

539

}

540

```

541

542

### Creating Buffered Sources and Sinks

543

544

Utility functions for creating buffered sources and sinks.

545

546

```kotlin { .api }

547

/**

548

* Wraps a Source with buffering

549

* @return BufferedSource that buffers reads from this source

550

*/

551

fun Source.buffer(): BufferedSource

552

553

/**

554

* Wraps a Sink with buffering

555

* @return BufferedSink that buffers writes to this sink

556

*/

557

fun Sink.buffer(): BufferedSink

558

559

/**

560

* Creates a sink that discards all bytes written to it

561

* @return Sink that ignores all data

562

*/

563

fun blackholeSink(): Sink

564

565

/**

566

* Execute block then close this resource. This will be closed even if block throws.

567

* This is similar to Java's try-with-resources but more concise.

568

* @param block Function to execute with this resource

569

* @return Result of executing the block

570

* @throws Exception any exception thrown by block or during closing

571

*/

572

inline fun <T : Closeable?, R> T.use(block: (T) -> R): R

573

```

574

575

**Usage Examples:**

576

577

```kotlin

578

// Basic source/sink usage

579

val buffer = Buffer()

580

val source: Source = buffer

581

val sink: Sink = buffer

582

583

// Write data

584

sink.write(Buffer().writeUtf8("Hello"), 5)

585

sink.flush()

586

587

// Read data

588

val readBuffer = Buffer()

589

val bytesRead = source.read(readBuffer, 1024)

590

println(readBuffer.readUtf8())

591

592

// Buffered operations

593

val bufferedSource = source.buffer()

594

val line = bufferedSource.readUtf8Line()

595

val number = bufferedSource.readInt()

596

597

val bufferedSink = sink.buffer()

598

bufferedSink.writeUtf8("Hello World")

599

.writeInt(42)

600

.writeLong(123456789L)

601

.flush()

602

603

// Resource management with use

604

FileSystem.SYSTEM.source("/tmp/file.txt".toPath()).use { source ->

605

val bufferedSource = source.buffer()

606

return bufferedSource.readUtf8()

607

}

608

609

// Chaining use with buffer

610

FileSystem.SYSTEM.sink("/tmp/output.txt".toPath()).buffer().use { sink ->

611

sink.writeUtf8("Hello World")

612

sink.writeInt(42)

613

}

614

615

// Using Options for selection

616

val options = Options.of("GET".encodeUtf8(), "POST".encodeUtf8(), "PUT".encodeUtf8())

617

val buffer = Buffer().writeUtf8("POST /api/users")

618

val selected = buffer.select(options)

619

when (selected) {

620

0 -> println("GET request")

621

1 -> println("POST request") // This will be selected

622

2 -> println("PUT request")

623

-1 -> println("No match")

624

}

625

626

// Using TypedOptions for typed selection

627

enum class HttpMethod { GET, POST, PUT }

628

val typedOptions = TypedOptions.of(

629

listOf(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT)

630

) { it.name.encodeUtf8() }

631

val method = buffer.select(typedOptions)

632

println("Selected method: $method")

633

```