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 public void nextByte() throws IOException {
076 int blockLength = currentBlockLength();
077 int x = _byteChannelReader.get();
078
079 _filePosition++;
080
081 _a -= x;
082 _b -= blockLength * x;
083
084 _byteChannelReader.maybeRead(_blockLength);
085
086 if (_byteChannelReader.remaining() >= _blockLength) {
087 x = _byteChannelReader.get(_blockLength - 1);
088
089 _a += x;
090 _b += _a;
091 }
092 }
093
094
097 public byte[] strongChecksum() {
098 ByteBuffer buffer = _byteChannelReader.getBuffer();
099
100 int oldPosition = buffer.position();
101 int oldLimit = buffer.limit();
102
103 buffer.limit(buffer.position() + currentBlockLength());
104
105 _messageDigest.update(buffer);
106
107 buffer.limit(oldLimit);
108 buffer.position(oldPosition);
109
110 return _messageDigest.digest();
111 }
112
113
116 public int weakChecksum() {
117 return (_a & 0xffff) | (_b << 16);
118 }
119
120 protected void generateWeakChecksum() throws IOException {
121 _byteChannelReader.maybeRead(_blockLength);
122
123 _a = 0;
124 _b = 0;
125
126 for (int i = 0; i < currentBlockLength(); i++) {
127 _a += _byteChannelReader.get(i);
128 _b += _a;
129 }
130 }
131
132 private static MessageDigest _messageDigest;
133
134 private int _a;
135 private int _b;
136 private int _blockLength;
137 private ByteChannelReader _byteChannelReader;
138 private int _filePosition;
139
140 static {
141 try {
142 _messageDigest = MessageDigest.getInstance("MD5");
143 }
144 catch (NoSuchAlgorithmException nsae) {
145 throw new ExceptionInInitializerError(nsae);
146 }
147 }
148
149 }