001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.codec.binary;
019    
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.util.Random;
023    
024    /**
025     * This random data was encoded by OpenSSL. Java had nothing to do with it. This data helps us test interop between
026     * Commons-Codec and OpenSSL. Notice that OpenSSL creates 64 character lines instead of the 76 of Commons-Codec.
027     *
028     * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
029     * @version $Id $
030     * @since 1.4
031     */
032    public class Base32TestData {
033    
034        static final String STRING_FIXTURE = "Hello World";
035    
036        static final String BASE32_FIXTURE = "JBSWY3DPEBLW64TMMQ======\r\n";
037    //  static final String BASE32HEX_FIXTURE = "91IMOR3F41BMUSJCCG======";
038    
039        // Some utility code to help test chunked reads of the InputStream.
040    
041        private final static int SIZE_KEY = 0;
042        private final static int LAST_READ_KEY = 1;
043    
044        static byte[] streamToBytes(final InputStream in) throws IOException {
045            // new byte[7] is obviously quite slow, but helps exercise the code.
046            return streamToBytes(in, new byte[7]);
047        }
048    
049        static byte[] streamToBytes(final InputStream in, byte[] buf) throws IOException {
050            try {
051                int[] status = fill(buf, 0, in);
052                int size = status[SIZE_KEY];
053                int lastRead = status[LAST_READ_KEY];
054                while (lastRead != -1) {
055                    buf = resizeArray(buf);
056                    status = fill(buf, size, in);
057                    size = status[SIZE_KEY];
058                    lastRead = status[LAST_READ_KEY];
059                }
060                if (buf.length != size) {
061                    byte[] smallerBuf = new byte[size];
062                    System.arraycopy(buf, 0, smallerBuf, 0, size);
063                    buf = smallerBuf;
064                }
065            }
066            finally {
067                in.close();
068            }
069            return buf;
070        }
071    
072        private static int[] fill(final byte[] buf, final int offset, final InputStream in)
073                throws IOException {
074            int read = in.read(buf, offset, buf.length - offset);
075            int lastRead = read;
076            if (read == -1) {
077                read = 0;
078            }
079            while (lastRead != -1 && read + offset < buf.length) {
080                lastRead = in.read(buf, offset + read, buf.length - read - offset);
081                if (lastRead != -1) {
082                    read += lastRead;
083                }
084            }
085            return new int[]{offset + read, lastRead};
086        }
087    
088        private static byte[] resizeArray(final byte[] bytes) {
089            byte[] biggerBytes = new byte[bytes.length * 2];
090            System.arraycopy(bytes, 0, biggerBytes, 0, bytes.length);
091            return biggerBytes;
092        }
093    
094    
095        /**
096         * Returns an encoded and decoded copy of the same random data.
097         *
098         * @param codec the codec to use
099         * @param size amount of random data to generate and encode
100         * @return two byte[] arrays:  [0] = decoded, [1] = encoded
101         */
102        static byte[][] randomData(BaseNCodec codec, int size) {
103            Random r = new Random();
104            byte[] decoded = new byte[size];
105            r.nextBytes(decoded);
106            byte[] encoded = codec.encode(decoded);
107            return new byte[][] {decoded, encoded};
108        }
109    
110        /**
111         * Tests the supplied byte[] array to see if it contains the specified byte c.
112         *
113         * @param bytes byte[] array to test
114         * @param c byte to look for
115         * @return true if bytes contains c, false otherwise
116         */
117        static boolean bytesContain(byte[] bytes, byte c) {
118            for (byte b : bytes) {
119                if (b == c) { return true; }
120            }
121            return false;
122        }
123    
124    }