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
018package org.apache.commons.codec.binary;
019
020import java.io.IOException;
021import java.io.InputStream;
022import 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 */
032public 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                final 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        final 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(final BaseNCodec codec, final int size) {
103        final Random r = new Random();
104        final byte[] decoded = new byte[size];
105        r.nextBytes(decoded);
106        final 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(final byte[] bytes, final byte c) {
118        for (final byte b : bytes) {
119            if (b == c) { return true; }
120        }
121        return false;
122    }
123
124}