summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/filetransfer/util/ChunkList.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/filetransfer/util/ChunkList.java')
-rw-r--r--src/main/java/org/openslx/filetransfer/util/ChunkList.java32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/filetransfer/util/ChunkList.java b/src/main/java/org/openslx/filetransfer/util/ChunkList.java
index c692499..cd1bc69 100644
--- a/src/main/java/org/openslx/filetransfer/util/ChunkList.java
+++ b/src/main/java/org/openslx/filetransfer/util/ChunkList.java
@@ -1,5 +1,6 @@
package org.openslx.filetransfer.util;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -7,6 +8,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.zip.CRC32;
import org.apache.log4j.Logger;
import org.openslx.util.ThriftUtil;
@@ -74,6 +76,36 @@ public class ChunkList
}
/**
+ * Get CRC32 list in DNBD3 format. All checksums are little
+ * endian and prefixed by the crc32 sum of the list itself.
+ */
+ public synchronized byte[] getDnbd3Crc32List() throws IOException
+ {
+ byte buffer[] = new byte[ allChunks.size() * 4 + 4 ]; // 4 byte per chunk plus master
+ long nextChunkOffset = 0;
+ int nextCrcArrayPos = 4;
+ for ( FileChunk c : allChunks ) {
+ if ( c.crc32 == null ) {
+ throw new IllegalStateException( "Called on ChunkList that doesn't have crc32 enabled" );
+ }
+ if ( c.range.startOffset != nextChunkOffset ) {
+ throw new IllegalStateException( "Chunk list is not in order or has wrong chunk size" );
+ }
+ nextChunkOffset += FileChunk.CHUNK_SIZE;
+ c.getCrc32Le( buffer, nextCrcArrayPos );
+ nextCrcArrayPos += 4;
+ }
+ CRC32 masterCrc = new CRC32();
+ masterCrc.update( buffer, 4, buffer.length - 4 );
+ int value = (int)masterCrc.getValue();
+ buffer[3] = (byte) ( value >>> 24 );
+ buffer[2] = (byte) ( value >>> 16 );
+ buffer[1] = (byte) ( value >>> 8 );
+ buffer[0] = (byte)value;
+ return buffer;
+ }
+
+ /**
* Get a missing chunk, marking it pending.
*
* @return chunk marked as missing