001/*
002 * Syncany, www.syncany.org
003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package org.syncany.chunk;
019
020import java.security.NoSuchAlgorithmException;
021
022/**
023 * A fingerprinter is used in content based {@link Chunker}s to determine at which  
024 * byte to break a file into {@link Chunk}s. 
025 * 
026 * <p>Implementations should make sure that the underlying algorithm is fast, because
027 * the {@link #roll(byte) roll()}-method is called for each byte of a file. It
028 * should rely on a rolling checksum algorithm (also: rolling hash) to reach optimal
029 * performance.
030 * 
031 * @see <a href="http://en.wikipedia.org/wiki/Rolling_hash">http://en.wikipedia.org/wiki/Rolling_hash</a>
032 * @author Philipp C. Heckel (philipp.heckel@gmail.com)
033 */
034public abstract class Fingerprinter {    
035    public static Fingerprinter getInstance(String name) throws NoSuchAlgorithmException {
036        try {
037            Class<?> clazz = Class.forName(Fingerprinter.class.getPackage().getName()+"."+name+Fingerprinter.class.getSimpleName());
038            return (Fingerprinter) clazz.newInstance();
039        }
040        catch (Exception e) {
041            throw new NoSuchAlgorithmException("No such fingerprinting algorithm: "+name, e);
042        }        
043    }
044    
045    /**
046     * Return the value of the currently computed checksum.
047     * @return The currently computed checksum.
048     */
049    public abstract int getValue();
050    
051    /**
052     * Reset the checksum.
053     */
054    public abstract void reset();
055    
056    /**
057     * "Roll" the checksum, i.e. update the underlying 
058     * rolling checksum by the given content byte.
059     *
060     * @param bt The next byte.
061     */
062    public abstract void roll(byte bt);
063    
064    /**
065     * Update the checksum with an entirely different block, and
066     * potentially a different block length.
067     *
068     * @param buf The byte array that holds the new block.
069     * @param off From whence to begin reading.
070     * @param len The length of the block to read.
071     */    
072    public abstract void check(byte[] buf, int off, int len);
073    
074    /**
075         * Returns a string representation of the fingerprinter
076         * implementation.
077         */
078    public abstract String toString();
079}