1Change Log 2========== 3 4## Version 2.9.0 5 6_2020-10-04_ 7 8 * Fix: Don't corrupt the `Buffer` when writing a slice of a segmented `ByteString`. We had a severe 9 bug where `ByteString` instances created with `snapshot()` and `readByteString()` incorrectly 10 adjusted the buffer's size by their full length, not the length of the slice. This would have 11 caused buffer reads to crash! We do not believe data was silently corrupted. 12 * New: `CipherSink` and `CipherSource`. Use these with `javax.crypto.Cipher` to encrypt and decrypt 13 streams of data. This is a low-level encryption API; most applications should use higher-level 14 APIs like TLS when available. 15 * New: Promote hash functions `md5`, `sha1()`, `sha512()`, and `sha256()` to common Kotlin. These 16 are currently only available on `ByteString`, multiplatform support for `HashingSource`, 17 `HashingSink`, and `Buffer` should come in a follow-up release. We wrote and optimized our own 18 implementations of these hash functions in Kotlin. On JVM and Android platforms Okio still uses 19 the platform's built-in hash functions. 20 * New: Support OSGi metadata. 21 * Upgrade: [Kotlin 1.4.10][kotlin_1_4_10]. 22 23 24## Version 2.8.0 25 26_2020-08-17_ 27 28 * New: Upgrade to Kotlin 1.4.0. 29 30 31## Version 2.7.0 32 33_2020-07-07_ 34 35 * New: `Pipe.cancel()` causes in-progress and future reads and writes on the pipe to immediately 36 fail with an `IOException`. The streams may still be canceled normally. 37 38 * New: Enlarge Okio's internal segment pool from a fixed 64 KiB total to 64 KiB per processor. For 39 example, on an Intel i9 8-core/16-thread machine the segment pool now uses up to 1 MiB of memory. 40 41 * New: Migrate from `synchronized` to lock-free when accessing the segment pool. Combined with the 42 change above we saw throughput increase 3x on a synthetic benchmark designed to create 43 contention. 44 45 46## Version 2.6.0 47 48_2020-04-22_ 49 50 * New: `InflaterSource.readOrInflate()` is like `InflaterSource.read()`, except it will return 0 if 51 consuming deflated bytes from the underlying stream did not produce new inflated bytes. 52 53 54## Version 2.5.0 55 56_2020-03-20_ 57 58 * New: Upgrade to Kotlin 1.3.70. 59 60 61## Version 2.4.3 62 63_2019-12-20_ 64 65 * New: Upgrade to Kotlin 1.3.61. 66 67 68## Version 2.4.2 69 70_2019-12-11_ 71 72 * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary. 73 We had a bug where a sequence of reads could violate a buffer's invariants, and this could result 74 in a crash when subsequent reads encountered an unexpected empty segment. 75 76 77## Version 1.17.5 78 79_2019-12-11_ 80 81 * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary. 82 We had a bug where a sequence of reads could violate a buffer's invariants, and this could result 83 in a crash when subsequent reads encountered an unexpected empty segment. 84 85 86### Version 2.4.1 87 88_2019-10-04_ 89 90 * Fix: Don't cache hash code and UTF-8 string in `ByteString` on Kotlin/Native which prevented freezing. 91 92### Version 2.4.0 93 94_2019-08-26_ 95 96 * New: Upgrade to Kotlin 1.3.50. 97 98 99### Version 2.3.0 100 101_2019-07-29_ 102 103**This release changes our build from Kotlin-JVM to Kotlin-multiplatform (which includes JVM).** 104Both native and JavaScript platforms are unstable preview releases and subject to 105backwards-incompatible changes in forthcoming releases. 106 107To try Okio in a multiplatform project use this Maven coordinate: 108 109```kotlin 110api('com.squareup.okio:okio-multiplatform:2.3.0') 111``` 112 113You’ll also need to [enable Gradle metadata][gradle_metadata] in your project's settings. The 114artifact name for JVM projects has not changed. 115 116 * New: Upgrade to Kotlin 1.3.40. 117 * Fix: Use Gradle `api` instead of `implementation` for the kotlin-stdlib dependency. 118 * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`. 119 120## Version 1.17.4 121 122_2019-04-29_ 123 124 * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`. 125 126 127## Version 2.2.2 128 129_2019-01-28_ 130 131 * Fix: Make `Pipe.fold()` close the underlying sink when necessary. 132 133 134## Version 1.17.3 135 136_2019-01-28_ 137 138 * Fix: Make `Pipe.fold()` close the underlying sink when necessary. 139 140 141## Version 1.17.2 142 143_2019-01-17_ 144 145 * Fix: Make `Pipe.fold()` flush the underlying sink. 146 147 148## Version 2.2.1 149 150_2019-01-17_ 151 152 * Fix: Make `Pipe.fold()` flush the underlying sink. 153 154 155## Version 2.2.0 156 157_2019-01-16_ 158 159 * New: `Throttler` limits sources and sinks to a maximum desired throughput. Multiple sources and 160 sinks can be attached to the same throttler and their combined throughput will not exceed the 161 desired throughput. Multiple throttlers can also be used on the same source or sink and they will 162 all be honored. 163 164 * New: `Pipe.fold()` replaces the actively-readable `Source` with a passively-writable `Sink`. 165 This can be used to forward one sink to a target that is initially undetermined. 166 167 * New: Optimize performance of ByteStrings created with `Buffer.snapshot()`. 168 169 170## Version 1.17.1 171 172_2019-01-16_ 173 174 * Fix: Make the newly-backported `Pipe.fold()` public. 175 176 177## Version 1.17.0 178 179_2019-01-16_ 180 181 * New: Backport `Pipe.fold()` to Okio 1.x. 182 183 184## Version 1.16.0 185 186_2018-10-08_ 187 188 * New: Backport `BufferedSource.peek()` and `BufferedSource.getBuffer()` to Okio 1.x. 189 * Fix: Enforce timeouts when closing `AsyncTimeout` sources. 190 191 192## Version 2.1.0 193 194_2018-09-22_ 195 196 * New: `BufferedSource.peek()` returns another `BufferedSource` that reads ahead on the current 197 source. Use this to process the same data multiple times. 198 199 * New: Deprecate `BufferedSource.buffer()`, replacing it with either `BufferedSource.getBuffer()` 200 (in Java) or `BufferedSource.buffer` (in Kotlin). We have done likewise for `BufferedSink`. 201 When we introduced the new extension method `Source.buffer()` in Okio 2.0 we inadvertently 202 collided with an existing method. This fixes that. 203 204 * New: Improve performance of `Buffer.writeUtf8()`. This comes alongside initial implementation of 205 UTF-8 encoding and decoding in JavaScript which [uses XOR masks][xor_utf8] for great performance. 206 207 208## Version 2.0.0 209 210_2018-08-27_ 211 212This release commits to a stable 2.0 API. Read the 2.0.0-RC1 changes for advice on upgrading from 2131.x to 2.x. 214 215We've also added APIs to ease migration for Kotlin users. They use Kotlin's `@Deprecated` annotation 216to help you change call sites from the 1.x style to the 2.x style. 217 218 219## Version 2.0.0-RC1 220 221_2018-07-26_ 222 223Okio 2 is a major release that upgrades the library's implementation language from Java to Kotlin. 224 225Okio 2.x is **binary-compatible** with Okio 1.x and does not change any behavior. Classes and .jar 226files compiled against 1.x can be used with 2.x without recompiling. 227 228Okio 2.x is **.java source compatible** with Okio 1.x in all but one corner case. In Okio 1.x 229`Buffer` would throw an unchecked `IllegalStateException` when attempting to read more bytes than 230available. Okio 2.x now throws a checked `EOFException` in this case. This is now consistent with 231the behavior of its `BufferedSource` interface. Java callers that don't already catch `IOException` 232will now need to. 233 234Okio 2.x is **.kt source-incompatible** with Okio 1.x. This release adopts Kotlin idioms where they 235are available. 236 237| Java | Kotlin | Idiom | 238| :--------------------------------------- | :---------------------------------- | :----------------- | 239| Buffer.getByte() | operator fun Buffer.get() | operator function | 240| Buffer.size() | val Buffer.size | val | 241| ByteString.decodeBase64(String) | fun String.decodeBase64() | extension function | 242| ByteString.decodeHex(String) | fun String.decodeHex() | extension function | 243| ByteString.encodeString(String, Charset) | fun String.encode(Charset) | extension function | 244| ByteString.encodeUtf8(String) | fun String.encodeUtf8() | extension function | 245| ByteString.getByte() | operator fun ByteString.get() | operator function | 246| ByteString.of(ByteBuffer) | fun ByteBuffer.toByteString() | extension function | 247| ByteString.of(byte[], int, int) | fun ByteArray.toByteString() | extension function | 248| ByteString.read(InputStream, int) | fun InputStream.readByteString(Int) | extension function | 249| ByteString.size() | val ByteString.size | val | 250| DeflaterSink(Sink) | fun Sink.deflater() | extension function | 251| ForwardingSink.delegate() | val ForwardingSink.delegate | val | 252| ForwardingSource.delegate() | val ForwardingSource.delegate | val | 253| GzipSink(Sink, Deflater) | fun Sink.gzip() | extension function | 254| GzipSink.deflater() | val GzipSink.deflater | val | 255| GzipSource(Source) | fun Source.gzip() | extension function | 256| HashingSink.hash() | val HashingSink.hash | val | 257| HashingSource.hash() | val HashingSource.hash | val | 258| InflaterSink(Source) | fun Source.inflater() | extension function | 259| Okio.appendingSink(File) | fun File.appendingSink() | extension function | 260| Okio.blackhole() | fun blackholeSink() | top level function | 261| Okio.buffer(Sink) | fun Sink.buffer() | extension function | 262| Okio.buffer(Source) | fun Source.buffer() | extension function | 263| Okio.sink(File) | fun File.sink() | extension function | 264| Okio.sink(OutputStream) | fun OutputStream.sink() | extension function | 265| Okio.sink(Path) | fun Path.sink() | extension function | 266| Okio.sink(Socket) | fun Socket.sink() | extension function | 267| Okio.source(File) | fun File.source() | extension function | 268| Okio.source(InputStream) | fun InputStream.source() | extension function | 269| Okio.source(Path) | fun Path.source() | extension function | 270| Okio.source(Socket) | fun Socket.source() | extension function | 271| Pipe.sink() | val Pipe.sink | val | 272| Pipe.source() | val Pipe.source | val | 273| Utf8.size(String) | fun String.utf8Size() | extension function | 274 275Okio 2.x has **similar performance** to Okio 1.x. We benchmarked both versions to find potential 276performance regressions. We found one regression and fixed it: we were using `==` instead of `===`. 277 278Other changes in this release: 279 280 * New: Add a dependency on kotlin-stdlib. Okio's transitive dependencies grow from none in 1.x to 281 three in 2.x. These are kotlin-stdlib (939 KiB), kotlin-stdlib-common (104 KiB), and JetBrains' 282 annotations (17 KiB). 283 284 * New: Change Okio to build with Gradle instead of Maven. 285 286 287## Version 1.15.0 288 289_2018-07-18_ 290 291 * New: Trie-based `Buffer.select()`. This improves performance when selecting 292 among large lists of options. 293 * Fix: Retain interrupted state when throwing `InterruptedIOException`. 294 295 296## Version 1.14.0 297 298_2018-02-11_ 299 300 * New: `Buffer.UnsafeCursor` provides direct access to Okio internals. This API 301 is like Okio's version of Java reflection: it's a very powerful API that can 302 be used for great things and dangerous things alike. The documentation is 303 extensive and anyone using it should review it carefully before proceeding! 304 * New: Change `BufferedSource` to implement `java.nio.ReadableByteChannel` and 305 `BufferedSink` to implement `java.nio.WritableByteChannel`. Now it's a little 306 easier to interop between Okio and NIO. 307 * New: Automatic module name of `okio` for use with the Java Platform Module 308 System. 309 * New: Optimize `Buffer.getByte()` to search backwards when doing so will be 310 more efficient. 311 * Fix: Honor the requested byte count in `InflaterSource`. Previously this 312 class could return more bytes than requested. 313 * Fix: Improve a performance bug in `AsyncTimeout.sink().write()`. 314 315 316## Version 1.13.0 317 318_2017-05-12_ 319 320 * **Okio now uses `@Nullable` to annotate all possibly-null values.** We've 321 added a compile-time dependency on the JSR 305 annotations. This is a 322 [provided][maven_provided] dependency and does not need to be included in 323 your build configuration, `.jar` file, or `.apk`. We use 324 `@ParametersAreNonnullByDefault` and all parameters and return types are 325 never null unless explicitly annotated `@Nullable`. 326 327 * **Warning: this release is source-incompatible for Kotlin users.** 328 Nullability was previously ambiguous and lenient but now the compiler will 329 enforce strict null checks. 330 331 332## Version 1.12.0 333 334_2017-04-11_ 335 336 * **Fix: Change Pipe's sink.flush() to not block.** Previously closing a pipe's 337 sink would block until the source had been exhausted. In practice this 338 blocked the caller for no benefit. 339 * **Fix: Change `writeUtf8CodePoint()` to emit `?` for partial surrogates.** 340 The previous behavior was inconsistent: given a malformed string with a 341 partial surrogate, `writeUtf8()` emitted `?` but `writeUtf8CodePoint()` threw 342 an `IllegalArgumentException`. Most applications will never encounter partial 343 surrogates, but for those that do this behavior was unexpected. 344 * New: Allow length of `readUtf8LineStrict()` to be limited. 345 * New: `Utf8.size()` method to get the number of bytes required to encode a 346 string as UTF-8. This may be useful for length-prefixed encodings. 347 * New: SHA-512 hash and HMAC APIs. 348 349 350## Version 1.11.0 351 352_2016-10-11_ 353 354 * **Fix: The four-argument overload of `Buffer.writeString()` had a major bug 355 where it didn't respect offsets if the specified charset was UTF-8.** This 356 was because our short-circuit optimization omitted necessary offset 357 parameters. 358 * New: HMAC support in `HashingSource`, `HashingSink`, `ByteString`, and 359 `Buffer`. This makes it easy to create a keyed-hash message authentication 360 code (HMAC) wherever your data is. Unlike the other hashes, HMAC uses a 361 `ByteString` secret key for authentication. 362 * New: `ByteString.of(ByteBuffer)` makes it easier to mix NIO with Okio. 363 364 365## Version 1.10.0 366 367_2016-08-28_ 368 369 * Fix: Support reading files larger than 2 GiB with `GzipSource`. Previously 370 attempting to decompress such files would fail due to an overflow when 371 validating the total length. 372 * Fix: Exit the watchdog thread after being idle for 60 seconds. This should 373 make it possible for class unloaders to fully unload Okio. 374 * New: `Okio.blackhole()` returns a sink where all bytes written are discarded. 375 This is Okio's equivalent of `/dev/null`. 376 * New: Encode a string with any charset using `ByteString.encodeString()` and 377 decode strings in any charset using `ByteString.string()`. Most applications 378 should prefer `ByteString.encodeUtf8()` and `ByteString.utf8()` unless it's 379 necessary to support a legacy charset. 380 * New: `GzipSink.deflater()` makes it possible to configure the compression 381 level. 382 383 384## Version 1.9.0 385 386_2016-07-01_ 387 388 * New: `Pipe` makes it easy to connect a producer thread to a consumer thread. 389 Reads block until data is available to read. Writes block if the pipe's is 390 full. Both sources and sinks support timeouts. 391 * New: `BufferedSource.rangeEquals()` makes it easy to compare a range in a 392 stream to an expected value. This does the right thing: it blocks to load 393 the data required return a definitive result. But it won't block 394 unnecessarily. 395 * New: `Timeout.waitUntilNotified()` makes it possible to use nice timeout 396 abstractions on Java's built-in wait/notify primitives. 397 * Fix: Don't return incorrect results when `HashingSource` does large reads. 398 There was a bug where it wasn't traversing through the segments of the buffer 399 being hashed. This means that `HashingSource` was returning incorrect answers 400 for any writes that spanned multiple segment boundaries. 401 402## Version 1.8.0 403 404_2016-05-02_ 405 406 * New: `BufferedSource.select(Options)` API for reading one of a set of 407 expected values. 408 * New: Make `ByteString.toString()` and `Buffer.toString()` friendlier. 409 These methods return text if the byte string is valid UTF-8. 410 * New: APIs to match byte strings: `indexOf()`, `startsWith()`, and 411 `endsWith()`. 412 413## Version 1.7.0 414 415_2016-04-10_ 416 417 * New: Change the segment size to 8 KiB. This has been reported to dramatically 418 improve performance in some applications. 419 * New: `md5()`, `sha1()`, and `sha256()` methods on `Buffer`. Also add a 420 `sha1()` method on `ByteString` for symmetry. 421 * New: `HashingSource` and `HashingSink`. These classes are Okio’s equivalent 422 to the JDK’s `DigestInputStream` and `DigestOutputStream`. They offer 423 convenient `md5()`, `sha1()`, and `sha256()` factory methods to avoid an 424 impossible `NoSuchAlgorithmException`. 425 * New: `ByteString.asByteBuffer()`. 426 * Fix: Limit snapshot byte strings to requested size. 427 * Fix: Change write timeouts to have a maximum write size. Previously large 428 writes could easly suffer timeouts because the entire write was subject to a 429 single timeout. 430 * Fix: Recover from EBADF failures, which could be triggered by asynchronously 431 closing a stream on older versions of Android. 432 * Fix: Don't share segments if doing so only saves a small copy. This should 433 improve performance for all applications. 434 * Fix: Optimize `BufferedSource.indexOfElement()` and `indexOf(ByteString)`. 435 Previously this method had a bug that caused it to be very slow on large 436 buffers. 437 438## Version 1.6.0 439 440_2015-08-25_ 441 442 * New: `BufferedSource.indexOf(ByteString)` searches a source for the next 443 occurrence of a byte string. 444 * Fix: Recover from unexpected `AssertionError` thrown on Android 4.2.2 and 445 earlier when asynchronously closing a socket. 446 447## Version 1.5.0 448 449_2015-06-19_ 450 451 * Sockets streams now throw `SocketTimeoutException`. This builds on new 452 extension point in `AsyncTimeout` to customize the exception when a timeout 453 occurs. 454 * New: `ByteString` now implements `Comparable`. The comparison sorts bytes as 455 unsigned: {@code ff} sorts after {@code 00}. 456 457## Version 1.4.0 458 459_2015-05-16_ 460 461 * **Timeout exception changed.** Previously `Timeout.throwIfReached()` would 462 throw `InterruptedIOException` on thread interruption, and `IOException` if 463 the deadline was reached. Now it throws `InterruptedIOException` in both 464 cases. 465 * Fix: throw `EOFException` when attempting to read digits from an empty 466 source. Previously this would crash with an unchecked exception. 467 * New: APIs to read and write UTF-8 code points without allocating strings. 468 * New: `BufferedSink` can now write substrings directly, potentially saving an 469 allocation for some callers. 470 * New: `ForwardingTimeout` class. 471 472## Version 1.3.0 473 474_2015-03-16_ 475 476 * New: Read and write signed decimal and unsigned hexadecimal values in 477 `BufferedSource` and `BufferedSink`. Unlike the alternatives, these methods 478 don’t do any memory allocations! 479 * New: Segment sharing. This improves the runtime of operations like 480 `Buffer.clone()` and `Buffer.copyTo()` by sharing underlying segments between 481 buffers. 482 * New: `Buffer.snapshot()` returns an immutable snapshot of a buffer as a 483 `ByteString`. This builds on segment sharing so that snapshots are shallow, 484 immutable copies. 485 * New: `ByteString.rangeEquals()`. 486 * New: `ByteString.md5()` and `ByteString.sha256()`. 487 * New: `ByteString.base64Url()` returns URL-safe Base64. The existing 488 decoding method has been extended to support URL-safe Base64 input. 489 * New: `ByteString.substring()` returns a prefix, infix, or suffix. 490 * New: `Sink` now implements `java.io.Flushable`. 491 * Fix: `Buffer.write(Source, long)` now always writes fully. The previous 492 behavior would return as soon as any data had been written; this was 493 inconsistent with all other _write()_ methods in the API. 494 * Fix: don't leak empty segments in DeflaterSink and InflaterSource. (This was 495 unlikely to cause problems in practice.) 496 497## Version 1.2.0 498 499_2014-12-30_ 500 501 * Fix: `Okio.buffer()` _always_ buffers for better predictability. 502 * Fix: Provide context when `readUtf8LineStrict()` throws. 503 * Fix: Buffers do not call through the `Source` on zero-byte writes. 504 505## Version 1.1.0 506 507_2014-12-11_ 508 509 * Do UTF-8 encoding natively for a performance increase, particularly on Android. 510 * New APIs: `BufferedSink.emit()`, `BufferedSource.request()` and `BufferedSink.indexOfElement()`. 511 * Fixed a performance bug in `Buffer.indexOf()` 512 513## Version 1.0.1 514 515_2014-08-08_ 516 517 * Added `read(byte[])`, `read(byte[], offset, byteCount)`, and 518 `void readFully(byte[])` to `BufferedSource`. 519 * Refined declared checked exceptions on `Buffer` methods. 520 521 522## Version 1.0.0 523 524_2014-05-23_ 525 526 * Bumped release version. No other changes! 527 528## Version 0.9.0 529 530_2014-05-03_ 531 532 * Use 0 as a sentinel for no timeout. 533 * Make AsyncTimeout public. 534 * Remove checked exception from Buffer.readByteArray. 535 536## Version 0.8.0 537 538_2014-04-24_ 539 540 * Eagerly verify preconditions on public APIs. 541 * Quick return on Buffer instance equivalence. 542 * Add delegate types for Sink and Source. 543 * Small changes to the way deadlines are managed. 544 * Add append variant of Okio.sink for File. 545 * Methods to exhaust BufferedSource to byte[] and ByteString. 546 547## Version 0.7.0 548 549_2014-04-18_ 550 551 * Don't use getters in timeout. 552 * Use the watchdog to interrupt sockets that have reached deadlines. 553 * Add java.io and java.nio file source/sink helpers. 554 555## Version 0.6.1 556 557_2014-04-17_ 558 559 * Methods to read a buffered source fully in UTF-8 or supplied charset. 560 * API to read a byte[] directly. 561 * New methods to move all data from a source to a sink. 562 * Fix a bug on input stream exhaustion. 563 564## Version 0.6.0 565 566_2014-04-15_ 567 568 * Make ByteString serializable. 569 * New API: `ByteString.of(byte[] data, int offset, int byteCount)` 570 * New API: stream-based copy, write, and read helpers. 571 572## Version 0.5.0 573 574_2014-04-08_ 575 576 * Initial public release. 577 * Imported from OkHttp. 578 579 580 [gradle_metadata]: https://blog.gradle.org/gradle-metadata-1.0 581 [kotlin_1_4_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.10 582 [maven_provided]: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html 583 [xor_utf8]: https://github.com/square/okio/blob/bbb29c459e5ccf0f286e0b17ccdcacd7ac4bc2a9/okio/src/main/kotlin/okio/Utf8.kt#L302 584