1 // Auto-generated: DO NOT EDIT
3 package net.jpountz.lz4;
5 import static net.jpountz.lz4.LZ4Constants.*;
6 import static net.jpountz.lz4.LZ4Utils.*;
8 import java.nio.ByteBuffer;
9 import java.util.Arrays;
11 import net.jpountz.util.ByteBufferUtils;
12 import net.jpountz.util.SafeUtils;
17 final class LZ4JavaSafeCompressor extends LZ4Compressor {
19 public static final LZ4Compressor INSTANCE = new LZ4JavaSafeCompressor();
21 static int compress64k(byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int destEnd) {
22 final int srcEnd = srcOff + srcLen;
23 final int srcLimit = srcEnd - LAST_LITERALS;
24 final int mflimit = srcEnd - MF_LIMIT;
26 int sOff = srcOff, dOff = destOff;
30 if (srcLen >= MIN_LENGTH) {
32 final short[] hashTable = new short[HASH_TABLE_SIZE_64K];
40 int forwardOff = sOff;
44 int searchMatchNb = 1 << SKIP_STRENGTH;
48 step = searchMatchNb++ >>> SKIP_STRENGTH;
50 if (forwardOff > mflimit) {
54 final int h = hash64k(SafeUtils.readInt(src, sOff));
55 ref = srcOff + SafeUtils.readShort(hashTable, h);
56 SafeUtils.writeShort(hashTable, h, sOff - srcOff);
57 } while (!LZ4SafeUtils.readIntEquals(src, ref, sOff));
60 final int excess = LZ4SafeUtils.commonBytesBackward(src, ref, sOff, srcOff, anchor);
64 // sequence == refsequence
65 final int runLen = sOff - anchor;
67 // encode literal length
68 int tokenOff = dOff++;
70 if (dOff + runLen + (2 + 1 + LAST_LITERALS) + (runLen >>> 8) > destEnd) {
71 throw new LZ4Exception("maxDestLen is too small");
74 if (runLen >= RUN_MASK) {
75 SafeUtils.writeByte(dest, tokenOff, RUN_MASK << ML_BITS);
76 dOff = LZ4SafeUtils.writeLen(runLen - RUN_MASK, dest, dOff);
78 SafeUtils.writeByte(dest, tokenOff, runLen << ML_BITS);
82 LZ4SafeUtils.wildArraycopy(src, anchor, dest, dOff, runLen);
87 SafeUtils.writeShortLE(dest, dOff, (short) (sOff - ref));
93 final int matchLen = LZ4SafeUtils.commonBytes(src, ref, sOff, srcLimit);
94 if (dOff + (1 + LAST_LITERALS) + (matchLen >>> 8) > destEnd) {
95 throw new LZ4Exception("maxDestLen is too small");
100 if (matchLen >= ML_MASK) {
101 SafeUtils.writeByte(dest, tokenOff, SafeUtils.readByte(dest, tokenOff) | ML_MASK);
102 dOff = LZ4SafeUtils.writeLen(matchLen - ML_MASK, dest, dOff);
104 SafeUtils.writeByte(dest, tokenOff, SafeUtils.readByte(dest, tokenOff) | matchLen);
108 if (sOff > mflimit) {
114 SafeUtils.writeShort(hashTable, hash64k(SafeUtils.readInt(src, sOff - 2)), sOff - 2 - srcOff);
116 // test next position
117 final int h = hash64k(SafeUtils.readInt(src, sOff));
118 ref = srcOff + SafeUtils.readShort(hashTable, h);
119 SafeUtils.writeShort(hashTable, h, sOff - srcOff);
121 if (!LZ4SafeUtils.readIntEquals(src, sOff, ref)) {
126 SafeUtils.writeByte(dest, tokenOff, 0);
134 dOff = LZ4SafeUtils.lastLiterals(src, anchor, srcEnd - anchor, dest, dOff, destEnd);
135 return dOff - destOff;
139 public int compress(byte[] src, final int srcOff, int srcLen, byte[] dest, final int destOff, int maxDestLen) {
141 SafeUtils.checkRange(src, srcOff, srcLen);
142 SafeUtils.checkRange(dest, destOff, maxDestLen);
143 final int destEnd = destOff + maxDestLen;
145 if (srcLen < LZ4_64K_LIMIT) {
146 return compress64k(src, srcOff, srcLen, dest, destOff, destEnd);
149 final int srcEnd = srcOff + srcLen;
150 final int srcLimit = srcEnd - LAST_LITERALS;
151 final int mflimit = srcEnd - MF_LIMIT;
153 int sOff = srcOff, dOff = destOff;
156 final int[] hashTable = new int[HASH_TABLE_SIZE];
157 Arrays.fill(hashTable, anchor);
163 int forwardOff = sOff;
167 int searchMatchNb = 1 << SKIP_STRENGTH;
172 step = searchMatchNb++ >>> SKIP_STRENGTH;
174 if (forwardOff > mflimit) {
178 final int h = hash(SafeUtils.readInt(src, sOff));
179 ref = SafeUtils.readInt(hashTable, h);
181 SafeUtils.writeInt(hashTable, h, sOff);
182 } while (back >= MAX_DISTANCE || !LZ4SafeUtils.readIntEquals(src, ref, sOff));
185 final int excess = LZ4SafeUtils.commonBytesBackward(src, ref, sOff, srcOff, anchor);
189 // sequence == refsequence
190 final int runLen = sOff - anchor;
192 // encode literal length
193 int tokenOff = dOff++;
195 if (dOff + runLen + (2 + 1 + LAST_LITERALS) + (runLen >>> 8) > destEnd) {
196 throw new LZ4Exception("maxDestLen is too small");
199 if (runLen >= RUN_MASK) {
200 SafeUtils.writeByte(dest, tokenOff, RUN_MASK << ML_BITS);
201 dOff = LZ4SafeUtils.writeLen(runLen - RUN_MASK, dest, dOff);
203 SafeUtils.writeByte(dest, tokenOff, runLen << ML_BITS);
207 LZ4SafeUtils.wildArraycopy(src, anchor, dest, dOff, runLen);
212 SafeUtils.writeShortLE(dest, dOff, back);
217 final int matchLen = LZ4SafeUtils.commonBytes(src, ref + MIN_MATCH, sOff, srcLimit);
218 if (dOff + (1 + LAST_LITERALS) + (matchLen >>> 8) > destEnd) {
219 throw new LZ4Exception("maxDestLen is too small");
224 if (matchLen >= ML_MASK) {
225 SafeUtils.writeByte(dest, tokenOff, SafeUtils.readByte(dest, tokenOff) | ML_MASK);
226 dOff = LZ4SafeUtils.writeLen(matchLen - ML_MASK, dest, dOff);
228 SafeUtils.writeByte(dest, tokenOff, SafeUtils.readByte(dest, tokenOff) | matchLen);
232 if (sOff > mflimit) {
238 SafeUtils.writeInt(hashTable, hash(SafeUtils.readInt(src, sOff - 2)), sOff - 2);
240 // test next position
241 final int h = hash(SafeUtils.readInt(src, sOff));
242 ref = SafeUtils.readInt(hashTable, h);
243 SafeUtils.writeInt(hashTable, h, sOff);
246 if (back >= MAX_DISTANCE || !LZ4SafeUtils.readIntEquals(src, ref, sOff)) {
251 SafeUtils.writeByte(dest, tokenOff, 0);
258 dOff = LZ4SafeUtils.lastLiterals(src, anchor, srcEnd - anchor, dest, dOff, destEnd);
259 return dOff - destOff;
263 static int compress64k(ByteBuffer src, int srcOff, int srcLen, ByteBuffer dest, int destOff, int destEnd) {
264 final int srcEnd = srcOff + srcLen;
265 final int srcLimit = srcEnd - LAST_LITERALS;
266 final int mflimit = srcEnd - MF_LIMIT;
268 int sOff = srcOff, dOff = destOff;
272 if (srcLen >= MIN_LENGTH) {
274 final short[] hashTable = new short[HASH_TABLE_SIZE_64K];
282 int forwardOff = sOff;
286 int searchMatchNb = 1 << SKIP_STRENGTH;
290 step = searchMatchNb++ >>> SKIP_STRENGTH;
292 if (forwardOff > mflimit) {
296 final int h = hash64k(ByteBufferUtils.readInt(src, sOff));
297 ref = srcOff + SafeUtils.readShort(hashTable, h);
298 SafeUtils.writeShort(hashTable, h, sOff - srcOff);
299 } while (!LZ4ByteBufferUtils.readIntEquals(src, ref, sOff));
302 final int excess = LZ4ByteBufferUtils.commonBytesBackward(src, ref, sOff, srcOff, anchor);
306 // sequence == refsequence
307 final int runLen = sOff - anchor;
309 // encode literal length
310 int tokenOff = dOff++;
312 if (dOff + runLen + (2 + 1 + LAST_LITERALS) + (runLen >>> 8) > destEnd) {
313 throw new LZ4Exception("maxDestLen is too small");
316 if (runLen >= RUN_MASK) {
317 ByteBufferUtils.writeByte(dest, tokenOff, RUN_MASK << ML_BITS);
318 dOff = LZ4ByteBufferUtils.writeLen(runLen - RUN_MASK, dest, dOff);
320 ByteBufferUtils.writeByte(dest, tokenOff, runLen << ML_BITS);
324 LZ4ByteBufferUtils.wildArraycopy(src, anchor, dest, dOff, runLen);
329 ByteBufferUtils.writeShortLE(dest, dOff, (short) (sOff - ref));
335 final int matchLen = LZ4ByteBufferUtils.commonBytes(src, ref, sOff, srcLimit);
336 if (dOff + (1 + LAST_LITERALS) + (matchLen >>> 8) > destEnd) {
337 throw new LZ4Exception("maxDestLen is too small");
342 if (matchLen >= ML_MASK) {
343 ByteBufferUtils.writeByte(dest, tokenOff, ByteBufferUtils.readByte(dest, tokenOff) | ML_MASK);
344 dOff = LZ4ByteBufferUtils.writeLen(matchLen - ML_MASK, dest, dOff);
346 ByteBufferUtils.writeByte(dest, tokenOff, ByteBufferUtils.readByte(dest, tokenOff) | matchLen);
350 if (sOff > mflimit) {
356 SafeUtils.writeShort(hashTable, hash64k(ByteBufferUtils.readInt(src, sOff - 2)), sOff - 2 - srcOff);
358 // test next position
359 final int h = hash64k(ByteBufferUtils.readInt(src, sOff));
360 ref = srcOff + SafeUtils.readShort(hashTable, h);
361 SafeUtils.writeShort(hashTable, h, sOff - srcOff);
363 if (!LZ4ByteBufferUtils.readIntEquals(src, sOff, ref)) {
368 ByteBufferUtils.writeByte(dest, tokenOff, 0);
376 dOff = LZ4ByteBufferUtils.lastLiterals(src, anchor, srcEnd - anchor, dest, dOff, destEnd);
377 return dOff - destOff;
381 public int compress(ByteBuffer src, final int srcOff, int srcLen, ByteBuffer dest, final int destOff, int maxDestLen) {
383 if (src.hasArray() && dest.hasArray()) {
384 return compress(src.array(), srcOff + src.arrayOffset(), srcLen, dest.array(), destOff + dest.arrayOffset(), maxDestLen);
386 src = ByteBufferUtils.inNativeByteOrder(src);
387 dest = ByteBufferUtils.inNativeByteOrder(dest);
389 ByteBufferUtils.checkRange(src, srcOff, srcLen);
390 ByteBufferUtils.checkRange(dest, destOff, maxDestLen);
391 final int destEnd = destOff + maxDestLen;
393 if (srcLen < LZ4_64K_LIMIT) {
394 return compress64k(src, srcOff, srcLen, dest, destOff, destEnd);
397 final int srcEnd = srcOff + srcLen;
398 final int srcLimit = srcEnd - LAST_LITERALS;
399 final int mflimit = srcEnd - MF_LIMIT;
401 int sOff = srcOff, dOff = destOff;
404 final int[] hashTable = new int[HASH_TABLE_SIZE];
405 Arrays.fill(hashTable, anchor);
411 int forwardOff = sOff;
415 int searchMatchNb = 1 << SKIP_STRENGTH;
420 step = searchMatchNb++ >>> SKIP_STRENGTH;
422 if (forwardOff > mflimit) {
426 final int h = hash(ByteBufferUtils.readInt(src, sOff));
427 ref = SafeUtils.readInt(hashTable, h);
429 SafeUtils.writeInt(hashTable, h, sOff);
430 } while (back >= MAX_DISTANCE || !LZ4ByteBufferUtils.readIntEquals(src, ref, sOff));
433 final int excess = LZ4ByteBufferUtils.commonBytesBackward(src, ref, sOff, srcOff, anchor);
437 // sequence == refsequence
438 final int runLen = sOff - anchor;
440 // encode literal length
441 int tokenOff = dOff++;
443 if (dOff + runLen + (2 + 1 + LAST_LITERALS) + (runLen >>> 8) > destEnd) {
444 throw new LZ4Exception("maxDestLen is too small");
447 if (runLen >= RUN_MASK) {
448 ByteBufferUtils.writeByte(dest, tokenOff, RUN_MASK << ML_BITS);
449 dOff = LZ4ByteBufferUtils.writeLen(runLen - RUN_MASK, dest, dOff);
451 ByteBufferUtils.writeByte(dest, tokenOff, runLen << ML_BITS);
455 LZ4ByteBufferUtils.wildArraycopy(src, anchor, dest, dOff, runLen);
460 ByteBufferUtils.writeShortLE(dest, dOff, back);
465 final int matchLen = LZ4ByteBufferUtils.commonBytes(src, ref + MIN_MATCH, sOff, srcLimit);
466 if (dOff + (1 + LAST_LITERALS) + (matchLen >>> 8) > destEnd) {
467 throw new LZ4Exception("maxDestLen is too small");
472 if (matchLen >= ML_MASK) {
473 ByteBufferUtils.writeByte(dest, tokenOff, ByteBufferUtils.readByte(dest, tokenOff) | ML_MASK);
474 dOff = LZ4ByteBufferUtils.writeLen(matchLen - ML_MASK, dest, dOff);
476 ByteBufferUtils.writeByte(dest, tokenOff, ByteBufferUtils.readByte(dest, tokenOff) | matchLen);
480 if (sOff > mflimit) {
486 SafeUtils.writeInt(hashTable, hash(ByteBufferUtils.readInt(src, sOff - 2)), sOff - 2);
488 // test next position
489 final int h = hash(ByteBufferUtils.readInt(src, sOff));
490 ref = SafeUtils.readInt(hashTable, h);
491 SafeUtils.writeInt(hashTable, h, sOff);
494 if (back >= MAX_DISTANCE || !LZ4ByteBufferUtils.readIntEquals(src, ref, sOff)) {
499 ByteBufferUtils.writeByte(dest, tokenOff, 0);
506 dOff = LZ4ByteBufferUtils.lastLiterals(src, anchor, srcEnd - anchor, dest, dOff, destEnd);
507 return dOff - destOff;