001
014
015 package com.liferay.portal.kernel.io.delta;
016
017 import java.io.IOException;
018
019 import java.nio.ByteBuffer;
020 import java.nio.channels.ReadableByteChannel;
021
022 import java.security.MessageDigest;
023 import java.security.NoSuchAlgorithmException;
024
025
028 public class RollingChecksum {
029
030 public RollingChecksum(
031 ReadableByteChannel readableByteChannel, int blockLength)
032 throws IOException {
033
034 _blockLength = blockLength;
035 _byteChannelReader = new ByteChannelReader(
036 readableByteChannel, _blockLength * DeltaUtil.BUFFER_FACTOR);
037
038 generateWeakChecksum();
039 }
040
041 public int currentBlockLength() {
042 return Math.min(_byteChannelReader.remaining(), _blockLength);
043 }
044
045
048 public byte getFirstByte() {
049 return _byteChannelReader.get(0);
050 }
051
052
055 public int getPosition() {
056 return _filePosition;
057 }
058
059 public boolean hasNext() throws IOException {
060 _byteChannelReader.maybeRead(1);
061
062 if (_byteChannelReader.remaining() >= 1) {
063 return true;
064 }
065 else {
066 return false;
067 }
068 }
069
070 public void nextBlock() throws IOException {
071 _filePosition += _byteChannelReader.skip(_blockLength);
072
073 generateWeakChecksum();
074 }
075
076 public void nextByte() throws IOException {
077 int blockLength = currentBlockLength();
078 int x = _byteChannelReader.get();
079
080 _filePosition++;
081
082 _a -= x;
083 _b -= blockLength * x;
084
085 _byteChannelReader.maybeRead(_blockLength);
086
087 if (_byteChannelReader.remaining() >= _blockLength) {
088 x = _byteChannelReader.get(_blockLength - 1);
089
090 _a += x;
091 _b += _a;
092 }
093 }
094
095
098 public byte[] strongChecksum() {
099 ByteBuffer buffer = _byteChannelReader.getBuffer();
100
101 int oldPosition = buffer.position();
102 int oldLimit = buffer.limit();
103
104 buffer.limit(buffer.position() + currentBlockLength());
105
106 _messageDigest.update(buffer);
107
108 buffer.limit(oldLimit);
109 buffer.position(oldPosition);
110
111 return _messageDigest.digest();
112 }
113
114
117 public int weakChecksum() {
118 return (_a & 0xffff) | (_b << 16);
119 }
120
121 protected void generateWeakChecksum() throws IOException {
122 _byteChannelReader.maybeRead(_blockLength);
123
124 _a = 0;
125 _b = 0;
126
127 for (int i = 0; i < currentBlockLength(); i++) {
128 _a += _byteChannelReader.get(i);
129 _b += _a;
130 }
131 }
132
133 private static MessageDigest _messageDigest;
134
135 private int _a;
136 private int _b;
137 private int _blockLength;
138 private ByteChannelReader _byteChannelReader;
139 private int _filePosition;
140
141 static {
142 try {
143 _messageDigest = MessageDigest.getInstance("MD5");
144 }
145 catch (NoSuchAlgorithmException nsae) {
146 throw new ExceptionInInitializerError(nsae);
147 }
148 }
149
150 }