de.rub.syssec.saaf.misc.ByteUtils.java Source code

Java tutorial

Introduction

Here is the source code for de.rub.syssec.saaf.misc.ByteUtils.java

Source

/* Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
 *                  Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
 *
 * Licensed under the Educational Community License Version 1.0 (the "License");
 * By obtaining, using and/or copying this Original Work, you agree that you have read,
 * understand, and will comply with the terms and conditions of the Educational Community License.
 * You may obtain a copy of the License at:
 *
 *      http://cvs.sakaiproject.org/licenses/license_1_0.html
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
package de.rub.syssec.saaf.misc;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Arrays;

import org.apache.http.util.ByteArrayBuffer;

/**
 * Byte utilities.
 * 
 * Some methods copied from http://www.java2s.com/Code/Java/Collections-Data-Structure/
 * Doesthisbytearraybeginwithmatcharraycontent.htm
 * 
 */
public class ByteUtils {

    /**
     * Does this byte array begin with match array content?
     * 
     * @param source
     *            Byte array to examine
     * @param match
     *            Byte array to locate in <code>source</code>
     * @return true If the starting bytes are equal
     */
    public static boolean startsWith(byte[] source, byte[] match) {
        return startsWith(source, 0, match);
    }

    /**
     * Does this byte array begin with match array content? The check is NOT case sensitive!
     * 
     * @param source
     *            Byte array to examine
     * @param offset
     *            An offset into the <code>source</code> array
     * @param match
     *            Byte array to locate in <code>source</code>
     * @return true If the starting bytes are equal
     */
    public static boolean startsWith(byte[] source, int offset, byte[] match) {

        if (match.length > (source.length - offset)) {
            return false;
        }

        for (int i = 0; i < match.length; i++) {
            if (source[offset + i] != match[i]) {
                // ignore cases
                if (source[offset + i] >= 65 && source[offset + i] <= 90 && source[offset + i] + 32 == match[i]) {
                    continue;
                } else if (source[offset + i] >= 97 && source[offset + i] <= 122
                        && source[offset + i] - 32 == match[i]) {
                    continue;
                } else
                    return false;
            }
        }
        return true;
    }

    public static boolean endsWith(byte[] source, char c) {
        return endsWith(source, new byte[] { (byte) c });
    }

    /**
     * Does this byte array end with match array content? The check is NOT case sensitive!
     */
    public static boolean endsWith(byte[] source, byte[] match) {
        if (match.length > (source.length)) {
            return false;
        }

        for (int i = 0; i < match.length; i++) {
            if (match[i] != source[source.length - match.length + i]) {
                if (match[i] >= 65 && match[i] <= 90 && match[i] + 32 == source[source.length - match.length + i]) {
                    continue;
                } else if (match[i] >= 97 && match[i] <= 122
                        && match[i] - 32 == source[source.length - match.length + i]) {
                    continue;
                }
                return false;
            }
        }
        return true;
    }

    /**
     * Does the source array equal the match array?
     * 
     * @param source
     *            Byte array to examine
     * @param offset
     *            An offset into the <code>source</code> array
     * @param match
     *            Byte array to locate in <code>source</code>
     * @return true If the two arrays are equal
     */
    public static boolean equals(byte[] source, byte[] match) {

        if (match.length != source.length) {
            return false;
        }
        return startsWith(source, 0, match);
    }

    /**
     * Copies bytes from the source byte array to the destination array
     * 
     * @param source
     *            The source array
     * @param srcBegin
     *            Index of the first source byte to copy
     * @param srcEnd
     *            Index after the last source byte to copy
     * @param destination
     *            The destination array
     * @param dstBegin
     *            The starting offset in the destination array
     */
    public static void getBytes(byte[] source, int srcBegin, int srcEnd, byte[] destination, int dstBegin) {
        System.arraycopy(source, srcBegin, destination, dstBegin, srcEnd - srcBegin);
    }

    /**
     * Return a new byte array containing a sub-portion of the source array
     * 
     * @param srcBegin
     *            The beginning index (inclusive)
     * @param srcEnd
     *            The ending index (exclusive)
     * @return The new, populated byte array
     */
    public static byte[] subbytes(byte[] source, int srcBegin, int srcEnd) {
        byte destination[];

        destination = new byte[srcEnd - srcBegin];
        getBytes(source, srcBegin, srcEnd, destination, 0);

        return destination;
    }

    /**
     * Return a new byte array containing a sub-portion of the source array
     * 
     * @param srcBegin
     *            The beginning index (inclusive)
     * @return The new, populated byte array
     */
    public static byte[] subbytes(byte[] source, int srcBegin) {
        return subbytes(source, srcBegin, source.length);
    }

    /**
     * Return the array as a printable string.
     * 
     * @param buffer
     * @param breakLines Insert \n in returned String if CRLF was found
     * @return
     */
    public static String dumpArray(byte[] buffer, boolean breakLines) {
        StringBuilder sb = new StringBuilder();
        boolean lastOneIsR = false;
        for (byte b : buffer) {
            if (b >= 32 && b <= 126)
                sb.append(new String(new byte[] { b }));
            else if (b == 10) {
                sb.append("\\n");
                if (lastOneIsR) {
                    if (breakLines)
                        sb.append("\n");
                    lastOneIsR = false;
                }
            } else if (b == 13) {
                sb.append("\\r");
                lastOneIsR = true;
            } else if (b == 0)
                sb.append("\\0");
            else
                sb.append("?");
        }
        return sb.toString();
    }

    /**
     * Read a line from an inputstream into a byte buffer. A line might end with a LF or an CRLF. CR's are accepted inside a line and
     * are not understood as a beginning new line. This should work therefore on Mac OS X, Unix, Linux and Windows.
     * 
     * See http://en.wikipedia.org/wiki/Newline for more.
     *  
     * @param in the inputstream
     * @param maxSize the maximum amount of bytes to read until a CRLF or LF is reached, a value of zero or smaller disables a limit (use w/ care!)
     * @return the buffer where read bytes are appended, this buffer will not contain any CR's or or CRLF's at the end of the array. Null is
     * returned if EOF is reached.
     * @throws IOException if something is wrong w/ the stream or the maxSize is reached
     */
    public static byte[] parseLine(BufferedInputStream in, int maxSize) throws IOException {
        ByteArrayBuffer bab = new ByteArrayBuffer(512);
        int b;
        while (true) {
            if (!(maxSize <= 0 || bab.length() <= maxSize)) {
                throw new IOException("Maximal bytearraybuffer size of " + maxSize + " exceeded!");
            }
            b = in.read();
            if (b == -1) {
                if (bab.isEmpty()) {
                    // we have nothing read yet and could nothing read, we will therefore return 'null' as this
                    // indicates EOF.
                    return null;
                } else {
                    // return what we got so far
                    return bab.toByteArray();
                }
            }
            // CRLF case
            if (b == '\r') { // check if we find a \n
                int next = in.read();
                if (b == -1) {
                    // EOF; return what we got
                    return bab.toByteArray();
                } else if (next == '\n') { // we did
                    in.mark(-1); // rest mark
                    return bab.toByteArray(); // return the line without CRLF
                } else {
                    // found no CRLF but only a CR and some other byte, so we need to add both to the buffer and proceed
                    bab.append('\r');
                    bab.append(b);
                }
            }
            // LF case
            else if (b == '\n') { // we found a LF and therefore the end of a line
                return bab.toByteArray();
            } else { // we just found a byte which is happily appended
                bab.append(b);
            }
        }
    }

    /**
     * http://stackoverflow.com/questions/80476/how-to-concatenate-two-arrays-in
     * -java
     * 
     * @param <T>
     * @param first
     * @param rest
     * @return
     */
    public static byte[] concatAll(byte[] first, byte[]... rest) {
        int totalLength = first.length;
        for (byte[] array : rest) {
            totalLength += array.length;
        }
        byte[] result = Arrays.copyOf(first, totalLength);
        int offset = first.length;
        for (byte[] array : rest) {
            System.arraycopy(array, 0, result, offset, array.length);
            offset += array.length;
        }
        return result;
    }

    /**
     * Checks if pattern is contained in source. This is just a wrapped KMP indexOf().
     * @param source
     * @param pattern
     * @return
     */
    public static boolean contains(byte[] source, byte[] pattern) {
        return KMP.indexOf(source, pattern) < 0 ? false : true;
    }

    /**
     * Checks if pattern is contained in source. This is just a wrapped KMP indexOf().
     * @param source
     * @param pattern
     * @return
     */
    public static boolean contains(byte[] source, char c) {
        return KMP.indexOf(source, new byte[] { (byte) c }) < 0 ? false : true;
    }

    public static int indexOf(byte[] source, char c) {
        return indexOf(source, c, 0);
    }

    public static int indexOf(byte[] source, char c, int offset) {
        for (int i = offset; i < source.length; i++) {
            if (source[i] == c)
                return i;
        }
        return -1;
    }

    /**
     * Searches forwards
     * @param source
     * @param c
     * @return
     */
    public static int indexOfReverse(byte[] source, char c) {
        return indexOfReverse(source, c, source.length - 1);
    }

    /**
     * Searches backwards
     */
    public static int indexOfReverse(byte[] source, char c, int offset) {
        for (int i = offset; i >= 0; i--) {
            if (source[i] == c)
                return i;
        }
        return -1;
    }

    /**
     * Get the first part of the array until a chosen char is found.
     * @param source
     * @param c the char to split at
     * @param offset the offest of source
     * @return
     */
    public static byte[] splitAtFirstOccurence(byte[] source, char c, int offset) {
        int index = indexOf(source, c, offset);
        if (index < 0)
            return source;
        else {
            return subbytes(source, 0, index);
        }
    }

    /**
     * Get the last part of the array until a chosen char is found, the char is searched from the end to the beginning of source.
     * @param source
     * @param c
     * @param offset the offest of source, from the beginning, NOT the end.
     * @return
     */
    public static byte[] splitAtLastOccurence(byte[] source, char c, int offset) {
        int index = indexOfReverse(source, c, offset);
        if (index < 0)
            return source;
        else {
            return subbytes(source, index, source.length);
        }
    }
}