blob: 94d355a119a4209b5d31f1d43db8908b579887be [file] [log] [blame]
/*******************************************************************************
* Copyright 2014 Trevor Robinson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.scurrilous.circe;
import java.nio.ByteBuffer;
/**
* Represents a stateful hash function, which can accumulate input from multiple
* method calls and provide output in various forms. Stateful hash functions
* should not be used concurrently from multiple threads.
* <p>
* Stateful hash functions can be incremental or non-incremental. Incremental
* hashing allows calling the {@link #update} methods to continue hashing using
* accumulated state after calling any of the output methods (such as
* {@link #getBytes}). Non-incremental hash functions <i>require</i> calling
* {@link #reset} to reinitialize the state between calling an output method and
* an update method.
*/
public interface StatefulHash extends Hash {
/**
* Returns a new instance of this stateful hash function reset to the
* initial state.
*
* @return a new instance of this hash in the initial state
*/
StatefulHash createNew();
/**
* Returns whether this hash function supports incremental hashing.
* Incremental hashing allows calling the {@link #update} methods to
* continue hashing using accumulated state after calling any of the output
* methods (such as {@link #getBytes}). Non-incremental hash functions
* require calling {@link #reset} to reinitialize the state between calling
* an output method and an update method.
*
* @return true if incremental hashing is supported, false if not
*/
boolean supportsIncremental();
/**
* Resets this hash function to its initial state. Resetting the state is
* required for non-incremental hash functions after any output methods have
* been called.
*/
void reset();
/**
* Updates the state of this hash function with the entire given input
* array.
*
* @param input the input array
* @throws IllegalStateException if this hash function is not incremental
* but an output method has been called without an intervening
* call to {@link #reset}
*/
void update(byte[] input);
/**
* Updates the state of this hash function with the given range of the given
* input array.
*
* @param input the input array
* @param index the starting index of the first input byte
* @param length the length of the input range
* @throws IllegalArgumentException if length is negative
* @throws IndexOutOfBoundsException if index is negative or
* {@code index + length} is greater than the array length
* @throws IllegalStateException if this hash function is not incremental
* but an output method has been called without an intervening
* call to {@link #reset}
*/
void update(byte[] input, int index, int length);
/**
* Updates the state of this hash function with the remaining contents of
* the given input buffer. This method leaves the buffer position at the
* limit.
*
* @param input the input buffer
* @throws IllegalStateException if this hash function is not incremental
* but an output method has been called without an intervening
* call to {@link #reset}
*/
void update(ByteBuffer input);
/**
* Updates the state of this hash function with memory with the given
* address and length. The arguments are generally not checked in any way
* and will likely lead to a VM crash or undefined results if invalid.
*
* @param address the base address of the input
* @param length the length of the input
* @throws UnsupportedOperationException if this function does not support
* unsafe memory access
* @throws IllegalStateException if this hash function is not incremental
* but an output method has been called without an intervening
* call to {@link #reset}
* @see #supportsUnsafe()
*/
void update(long address, long length);
/**
* Returns a new byte array containing the output of this hash function. The
* caller may freely modify the contents of the array.
*
* @return a new byte array containing the hash output
*/
byte[] getBytes();
/**
* Writes the output of this hash function into the given byte array at the
* given offset.
*
* @param output the destination array for the output
* @param index the starting index of the first output byte
* @param maxLength the maximum number of bytes to write
* @return the number of bytes written
* @throws IllegalArgumentException if {@code maxLength} is negative
* @throws IndexOutOfBoundsException if {@code index} is negative or if
* {@code index + maxLength} is greater than the array length
*/
int getBytes(byte[] output, int index, int maxLength);
/**
* Returns the first byte of the output of this hash function.
*
* @return the first output byte
*/
byte getByte();
/**
* Returns the first two bytes of the output of this hash function as a
* little-endian {@code short}. If the output is less than two bytes, the
* remaining bytes are set to 0.
*
* @return the first two output bytes as a short
*/
short getShort();
/**
* Returns the first four bytes of the output of this hash function as a
* little-endian {@code int}. If the output is less than four bytes, the
* remaining bytes are set to 0.
*
* @return the first four output bytes as an int
*/
int getInt();
/**
* Returns the first eight bytes of the output of this hash function as a
* little-endian {@code long}. If the output is less than eight bytes, the
* remaining bytes are set to 0.
*
* @return the first eight output bytes as a long
*/
long getLong();
}