Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added deltazip file header.

Adapted tests (incl. test bug fixes)
Some ByteBuffer-position-related cleanup.
  • Loading branch information...
commit d6d87db37486f2c7eb2ee88e9b603e91777dca20 1 parent 7abc6f6
Erik Søe Sørensen eriksoe authored
13 src/main/java/com/trifork/deltazip/DZUtil.java
@@ -25,12 +25,15 @@ public ByteBuffer pread(long pos, int len) throws IOException {
25 25 }
26 26
27 27 public byte[] applyAppendSpec(DeltaZip.AppendSpecification spec) {
  28 + int pos = (int) spec.prefix_size;
  29 + ByteBuffer tail = spec.new_tail;
  30 + int total_length = (int) (spec.prefix_size + tail.remaining());
28 31 try {
29   - int length = (int) (spec.prefix_size + spec.new_tail.remaining());
30   - ByteArrayOutputStream baos = new ByteArrayOutputStream(length);
31   - baos.write(data);
  32 + ByteArrayOutputStream baos = new ByteArrayOutputStream(total_length);
  33 + baos.write(data, 0, pos);
  34 +
32 35 WritableByteChannel channel = Channels.newChannel(baos);
33   - channel.write(spec.new_tail);
  36 + channel.write(tail);
34 37 channel.close();
35 38 return baos.toByteArray();
36 39 } catch (IOException ioe) {throw new RuntimeException(ioe);}
@@ -73,7 +76,7 @@ public ByteBuffer pread(long pos, int len) throws IOException {
73 76 public void applyAppendSpec(DeltaZip.AppendSpecification spec) throws IOException {
74 77 long pos = spec.prefix_size;
75 78 ByteBuffer tail = spec.new_tail;
76   - long total_length = (spec.prefix_size + tail.remaining());
  79 + long total_length = spec.prefix_size + tail.remaining();
77 80
78 81 while (tail.hasRemaining()) {
79 82 int w = file.write(tail, pos);
33 src/main/java/com/trifork/deltazip/DeltaZip.java
@@ -16,12 +16,16 @@
16 16
17 17 //==================== Constants =======================================
18 18
  19 + public static final int DELTAZIP_MAGIC_HEADER = 0xCEB47A10;
  20 + public static final int FILE_HEADER_LENGTH = 4;
  21 +
19 22 private static final int VERSION_SIZE_BITS = 28;
20 23 private static final int VERSION_SIZE_LIMIT = 1 << VERSION_SIZE_BITS;
21 24
22 25 public static final int METHOD_UNCOMPRESSED = 0;
23 26 public static final int METHOD_CHUNKED = 2;
24 27
  28 +
25 29 protected static final CompressionMethod[] COMPRESSION_METHODS;
26 30 protected static final CompressionMethod UNCOMPRESSED_INSTANCE = new UncompressedMethod();
27 31 protected static final CompressionMethod CHUNKED_INSTANCE = new ChunkedMethod();
@@ -49,6 +53,7 @@ private static void insertCM(CompressionMethod[] table, CompressionMethod cm) {
49 53
50 54 public DeltaZip(Access access) throws IOException {
51 55 this.access = access;
  56 + check_magic_header();
52 57 set_cursor_at_end();
53 58 }
54 59
@@ -75,17 +80,19 @@ public void previous() throws IOException {
75 80 * Has the side effect of placing the cursor at the end.
76 81 */
77 82 public AppendSpecification add(ByteBuffer new_version) throws IOException {
78   - int save_pos = new_version.position();
79   -
80 83 set_cursor_at_end();
81 84 ExtByteArrayOutputStream baos = new ExtByteArrayOutputStream();
  85 +
  86 + // If the file is empty, add a header:
  87 + if (current_pos==0) baos.writeBigEndianInteger(DELTAZIP_MAGIC_HEADER, 4);
  88 +
82 89 ByteBuffer last_version = get();
  90 +
83 91 if (last_version != null) {
84 92 pack_compressed(last_version, allToByteArray(new_version), baos);
85 93 }
86 94 pack_uncompressed(new_version, baos);
87 95
88   - new_version.position(save_pos); // Restore as-was.
89 96 return new AppendSpecification(current_pos, baos.toByteArray());
90 97 }
91 98
@@ -95,6 +102,10 @@ public AppendSpecification add(ByteBuffer new_version) throws IOException {
95 102 public AppendSpecification add(Iterator<ByteBuffer> versions_to_add) throws IOException {
96 103 set_cursor_at_end();
97 104 ExtByteArrayOutputStream baos = new ExtByteArrayOutputStream();
  105 +
  106 + // If the file is empty, add a header:
  107 + if (current_pos==0) baos.writeBigEndianInteger(DELTAZIP_MAGIC_HEADER, 4);
  108 +
98 109 ByteBuffer prev_version = get();
99 110
100 111 while (versions_to_add.hasNext()) {
@@ -110,6 +121,20 @@ public AppendSpecification add(Iterator<ByteBuffer> versions_to_add) throws IOEx
110 121
111 122 //==================== Internals =======================================
112 123
  124 + protected void check_magic_header() throws IOException {
  125 + long size = access.getSize();
  126 + if (size == 0) return; // OK (empty)
  127 + if (size < FILE_HEADER_LENGTH ||
  128 + read_magic_header() != DELTAZIP_MAGIC_HEADER)
  129 + throw new IOException("Not a deltazip file (invalid header)");
  130 + }
  131 +
  132 + protected int read_magic_header() throws IOException {
  133 + ByteBuffer header = access.pread(0,4);
  134 + int magic = header.getInt(0);
  135 + return magic;
  136 + }
  137 +
113 138 protected void set_cursor_at_end() throws IOException {
114 139 set_initial_position();
115 140 if (hasPrevious()) previous();
@@ -156,7 +181,7 @@ protected void pack_compressed(ByteBuffer version, byte[] ref_version, ExtByteAr
156 181 protected void pack_entry(ByteBuffer version, byte[] ref_version, CompressionMethod cm, ExtByteArrayOutputStream dst) {
157 182 int tag_blank = dst.insertBlank(4);
158 183 int size_before = dst.size();
159   - cm.compress(version, ref_version, dst);
  184 + cm.compress(version.duplicate(), ref_version, dst);
160 185 int size_after = dst.size();
161 186 int length = size_after - size_before;
162 187
10 src/test/java/com/trifork/deltazip/DeltaZipTest.java
@@ -23,6 +23,7 @@ public void test_read_known() throws Exception {
23 23
24 24 /** Chunked-deflate, no prefix/suffix. */
25 25 byte[] two_revs1 = {
  26 + (byte)0xCE, (byte)0xB4, 0x7A, 0x10,
26 27 32,0,0,7,0,0,4,(byte)243,
27 28 0,113,0,32,0,0,7,0,
28 29 0,0,13,72,101,108,108,111,
@@ -31,6 +32,7 @@ public void test_read_known() throws Exception {
31 32
32 33 /** Chunked-deflate, using prefix. */
33 34 byte[] two_revs2 = {
  35 + (byte)0xCE, (byte)0xB4, 0x7A, 0x10,
34 36 32,0,0,5,8,0,2,0,
35 37 4,32,0,0,5,0,0,0,
36 38 13,72,101,108,108,111,44,32,
@@ -84,7 +86,7 @@ public void test_add_get_with(byte[] file0, ByteBuffer rev1, ByteBuffer rev2) th
84 86 ByteArrayAccess access1 = new ByteArrayAccess(file1);
85 87 DeltaZip dz1 = new DeltaZip(access1);
86 88 AppendSpecification app2 = dz1.add(rev2);
87   - byte[] file2 = access0.applyAppendSpec(app2);
  89 + byte[] file2 = access1.applyAppendSpec(app2);
88 90 dump("file2=", file2);
89 91
90 92 ByteArrayAccess access2 = new ByteArrayAccess(file2);
@@ -110,14 +112,12 @@ public void test_add_get_with(byte[] file0, ByteBuffer rev1, ByteBuffer rev2) th
110 112 //======================================================================
111 113
112 114 public static String toString(ByteBuffer buf) {
113   - int save_pos = buf.position();
114   - String r = new String(DeltaZip.toByteArray(buf));
115   - buf.position(save_pos);
  115 + String r = new String(DeltaZip.allToByteArray(buf.duplicate()));
116 116 return r;
117 117 }
118 118
119 119 public static void dump(String s, ByteBuffer buf) {
120   - dump(s, DeltaZip.toByteArray(buf));
  120 + dump(s, DeltaZip.allToByteArray(buf.duplicate()));
121 121 }
122 122
123 123 public static void dump(String s, byte[] buf) {

0 comments on commit d6d87db

Please sign in to comment.
Something went wrong with that request. Please try again.