• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Change Log
2==========
3
4## Version 3.10.2
5
6_2025-01-08_
7
8 * Fix: `okio-nodefilesystem` artifact is no longer empty.
9
10
11## Version 3.10.1
12
13_2025-01-07_
14
15 * New: `FileSystem.close()` may prevent future access and/or clean up associated resources depending on the backing implementation. `FakeFileSystem` will prevent future operations once closed.
16 * `InputStream`s created from `BufferedSource.inputStream()` now have a more efficient version of `InputStream.transferTo()` which reduces memory copies.
17 * `okio-nodefilesystem` is no longer publised as a JS project, but a Kotlin multiplatform project with only a JS target. ~This change should not affect consumers in any way, and is motivated by the Kotlin Gradle plugin deprecating the JS-only plugin.~ Please use 3.10.2 to ensure this change actually does not affect your builds.
18
19
20## Version 3.10.0
21
22_2025-01-06_
23
24This version is equivalent to the subsequent 3.10.1, but it did not fully publish to Maven Central due to infrastructure problems.
25
26
27## Version 3.9.1
28
29_2024-09-12_
30
31 * Fix: Support paths containing a single dot (".") in `Path.relativeTo`.
32 * Fix: Do not read from the upstream source when a 0-byte read is requested.
33 * Fix: Update kotlinx.datetime to 0.6.0 to correct a Gradle module metadata problem with 0.5.0.
34   Note: this artifact is only used in 'okio-fakefilesystem' and 'okio-nodefilesystem' and not in the Okio core.
35
36
37## Version 3.9.0
38
39_2024-03-12_
40
41 * New: `FileSystem.SYSTEM` can be used in source sets that target both Kotlin/Native and
42   Kotlin/JVM. Previously, we had this symbol in each source set but it wasn't available to
43   common source sets.
44 * New: `COpaquePointer.readByteString(...)` creates a ByteString from a memory address.
45 * New: Support `InflaterSource`, `DeflaterSink`, `GzipSink`, and `GzipSource` in Kotlin/Native.
46 * New: Support openZip() on Kotlin/Native. One known bug in this implementation is that
47   `FileMetadata.lastModifiedAtMillis()` is interpreted as UTC and not the host machine's time zone.
48 * New: Prefer NTFS timestamps in ZIP file systems' metadata. This avoids the time zone problems
49   of ZIP's built-in DOS timestamps, and the 2038 time bombs of ZIP's extended timestamps.
50 * Fix: Don't leak file handles to opened JAR files open in `FileSystem.RESOURCES`.
51 * Fix: Don't throw a `NullPointerException` if `Closeable.use { ... }` returns null.
52
53
54## Version 3.8.0
55
56_2024-02-09_
57
58 * New: `TypedOptions` works like `Options`, but it returns a `T` rather than an index.
59 * Fix: Don't leave sinks open when there's a race in `Pipe.fold()`.
60
61
62## Version 3.7.0
63
64_2023-12-16_
65
66 * New: `Timeout.cancel()` prevents a timeout from firing.
67 * Breaking: Drop the `watchosX86` Kotlin/Native target. From [the Kotlin blog][watchosX86],
68   _‘This is an obsolete simulator for Intel Macs. Use the watchosX64 target instead.’_
69 * New: Add the `watchosDeviceArm64` Kotlin/Native target.
70 * New: `Timeout` APIs that accept `kotlin.time.Duration`.
71 * Upgrade: [Kotlin 1.9.21][kotlin_1_9_21].
72
73
74## Version 3.6.0
75
76_2023-10-01_
77
78 * Fix: Don't leak file handles when using `metadata` functions on `ZipFileSystem`. We had a bug
79   where we were closing the `.zip` file, but not a stream inside of it. We would have prevented
80   this bug if only we’d used `FakeFileSystem.checkNoOpenFiles()` in our tests!
81 * Fix: Don't build an index of a class loader's resources in `ResourceFileSystem.read()`. This
82   operation doesn't need this index, and building it is potentially expensive.
83 * New: Experimentally support Linux on ARM64 for Kotlin/Native targets (`linuxArm64`). Note that
84   we haven't yet added CI test coverage for this platform.
85 * Upgrade: [Kotlin 1.9.10][kotlin_1_9_10].
86
87
88## Version 1.17.6
89
90_2023-10-01_
91
92 * Fix: Don't crash decoding GZIP files when the optional extra data (`XLEN`) is 32 KiB or larger.
93
94
95## Version 3.5.0
96
97_2023-08-02_
98
99 * New: Support the WebAssembly (WASM) platform. Okio's support for WASM is experimental, but
100   improving, just like Kotlin's own support for WASM.
101 * New: Adapt WebAssembly System Interface (WASI) API's as an Okio FileSystem using
102   `WasiFileSystem`. This is in the new `okio-wasifilesystem` module. It requires the [preview1]
103   WASI API. We’ll make backwards-incompatible upgrades to new WASI API versions as they become
104   available.
105 * Fix: Return relative paths in the NIO adapter FileSystem when required. `FileSystem.list()`
106   had always returned absolute paths, even when the target directory was supplied as a relative
107   path.
108 * Fix: Don't crash when reading into an empty array using `FileHandle` on Kotlin/Native.
109 * Upgrade: [Kotlin 1.9.0][kotlin_1_9_0].
110
111
112## Version 3.4.0
113
114_2023-07-07_
115
116 * New: Adapt a Java NIO FileSystem (`java.nio.file.FileSystem`) as an Okio FileSystem using
117   `fileSystem.asOkioFileSystem()`.
118 * New: Adapt Android’s `AssetManager` as an Okio FileSystem using `AssetFileSystem`. This is in the
119   new `okio-assetfilesystem` module. Android applications should prefer this over
120   `FileSystem.RESOURCES` as it’s faster to load.
121 * Fix: Don't crash decoding GZIP files when the optional extra data (`XLEN`) is 32 KiB or larger.
122 * Fix: Resolve symlinks in `FakeFileSystem.canonicalize()`.
123 * Fix: Report the correct `createdAtMillis` in `NodeJsFileSystem` file metadata. We were
124   incorrectly using `ctimeMs`, where `c` means _changed_, not _created_.
125 * Fix: `UnsafeCursor` is now `Closeable`.
126
127
128## Version 3.3.0
129
130_2023-01-07_
131
132 * Fix: Don't leak resources when `use {}` is used with a non-local return. We introduced this
133   performance and stability bug by not considering that non-local returns execute neither the
134   `return` nor `catch` control flows.
135 * Fix: Use a sealed interface for `BufferedSink` and `BufferedSource`. These were never intended
136   for end-users to implement, and we're happy that Kotlin now allows us to express that in our API.
137 * New: Change internal locks from `synchronized` to `ReentrantLock` and `Condition`. We expect this
138   to improve help when using Okio with Java virtual threads ([Project Loom][loom]).
139 * Upgrade: [Kotlin 1.8.0][kotlin_1_8_0].
140
141
142## Version 3.2.0
143
144_2022-06-26_
145
146 * Fix: Configure the multiplatform artifact (`com.squareup.okio:okio:3.x.x`) to depend on the
147   JVM artifact (`com.squareup.okio:okio-jvm:3.x.x`) for Maven builds. This should work-around an
148   issue where Maven doesn't interpret Gradle metadata.
149 * Fix: Change `CipherSource` and `CipherSink` to recover if the cipher doesn't support streaming.
150   This should work around a crash with AES/GCM ciphers on Android.
151 * New: Enable compatibility with non-hierarchical projects.
152
153
154## Version 3.1.0
155
156_2022-04-19_
157
158 * Upgrade: [Kotlin 1.6.20][kotlin_1_6_20].
159 * New: Support [Hierarchical project structure][hierarchical_projects]. If you're using Okio in a
160   multiplatform project please upgrade your project to Kotlin 1.6.20 (or newer) to take advantage
161   of this. With hierarchical projects it's easier to use properties like `FileSystem.SYSTEM` that
162   are available on most Okio platforms but not all of them.
163 * New: `ForwardingSource` is now available on all platforms.
164 * New: The `watchosX64` platform is now supported.
165 * Fix: Don't crash in `NSData.toByteString()' when the input is empty.
166 * Fix: Support empty ZIP files in `FileSystem.openZip()`.
167 * Fix: Throw in `canonicalize()` of ZIP file systems if the path doesn't exist.
168 * Fix: Don't require ZIP files start with a local file header.
169 * New: `okio.ProtocolException` is a new exception type for multiplatform users. (It is aliased to
170   `java.net.ProtocolException` on JVM platforms).
171
172
173## Version 3.0.0
174
175_2021-10-28_
176
177This is the first stable release of Okio 3.x. This release is strongly backwards-compatible with
178Okio 2.x, and the new major version signifies new capabilities more than it does backwards
179incompatibility.
180
181Most users should be able to upgrade from 2.x by just changing the version. If you're using Okio
182in a Kotlin Multiplatform project, you'll need to drop the `-multiplatform` suffix in your Gradle
183dependencies.
184
185 * New: Remove `@ExperimentalFileSystem`. This annotation is no longer necessary as the file system
186   is no longer experimental!
187 * New: Path no longer aggressively normalizes `..` segments. Use `Path.normalize()` to apply these
188   based on the content of the path, or `FileSystem.canonicalize()` to do it honoring any symlinks
189   on a particular file system.
190 * New: Publish a [bill of materials (BOM)][bom] for Okio. Depend on this from Gradle or Maven to
191   keep all of your Okio artifacts on the same version, even if they're declared via transitive
192   dependencies. You can even omit versions when declaring other Okio dependencies.
193
194   ```kotlin
195   dependencies {
196      api(platform("com.squareup.okio:okio-bom:3.0.0"))
197      api("com.squareup.okio:okio")                // No version!
198      api("com.squareup.okio:okio-fakefilesystem") // No version!
199   }
200   ```
201
202 * New: `FileSystem.delete()` silently succeeds when deleting a file that doesn't exist. Use
203   the new `mustExist` parameter to trigger an exception instead.
204 * New: `FileSystem.createDirectories()` silently succeeds when creating a directory that already
205   exists. Use the new `mustCreate` parameter to trigger an exception instead.
206 * New: `FileSystem` offers Java-language overloads where appropriate. Previously functions that
207   had default parameters were potentially awkward to invoke from Java.
208 * New: `Timeout.intersectWith()` returns a value instead of `Unit`. This is a binary-incompatible
209   change. We expect that this public API is very rarely used outside of Okio itself.
210 * Fix: Change `BufferedSource.readDecimalLong()` to fail if the input value is just `-`. Previously
211   Okio incorrectly returned `0` for this.
212
213
214## Version 3.0.0-alpha.11
215
216_2021-10-23_
217
218 * Upgrade: [Kotlin 1.5.31][kotlin_1_5_31].
219 * Upgrade: [kotlinx-datetime 0.3.0][datetime_0_3_0]. (This is a dependency of `okio-fakefilesystem`
220   only.)
221 * New: Support creating and accessing symlinks. We were reluctant to include symlinks in our API
222   (to keep it small!) but decided that supporting them was essential to properly implement
223   recursive traversal.
224 * New: `FileMetadata.extras` can track metadata for custom `FileSystem` implementations.
225 * New: Support Apple Silicon Kotlin/Native targets (`macosArm64`, `iosSimulatorArm64`,
226   `tvosSimulatorArm64`, and `watchosSimulatorArm64`).
227 * New: `FileSystem.listRecursively()` returns a `Sequence` that includes all of a directory's
228   children, and all of their children recursively. The implementation does a lazy, depth-first
229   traversal.
230 * New: `Path.relativeTo()` computes how to get from one path to another.
231 * New: `Path.root` and `Path.segments`. These APIs decompose a path into its component parts.
232 * New: `FileSystem.listOrNull()` returns a directory's children, or null if the path doesn't
233   reference a readable directory.
234 * New: Option to fail if the file being updated doesn't already exist: `mustExist`. Use this to
235   avoid creating a new file when your intention is to update an existing file.
236 * New: Option to fail if a file being created already exists: `mustCreate`. Use this to avoid
237   updating an existing file when your intention is to create a new file.
238 * Fix: Restore support for Kotlin/JS on browser platforms. We were relying on NodeJS-only features
239   to fetch the local directory separator (`/` or `\`) and temporary directory.
240 * Fix: Don't ignore the caller's specified write offset running Okio on Kotlin/Native on Linux.
241   (`FileHandle.write()` was broken and always appended to the end of the file.)
242
243
244## Version 3.0.0-alpha.10
245
246_2021-09-09_
247
248This release drops the `-multiplatform` suffix on Kotlin Multiplatform artifacts. All artifacts now
249share the same name (like `com.squareup.okio:okio:3.0.0-alpha.10`) for both Kotlin/JVM and Kotlin
250Multiplatform.
251
252 * Fix: Don't crash in `ResourceFileSystem` when classpath `.jar` files have special characters in
253   their paths.
254
255
256## Version 3.0.0-alpha.9
257
258_2021-08-01_
259
260 * New: `ByteString.copyInto()` saves an allocation when extracting data from a `ByteString`.
261 * Fix: Create `FileHandle.protectedSize()` to match other abstract functions.
262 * Fix: Open files in binary mode on Windows. Without this, files that contain `0x1a` will be
263   truncated prematurely.
264
265
266## Version 3.0.0-alpha.8
267
268_2021-07-13_
269
270 * Fix: Don't crash on duplicate entries in a .zip file.
271 * Fix: Change `FileSystem.RESOURCES` to initialize itself lazily.
272
273
274## Version 3.0.0-alpha.7
275
276_2021-07-12_
277
278 * Fix: Change `ResourceFileSystem` to load roots eagerly. We had a bug where `list()` on the root
279   returned an empty list even if resources were present.
280 * New: `FileHandle.reposition()` can seek on a source or sink returned by that `FileHandle`.
281 * New: Move the system resources instance to `FileSystem.RESOURCES`.
282 * Upgrade: [Kotlin 1.5.20][kotlin_1_5_20].
283
284
285## Version 3.0.0-alpha.6
286
287_2021-06-01_
288
289 * New: `FileHandle` supports random access reads, writes, and resizes on files. Create an instance
290   with `FileSystem.openReadOnly()` or `FileSystem.openReadWrite()`.
291 * New: Remove `Cursor` which is obsoleted by `FileHandle`. (`UnsafeCursor` is still around!)
292 * New: Add support for the new intermediate representation (IR) artifacts in Kotlin/JS. We still
293   support the legacy artifact format.
294 * New: Support tvOS (tvosArm64, tvosX64) in multiplatform.
295 * New: Change `ResourceFileSystem` to omit `.class` files when indexing `.zip` files. We expect
296   this to lower the memory footprint of `ResourceFileSystem`.
297 * Fix: Don't crash on background thread access in Kotlin/Native. We had to apply `@SharedImmutable`
298   and run our test suite on a background thread.
299
300
301## Version 3.0.0-alpha.5
302
303_2021-04-27_
304
305 * New: Promote the `ZipFileSystem` and `ResourceFileSystem` to the main Okio module. These are
306   currently JVM-only. The `okio-zipfilesystem` module is no longer published.
307
308
309## Version 3.0.0-alpha.4
310
311_2021-04-14_
312
313 * Fix: Rename internal classes to avoid name collisions. We were seeing problems due to having
314   multiple files named `-Platform.kt`.
315
316
317## Version 3.0.0-alpha.3
318
319_2021-04-06_
320
321 * New: Move `NodeJsFileSystem` into its own module. Having it built-in prevented Okio from working
322   in a browser where there's no synchronous file system API. This is in the `okio-nodefilesystem`
323   artifact.
324
325
326## Version 3.0.0-alpha.2
327
328_2021-03-24_
329
330 * New: Require Java 8+ for Okio 3.x.
331 * New: `Cursor` supports random access reads on a `Source`.
332 * New: `FileSystem.openZip(path)` returns a file system backed by a `.zip` file. This is in the
333   `okio-zipfilesystem` artifact.
334
335
336## Version 3.0.0-alpha.1
337
338_2021-01-07_
339
340* New: Experimental file system API. The `Path`, `FileMetadata`, `FileSystem` and
341  `ForwardingFileSystem` types are subject to API changes in a future release.
342* New: Experimental `okio-fakefilesystem` artifact.
343
344
345## Version 2.10.0
346
347_2021-01-07_
348
349* New: Support Windows (mingwX64) in multiplatform.
350* New: Support watchOS (watchosArm32, watchosArm64, watchosX86) in multiplatform.
351* New: Support `HashingSource`, `HashingSink`, buffer hash functions, and `UnsafeCursor` on non-JVM
352  platforms. Previously these were all JVM-only.
353* New: Implement `Closeable` on `Sink` and `Source` on non-JVM platforms. Okio now includes a
354  multiplatform `okio.Closeable` interface and corresponding `use {}` extension. Closing resources
355  when you're done with them shouldn't be JVM-only!
356* New: `Sink.hashingSink` and `Source.hashingSource` functions that accept
357  `java.security.MessageDigest` and `javax.crypto.Mac` instances. Use these when your hash function
358  isn't built-in.
359* Fix: Don't crash with a `ShortBufferException` in `CipherSink` and `CipherSource` on Android.
360  (Android may throw a `ShortBufferException` even if the buffer is not too short. We now
361  avoid this problem!)
362* Upgrade: [Kotlin 1.4.20][kotlin_1_4_20].
363
364
365## Version 2.9.0
366
367_2020-10-04_
368
369 * Fix: Don't corrupt the `Buffer` when writing a slice of a segmented `ByteString`. We had a severe
370   bug where `ByteString` instances created with `snapshot()` and `readByteString()` incorrectly
371   adjusted the buffer's size by their full length, not the length of the slice. This would have
372   caused buffer reads to crash! We do not believe data was silently corrupted.
373 * New: `CipherSink` and `CipherSource`. Use these with `javax.crypto.Cipher` to encrypt and decrypt
374   streams of data. This is a low-level encryption API; most applications should use higher-level
375   APIs like TLS when available.
376 * New: Promote hash functions `md5`, `sha1()`, `sha512()`, and `sha256()` to common Kotlin. These
377   are currently only available on `ByteString`, multiplatform support for `HashingSource`,
378   `HashingSink`, and `Buffer` should come in a follow-up release. We wrote and optimized our own
379   implementations of these hash functions in Kotlin. On JVM and Android platforms Okio still uses
380   the platform's built-in hash functions.
381 * New: Support OSGi metadata.
382 * Upgrade: [Kotlin 1.4.10][kotlin_1_4_10].
383
384
385## Version 2.8.0
386
387_2020-08-17_
388
389 * New: Upgrade to Kotlin 1.4.0.
390
391
392## Version 2.7.0
393
394_2020-07-07_
395
396 * New: `Pipe.cancel()` causes in-progress and future reads and writes on the pipe to immediately
397   fail with an `IOException`. The streams may still be canceled normally.
398
399 * New: Enlarge Okio's internal segment pool from a fixed 64 KiB total to 64 KiB per processor. For
400   example, on an Intel i9 8-core/16-thread machine the segment pool now uses up to 1 MiB of memory.
401
402 * New: Migrate from `synchronized` to lock-free when accessing the segment pool. Combined with the
403   change above we saw throughput increase 3x on a synthetic benchmark designed to create
404   contention.
405
406
407## Version 2.6.0
408
409_2020-04-22_
410
411 * New: `InflaterSource.readOrInflate()` is like `InflaterSource.read()`, except it will return 0 if
412   consuming deflated bytes from the underlying stream did not produce new inflated bytes.
413
414
415## Version 2.5.0
416
417_2020-03-20_
418
419 * New: Upgrade to Kotlin 1.3.70.
420
421
422## Version 2.4.3
423
424_2019-12-20_
425
426 * New: Upgrade to Kotlin 1.3.61.
427
428
429## Version 2.4.2
430
431_2019-12-11_
432
433 * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary.
434   We had a bug where a sequence of reads could violate a buffer's invariants, and this could result
435   in a crash when subsequent reads encountered an unexpected empty segment.
436
437
438## Version 1.17.5
439
440_2019-12-11_
441
442 * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary.
443   We had a bug where a sequence of reads could violate a buffer's invariants, and this could result
444   in a crash when subsequent reads encountered an unexpected empty segment.
445
446
447## Version 2.4.1
448
449_2019-10-04_
450
451 * Fix: Don't cache hash code and UTF-8 string in `ByteString` on Kotlin/Native which prevented freezing.
452
453## Version 2.4.0
454
455_2019-08-26_
456
457 * New: Upgrade to Kotlin 1.3.50.
458
459
460## Version 2.3.0
461
462_2019-07-29_
463
464**This release changes our build from Kotlin-JVM to Kotlin-multiplatform (which includes JVM).**
465Both native and JavaScript platforms are unstable preview releases and subject to
466backwards-incompatible changes in forthcoming releases.
467
468To try Okio in a multiplatform project use this Maven coordinate:
469
470```kotlin
471api('com.squareup.okio:okio-multiplatform:2.3.0')
472```
473
474You’ll also need to [enable Gradle metadata][gradle_metadata] in your project's settings. The
475artifact name for JVM projects has not changed.
476
477 * New: Upgrade to Kotlin 1.3.40.
478 * Fix: Use Gradle `api` instead of `implementation` for the kotlin-stdlib dependency.
479 * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`.
480
481## Version 1.17.4
482
483_2019-04-29_
484
485 * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`.
486
487
488## Version 2.2.2
489
490_2019-01-28_
491
492 * Fix: Make `Pipe.fold()` close the underlying sink when necessary.
493
494
495## Version 1.17.3
496
497_2019-01-28_
498
499 * Fix: Make `Pipe.fold()` close the underlying sink when necessary.
500
501
502## Version 1.17.2
503
504_2019-01-17_
505
506 * Fix: Make `Pipe.fold()` flush the underlying sink.
507
508
509## Version 2.2.1
510
511_2019-01-17_
512
513 * Fix: Make `Pipe.fold()` flush the underlying sink.
514
515
516## Version 2.2.0
517
518_2019-01-16_
519
520 * New: `Throttler` limits sources and sinks to a maximum desired throughput. Multiple sources and
521   sinks can be attached to the same throttler and their combined throughput will not exceed the
522   desired throughput. Multiple throttlers can also be used on the same source or sink and they will
523   all be honored.
524
525 * New: `Pipe.fold()` replaces the actively-readable `Source` with a passively-writable `Sink`.
526   This can be used to forward one sink to a target that is initially undetermined.
527
528 * New: Optimize performance of ByteStrings created with `Buffer.snapshot()`.
529
530
531## Version 1.17.1
532
533_2019-01-16_
534
535 * Fix: Make the newly-backported `Pipe.fold()` public.
536
537
538## Version 1.17.0
539
540_2019-01-16_
541
542 * New: Backport `Pipe.fold()` to Okio 1.x.
543
544
545## Version 1.16.0
546
547_2018-10-08_
548
549 * New: Backport `BufferedSource.peek()` and `BufferedSource.getBuffer()` to Okio 1.x.
550 * Fix: Enforce timeouts when closing `AsyncTimeout` sources.
551
552
553## Version 2.1.0
554
555_2018-09-22_
556
557 * New: `BufferedSource.peek()` returns another `BufferedSource` that reads ahead on the current
558   source. Use this to process the same data multiple times.
559
560 * New: Deprecate `BufferedSource.buffer()`, replacing it with either `BufferedSource.getBuffer()`
561   (in Java) or `BufferedSource.buffer` (in Kotlin). We have done likewise for `BufferedSink`.
562   When we introduced the new extension method `Source.buffer()` in Okio 2.0 we inadvertently
563   collided with an existing method. This fixes that.
564
565 * New: Improve performance of `Buffer.writeUtf8()`. This comes alongside initial implementation of
566   UTF-8 encoding and decoding in JavaScript which [uses XOR masks][xor_utf8] for great performance.
567
568
569## Version 2.0.0
570
571_2018-08-27_
572
573This release commits to a stable 2.0 API. Read the 2.0.0-RC1 changes for advice on upgrading from
5741.x to 2.x.
575
576We've also added APIs to ease migration for Kotlin users. They use Kotlin's `@Deprecated` annotation
577to help you change call sites from the 1.x style to the 2.x style.
578
579
580## Version 2.0.0-RC1
581
582_2018-07-26_
583
584Okio 2 is a major release that upgrades the library's implementation language from Java to Kotlin.
585
586Okio 2.x is **binary-compatible** with Okio 1.x and does not change any behavior. Classes and .jar
587files compiled against 1.x can be used with 2.x without recompiling.
588
589Okio 2.x is **.java source compatible** with Okio 1.x in all but one corner case. In Okio 1.x
590`Buffer` would throw an unchecked `IllegalStateException` when attempting to read more bytes than
591available. Okio 2.x now throws a checked `EOFException` in this case. This is now consistent with
592the behavior of its `BufferedSource` interface. Java callers that don't already catch `IOException`
593will now need to.
594
595Okio 2.x is **.kt source-incompatible** with Okio 1.x. This release adopts Kotlin idioms where they
596are available.
597
598| Java                                     |  Kotlin                              | Idiom              |
599| :--------------------------------------- |  :---------------------------------- | :----------------- |
600| Buffer.getByte()                         |  operator fun Buffer.get()           | operator function  |
601| Buffer.size()                            |  val Buffer.size                     | val                |
602| ByteString.decodeBase64(String)          |  fun String.decodeBase64()           | extension function |
603| ByteString.decodeHex(String)             |  fun String.decodeHex()              | extension function |
604| ByteString.encodeString(String, Charset) |  fun String.encode(Charset)          | extension function |
605| ByteString.encodeUtf8(String)            |  fun String.encodeUtf8()             | extension function |
606| ByteString.getByte()                     |  operator fun ByteString.get()       | operator function  |
607| ByteString.of(ByteBuffer)                |  fun ByteBuffer.toByteString()       | extension function |
608| ByteString.of(byte[], int, int)          |  fun ByteArray.toByteString()        | extension function |
609| ByteString.read(InputStream, int)        |  fun InputStream.readByteString(Int) | extension function |
610| ByteString.size()                        |  val ByteString.size                 | val                |
611| DeflaterSink(Sink)                       |  fun Sink.deflater()                 | extension function |
612| ForwardingSink.delegate()                |  val ForwardingSink.delegate         | val                |
613| ForwardingSource.delegate()              |  val ForwardingSource.delegate       | val                |
614| GzipSink(Sink, Deflater)                 |  fun Sink.gzip()                     | extension function |
615| GzipSink.deflater()                      |  val GzipSink.deflater               | val                |
616| GzipSource(Source)                       |  fun Source.gzip()                   | extension function |
617| HashingSink.hash()                       |  val HashingSink.hash                | val                |
618| HashingSource.hash()                     |  val HashingSource.hash              | val                |
619| InflaterSink(Source)                     |  fun Source.inflater()               | extension function |
620| Okio.appendingSink(File)                 |  fun File.appendingSink()            | extension function |
621| Okio.blackhole()                         |  fun blackholeSink()                 | top level function |
622| Okio.buffer(Sink)                        |  fun Sink.buffer()                   | extension function |
623| Okio.buffer(Source)                      |  fun Source.buffer()                 | extension function |
624| Okio.sink(File)                          |  fun File.sink()                     | extension function |
625| Okio.sink(OutputStream)                  |  fun OutputStream.sink()             | extension function |
626| Okio.sink(Path)                          |  fun Path.sink()                     | extension function |
627| Okio.sink(Socket)                        |  fun Socket.sink()                   | extension function |
628| Okio.source(File)                        |  fun File.source()                   | extension function |
629| Okio.source(InputStream)                 |  fun InputStream.source()            | extension function |
630| Okio.source(Path)                        |  fun Path.source()                   | extension function |
631| Okio.source(Socket)                      |  fun Socket.source()                 | extension function |
632| Pipe.sink()                              |  val Pipe.sink                       | val                |
633| Pipe.source()                            |  val Pipe.source                     | val                |
634| Utf8.size(String)                        |  fun String.utf8Size()               | extension function |
635
636Okio 2.x has **similar performance** to Okio 1.x. We benchmarked both versions to find potential
637performance regressions. We found one regression and fixed it: we were using `==` instead of `===`.
638
639Other changes in this release:
640
641 * New: Add a dependency on kotlin-stdlib. Okio's transitive dependencies grow from none in 1.x to
642   three in 2.x. These are kotlin-stdlib (939 KiB), kotlin-stdlib-common (104 KiB), and JetBrains'
643   annotations (17 KiB).
644
645 * New: Change Okio to build with Gradle instead of Maven.
646
647
648## Version 1.15.0
649
650_2018-07-18_
651
652 * New: Trie-based `Buffer.select()`. This improves performance when selecting
653   among large lists of options.
654 * Fix: Retain interrupted state when throwing `InterruptedIOException`.
655
656
657## Version 1.14.0
658
659_2018-02-11_
660
661 * New: `Buffer.UnsafeCursor` provides direct access to Okio internals. This API
662   is like Okio's version of Java reflection: it's a very powerful API that can
663   be used for great things and dangerous things alike. The documentation is
664   extensive and anyone using it should review it carefully before proceeding!
665 * New: Change `BufferedSource` to implement `java.nio.ReadableByteChannel` and
666   `BufferedSink` to implement `java.nio.WritableByteChannel`. Now it's a little
667   easier to interop between Okio and NIO.
668 * New: Automatic module name of `okio` for use with the Java Platform Module
669   System.
670 * New: Optimize `Buffer.getByte()` to search backwards when doing so will be
671   more efficient.
672 * Fix: Honor the requested byte count in `InflaterSource`. Previously this
673   class could return more bytes than requested.
674 * Fix: Improve a performance bug in `AsyncTimeout.sink().write()`.
675
676
677## Version 1.13.0
678
679_2017-05-12_
680
681 * **Okio now uses `@Nullable` to annotate all possibly-null values.** We've
682   added a compile-time dependency on the JSR 305 annotations. This is a
683   [provided][maven_provided] dependency and does not need to be included in
684   your build configuration, `.jar` file, or `.apk`. We use
685   `@ParametersAreNonnullByDefault` and all parameters and return types are
686   never null unless explicitly annotated `@Nullable`.
687
688 * **Warning: this release is source-incompatible for Kotlin users.**
689   Nullability was previously ambiguous and lenient but now the compiler will
690   enforce strict null checks.
691
692
693## Version 1.12.0
694
695_2017-04-11_
696
697 * **Fix: Change Pipe's sink.flush() to not block.** Previously closing a pipe's
698   sink would block until the source had been exhausted. In practice this
699   blocked the caller for no benefit.
700 * **Fix: Change `writeUtf8CodePoint()` to emit `?` for partial surrogates.**
701   The previous behavior was inconsistent: given a malformed string with a
702   partial surrogate, `writeUtf8()` emitted `?` but `writeUtf8CodePoint()` threw
703   an `IllegalArgumentException`. Most applications will never encounter partial
704   surrogates, but for those that do this behavior was unexpected.
705 * New: Allow length of `readUtf8LineStrict()` to be limited.
706 * New: `Utf8.size()` method to get the number of bytes required to encode a
707   string as UTF-8. This may be useful for length-prefixed encodings.
708 * New: SHA-512 hash and HMAC APIs.
709
710
711## Version 1.11.0
712
713_2016-10-11_
714
715 * **Fix: The four-argument overload of `Buffer.writeString()` had a major bug
716   where it didn't respect offsets if the specified charset was UTF-8.** This
717   was because our short-circuit optimization omitted necessary offset
718   parameters.
719 * New: HMAC support in `HashingSource`, `HashingSink`, `ByteString`, and
720   `Buffer`. This makes it easy to create a keyed-hash message authentication
721   code (HMAC) wherever your data is. Unlike the other hashes, HMAC uses a
722   `ByteString` secret key for authentication.
723 * New: `ByteString.of(ByteBuffer)` makes it easier to mix NIO with Okio.
724
725
726## Version 1.10.0
727
728_2016-08-28_
729
730 * Fix: Support reading files larger than 2 GiB with `GzipSource`. Previously
731   attempting to decompress such files would fail due to an overflow when
732   validating the total length.
733 * Fix: Exit the watchdog thread after being idle for 60 seconds. This should
734   make it possible for class unloaders to fully unload Okio.
735 * New: `Okio.blackhole()` returns a sink where all bytes written are discarded.
736   This is Okio's equivalent of `/dev/null`.
737 * New: Encode a string with any charset using `ByteString.encodeString()` and
738   decode strings in any charset using `ByteString.string()`. Most applications
739   should prefer `ByteString.encodeUtf8()` and `ByteString.utf8()` unless it's
740   necessary to support a legacy charset.
741 * New: `GzipSink.deflater()` makes it possible to configure the compression
742   level.
743
744
745## Version 1.9.0
746
747_2016-07-01_
748
749 * New: `Pipe` makes it easy to connect a producer thread to a consumer thread.
750   Reads block until data is available to read. Writes block if the pipe's is
751   full. Both sources and sinks support timeouts.
752 * New: `BufferedSource.rangeEquals()` makes it easy to compare a range in a
753   stream to an expected value. This does the right thing: it blocks to load
754   the data required return a definitive result. But it won't block
755   unnecessarily.
756 * New: `Timeout.waitUntilNotified()` makes it possible to use nice timeout
757   abstractions on Java's built-in wait/notify primitives.
758 * Fix: Don't return incorrect results when `HashingSource` does large reads.
759   There was a bug where it wasn't traversing through the segments of the buffer
760   being hashed. This means that `HashingSource` was returning incorrect answers
761   for any writes that spanned multiple segment boundaries.
762
763## Version 1.8.0
764
765_2016-05-02_
766
767 * New: `BufferedSource.select(Options)` API for reading one of a set of
768   expected values.
769 * New: Make `ByteString.toString()` and `Buffer.toString()` friendlier.
770   These methods return text if the byte string is valid UTF-8.
771 * New: APIs to match byte strings: `indexOf()`, `startsWith()`, and
772   `endsWith()`.
773
774## Version 1.7.0
775
776_2016-04-10_
777
778 * New: Change the segment size to 8 KiB. This has been reported to dramatically
779   improve performance in some applications.
780 * New: `md5()`, `sha1()`, and `sha256()` methods on `Buffer`. Also add a
781   `sha1()` method on `ByteString` for symmetry.
782 * New: `HashingSource` and `HashingSink`. These classes are Okio’s equivalent
783   to the JDK’s `DigestInputStream` and `DigestOutputStream`. They offer
784   convenient `md5()`, `sha1()`, and `sha256()` factory methods to avoid an
785   impossible `NoSuchAlgorithmException`.
786 * New: `ByteString.asByteBuffer()`.
787 * Fix: Limit snapshot byte strings to requested size.
788 * Fix: Change write timeouts to have a maximum write size. Previously large
789   writes could easly suffer timeouts because the entire write was subject to a
790   single timeout.
791 * Fix: Recover from EBADF failures, which could be triggered by asynchronously
792   closing a stream on older versions of Android.
793 * Fix: Don't share segments if doing so only saves a small copy. This should
794   improve performance for all applications.
795 * Fix: Optimize `BufferedSource.indexOfElement()` and `indexOf(ByteString)`.
796   Previously this method had a bug that caused it to be very slow on large
797   buffers.
798
799## Version 1.6.0
800
801_2015-08-25_
802
803 * New: `BufferedSource.indexOf(ByteString)` searches a source for the next
804   occurrence of a byte string.
805 * Fix: Recover from unexpected `AssertionError` thrown on Android 4.2.2 and
806   earlier when asynchronously closing a socket.
807
808## Version 1.5.0
809
810_2015-06-19_
811
812 * Sockets streams now throw `SocketTimeoutException`. This builds on new
813   extension point in `AsyncTimeout` to customize the exception when a timeout
814   occurs.
815 * New: `ByteString` now implements `Comparable`. The comparison sorts bytes as
816   unsigned: {@code ff} sorts after {@code 00}.
817
818## Version 1.4.0
819
820_2015-05-16_
821
822 * **Timeout exception changed.** Previously `Timeout.throwIfReached()` would
823   throw `InterruptedIOException` on thread interruption, and `IOException` if
824   the deadline was reached. Now it throws `InterruptedIOException` in both
825   cases.
826 * Fix: throw `EOFException` when attempting to read digits from an empty
827   source. Previously this would crash with an unchecked exception.
828 * New: APIs to read and write UTF-8 code points without allocating strings.
829 * New: `BufferedSink` can now write substrings directly, potentially saving an
830   allocation for some callers.
831 * New: `ForwardingTimeout` class.
832
833## Version 1.3.0
834
835_2015-03-16_
836
837 * New: Read and write signed decimal and unsigned hexadecimal values in
838   `BufferedSource` and `BufferedSink`. Unlike the alternatives, these methods
839   don’t do any memory allocations!
840 * New: Segment sharing. This improves the runtime of operations like
841   `Buffer.clone()` and `Buffer.copyTo()` by sharing underlying segments between
842   buffers.
843 * New: `Buffer.snapshot()` returns an immutable snapshot of a buffer as a
844   `ByteString`. This builds on segment sharing so that snapshots are shallow,
845   immutable copies.
846 * New: `ByteString.rangeEquals()`.
847 * New: `ByteString.md5()` and `ByteString.sha256()`.
848 * New: `ByteString.base64Url()` returns URL-safe Base64. The existing
849   decoding method has been extended to support URL-safe Base64 input.
850 * New: `ByteString.substring()` returns a prefix, infix, or suffix.
851 * New: `Sink` now implements `java.io.Flushable`.
852 * Fix: `Buffer.write(Source, long)` now always writes fully. The previous
853   behavior would return as soon as any data had been written; this was
854   inconsistent with all other _write()_ methods in the API.
855 * Fix: don't leak empty segments in DeflaterSink and InflaterSource. (This was
856   unlikely to cause problems in practice.)
857
858## Version 1.2.0
859
860_2014-12-30_
861
862 * Fix: `Okio.buffer()` _always_ buffers for better predictability.
863 * Fix: Provide context when `readUtf8LineStrict()` throws.
864 * Fix: Buffers do not call through the `Source` on zero-byte writes.
865
866## Version 1.1.0
867
868_2014-12-11_
869
870 * Do UTF-8 encoding natively for a performance increase, particularly on Android.
871 * New APIs: `BufferedSink.emit()`, `BufferedSource.request()` and `BufferedSink.indexOfElement()`.
872 * Fixed a performance bug in `Buffer.indexOf()`
873
874## Version 1.0.1
875
876_2014-08-08_
877
878 * Added `read(byte[])`, `read(byte[], offset, byteCount)`,  and
879   `void readFully(byte[])` to `BufferedSource`.
880 * Refined declared checked exceptions on `Buffer` methods.
881
882
883## Version 1.0.0
884
885_2014-05-23_
886
887 * Bumped release version. No other changes!
888
889## Version 0.9.0
890
891_2014-05-03_
892
893 * Use 0 as a sentinel for no timeout.
894 * Make AsyncTimeout public.
895 * Remove checked exception from Buffer.readByteArray.
896
897## Version 0.8.0
898
899_2014-04-24_
900
901 * Eagerly verify preconditions on public APIs.
902 * Quick return on Buffer instance equivalence.
903 * Add delegate types for Sink and Source.
904 * Small changes to the way deadlines are managed.
905 * Add append variant of Okio.sink for File.
906 * Methods to exhaust BufferedSource to byte[] and ByteString.
907
908## Version 0.7.0
909
910_2014-04-18_
911
912 * Don't use getters in timeout.
913 * Use the watchdog to interrupt sockets that have reached deadlines.
914 * Add java.io and java.nio file source/sink helpers.
915
916## Version 0.6.1
917
918_2014-04-17_
919
920 * Methods to read a buffered source fully in UTF-8 or supplied charset.
921 * API to read a byte[] directly.
922 * New methods to move all data from a source to a sink.
923 * Fix a bug on input stream exhaustion.
924
925## Version 0.6.0
926
927_2014-04-15_
928
929 * Make ByteString serializable.
930 * New API: `ByteString.of(byte[] data, int offset, int byteCount)`
931 * New API: stream-based copy, write, and read helpers.
932
933## Version 0.5.0
934
935_2014-04-08_
936
937 * Initial public release.
938 * Imported from OkHttp.
939
940
941[bom]: https://docs.gradle.org/6.2/userguide/platforms.html#sub:bom_import
942[datetime_0_3_0]: https://github.com/Kotlin/kotlinx-datetime/releases/tag/v0.3.0
943[gradle_metadata]: https://blog.gradle.org/gradle-metadata-1.0
944[hierarchical_projects]: https://kotlinlang.org/docs/multiplatform-hierarchy.html
945[kotlin_1_4_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.10
946[kotlin_1_4_20]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.20
947[kotlin_1_5_20]: https://github.com/JetBrains/kotlin/releases/tag/v1.5.20
948[kotlin_1_5_31]: https://github.com/JetBrains/kotlin/releases/tag/v1.5.31
949[kotlin_1_6_20]: https://blog.jetbrains.com/kotlin/2022/04/kotlin-1-6-20-released/
950[kotlin_1_8_0]: https://kotlinlang.org/docs/whatsnew18.html
951[kotlin_1_9_0]: https://kotlinlang.org/docs/whatsnew19.html
952[kotlin_1_9_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.9.10
953[kotlin_1_9_21]: https://github.com/JetBrains/kotlin/releases/tag/v1.9.21
954[loom]: https://wiki.openjdk.org/display/loom/Getting+started
955[maven_provided]: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
956[preview1]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md
957[watchosX86]: https://blog.jetbrains.com/kotlin/2023/02/update-regarding-kotlin-native-targets/
958[xor_utf8]: https://github.com/square/okio/blob/bbb29c459e5ccf0f286e0b17ccdcacd7ac4bc2a9/okio/src/main/kotlin/okio/Utf8.kt#L302
959