1/*
2 * Copyright (C) 2007 The Android Open Source Project
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 */
16
17package libcore.java.io;
18
19import java.io.PipedInputStream;
20import java.io.PipedOutputStream;
21import junit.framework.TestCase;
22
23public class OldAndroidPipedStreamTest extends TestCase {
24
25    private abstract static class TestThread extends Thread {
26        public abstract void runTest() throws Exception;
27
28        public final void run() {
29            try {
30                runTest();
31            } catch (Throwable e) {
32                exception = e;
33            }
34        }
35
36        Throwable exception;
37        int countRead = 0;
38    }
39
40    public void testA() throws Exception {
41
42        final PipedInputStream in = new PipedInputStream();
43        final PipedOutputStream out = new PipedOutputStream(in);
44
45        assertEquals(0, in.available());
46
47        TestThread reader, writer;
48
49        reader = new TestThread() {
50            Fibonacci fib = new Fibonacci();
51
52            @Override
53            public void runTest() throws Exception {
54                int readInt;
55                byte readByte;
56
57                for (; ;) {
58                    readInt = in.read();
59
60                    if (readInt == -1) {
61                        return;
62                    }
63
64                    readByte = (byte) readInt;
65                    assertEquals(readByte, (byte) fib.next());
66                    countRead++;
67                }
68            }
69        };
70
71        reader.start();
72
73        writer = new TestThread() {
74            Fibonacci fib = new Fibonacci();
75
76            @Override
77            public void runTest() throws Exception {
78                for (int i = 0; i < 2000; i++) {
79                    int toWrite = fib.next();
80                    out.write(toWrite);
81                }
82                out.close();
83            }
84        };
85
86        writer.start();
87
88
89        for (; ;) {
90            try {
91                reader.join(60 * 1000);
92                writer.join(1000);
93                break;
94            } catch (InterruptedException ex) {
95            }
96        }
97
98        assertEquals(2000, reader.countRead);
99
100        if (writer.exception != null) {
101            throw new Exception(writer.exception);
102        }
103        if (reader.exception != null) {
104            throw new Exception(reader.exception);
105        }
106    }
107
108    public void testB() throws Exception {
109        final PipedInputStream in = new PipedInputStream();
110        final PipedOutputStream out = new PipedOutputStream(in);
111
112        assertEquals(0, in.available());
113
114        TestThread reader, writer;
115
116        reader = new TestThread() {
117            Fibonacci fib = new Fibonacci();
118
119            @Override
120            public void runTest() throws Exception {
121                byte readBytes[] = new byte[5];
122                int ret;
123
124                for (; ;) {
125                    int nread = 0;
126                    while (nread < 5) {
127                        ret = in.read(readBytes, nread, readBytes.length - nread);
128
129                        if (ret == -1) {
130                            return;
131                        }
132                        nread += ret;
133                    }
134
135                    assertEquals(5, nread);
136
137                    int readInt = (((int) readBytes[0] & 0xff) << 24)
138                            | (((int) readBytes[1] & 0xff) << 16)
139                            | (((int) readBytes[2] & 0xff) << 8)
140                            | (((int) readBytes[3] & 0xff));
141
142
143                    assertEquals("Error at " + countRead, fib.next(), readInt);
144                    assertEquals("Error at " + countRead, 0, readBytes[4]);
145                    countRead++;
146                }
147            }
148        };
149
150        reader.start();
151
152        writer = new TestThread() {
153            Fibonacci fib = new Fibonacci();
154
155            @Override
156            public void runTest() throws Exception {
157                byte writeBytes[] = new byte[5];
158                for (int i = 0; i < 2000; i++) {
159                    int toWrite = fib.next();
160                    writeBytes[0] = (byte) (toWrite >> 24);
161                    writeBytes[1] = (byte) (toWrite >> 16);
162                    writeBytes[2] = (byte) (toWrite >> 8);
163                    writeBytes[3] = (byte) (toWrite);
164                    writeBytes[4] = 0;
165                    out.write(writeBytes, 0, writeBytes.length);
166                }
167                out.close();
168            }
169        };
170
171        writer.start();
172
173
174        for (; ;) {
175            try {
176                reader.join(60 * 1000);
177                writer.join(1000);
178                break;
179            } catch (InterruptedException ex) {
180            }
181        }
182
183        if (reader.exception != null) {
184            throw new Exception(reader.exception);
185        }
186        if (writer.exception != null) {
187            throw new Exception(writer.exception);
188        }
189
190        assertEquals(2000, reader.countRead);
191    }
192
193    public void testC() throws Exception {
194        final PipedInputStream in = new PipedInputStream();
195        final PipedOutputStream out = new PipedOutputStream(in);
196        final byte readBytes[] = new byte[1024 * 2];
197
198        assertEquals(0, in.available());
199
200        TestThread reader, writer;
201
202        reader = new TestThread() {
203            @Override
204            public void runTest() throws Exception {
205                int ret;
206
207                for (; ;) {
208                    int nread = 0;
209                    while (nread < readBytes.length) {
210                        ret = in.read(readBytes, nread, readBytes.length - nread);
211
212                        if (ret == -1) {
213                            return;
214                        }
215                        nread += ret;
216                    }
217                }
218            }
219        };
220
221        reader.start();
222
223        writer = new TestThread() {
224            Fibonacci fib = new Fibonacci();
225
226            @Override
227            public void runTest() throws Exception {
228                byte writeBytes[] = new byte[1024 * 2];
229                for (int i = 0; i < (writeBytes.length - 4); i += 4) {
230                    int toWrite = fib.next();
231                    writeBytes[i    ] = (byte) (toWrite >> 24);
232                    writeBytes[i + 1] = (byte) (toWrite >> 16);
233                    writeBytes[i + 2] = (byte) (toWrite >> 8);
234                    writeBytes[i + 3] = (byte) (toWrite);
235                }
236                out.write(writeBytes, 0, writeBytes.length);
237                out.close();
238            }
239        };
240
241        writer.start();
242
243
244        for (; ;) {
245            try {
246                reader.join(60 * 1000);
247                writer.join(1000);
248                break;
249            } catch (InterruptedException ex) {
250            }
251        }
252
253        if (reader.exception != null) {
254            throw new Exception(reader.exception);
255        }
256        if (writer.exception != null) {
257            throw new Exception(writer.exception);
258        }
259
260        Fibonacci fib = new Fibonacci();
261        for (int i = 0; i < (readBytes.length - 4); i += 4) {
262            int readInt = (((int) readBytes[i] & 0xff) << 24)
263                    | (((int) readBytes[i + 1] & 0xff) << 16)
264                    | (((int) readBytes[i + 2] & 0xff) << 8)
265                    | (((int) readBytes[i + 3] & 0xff));
266
267            assertEquals("Error at " + i, readInt, fib.next());
268        }
269    }
270
271    static class Fibonacci {
272        int n1 = -1;
273        int n2;
274
275        public int next() {
276            if (n1 < 0) {
277                n1 = 0;
278                return 0;
279            } else if (n1 == 0) {
280                n2 = 0;
281                n1 = 1;
282                return 1;
283            } else {
284                int ret = n1 + n2;
285                n2 = n1;
286                n1 = ret;
287                return ret;
288            }
289        }
290    }
291}
292