1/* 2 * Copyright (C) 2014 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package okio; 17 18import java.io.EOFException; 19import java.io.IOException; 20import java.io.InputStream; 21import java.util.Arrays; 22import org.junit.Test; 23 24import static okio.Util.UTF_8; 25import static org.junit.Assert.assertEquals; 26import static org.junit.Assert.fail; 27 28public final class RealBufferedSourceTest { 29 @Test public void inputStreamFromSource() throws Exception { 30 OkBuffer source = new OkBuffer(); 31 source.writeUtf8("a"); 32 source.writeUtf8(repeat('b', Segment.SIZE)); 33 source.writeUtf8("c"); 34 35 InputStream in = new RealBufferedSource(source).inputStream(); 36 assertEquals(0, in.available()); 37 assertEquals(Segment.SIZE + 2, source.size()); 38 39 // Reading one byte buffers a full segment. 40 assertEquals('a', in.read()); 41 assertEquals(Segment.SIZE - 1, in.available()); 42 assertEquals(2, source.size()); 43 44 // Reading as much as possible reads the rest of that buffered segment. 45 byte[] data = new byte[Segment.SIZE * 2]; 46 assertEquals(Segment.SIZE - 1, in.read(data, 0, data.length)); 47 assertEquals(repeat('b', Segment.SIZE - 1), new String(data, 0, Segment.SIZE - 1, UTF_8)); 48 assertEquals(2, source.size()); 49 50 // Continuing to read buffers the next segment. 51 assertEquals('b', in.read()); 52 assertEquals(1, in.available()); 53 assertEquals(0, source.size()); 54 55 // Continuing to read reads from the buffer. 56 assertEquals('c', in.read()); 57 assertEquals(0, in.available()); 58 assertEquals(0, source.size()); 59 60 // Once we've exhausted the source, we're done. 61 assertEquals(-1, in.read()); 62 assertEquals(0, source.size()); 63 } 64 65 @Test public void inputStreamFromSourceBounds() throws IOException { 66 OkBuffer source = new OkBuffer(); 67 source.writeUtf8(repeat('a', 100)); 68 InputStream in = new RealBufferedSource(source).inputStream(); 69 try { 70 in.read(new byte[100], 50, 51); 71 fail(); 72 } catch (ArrayIndexOutOfBoundsException expected) { 73 } 74 } 75 76 @Test public void requireTracksBufferFirst() throws Exception { 77 OkBuffer source = new OkBuffer(); 78 source.writeUtf8("bb"); 79 80 BufferedSource bufferedSource = new RealBufferedSource(source); 81 bufferedSource.buffer().writeUtf8("aa"); 82 83 bufferedSource.require(2); 84 assertEquals(2, bufferedSource.buffer().size()); 85 assertEquals(2, source.size()); 86 } 87 88 @Test public void requireIncludesBufferBytes() throws Exception { 89 OkBuffer source = new OkBuffer(); 90 source.writeUtf8("b"); 91 92 BufferedSource bufferedSource = new RealBufferedSource(source); 93 bufferedSource.buffer().writeUtf8("a"); 94 95 bufferedSource.require(2); 96 assertEquals("ab", bufferedSource.buffer().readUtf8(2)); 97 } 98 99 @Test public void requireInsufficientData() throws Exception { 100 OkBuffer source = new OkBuffer(); 101 source.writeUtf8("a"); 102 103 BufferedSource bufferedSource = new RealBufferedSource(source); 104 105 try { 106 bufferedSource.require(2); 107 fail(); 108 } catch (EOFException expected) { 109 } 110 } 111 112 @Test public void requireReadsOneSegmentAtATime() throws Exception { 113 OkBuffer source = new OkBuffer(); 114 source.writeUtf8(repeat('a', Segment.SIZE)); 115 source.writeUtf8(repeat('b', Segment.SIZE)); 116 117 BufferedSource bufferedSource = new RealBufferedSource(source); 118 119 bufferedSource.require(2); 120 assertEquals(Segment.SIZE, source.size()); 121 assertEquals(Segment.SIZE, bufferedSource.buffer().size()); 122 } 123 124 @Test public void skipInsufficientData() throws Exception { 125 OkBuffer source = new OkBuffer(); 126 source.writeUtf8("a"); 127 128 BufferedSource bufferedSource = new RealBufferedSource(source); 129 try { 130 bufferedSource.skip(2); 131 fail(); 132 } catch (EOFException expected) { 133 } 134 } 135 136 @Test public void skipReadsOneSegmentAtATime() throws Exception { 137 OkBuffer source = new OkBuffer(); 138 source.writeUtf8(repeat('a', Segment.SIZE)); 139 source.writeUtf8(repeat('b', Segment.SIZE)); 140 BufferedSource bufferedSource = new RealBufferedSource(source); 141 bufferedSource.skip(2); 142 assertEquals(Segment.SIZE, source.size()); 143 assertEquals(Segment.SIZE - 2, bufferedSource.buffer().size()); 144 } 145 146 @Test public void skipTracksBufferFirst() throws Exception { 147 OkBuffer source = new OkBuffer(); 148 source.writeUtf8("bb"); 149 150 BufferedSource bufferedSource = new RealBufferedSource(source); 151 bufferedSource.buffer().writeUtf8("aa"); 152 153 bufferedSource.skip(2); 154 assertEquals(0, bufferedSource.buffer().size()); 155 assertEquals(2, source.size()); 156 } 157 158 @Test public void operationsAfterClose() throws IOException { 159 OkBuffer source = new OkBuffer(); 160 BufferedSource bufferedSource = new RealBufferedSource(source); 161 bufferedSource.close(); 162 163 // Test a sample set of methods. 164 try { 165 bufferedSource.indexOf((byte) 1); 166 fail(); 167 } catch (IllegalStateException expected) { 168 } 169 170 try { 171 bufferedSource.skip(1); 172 fail(); 173 } catch (IllegalStateException expected) { 174 } 175 176 try { 177 bufferedSource.readByte(); 178 fail(); 179 } catch (IllegalStateException expected) { 180 } 181 182 try { 183 bufferedSource.readByteString(10); 184 fail(); 185 } catch (IllegalStateException expected) { 186 } 187 188 // Test a sample set of methods on the InputStream. 189 InputStream is = bufferedSource.inputStream(); 190 try { 191 is.read(); 192 fail(); 193 } catch (IOException expected) { 194 } 195 196 try { 197 is.read(new byte[10]); 198 fail(); 199 } catch (IOException expected) { 200 } 201 } 202 203 private String repeat(char c, int count) { 204 char[] array = new char[count]; 205 Arrays.fill(array, c); 206 return new String(array); 207 } 208} 209