xref: /aosp_15_r20/external/okhttp/okio/README.md (revision ab625e417e7950f52094c019474d2a9e9f14a68c)
1*ab625e41SAndroid Build Coastguard WorkerOkio
2*ab625e41SAndroid Build Coastguard Worker====
3*ab625e41SAndroid Build Coastguard Worker
4*ab625e41SAndroid Build Coastguard WorkerOkio is a new library that complements `java.io` and `java.nio` to make it much
5*ab625e41SAndroid Build Coastguard Workereasier to access, store, and process your data.
6*ab625e41SAndroid Build Coastguard Worker
7*ab625e41SAndroid Build Coastguard WorkerByteStrings and Buffers
8*ab625e41SAndroid Build Coastguard Worker-----------------------
9*ab625e41SAndroid Build Coastguard Worker
10*ab625e41SAndroid Build Coastguard WorkerOkio is built around two types that pack a lot of capability into a
11*ab625e41SAndroid Build Coastguard Workerstraightforward API:
12*ab625e41SAndroid Build Coastguard Worker
13*ab625e41SAndroid Build Coastguard Worker * [**ByteString**][3] is an immutable sequence of bytes. For character data, `String`
14*ab625e41SAndroid Build Coastguard Worker   is fundamental. `ByteString` is String's long-lost brother, making it easy to
15*ab625e41SAndroid Build Coastguard Worker   treat binary data as a value. This class is ergonomic: it knows how to encode
16*ab625e41SAndroid Build Coastguard Worker   and decode itself as hex, base64, and UTF-8.
17*ab625e41SAndroid Build Coastguard Worker
18*ab625e41SAndroid Build Coastguard Worker * [**Buffer**][4] is a mutable sequence of bytes. Like `ArrayList`, you don't need
19*ab625e41SAndroid Build Coastguard Worker   to size your buffer in advance. You read and write buffers as a queue: write
20*ab625e41SAndroid Build Coastguard Worker   data to the end and read it from the front. There's no obligation to manage
21*ab625e41SAndroid Build Coastguard Worker   positions, limits, or capacities.
22*ab625e41SAndroid Build Coastguard Worker
23*ab625e41SAndroid Build Coastguard WorkerInternally, `ByteString` and `Buffer` do some clever things to save CPU and
24*ab625e41SAndroid Build Coastguard Workermemory. If you encode a UTF-8 string as a `ByteString`, it caches a reference to
25*ab625e41SAndroid Build Coastguard Workerthat string so that if you decode it later, there's no work to do.
26*ab625e41SAndroid Build Coastguard Worker
27*ab625e41SAndroid Build Coastguard Worker`Buffer` is implemented as a linked list of segments. When you move data from
28*ab625e41SAndroid Build Coastguard Workerone buffer to another, it _reassigns ownership_ of the segments rather than
29*ab625e41SAndroid Build Coastguard Workercopying the data across. This approach is particularly helpful for multithreaded
30*ab625e41SAndroid Build Coastguard Workerprograms: a thread that talks to the network can exchange data with a worker
31*ab625e41SAndroid Build Coastguard Workerthread without any copying or ceremony.
32*ab625e41SAndroid Build Coastguard Worker
33*ab625e41SAndroid Build Coastguard WorkerSources and Sinks
34*ab625e41SAndroid Build Coastguard Worker-----------------
35*ab625e41SAndroid Build Coastguard Worker
36*ab625e41SAndroid Build Coastguard WorkerAn elegant part of the `java.io` design is how streams can be layered for
37*ab625e41SAndroid Build Coastguard Workertransformations like encryption and compression. Okio includes its own stream
38*ab625e41SAndroid Build Coastguard Workertypes called [`Source`][5] and [`Sink`][6] that work like `InputStream` and
39*ab625e41SAndroid Build Coastguard Worker`OutputStream`, but with some key differences:
40*ab625e41SAndroid Build Coastguard Worker
41*ab625e41SAndroid Build Coastguard Worker * **Timeouts.** The streams provide access to the timeouts of the underlying
42*ab625e41SAndroid Build Coastguard Worker   I/O mechanism. Unlike the `java.io` socket streams, both `read()` and
43*ab625e41SAndroid Build Coastguard Worker   `write()` calls honor timeouts.
44*ab625e41SAndroid Build Coastguard Worker
45*ab625e41SAndroid Build Coastguard Worker * **Easy to implement.** `Source` declares three methods: `read()`, `close()`,
46*ab625e41SAndroid Build Coastguard Worker   and `timeout()`. There are no hazards like `available()` or single-byte reads
47*ab625e41SAndroid Build Coastguard Worker   that cause correctness and performance surprises.
48*ab625e41SAndroid Build Coastguard Worker
49*ab625e41SAndroid Build Coastguard Worker * **Easy to use.** Although _implementations_ of `Source` and `Sink` have only
50*ab625e41SAndroid Build Coastguard Worker   three methods to write, _callers_ are given a rich API with the
51*ab625e41SAndroid Build Coastguard Worker   [`BufferedSource`][7] and [`BufferedSink`][8] interfaces. These interfaces give you
52*ab625e41SAndroid Build Coastguard Worker   everything you need in one place.
53*ab625e41SAndroid Build Coastguard Worker
54*ab625e41SAndroid Build Coastguard Worker * **No artificial distinction between byte streams and char streams.** It's all
55*ab625e41SAndroid Build Coastguard Worker   data. Read and write it as bytes, UTF-8 strings, big-endian 32-bit integers,
56*ab625e41SAndroid Build Coastguard Worker   little-endian shorts; whatever you want. No more `InputStreamReader`!
57*ab625e41SAndroid Build Coastguard Worker
58*ab625e41SAndroid Build Coastguard Worker * **Easy to test.** The `Buffer` class implements both `BufferedSource` and
59*ab625e41SAndroid Build Coastguard Worker   `BufferedSink` so your test code is simple and clear.
60*ab625e41SAndroid Build Coastguard Worker
61*ab625e41SAndroid Build Coastguard WorkerSources and sinks interoperate with `InputStream` and `OutputStream`. You can
62*ab625e41SAndroid Build Coastguard Workerview any `Source` as an `InputStream`, and you can view any `InputStream` as a
63*ab625e41SAndroid Build Coastguard Worker`Source`. Similarly for `Sink` and `OutputStream`.
64*ab625e41SAndroid Build Coastguard Worker
65*ab625e41SAndroid Build Coastguard WorkerDependable
66*ab625e41SAndroid Build Coastguard Worker----------
67*ab625e41SAndroid Build Coastguard Worker
68*ab625e41SAndroid Build Coastguard WorkerOkio started as a component of [OkHttp][1], the capable HTTP+SPDY client
69*ab625e41SAndroid Build Coastguard Workerincluded in Android. It's well-exercised and ready to solve new problems.
70*ab625e41SAndroid Build Coastguard Worker
71*ab625e41SAndroid Build Coastguard Worker
72*ab625e41SAndroid Build Coastguard WorkerExample: a PNG decoder
73*ab625e41SAndroid Build Coastguard Worker----------------------
74*ab625e41SAndroid Build Coastguard Worker
75*ab625e41SAndroid Build Coastguard WorkerDecoding the chunks of a PNG file demonstrates Okio in practice.
76*ab625e41SAndroid Build Coastguard Worker
77*ab625e41SAndroid Build Coastguard Worker```java
78*ab625e41SAndroid Build Coastguard Workerprivate static final ByteString PNG_HEADER = ByteString.decodeHex("89504e470d0a1a0a");
79*ab625e41SAndroid Build Coastguard Worker
80*ab625e41SAndroid Build Coastguard Workerpublic void decodePng(InputStream in) throws IOException {
81*ab625e41SAndroid Build Coastguard Worker  BufferedSource pngSource = Okio.buffer(Okio.source(in));
82*ab625e41SAndroid Build Coastguard Worker
83*ab625e41SAndroid Build Coastguard Worker  ByteString header = pngSource.readByteString(PNG_HEADER.size());
84*ab625e41SAndroid Build Coastguard Worker  if (!header.equals(PNG_HEADER)) {
85*ab625e41SAndroid Build Coastguard Worker    throw new IOException("Not a PNG.");
86*ab625e41SAndroid Build Coastguard Worker  }
87*ab625e41SAndroid Build Coastguard Worker
88*ab625e41SAndroid Build Coastguard Worker  while (true) {
89*ab625e41SAndroid Build Coastguard Worker    Buffer chunk = new Buffer();
90*ab625e41SAndroid Build Coastguard Worker
91*ab625e41SAndroid Build Coastguard Worker    // Each chunk is a length, type, data, and CRC offset.
92*ab625e41SAndroid Build Coastguard Worker    int length = pngSource.readInt();
93*ab625e41SAndroid Build Coastguard Worker    String type = pngSource.readUtf8(4);
94*ab625e41SAndroid Build Coastguard Worker    pngSource.readFully(chunk, length);
95*ab625e41SAndroid Build Coastguard Worker    int crc = pngSource.readInt();
96*ab625e41SAndroid Build Coastguard Worker
97*ab625e41SAndroid Build Coastguard Worker    decodeChunk(type, chunk);
98*ab625e41SAndroid Build Coastguard Worker    if (type.equals("IEND")) break;
99*ab625e41SAndroid Build Coastguard Worker  }
100*ab625e41SAndroid Build Coastguard Worker
101*ab625e41SAndroid Build Coastguard Worker  pngSource.close();
102*ab625e41SAndroid Build Coastguard Worker}
103*ab625e41SAndroid Build Coastguard Worker
104*ab625e41SAndroid Build Coastguard Workerprivate void decodeChunk(String type, Buffer chunk) {
105*ab625e41SAndroid Build Coastguard Worker  if (type.equals("IHDR")) {
106*ab625e41SAndroid Build Coastguard Worker    int width = chunk.readInt();
107*ab625e41SAndroid Build Coastguard Worker    int height = chunk.readInt();
108*ab625e41SAndroid Build Coastguard Worker    System.out.printf("%08x: %s %d x %d%n", chunk.size(), type, width, height);
109*ab625e41SAndroid Build Coastguard Worker  } else {
110*ab625e41SAndroid Build Coastguard Worker    System.out.printf("%08x: %s%n", chunk.size(), type);
111*ab625e41SAndroid Build Coastguard Worker  }
112*ab625e41SAndroid Build Coastguard Worker}
113*ab625e41SAndroid Build Coastguard Worker```
114*ab625e41SAndroid Build Coastguard Worker
115*ab625e41SAndroid Build Coastguard WorkerDownload
116*ab625e41SAndroid Build Coastguard Worker--------
117*ab625e41SAndroid Build Coastguard Worker
118*ab625e41SAndroid Build Coastguard WorkerDownload [the latest JAR][2] or grab via Maven:
119*ab625e41SAndroid Build Coastguard Worker```xml
120*ab625e41SAndroid Build Coastguard Worker<dependency>
121*ab625e41SAndroid Build Coastguard Worker    <groupId>com.squareup.okio</groupId>
122*ab625e41SAndroid Build Coastguard Worker    <artifactId>okio</artifactId>
123*ab625e41SAndroid Build Coastguard Worker    <version>1.6.0</version>
124*ab625e41SAndroid Build Coastguard Worker</dependency>
125*ab625e41SAndroid Build Coastguard Worker```
126*ab625e41SAndroid Build Coastguard Workeror Gradle:
127*ab625e41SAndroid Build Coastguard Worker```groovy
128*ab625e41SAndroid Build Coastguard Workercompile 'com.squareup.okio:okio:1.6.0'
129*ab625e41SAndroid Build Coastguard Worker```
130*ab625e41SAndroid Build Coastguard Worker
131*ab625e41SAndroid Build Coastguard WorkerSnapshots of the development version are available in [Sonatype's `snapshots` repository][snap].
132*ab625e41SAndroid Build Coastguard Worker
133*ab625e41SAndroid Build Coastguard Worker
134*ab625e41SAndroid Build Coastguard Worker [1]: https://github.com/square/okhttp
135*ab625e41SAndroid Build Coastguard Worker [2]: https://search.maven.org/remote_content?g=com.squareup.okio&a=okio&v=LATEST
136*ab625e41SAndroid Build Coastguard Worker [3]: http://square.github.io/okio/okio/ByteString.html
137*ab625e41SAndroid Build Coastguard Worker [4]: http://square.github.io/okio/okio/Buffer.html
138*ab625e41SAndroid Build Coastguard Worker [5]: http://square.github.io/okio/okio/Source.html
139*ab625e41SAndroid Build Coastguard Worker [6]: http://square.github.io/okio/okio/Sink.html
140*ab625e41SAndroid Build Coastguard Worker [7]: http://square.github.io/okio/okio/BufferedSource.html
141*ab625e41SAndroid Build Coastguard Worker [8]: http://square.github.io/okio/okio/BufferedSink.html
142*ab625e41SAndroid Build Coastguard Worker [snap]: https://oss.sonatype.org/content/repositories/snapshots/
143