]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.lz4/src/net/jpountz/lz4/LZ4JNISafeDecompressor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.lz4 / src / net / jpountz / lz4 / LZ4JNISafeDecompressor.java
1 package net.jpountz.lz4;
2
3 /*
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 import java.nio.ByteBuffer;
19
20 import net.jpountz.util.ByteBufferUtils;
21 import net.jpountz.util.SafeUtils;
22
23 /**
24  * {@link LZ4SafeDecompressor} implemented with JNI bindings to the original C
25  * implementation of LZ4.
26  */
27 final class LZ4JNISafeDecompressor extends LZ4SafeDecompressor {
28
29   public static final LZ4JNISafeDecompressor INSTANCE = new LZ4JNISafeDecompressor();
30   private static LZ4SafeDecompressor SAFE_INSTANCE;
31
32   @Override
33   public final int decompress(byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen) {
34     SafeUtils.checkRange(src, srcOff, srcLen);
35     SafeUtils.checkRange(dest, destOff, maxDestLen);
36     final int result = LZ4JNI.LZ4_decompress_safe(src, null, srcOff, srcLen, dest, null, destOff, maxDestLen);
37     if (result < 0) {
38       throw new LZ4Exception("Error decoding offset " + (srcOff - result) + " of input buffer");
39     }
40     return result;
41   }
42
43   @Override
44   public int decompress(ByteBuffer src, int srcOff, int srcLen, ByteBuffer dest, int destOff, int maxDestLen) {
45     ByteBufferUtils.checkNotReadOnly(dest);
46     ByteBufferUtils.checkRange(src, srcOff, srcLen);
47     ByteBufferUtils.checkRange(dest, destOff, maxDestLen);
48
49     if ((src.hasArray() || src.isDirect()) && (dest.hasArray() || dest.isDirect())) {
50       byte[] srcArr = null, destArr = null;
51       ByteBuffer srcBuf = null, destBuf = null;
52       if (src.hasArray()) {
53         srcArr = src.array();
54         srcOff += src.arrayOffset();
55       } else {
56         assert src.isDirect();
57         srcBuf = src;
58       }
59       if (dest.hasArray()) {
60         destArr = dest.array();
61         destOff += dest.arrayOffset();
62       } else {
63         assert dest.isDirect();
64         destBuf = dest;
65       }
66
67       final int result = LZ4JNI.LZ4_decompress_safe(srcArr, srcBuf, srcOff, srcLen, destArr, destBuf, destOff, maxDestLen);
68       if (result < 0) {
69         throw new LZ4Exception("Error decoding offset " + (srcOff - result) + " of input buffer");
70       }
71       return result;
72     } else {
73       LZ4SafeDecompressor safeInstance = SAFE_INSTANCE;
74       if (safeInstance == null) {
75         safeInstance = SAFE_INSTANCE = LZ4Factory.safeInstance().safeDecompressor();
76       }
77       return safeInstance.decompress(src, srcOff, srcLen, dest, destOff, maxDestLen);
78     }
79   }
80
81 }