1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.jdkim.canon;
21  
22  import java.io.BufferedInputStream;
23  import java.io.ByteArrayInputStream;
24  import java.io.ByteArrayOutputStream;
25  import java.io.IOException;
26  import java.io.OutputStream;
27  import java.security.NoSuchAlgorithmException;
28  import java.util.Arrays;
29  
30  import junit.framework.TestCase;
31  
32  /**
33   * Base class useful when testing outputstreams It simplify the job of testing
34   * any weird chunking during the streamin.
35   */
36  public abstract class AbstractOutputStreamTestCase extends TestCase {
37  
38      protected AbstractOutputStreamTestCase() {
39      }
40  
41      public void chunker(BufferedInputStream is, OutputStream os)
42              throws IOException {
43          byte[] buffer = new byte[307];
44          int read;
45          int chunksCounter = 0; // 
46          int bytesCounter = 0; // 
47          while ((read = is.read(buffer, 0,
48                  (buffer.length / (chunksCounter % 8 + 1)))) > 0) {
49              if (read == buffer.length && chunksCounter % 13 % 7 % 2 == 1) {
50                  os.write(buffer);
51              } else if (chunksCounter % 11 != 0) {
52                  os.write(buffer, 0, read);
53              } else
54                  for (int i = 0; i < read; i++) {
55                      os.write(buffer[i]);
56                  }
57              if (chunksCounter % 3 == 2)
58                  os.flush();
59              chunksCounter++;
60              bytesCounter += read;
61          }
62          os.close();
63      }
64  
65      public void chunker(byte[] data, OutputStream os) throws IOException {
66          BufferedInputStream is = new BufferedInputStream(
67                  new ByteArrayInputStream(data));
68          chunker(is, os);
69      }
70  
71      public void writeChunk(OutputStream os, byte[] data, int from, int len)
72              throws IOException {
73          if (len == 1)
74              os.write(data[from]);
75          else if (len == data.length)
76              os.write(data);
77          else
78              os.write(data, from, len);
79      }
80  
81      public void assertArrayEquals(String explanation, byte[] expected,
82              byte[] actual) {
83          if (!Arrays.equals(expected, actual)) {
84              assertEquals(explanation, new String(expected), new String(actual));
85          }
86      }
87  
88      public void assertArrayEquals(byte[] expected, byte[] actual) {
89          if (!Arrays.equals(expected, actual)) {
90              assertEquals(new String(expected), new String(actual));
91          }
92      }
93  
94      protected OutputStream newInstance(ByteArrayOutputStream bos) {
95          throw new IllegalStateException(
96                  "Implement newInstance in order to use extensive chunker");
97      }
98  
99      /**
100      * An extensive checker for streams. It split the buffer every possibile 1,
101      * to and 3 part sequences and check the results.
102      * 
103      * @throws NoSuchAlgorithmException
104      * @throws IOException
105      */
106     public void extensiveChunker(byte[] data, byte[] expectedData)
107             throws IOException {
108         for (int i = 0; i < data.length; i++)
109             for (int j = i; j < data.length; j++) {
110                 ByteArrayOutputStream bos = new ByteArrayOutputStream();
111                 OutputStream os = newInstance(bos);
112 
113                 writeChunk(os, data, 0, i);
114                 writeChunk(os, data, i, j - i);
115                 writeChunk(os, data, j, data.length - j);
116                 os.close();
117 
118                 assertArrayEquals("i=" + i + ", j=" + j + ", l=" + data.length,
119                         expectedData, bos.toByteArray());
120             }
121     }
122 
123 }