/*
* Copyright 2008-2009 LinkedIn, Inc
*
* 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 voldemort.store.readonly.checksum;
import java.security.NoSuchAlgorithmException;
import voldemort.utils.ByteUtils;
public abstract class CheckSum {
/**
* Update the checksum buffer to include input with startIndex and length.
* Following calls to multiple 'update's you need to call 'getCheckSum'
* which will reset the buffer as well
*
* @param input
* @param startIndex
* @param length
*/
public abstract void update(byte[] input, int startIndex, int length);
/**
* Get the checkSum of the buffer till now, after which buffer is reset
*/
public abstract byte[] getCheckSum();
/**
* Reset the checksum generator
*/
public abstract void reset();
/**
* Update and get checksum + reset the digest for next use
*
* @param input The input byte array
* @param startIndex The index to start reading from
* @param length The number of bytes to read
* @return Returns the checksum byte array
*/
public byte[] updateAndGetCheckSum(byte[] input, int startIndex, int length) {
update(input, startIndex, length);
return getCheckSum();
}
/**
* Update the underlying buffer using the integer
*
* @param number number to be stored in checksum buffer
*/
public void update(int number) {
byte[] numberInBytes = new byte[ByteUtils.SIZE_OF_INT];
ByteUtils.writeInt(numberInBytes, number, 0);
update(numberInBytes);
}
/**
* Update the underlying buffer using the short
*
* @param number number to be stored in checksum buffer
*/
public void update(short number) {
byte[] numberInBytes = new byte[ByteUtils.SIZE_OF_SHORT];
ByteUtils.writeShort(numberInBytes, number, 0);
update(numberInBytes);
}
/**
* Update the checksum buffer to include input
*
* @param input bytes added to the buffer
*/
public void update(byte[] input) {
update(input, 0, input.length);
}
public enum CheckSumType {
NONE,
ADLER32,
MD5,
CRC32;
public static CheckSumType toType(String val) {
return CheckSum.fromString(val);
}
}
public static CheckSum getInstance(CheckSumType type) {
if(type == CheckSumType.ADLER32) {
return new Adler32CheckSum();
} else if(type == CheckSumType.CRC32) {
return new CRC32CheckSum();
} else if(type == CheckSumType.MD5) {
try {
return new MD5CheckSum();
} catch(NoSuchAlgorithmException e) {
return null;
}
}
return null;
}
public static int checkSumLength(CheckSumType type) {
if(type == CheckSumType.ADLER32) {
return ByteUtils.SIZE_OF_LONG;
} else if(type == CheckSumType.CRC32) {
return ByteUtils.SIZE_OF_LONG;
} else if(type == CheckSumType.MD5) {
return 16;
}
return 0;
}
public static String toString(CheckSumType type) {
if(type == CheckSumType.ADLER32) {
return "adler32";
} else if(type == CheckSumType.CRC32) {
return "crc32";
} else if(type == CheckSumType.MD5) {
return "md5";
} else if(type == CheckSumType.NONE) {
return "none";
}
return "none";
}
public static CheckSumType fromString(String input) {
if(input.contains("adler32")) {
return CheckSumType.ADLER32;
} else if(input.contains("crc32")) {
return CheckSumType.CRC32;
} else if(input.contains("md5")) {
return CheckSumType.MD5;
}
return CheckSumType.NONE;
}
public static CheckSum getInstance(String algorithm) {
return getInstance(fromString(algorithm));
}
}