Merge branch 'release/1.1.0'
This commit is contained in:
commit
df38a6fe00
24
Makefile
24
Makefile
|
@ -16,19 +16,27 @@ SNAPPY_UNPACKED:=$(TARGET)/snappy-extracted.log
|
|||
|
||||
CXXFLAGS:=$(CXXFLAGS) -I$(SNAPPY_SRC_DIR)
|
||||
|
||||
ifeq ($(OS_NAME),SunOS)
|
||||
TAR:= gtar
|
||||
else
|
||||
TAR:= tar
|
||||
endif
|
||||
|
||||
$(SNAPPY_ARCHIVE):
|
||||
@mkdir -p $(@D)
|
||||
curl -o$@ http://snappy.googlecode.com/files/snappy-$(VERSION).tar.gz
|
||||
|
||||
$(SNAPPY_UNPACKED): $(SNAPPY_ARCHIVE)
|
||||
tar xvfz $< -C $(TARGET)
|
||||
$(TAR) xvfz $< -C $(TARGET)
|
||||
touch $@
|
||||
|
||||
jni-header: $(SRC)/org/xerial/snappy/SnappyNative.h
|
||||
|
||||
|
||||
$(SRC)/org/xerial/snappy/SnappyNative.h: $(SRC)/org/xerial/snappy/SnappyNative.java
|
||||
$(TARGET)/classes/org/xerial/snappy/SnappyNative.class : $(SRC)/org/xerial/snappy/SnappyNative.java
|
||||
@mkdir -p $(TARGET)/classes
|
||||
$(JAVAC) -source 1.6 -target 1.6 -d $(TARGET)/classes -sourcepath $(SRC) $<
|
||||
|
||||
$(SRC)/org/xerial/snappy/SnappyNative.h: $(TARGET)/classes/org/xerial/snappy/SnappyNative.class
|
||||
$(JAVAH) -classpath $(TARGET)/classes -o $@ org.xerial.snappy.SnappyNative
|
||||
|
||||
bytecode: src/main/resources/org/xerial/snappy/SnappyNativeLoader.bytecode
|
||||
|
@ -86,16 +94,16 @@ win32:
|
|||
|
||||
# for cross-compilation on Ubuntu, install the g++-mingw-w64-x86-64 package
|
||||
win64:
|
||||
$(MAKE) native CROSS_PREFIX=x86_64-w64-mingw32- OS_NAME=Windows OS_ARCH=amd64
|
||||
$(MAKE) native CROSS_PREFIX=x86_64-w64-mingw32- OS_NAME=Windows OS_ARCH=x86_64
|
||||
|
||||
mac32:
|
||||
$(MAKE) native OS_NAME=Mac OS_ARCH=i386
|
||||
$(MAKE) native OS_NAME=Mac OS_ARCH=x86
|
||||
|
||||
linux32:
|
||||
$(MAKE) native OS_NAME=Linux OS_ARCH=i386
|
||||
$(MAKE) native OS_NAME=Linux OS_ARCH=x86
|
||||
|
||||
freebsd64:
|
||||
$(MAKE) native OS_NAME=FreeBSD OS_ARCH=amd64
|
||||
$(MAKE) native OS_NAME=FreeBSD OS_ARCH=x86_64
|
||||
|
||||
# for cross-compilation on Ubuntu, install the g++-arm-linux-gnueabi package
|
||||
linux-arm:
|
||||
|
@ -106,7 +114,7 @@ linux-armhf:
|
|||
$(MAKE) native CROSS_PREFIX=arm-linux-gnueabihf- OS_NAME=Linux OS_ARCH=armhf
|
||||
|
||||
clean-native-linux32:
|
||||
$(MAKE) clean-native OS_NAME=Linux OS_ARCH=i386
|
||||
$(MAKE) clean-native OS_NAME=Linux OS_ARCH=x86
|
||||
|
||||
clean-native-win32:
|
||||
$(MAKE) clean-native OS_NAME=Windows OS_ARCH=x86
|
||||
|
|
|
@ -33,7 +33,7 @@ endif
|
|||
snappy := snappy-$(VERSION)
|
||||
|
||||
|
||||
jni_md := $(shell find -L "$(JAVA_HOME)" -name jni_md.h)
|
||||
jni_md := $(shell find -L "$(JAVA_HOME)" -name jni_md.h | head -1)
|
||||
ifneq ($(jni_md),)
|
||||
jni_include := $(shell dirname "$(jni_md)")
|
||||
endif
|
||||
|
@ -41,7 +41,7 @@ endif
|
|||
|
||||
# os=Default is meant to be generic unix/linux
|
||||
|
||||
known_os_archs := Linux-i386 Linux-amd64 Linux-arm Linux-armhf Mac-i386 Mac-x86_64 FreeBSD-amd64 Windows-x86 Windows-amd64
|
||||
known_os_archs := Linux-x86 Linux-x86_64 Linux-arm Linux-armhf Mac-x86 Mac-x86_64 FreeBSD-x86_64 Windows-x86 Windows-x86_64 SunOS-x86 SunOS-sparc
|
||||
os_arch := $(OS_NAME)-$(OS_ARCH)
|
||||
|
||||
ifeq (,$(findstring $(strip $(os_arch)),$(known_os_archs)))
|
||||
|
@ -58,19 +58,33 @@ Default_LINKFLAGS := -shared -static
|
|||
Default_LIBNAME := libsnappyjava.so
|
||||
Default_SNAPPY_FLAGS :=
|
||||
|
||||
Linux-i386_CXX := $(CROSS_PREFIX)g++
|
||||
Linux-i386_STRIP := $(CROSS_PREFIX)strip
|
||||
Linux-i386_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden -m32
|
||||
Linux-i386_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
Linux-i386_LIBNAME := libsnappyjava.so
|
||||
Linux-i386_SNAPPY_FLAGS:=
|
||||
Linux-x86_CXX := $(CROSS_PREFIX)g++
|
||||
Linux-x86_STRIP := $(CROSS_PREFIX)strip
|
||||
Linux-x86_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden -m32
|
||||
Linux-x86_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
Linux-x86_LIBNAME := libsnappyjava.so
|
||||
Linux-x86_SNAPPY_FLAGS:=
|
||||
|
||||
Linux-amd64_CXX := $(CROSS_PREFIX)g++
|
||||
Linux-amd64_STRIP := $(CROSS_PREFIX)strip
|
||||
Linux-amd64_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden -m64
|
||||
Linux-amd64_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
Linux-amd64_LIBNAME := libsnappyjava.so
|
||||
Linux-amd64_SNAPPY_FLAGS :=
|
||||
Linux-x86_64_CXX := $(CROSS_PREFIX)g++
|
||||
Linux-x86_64_STRIP := $(CROSS_PREFIX)strip
|
||||
Linux-x86_64_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden -m64
|
||||
Linux-x86_64_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
Linux-x86_64_LIBNAME := libsnappyjava.so
|
||||
Linux-x86_64_SNAPPY_FLAGS :=
|
||||
|
||||
SunOS-x86_CXX := g++
|
||||
SunOS-x86_STRIP := strip
|
||||
SunOS-x86_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden
|
||||
SunOS-x86_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
SunOS-x86_LIBNAME := libsnappyjava.so
|
||||
SunOS-x86_SNAPPY_FLAGS :=
|
||||
|
||||
SunOS-sparc_CXX := g++
|
||||
SunOS-sparc_STRIP := strip
|
||||
SunOS-sparc_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden
|
||||
SunOS-sparc_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
SunOS-sparc_LIBNAME := libsnappyjava.so
|
||||
SunOS-sparc_SNAPPY_FLAGS :=
|
||||
|
||||
# '-include lib/inc_linux/jni_md.h' is used to force the use of our version,
|
||||
# which defines JNIEXPORT differently; otherwise, since OpenJDK includes
|
||||
|
@ -91,12 +105,12 @@ Linux-armhf_LINKFLAGS := -shared -static-libgcc
|
|||
Linux-armhf_LIBNAME := libsnappyjava.so
|
||||
Linux-armhf_SNAPPY_FLAGS:=
|
||||
|
||||
Mac-i386_CXX := g++ -arch $(OS_ARCH)
|
||||
Mac-i386_STRIP := strip -x
|
||||
Mac-i386_CXXFLAGS := -Ilib/inc_mac -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.4 -fvisibility=hidden
|
||||
Mac-i386_LINKFLAGS := -dynamiclib -static-libgcc
|
||||
Mac-i386_LIBNAME := libsnappyjava.jnilib
|
||||
Mac-i386_SNAPPY_FLAGS :=
|
||||
Mac-x86_CXX := g++ -arch i386
|
||||
Mac-x86_STRIP := strip -x
|
||||
Mac-x86_CXXFLAGS := -Ilib/inc_mac -I$(JAVA_HOME)/include -O2 -fPIC -mmacosx-version-min=10.4 -fvisibility=hidden
|
||||
Mac-x86_LINKFLAGS := -dynamiclib -static-libgcc
|
||||
Mac-x86_LIBNAME := libsnappyjava.jnilib
|
||||
Mac-x86_SNAPPY_FLAGS :=
|
||||
|
||||
Mac-x86_64_CXX := g++ -arch $(OS_ARCH)
|
||||
Mac-x86_64_STRIP := strip -x
|
||||
|
@ -105,12 +119,12 @@ Mac-x86_64_LINKFLAGS := -dynamiclib -static-libgcc
|
|||
Mac-x86_64_LIBNAME := libsnappyjava.jnilib
|
||||
Mac-x86_64_SNAPPY_FLAGS :=
|
||||
|
||||
FreeBSD-amd64_CXX := $(CROSS_PREFIX)g++
|
||||
FreeBSD-amd64_STRIP := $(CROSS_PREFIX)strip
|
||||
FreeBSD-amd64_CXXFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_mac -O2 -fPIC -fvisibility=hidden
|
||||
FreeBSD-amd64_LINKFLAGS := -shared -static-libgcc
|
||||
FreeBSD-amd64_LIBNAME := libsnappyjava.so
|
||||
FreeBSD-amd64_SNAPPY_FLAGS :=
|
||||
FreeBSD-x86_64_CXX := $(CROSS_PREFIX)g++
|
||||
FreeBSD-x86_64_STRIP := $(CROSS_PREFIX)strip
|
||||
FreeBSD-x86_64_CXXFLAGS := -I$(JAVA_HOME)/include -Ilib/inc_mac -O2 -fPIC -fvisibility=hidden
|
||||
FreeBSD-x86_64_LINKFLAGS := -shared -static-libgcc
|
||||
FreeBSD-x86_64_LIBNAME := libsnappyjava.so
|
||||
FreeBSD-x86_64_SNAPPY_FLAGS :=
|
||||
|
||||
Windows-x86_CXX := $(CROSS_PREFIX)g++
|
||||
Windows-x86_STRIP := $(CROSS_PREFIX)strip
|
||||
|
@ -119,12 +133,12 @@ Windows-x86_LINKFLAGS := -Wl,--kill-at -shared -static
|
|||
Windows-x86_LIBNAME := snappyjava.dll
|
||||
Windows-x86_SNAPPY_FLAGS :=
|
||||
|
||||
Windows-amd64_CXX := $(CROSS_PREFIX)g++
|
||||
Windows-amd64_STRIP := $(CROSS_PREFIX)strip
|
||||
Windows-amd64_CXXFLAGS := -Ilib/inc_win -O2
|
||||
Windows-amd64_LINKFLAGS := -Wl,--kill-at -shared -static
|
||||
Windows-amd64_LIBNAME := snappyjava.dll
|
||||
Windows-amd64_SNAPPY_FLAGS :=
|
||||
Windows-x86_64_CXX := $(CROSS_PREFIX)g++
|
||||
Windows-x86_64_STRIP := $(CROSS_PREFIX)strip
|
||||
Windows-x86_64_CXXFLAGS := -Ilib/inc_win -O2
|
||||
Windows-x86_64_LINKFLAGS := -Wl,--kill-at -shared -static
|
||||
Windows-x86_64_LIBNAME := snappyjava.dll
|
||||
Windows-x86_64_SNAPPY_FLAGS :=
|
||||
|
||||
|
||||
CXX := $($(os_arch)_CXX)
|
||||
|
|
15
Milestone.md
15
Milestone.md
|
@ -2,6 +2,21 @@
|
|||
* `SnappyIndexer` for parallel compression/decompression
|
||||
* CUI commands (snap/unsnap)
|
||||
|
||||
## snappy-java-1.1.0 (17 October 2013)
|
||||
* Add Snappy framed format support (SnappyFramedInputStream, SnappyFramedOutputStream)
|
||||
* Add SunOS support
|
||||
* Dropped OpenBSD support
|
||||
* OSGi support
|
||||
|
||||
## snappy-java-1.1.0-M4 (20 August 2013)
|
||||
* New JNI native code loading mechanism, which does not rely on native code injection.
|
||||
* Add OpenBSD support
|
||||
* Add Framed format support
|
||||
* Recovered 32-bit Mac support
|
||||
* Fixes several issues
|
||||
* Target to Java6 (Java5 will be no longer supported)
|
||||
* Add zero-copy compression, decompression and isValidCompressedData for LArray <https://github.com/xerial/larray>
|
||||
|
||||
## snappy-java-1.1.0-M3 (28 March 2013)
|
||||
* Fix linux amd64 build (embed libstdc++)
|
||||
* Fixes #26
|
||||
|
|
3
NOTICE
3
NOTICE
|
@ -1,6 +1,9 @@
|
|||
This product includes software developed by Google
|
||||
Snappy: http://code.google.com/p/snappy/ (New BSD License)
|
||||
|
||||
This product includes software developed by Apache
|
||||
PureJavaCrc32C from apache-hadoop-common http://hadoop.apache.org/
|
||||
(Apache 2.0 license)
|
||||
|
||||
This library containd statically linked libstdc++. This inclusion is allowed by
|
||||
"GCC RUntime Library Exception"
|
||||
|
|
10
README.md
10
README.md
|
@ -8,6 +8,7 @@ The snappy-java is a Java port of the snappy
|
|||
* Although snappy-java uses JNI, it can be used safely with multiple class loaders (e.g. Tomcat, etc.).
|
||||
* Portable across various operating systems; Snappy-java contains native libraries built for Window/Mac/Linux (64-bit). At runtime, snappy-java loads one of these libraries according to your machine environment (It looks system properties, `os.name` and `os.arch`).
|
||||
* Simple usage. Add the snappy-java-(version).jar file to your classpath. Then call compression/decompression methods in org.xerial.snappy.Snappy.
|
||||
* [Framing-format support](http://snappy.googlecode.com/svn/trunk/framing_format.txt) (Since 1.1.0-SNAPSHOT version)
|
||||
|
||||
## Performance
|
||||
* Snappy's main target is very high-speed compression/decompression with reasonable compression size. So the compression ratio of snappy-java is modest and about the same as `LZF` (ranging 20%-100% according to the dataset).
|
||||
|
@ -24,7 +25,7 @@ The snappy-java is a Java port of the snappy
|
|||
## Download
|
||||
The current stable version is available from here:
|
||||
* Release version: http://code.google.com/p/snappy-java/downloads/list
|
||||
* [Release plans](https://github.com/xerial/snappy-java/blob/develop/Milestone.md)
|
||||
* [Release plans](Milestone.md)
|
||||
* Snapshot version (the latest beta version): https://oss.sonatype.org/content/repositories/snapshots/org/xerial/snappy/snappy-java/
|
||||
If you are a Maven user, see [pom.xml example](#using-with-maven).
|
||||
|
||||
|
@ -53,7 +54,7 @@ In addition, high-level methods (`Snappy.compress(String)`, `Snappy.compress(flo
|
|||
### Stream-based API
|
||||
Stream-based compressor/decompressor `SnappyOutputStream`/`SnappyInputStream` are also available for reading/writing large data sets.
|
||||
|
||||
* [Javadoc API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/snappy/snappy-java/1.1.0-M3/snappy-java-1.1.0-M3-javadoc.jar/!/index.html)
|
||||
* [Javadoc API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/snappy/snappy-java/1.1.0/snappy-java-1.1.0-javadoc.jar/!/index.html)
|
||||
|
||||
### Setting classpath
|
||||
If you have snappy-java-(VERSION).jar in the current directory, use `-classpath` option as follows:
|
||||
|
@ -90,6 +91,9 @@ See the [installation instruction](https://github.com/xerial/snappy-java/blob/de
|
|||
$ cd snappy-java
|
||||
$ make
|
||||
|
||||
When building on Solaris use
|
||||
|
||||
$ gmake
|
||||
|
||||
A file `target/snappy-java-$(version).jar` is the product additionally containing the native library built for your platform.
|
||||
|
||||
|
@ -125,7 +129,7 @@ If you are using Mac and openjdk7 (or higher), use the following option:
|
|||
## Miscellaneous Notes
|
||||
### Using snappy-java with Tomcat 6 (or higher) Web Server
|
||||
|
||||
Simply put the snappy-java's jar to WEB-INF/lib folder of your web application. Usual JNI-library specific problem no longer exists since snappy-java version 1.0.3 or higher can be loaded by multiple class loaders in the same JVM by using native code injection to the parent class loader (Issue 21).
|
||||
Simply put the snappy-java's jar to WEB-INF/lib folder of your web application. Usual JNI-library specific problem no longer exists since snappy-java version 1.0.3 or higher can be loaded by multiple class loaders.
|
||||
|
||||
----
|
||||
Snappy-java is developed by [Taro L. Saito](http://www.xerial.org/leo). Twitter [@taroleo](http://twitter.com/#!/taroleo)
|
||||
|
|
Binary file not shown.
41
pom.xml
41
pom.xml
|
@ -4,7 +4,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.xerial.snappy</groupId>
|
||||
<artifactId>snappy-java</artifactId>
|
||||
<version>1.1.0-M3</version>
|
||||
<version>1.1.0</version>
|
||||
<name>Snappy for Java</name>
|
||||
<description>snappy-java: A fast compression/decompression library</description>
|
||||
<packaging>bundle</packaging>
|
||||
|
@ -182,12 +182,15 @@
|
|||
<Import-Package>org.osgi.framework;version="[1.5,2)"</Import-Package>
|
||||
<Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
|
||||
<Bundle-NativeCode>
|
||||
org/xerial/snappy/native/Windows/amd64/snappyjava.dll;selection-filter="(&(osgi.arch=x86_64)(osgi.os=win32))",
|
||||
org/xerial/snappy/native/Windows/x86/snappyjava.dll;selection-filter="(&(osgi.arch=x86)(osgi.os=win32))",
|
||||
org/xerial/snappy/native/Mac/x86_64/libsnappyjava.jnilib;selection-filter="(&(osgi.arch=x86_64)(osgi.os=macosx))",
|
||||
org/xerial/snappy/native/Linux/amd64/libsnappyjava.so;selection-filter="(&(osgi.arch=x86_64)(osgi.os=linux))",
|
||||
org/xerial/snappy/native/Linux/i386/libsnappyjava.so;selection-filter="(&(osgi.arch=x86)(osgi.os=linux))",
|
||||
org/xerial/snappy/native/Linux/arm/libsnappyjava.so;selection-filter="(&(osgi.arch=arm)(osgi.os=linux))"
|
||||
org/xerial/snappy/native/Windows/x86_64/snappyjava.dll;osname=win32;processor=x86-64,
|
||||
org/xerial/snappy/native/Windows/x86/snappyjava.dll;osname=win32;processor=x86,
|
||||
org/xerial/snappy/native/Mac/x86/libsnappyjava.jnilib;osname=macosx;processor=x86,
|
||||
org/xerial/snappy/native/Mac/x86_64/libsnappyjava.jnilib;osname=macosx;processor=x86-64,
|
||||
org/xerial/snappy/native/Linux/x86_64/libsnappyjava.so;osname=linux;processor=x86-64,
|
||||
org/xerial/snappy/native/Linux/x86/libsnappyjava.so;osname=linux;processor=x86,
|
||||
org/xerial/snappy/native/SunOS/x86/libsnappyjava.so;osname=sunos;processor=x86,
|
||||
org/xerial/snappy/native/SunOS/sparc/libsnappyjava.so;osname=sunos;processor=sparc,
|
||||
org/xerial/snappy/native/Linux/arm/libsnappyjava.so;osname=linux;processor=arm
|
||||
</Bundle-NativeCode>
|
||||
<!-- TODO: unsure about ARMHF -->
|
||||
</instructions>
|
||||
|
@ -278,30 +281,6 @@
|
|||
<url>git@github.com:xerial/snappy-java.git</url>
|
||||
</scm>
|
||||
|
||||
<profiles>
|
||||
<!-- for local updates -->
|
||||
<profile>
|
||||
<id>xerial.local</id>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>xerial.local</id>
|
||||
<name>Xerial Maven Repository</name>
|
||||
<url>file:///home/web/maven.xerial.org/repository/artifact</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>xerial.local</id>
|
||||
<name>Xerial Maven Snapshot Repository</name>
|
||||
<url>file:///home/web/maven.xerial.org/repository/snapshot</url>
|
||||
<uniqueVersion>false</uniqueVersion>
|
||||
</snapshotRepository>
|
||||
<site>
|
||||
<id>xerial.local</id>
|
||||
<url>file:///home/web/maven.xerial.org/repository/site</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
package org.xerial.snappy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Provides OS name and architecture name.
|
||||
|
@ -34,6 +36,48 @@ import java.io.IOException;
|
|||
*/
|
||||
public class OSInfo
|
||||
{
|
||||
private static HashMap<String, String> archMapping = new HashMap<String, String>();
|
||||
|
||||
public static final String X86 = "x86";
|
||||
public static final String X86_64 = "x86_64";
|
||||
public static final String IA64_32 = "ia64_32";
|
||||
public static final String IA64 = "ia64";
|
||||
public static final String PPC = "ppc";
|
||||
|
||||
static {
|
||||
// x86 mappings
|
||||
archMapping.put(X86, X86);
|
||||
archMapping.put("i386", X86);
|
||||
archMapping.put("i486", X86);
|
||||
archMapping.put("i586", X86);
|
||||
archMapping.put("i686", X86);
|
||||
archMapping.put("pentium", X86);
|
||||
|
||||
// x86_64 mappings
|
||||
archMapping.put(X86_64, X86_64);
|
||||
archMapping.put("amd64", X86_64);
|
||||
archMapping.put("em64t", X86_64);
|
||||
archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac
|
||||
|
||||
// Itenium 64-bit mappings
|
||||
archMapping.put(IA64, IA64);
|
||||
archMapping.put("ia64w", IA64);
|
||||
|
||||
// Itenium 32-bit mappings, usually an HP-UX construct
|
||||
archMapping.put(IA64_32, IA64_32);
|
||||
archMapping.put("ia64n", IA64_32);
|
||||
|
||||
// PowerPC mappings
|
||||
archMapping.put(PPC, PPC);
|
||||
archMapping.put("pwoer", PPC);
|
||||
archMapping.put("powerpc", PPC);
|
||||
archMapping.put("power_pc", PPC);
|
||||
archMapping.put("power_rs", PPC);
|
||||
|
||||
// TODO: PowerPC 64bit mappings
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length >= 1) {
|
||||
if ("--os".equals(args[0])) {
|
||||
|
@ -78,8 +122,10 @@ public class OSInfo
|
|||
// ignored: fall back to "arm" arch (soft-float ABI)
|
||||
}
|
||||
}
|
||||
else if(getOSName().equals("Mac") && (osArch.equals("universal") || osArch.equals("amd64"))) {
|
||||
return "x86_64"; // Fix for openjdk7
|
||||
else {
|
||||
String lc = osArch.toLowerCase(Locale.US);
|
||||
if(archMapping.containsKey(lc))
|
||||
return archMapping.get(lc);
|
||||
}
|
||||
return translateArchNameToFolderName(osArch);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,617 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Some portions of this file Copyright (c) 2004-2006 Intel Corportation
|
||||
* and licensed under the BSD license.
|
||||
*/
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
/**
|
||||
* A pure-java implementation of the CRC32 checksum that uses
|
||||
* the CRC32-C polynomial, the same polynomial used by iSCSI
|
||||
* and implemented on many Intel chipsets supporting SSE4.2.
|
||||
*/
|
||||
public class PureJavaCrc32C implements Checksum {
|
||||
|
||||
/** the current CRC value, bit-flipped */
|
||||
private int crc;
|
||||
|
||||
/** Create a new PureJavaCrc32 object. */
|
||||
public PureJavaCrc32C() {
|
||||
reset();
|
||||
}
|
||||
|
||||
public int getIntegerValue() {
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public long getValue() {
|
||||
long ret = crc;
|
||||
return (~ret) & 0xffffffffL;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void reset() {
|
||||
crc = 0xffffffff;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void update(byte[] b, int off, int len) {
|
||||
int localCrc = crc;
|
||||
while(len > 7) {
|
||||
int c0 = b[off++] ^ localCrc;
|
||||
int c1 = b[off++] ^ (localCrc >>>= 8);
|
||||
int c2 = b[off++] ^ (localCrc >>>= 8);
|
||||
int c3 = b[off++] ^ (localCrc >>>= 8);
|
||||
localCrc = (T8_7[c0 & 0xff] ^ T8_6[c1 & 0xff])
|
||||
^ (T8_5[c2 & 0xff] ^ T8_4[c3 & 0xff]);
|
||||
|
||||
localCrc ^= (T8_3[b[off++] & 0xff] ^ T8_2[b[off++] & 0xff])
|
||||
^ (T8_1[b[off++] & 0xff] ^ T8_0[b[off++] & 0xff]);
|
||||
|
||||
len -= 8;
|
||||
}
|
||||
while(len > 0) {
|
||||
localCrc = (localCrc >>> 8) ^ T8_0[(localCrc ^ b[off++]) & 0xff];
|
||||
len--;
|
||||
}
|
||||
|
||||
// Publish crc out to object
|
||||
crc = localCrc;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
final public void update(int b) {
|
||||
crc = (crc >>> 8) ^ T8_0[(crc ^ b) & 0xff];
|
||||
}
|
||||
|
||||
// CRC polynomial tables generated by:
|
||||
// java -cp build/test/classes/:build/classes/ \
|
||||
// org.apache.hadoop.util.TestPureJavaCrc32\$Table 82F63B78
|
||||
|
||||
static final int[] T8_0 = new int[] {
|
||||
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
|
||||
0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
|
||||
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
|
||||
0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
|
||||
0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
|
||||
0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
|
||||
0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
|
||||
0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
|
||||
0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
|
||||
0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
|
||||
0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
|
||||
0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
|
||||
0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
|
||||
0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
|
||||
0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
|
||||
0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
|
||||
0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
|
||||
0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
|
||||
0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
|
||||
0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
|
||||
0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
|
||||
0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
|
||||
0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
|
||||
0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
|
||||
0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
|
||||
0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
|
||||
0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
|
||||
0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
|
||||
0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
|
||||
0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
|
||||
0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
|
||||
0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
|
||||
0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
|
||||
0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
|
||||
0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
|
||||
0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
|
||||
0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
|
||||
0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
|
||||
0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
|
||||
0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
|
||||
0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
|
||||
0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
|
||||
0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
|
||||
0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
|
||||
0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
|
||||
0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
|
||||
0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
|
||||
0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
|
||||
0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
|
||||
0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
|
||||
0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
|
||||
0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
|
||||
0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
|
||||
0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
|
||||
0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
|
||||
0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
|
||||
0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
|
||||
0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
|
||||
0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
|
||||
0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
|
||||
0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
|
||||
0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
|
||||
0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
|
||||
0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
|
||||
};
|
||||
static final int[] T8_1 = new int[] {
|
||||
0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
|
||||
0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
|
||||
0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
|
||||
0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
|
||||
0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
|
||||
0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
|
||||
0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
|
||||
0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
|
||||
0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
|
||||
0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
|
||||
0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
|
||||
0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
|
||||
0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
|
||||
0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
|
||||
0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
|
||||
0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
|
||||
0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
|
||||
0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
|
||||
0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
|
||||
0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
|
||||
0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
|
||||
0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
|
||||
0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
|
||||
0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
|
||||
0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
|
||||
0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
|
||||
0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
|
||||
0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
|
||||
0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
|
||||
0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
|
||||
0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
|
||||
0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
|
||||
0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
|
||||
0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
|
||||
0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
|
||||
0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
|
||||
0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
|
||||
0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
|
||||
0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
|
||||
0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
|
||||
0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
|
||||
0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
|
||||
0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
|
||||
0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
|
||||
0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
|
||||
0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
|
||||
0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
|
||||
0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
|
||||
0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
|
||||
0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
|
||||
0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
|
||||
0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
|
||||
0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
|
||||
0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
|
||||
0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
|
||||
0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
|
||||
0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
|
||||
0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
|
||||
0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
|
||||
0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
|
||||
0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
|
||||
0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
|
||||
0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
|
||||
0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
|
||||
};
|
||||
static final int[] T8_2 = new int[] {
|
||||
0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
|
||||
0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
|
||||
0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
|
||||
0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
|
||||
0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
|
||||
0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
|
||||
0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
|
||||
0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
|
||||
0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
|
||||
0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
|
||||
0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
|
||||
0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
|
||||
0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
|
||||
0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
|
||||
0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
|
||||
0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
|
||||
0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
|
||||
0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
|
||||
0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
|
||||
0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
|
||||
0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
|
||||
0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
|
||||
0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
|
||||
0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
|
||||
0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
|
||||
0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
|
||||
0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
|
||||
0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
|
||||
0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
|
||||
0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
|
||||
0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
|
||||
0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
|
||||
0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
|
||||
0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
|
||||
0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
|
||||
0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
|
||||
0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
|
||||
0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
|
||||
0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
|
||||
0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
|
||||
0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
|
||||
0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
|
||||
0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
|
||||
0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
|
||||
0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
|
||||
0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
|
||||
0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
|
||||
0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
|
||||
0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
|
||||
0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
|
||||
0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
|
||||
0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
|
||||
0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
|
||||
0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
|
||||
0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
|
||||
0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
|
||||
0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
|
||||
0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
|
||||
0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
|
||||
0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
|
||||
0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
|
||||
0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
|
||||
0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
|
||||
0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
|
||||
};
|
||||
static final int[] T8_3 = new int[] {
|
||||
0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
|
||||
0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
|
||||
0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
|
||||
0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
|
||||
0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
|
||||
0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
|
||||
0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
|
||||
0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
|
||||
0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
|
||||
0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
|
||||
0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
|
||||
0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
|
||||
0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
|
||||
0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
|
||||
0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
|
||||
0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
|
||||
0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
|
||||
0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
|
||||
0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
|
||||
0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
|
||||
0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
|
||||
0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
|
||||
0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
|
||||
0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
|
||||
0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
|
||||
0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
|
||||
0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
|
||||
0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
|
||||
0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
|
||||
0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
|
||||
0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
|
||||
0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
|
||||
0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
|
||||
0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
|
||||
0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
|
||||
0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
|
||||
0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
|
||||
0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
|
||||
0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
|
||||
0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
|
||||
0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
|
||||
0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
|
||||
0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
|
||||
0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
|
||||
0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
|
||||
0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
|
||||
0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
|
||||
0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
|
||||
0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
|
||||
0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
|
||||
0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
|
||||
0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
|
||||
0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
|
||||
0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
|
||||
0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
|
||||
0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
|
||||
0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
|
||||
0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
|
||||
0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
|
||||
0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
|
||||
0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
|
||||
0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
|
||||
0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
|
||||
0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
|
||||
};
|
||||
static final int[] T8_4 = new int[] {
|
||||
0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
|
||||
0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
|
||||
0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
|
||||
0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
|
||||
0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
|
||||
0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
|
||||
0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
|
||||
0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
|
||||
0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
|
||||
0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
|
||||
0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
|
||||
0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
|
||||
0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
|
||||
0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
|
||||
0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
|
||||
0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
|
||||
0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
|
||||
0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
|
||||
0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
|
||||
0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
|
||||
0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
|
||||
0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
|
||||
0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
|
||||
0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
|
||||
0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
|
||||
0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
|
||||
0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
|
||||
0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
|
||||
0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
|
||||
0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
|
||||
0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
|
||||
0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
|
||||
0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
|
||||
0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
|
||||
0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
|
||||
0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
|
||||
0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
|
||||
0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
|
||||
0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
|
||||
0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
|
||||
0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
|
||||
0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
|
||||
0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
|
||||
0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
|
||||
0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
|
||||
0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
|
||||
0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
|
||||
0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
|
||||
0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
|
||||
0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
|
||||
0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
|
||||
0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
|
||||
0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
|
||||
0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
|
||||
0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
|
||||
0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
|
||||
0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
|
||||
0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
|
||||
0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
|
||||
0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
|
||||
0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
|
||||
0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
|
||||
0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
|
||||
0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
|
||||
};
|
||||
static final int[] T8_5 = new int[] {
|
||||
0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
|
||||
0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
|
||||
0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
|
||||
0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
|
||||
0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
|
||||
0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
|
||||
0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
|
||||
0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
|
||||
0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
|
||||
0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
|
||||
0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
|
||||
0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
|
||||
0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
|
||||
0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
|
||||
0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
|
||||
0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
|
||||
0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
|
||||
0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
|
||||
0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
|
||||
0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
|
||||
0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
|
||||
0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
|
||||
0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
|
||||
0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
|
||||
0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
|
||||
0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
|
||||
0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
|
||||
0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
|
||||
0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
|
||||
0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
|
||||
0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
|
||||
0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
|
||||
0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
|
||||
0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
|
||||
0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
|
||||
0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
|
||||
0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
|
||||
0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
|
||||
0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
|
||||
0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
|
||||
0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
|
||||
0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
|
||||
0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
|
||||
0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
|
||||
0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
|
||||
0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
|
||||
0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
|
||||
0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
|
||||
0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
|
||||
0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
|
||||
0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
|
||||
0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
|
||||
0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
|
||||
0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
|
||||
0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
|
||||
0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
|
||||
0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
|
||||
0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
|
||||
0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
|
||||
0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
|
||||
0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
|
||||
0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
|
||||
0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
|
||||
0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
|
||||
};
|
||||
static final int[] T8_6 = new int[] {
|
||||
0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
|
||||
0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
|
||||
0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
|
||||
0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
|
||||
0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
|
||||
0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
|
||||
0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
|
||||
0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
|
||||
0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
|
||||
0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
|
||||
0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
|
||||
0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
|
||||
0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
|
||||
0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
|
||||
0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
|
||||
0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
|
||||
0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
|
||||
0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
|
||||
0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
|
||||
0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
|
||||
0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
|
||||
0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
|
||||
0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
|
||||
0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
|
||||
0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
|
||||
0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
|
||||
0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
|
||||
0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
|
||||
0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
|
||||
0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
|
||||
0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
|
||||
0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
|
||||
0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
|
||||
0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
|
||||
0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
|
||||
0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
|
||||
0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
|
||||
0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
|
||||
0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
|
||||
0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
|
||||
0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
|
||||
0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
|
||||
0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
|
||||
0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
|
||||
0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
|
||||
0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
|
||||
0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
|
||||
0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
|
||||
0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
|
||||
0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
|
||||
0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
|
||||
0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
|
||||
0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
|
||||
0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
|
||||
0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
|
||||
0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
|
||||
0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
|
||||
0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
|
||||
0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
|
||||
0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
|
||||
0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
|
||||
0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
|
||||
0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
|
||||
0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
|
||||
};
|
||||
static final int[] T8_7 = new int[] {
|
||||
0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
|
||||
0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
|
||||
0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
|
||||
0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
|
||||
0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
|
||||
0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
|
||||
0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
|
||||
0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
|
||||
0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
|
||||
0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
|
||||
0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
|
||||
0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
|
||||
0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
|
||||
0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
|
||||
0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
|
||||
0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
|
||||
0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
|
||||
0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
|
||||
0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
|
||||
0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
|
||||
0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
|
||||
0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
|
||||
0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
|
||||
0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
|
||||
0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
|
||||
0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
|
||||
0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
|
||||
0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
|
||||
0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
|
||||
0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
|
||||
0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
|
||||
0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
|
||||
0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
|
||||
0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
|
||||
0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
|
||||
0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
|
||||
0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
|
||||
0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
|
||||
0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
|
||||
0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
|
||||
0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
|
||||
0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
|
||||
0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
|
||||
0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
|
||||
0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
|
||||
0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
|
||||
0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
|
||||
0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
|
||||
0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
|
||||
0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
|
||||
0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
|
||||
0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
|
||||
0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
|
||||
0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
|
||||
0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
|
||||
0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
|
||||
0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
|
||||
0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
|
||||
0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
|
||||
0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
|
||||
0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
|
||||
0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
|
||||
0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
|
||||
0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
|
||||
};
|
||||
}
|
|
@ -26,7 +26,6 @@ package org.xerial.snappy;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ExceptionInInitializerError;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -35,7 +34,7 @@ import java.util.Properties;
|
|||
/**
|
||||
* Snappy API for data compression/decompression
|
||||
*
|
||||
* Note: if the native libraries cannot be loaded, then an ExceptionInInitializerError
|
||||
* Note: if the native libraries cannot be loaded, an ExceptionInInitializerError
|
||||
* will be thrown at first use of this class.
|
||||
*
|
||||
* @author leo
|
||||
|
@ -53,9 +52,23 @@ public class Snappy
|
|||
}
|
||||
|
||||
/**
|
||||
* An instance of SnappyNativeAPI
|
||||
* An instance of SnappyNative
|
||||
*/
|
||||
private static Object impl;
|
||||
private static SnappyNative impl;
|
||||
|
||||
|
||||
/**
|
||||
* Clean up a temporary file (native lib) generated by snappy-java.
|
||||
* General users do not need to call this method, since the native library extracted in snappy-java
|
||||
* is deleted upon JVM termination (vie deleteOnExit()).
|
||||
* This method is useful when using a J2EE container, which will restart servlet containers multiple times without
|
||||
* restarting JVM.
|
||||
*/
|
||||
public static void cleanUp() {
|
||||
SnappyLoader.cleanUpExtractedNativeLib();
|
||||
SnappyLoader.setApi(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy bytes from source to destination
|
||||
|
@ -74,7 +87,7 @@ public class Snappy
|
|||
*/
|
||||
public static void arrayCopy(Object src, int offset, int byteLength, Object dest, int dest_offset)
|
||||
throws IOException {
|
||||
((SnappyNativeAPI) impl).arrayCopy(src, offset, byteLength, dest, dest_offset);
|
||||
impl.arrayCopy(src, offset, byteLength, dest, dest_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,7 +148,7 @@ public class Snappy
|
|||
// output: compressed
|
||||
int uPos = uncompressed.position();
|
||||
int uLen = uncompressed.remaining();
|
||||
int compressedSize = ((SnappyNativeAPI) impl).rawCompress(uncompressed, uPos, uLen, compressed,
|
||||
int compressedSize = impl.rawCompress(uncompressed, uPos, uLen, compressed,
|
||||
compressed.position());
|
||||
|
||||
// pos limit
|
||||
|
@ -284,7 +297,7 @@ public class Snappy
|
|||
public static boolean isValidCompressedBuffer(byte[] input, int offset, int length) throws IOException {
|
||||
if (input == null)
|
||||
throw new NullPointerException("input is null");
|
||||
return ((SnappyNativeAPI) impl).isValidCompressedBuffer(input, offset, length);
|
||||
return impl.isValidCompressedBuffer(input, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,10 +317,21 @@ public class Snappy
|
|||
* factor of four faster than actual decompression.
|
||||
*/
|
||||
public static boolean isValidCompressedBuffer(ByteBuffer compressed) throws IOException {
|
||||
return ((SnappyNativeAPI) impl).isValidCompressedBuffer(compressed, compressed.position(),
|
||||
return impl.isValidCompressedBuffer(compressed, compressed.position(),
|
||||
compressed.remaining());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff the contents of compressed buffer [offset,
|
||||
* offset+length) can be uncompressed successfully. Does not return the
|
||||
* uncompressed data. Takes time proportional to the input length, but is
|
||||
* usually at least a factor of four faster than actual decompression.
|
||||
*/
|
||||
public static boolean isValidCompressedBuffer(long inputAddr, long offset, long length) throws IOException {
|
||||
return impl.isValidCompressedBuffer(inputAddr, offset, length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the maximum byte size needed for compressing data of the given byte
|
||||
* size.
|
||||
|
@ -317,7 +341,7 @@ public class Snappy
|
|||
* @return maximum byte size of the compressed data
|
||||
*/
|
||||
public static int maxCompressedLength(int byteSize) {
|
||||
return ((SnappyNativeAPI) impl).maxCompressedLength(byteSize);
|
||||
return impl.maxCompressedLength(byteSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,7 +353,7 @@ public class Snappy
|
|||
* @throws IOException
|
||||
*/
|
||||
public static long rawCompress(long inputAddr, long inputSize, long destAddr) throws IOException {
|
||||
return ((SnappyNativeAPI) impl).rawCompress(inputAddr, inputSize, destAddr);
|
||||
return impl.rawCompress(inputAddr, inputSize, destAddr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -341,7 +365,7 @@ public class Snappy
|
|||
* @throws IOException
|
||||
*/
|
||||
public static long rawUncompress(long inputAddr, long inputSize, long destAddr) throws IOException {
|
||||
return ((SnappyNativeAPI) impl).rawUncompress(inputAddr, inputSize, destAddr);
|
||||
return impl.rawUncompress(inputAddr, inputSize, destAddr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -356,7 +380,7 @@ public class Snappy
|
|||
*/
|
||||
public static byte[] rawCompress(Object data, int byteSize) throws IOException {
|
||||
byte[] buf = new byte[Snappy.maxCompressedLength(byteSize)];
|
||||
int compressedByteSize = ((SnappyNativeAPI) impl).rawCompress(data, 0, byteSize, buf, 0);
|
||||
int compressedByteSize = impl.rawCompress(data, 0, byteSize, buf, 0);
|
||||
byte[] result = new byte[compressedByteSize];
|
||||
System.arraycopy(buf, 0, result, 0, compressedByteSize);
|
||||
return result;
|
||||
|
@ -384,7 +408,7 @@ public class Snappy
|
|||
if (input == null || output == null)
|
||||
throw new NullPointerException("input or output is null");
|
||||
|
||||
int compressedSize = ((SnappyNativeAPI) impl)
|
||||
int compressedSize = impl
|
||||
.rawCompress(input, inputOffset, inputLength, output, outputOffset);
|
||||
return compressedSize;
|
||||
}
|
||||
|
@ -417,7 +441,7 @@ public class Snappy
|
|||
throws IOException {
|
||||
if (input == null || output == null)
|
||||
throw new NullPointerException("input or output is null");
|
||||
return ((SnappyNativeAPI) impl).rawUncompress(input, inputOffset, inputLength, output, outputOffset);
|
||||
return impl.rawUncompress(input, inputOffset, inputLength, output, outputOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -489,7 +513,7 @@ public class Snappy
|
|||
|
||||
// pos limit
|
||||
// [ ......UUUUUU.........]
|
||||
int decompressedSize = ((SnappyNativeAPI) impl).rawUncompress(compressed, cPos, cLen, uncompressed,
|
||||
int decompressedSize = impl.rawUncompress(compressed, cPos, cLen, uncompressed,
|
||||
uncompressed.position());
|
||||
uncompressed.limit(uncompressed.position() + decompressedSize);
|
||||
|
||||
|
@ -519,7 +543,7 @@ public class Snappy
|
|||
public static char[] uncompressCharArray(byte[] input, int offset, int length) throws IOException {
|
||||
int uncompressedLength = Snappy.uncompressedLength(input, offset, length);
|
||||
char[] result = new char[uncompressedLength / 2];
|
||||
int byteSize = ((SnappyNativeAPI) impl).rawUncompress(input, offset, length, result, 0);
|
||||
int byteSize = impl.rawUncompress(input, offset, length, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -533,7 +557,7 @@ public class Snappy
|
|||
public static double[] uncompressDoubleArray(byte[] input) throws IOException {
|
||||
int uncompressedLength = Snappy.uncompressedLength(input, 0, input.length);
|
||||
double[] result = new double[uncompressedLength / 8];
|
||||
int byteSize = ((SnappyNativeAPI) impl).rawUncompress(input, 0, input.length, result, 0);
|
||||
int byteSize = impl.rawUncompress(input, 0, input.length, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -548,7 +572,7 @@ public class Snappy
|
|||
* {@link SnappyErrorCode#PARSING_ERROR}
|
||||
*/
|
||||
public static int uncompressedLength(byte[] input) throws IOException {
|
||||
return ((SnappyNativeAPI) impl).uncompressedLength(input, 0, input.length);
|
||||
return impl.uncompressedLength(input, 0, input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,7 +591,7 @@ public class Snappy
|
|||
if (input == null)
|
||||
throw new NullPointerException("input is null");
|
||||
|
||||
return ((SnappyNativeAPI) impl).uncompressedLength(input, offset, length);
|
||||
return impl.uncompressedLength(input, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -587,7 +611,7 @@ public class Snappy
|
|||
if (!compressed.isDirect())
|
||||
throw new SnappyError(SnappyErrorCode.NOT_A_DIRECT_BUFFER, "input is not a direct buffer");
|
||||
|
||||
return ((SnappyNativeAPI) impl).uncompressedLength(compressed, compressed.position(), compressed.remaining());
|
||||
return impl.uncompressedLength(compressed, compressed.position(), compressed.remaining());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -599,7 +623,7 @@ public class Snappy
|
|||
* {@link SnappyErrorCode#PARSING_ERROR}
|
||||
*/
|
||||
public static long uncompressedLength(long inputAddr, long len) throws IOException {
|
||||
return ((SnappyNativeAPI) impl).uncompressedLength(inputAddr, len);
|
||||
return impl.uncompressedLength(inputAddr, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -625,7 +649,7 @@ public class Snappy
|
|||
public static float[] uncompressFloatArray(byte[] input, int offset, int length) throws IOException {
|
||||
int uncompressedLength = Snappy.uncompressedLength(input, offset, length);
|
||||
float[] result = new float[uncompressedLength / 4];
|
||||
int byteSize = ((SnappyNativeAPI) impl).rawUncompress(input, offset, length, result, 0);
|
||||
int byteSize = impl.rawUncompress(input, offset, length, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -652,7 +676,7 @@ public class Snappy
|
|||
public static int[] uncompressIntArray(byte[] input, int offset, int length) throws IOException {
|
||||
int uncompressedLength = Snappy.uncompressedLength(input, offset, length);
|
||||
int[] result = new int[uncompressedLength / 4];
|
||||
int byteSize = ((SnappyNativeAPI) impl).rawUncompress(input, offset, length, result, 0);
|
||||
int byteSize = impl.rawUncompress(input, offset, length, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -679,7 +703,7 @@ public class Snappy
|
|||
public static long[] uncompressLongArray(byte[] input, int offset, int length) throws IOException {
|
||||
int uncompressedLength = Snappy.uncompressedLength(input, offset, length);
|
||||
long[] result = new long[uncompressedLength / 8];
|
||||
int byteSize = ((SnappyNativeAPI) impl).rawUncompress(input, offset, length, result, 0);
|
||||
int byteSize = impl.rawUncompress(input, offset, length, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -706,7 +730,7 @@ public class Snappy
|
|||
public static short[] uncompressShortArray(byte[] input, int offset, int length) throws IOException {
|
||||
int uncompressedLength = Snappy.uncompressedLength(input, offset, length);
|
||||
short[] result = new short[uncompressedLength / 2];
|
||||
int byteSize = ((SnappyNativeAPI) impl).rawUncompress(input, offset, length, result, 0);
|
||||
int byteSize = impl.rawUncompress(input, offset, length, result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
/**
|
||||
* OSGi bundle entry point
|
||||
*
|
||||
|
@ -56,5 +56,6 @@ public class SnappyBundleActivator implements BundleActivator
|
|||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
SnappyLoader.setApi(null);
|
||||
SnappyLoader.cleanUpExtractedNativeLib();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ public class SnappyCodec
|
|||
public static SnappyCodec readHeader(InputStream in) throws IOException {
|
||||
DataInputStream d = new DataInputStream(in);
|
||||
byte[] magic = new byte[MAGIC_LEN];
|
||||
d.read(magic, 0, MAGIC_LEN);
|
||||
d.readFully(magic, 0, MAGIC_LEN);
|
||||
int version = d.readInt();
|
||||
int compatibleVersion = d.readInt();
|
||||
return new SnappyCodec(magic, version, compatibleVersion);
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Created: Apr 12, 2013
|
||||
*/
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
/**
|
||||
* Constants and utilities for implementing x-snappy-framed.
|
||||
*
|
||||
* @author Brett Okken
|
||||
* @since 1.1.0
|
||||
*/
|
||||
final class SnappyFramed {
|
||||
public static final int COMPRESSED_DATA_FLAG = 0x00;
|
||||
|
||||
public static final int UNCOMPRESSED_DATA_FLAG = 0x01;
|
||||
|
||||
public static final int STREAM_IDENTIFIER_FLAG = 0xff;
|
||||
|
||||
private static final int MASK_DELTA = 0xa282ead8;
|
||||
|
||||
/**
|
||||
* The header consists of the stream identifier flag, 3 bytes indicating a
|
||||
* length of 6, and "sNaPpY" in ASCII.
|
||||
*/
|
||||
public static final byte[] HEADER_BYTES = new byte[] {
|
||||
(byte) STREAM_IDENTIFIER_FLAG, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61,
|
||||
0x50, 0x70, 0x59 };
|
||||
|
||||
public static int maskedCrc32c(byte[] data)
|
||||
{
|
||||
return maskedCrc32c(data, 0, data.length);
|
||||
}
|
||||
|
||||
public static int maskedCrc32c(byte[] data, int offset, int length)
|
||||
{
|
||||
final PureJavaCrc32C crc32c = new PureJavaCrc32C();
|
||||
crc32c.update(data, offset, length);
|
||||
return mask(crc32c.getIntegerValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checksums are not stored directly, but masked, as checksumming data and
|
||||
* then its own checksum can be problematic. The masking is the same as used
|
||||
* in Apache Hadoop: Rotate the checksum by 15 bits, then add the constant
|
||||
* 0xa282ead8 (using wraparound as normal for unsigned integers). This is
|
||||
* equivalent to the following C code:
|
||||
*
|
||||
* <pre>
|
||||
* uint32_t mask_checksum(uint32_t x) {
|
||||
* return ((x >> 15) | (x << 17)) + 0xa282ead8;
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public static int mask(int crc)
|
||||
{
|
||||
// Rotate right by 15 bits and add a constant.
|
||||
return ((crc >>> 15) | (crc << 17)) + MASK_DELTA;
|
||||
}
|
||||
|
||||
|
||||
static final int readBytes(ReadableByteChannel source, ByteBuffer dest) throws IOException
|
||||
{
|
||||
// tells how many bytes to read.
|
||||
final int expectedLength = dest.remaining();
|
||||
|
||||
int totalRead = 0;
|
||||
|
||||
// how many bytes were read.
|
||||
int lastRead = source.read(dest);
|
||||
|
||||
totalRead = lastRead;
|
||||
|
||||
// if we did not read as many bytes as we had hoped, try reading again.
|
||||
if (lastRead < expectedLength)
|
||||
{
|
||||
// as long the buffer is not full (remaining() == 0) and we have not reached EOF (lastRead == -1) keep reading.
|
||||
while (dest.remaining() != 0 && lastRead != -1)
|
||||
{
|
||||
lastRead = source.read(dest);
|
||||
|
||||
// if we got EOF, do not add to total read.
|
||||
if (lastRead != -1)
|
||||
{
|
||||
totalRead += lastRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (totalRead > 0)
|
||||
{
|
||||
dest.limit(dest.position());
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.position(dest.limit());
|
||||
}
|
||||
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
static int skip(final ReadableByteChannel source, final int skip, final ByteBuffer buffer) throws IOException
|
||||
{
|
||||
if (skip <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int toSkip = skip;
|
||||
int skipped = 0;
|
||||
while(toSkip > 0 && skipped != -1) {
|
||||
buffer.clear();
|
||||
if (toSkip < buffer.capacity()) {
|
||||
buffer.limit(toSkip);
|
||||
}
|
||||
|
||||
skipped = source.read(buffer);
|
||||
if (skipped > 0) {
|
||||
toSkip -= skipped;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.clear();
|
||||
return skip - toSkip;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,452 @@
|
|||
/*
|
||||
* Created: Apr 15, 2013
|
||||
*/
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static java.lang.Math.min;
|
||||
import static org.xerial.snappy.SnappyFramed.*;
|
||||
import static org.xerial.snappy.SnappyFramedOutputStream.*;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Implements the <a
|
||||
* href="http://snappy.googlecode.com/svn/trunk/framing_format.txt"
|
||||
* >x-snappy-framed</a> as an {@link InputStream} and
|
||||
* {@link ReadableByteChannel}.
|
||||
*
|
||||
* @author Brett Okken
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final class SnappyFramedInputStream extends InputStream implements
|
||||
ReadableByteChannel {
|
||||
|
||||
private final ReadableByteChannel rbc;
|
||||
private final ByteBuffer frameHeader;
|
||||
private final boolean verifyChecksums;
|
||||
|
||||
/**
|
||||
* A single frame read from the underlying {@link InputStream}.
|
||||
*/
|
||||
private ByteBuffer input;
|
||||
|
||||
/**
|
||||
* The decompressed data from {@link #input}.
|
||||
*/
|
||||
private ByteBuffer uncompressedDirect;
|
||||
|
||||
/**
|
||||
* Indicates if this instance has been closed.
|
||||
*/
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* Indicates if we have reached the EOF on {@link #in}.
|
||||
*/
|
||||
private boolean eof;
|
||||
|
||||
/**
|
||||
* The position in {@link buffer} to read to.
|
||||
*/
|
||||
private int valid;
|
||||
|
||||
/**
|
||||
* The next position to read from {@link #buffer}.
|
||||
*/
|
||||
private int position;
|
||||
|
||||
/**
|
||||
* Buffer contains a copy of the uncompressed data for the block.
|
||||
*/
|
||||
private byte[] buffer;
|
||||
|
||||
/**
|
||||
* Creates a Snappy input stream to read data from the specified underlying
|
||||
* input stream.
|
||||
*
|
||||
* @param in
|
||||
* the underlying input stream. Must not be {@code null}.
|
||||
*/
|
||||
public SnappyFramedInputStream(InputStream in) throws IOException {
|
||||
this(in, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Snappy input stream to read data from the specified underlying
|
||||
* input stream.
|
||||
*
|
||||
* @param in
|
||||
* the underlying input stream. Must not be {@code null}.
|
||||
* @param verifyChecksums
|
||||
* if true, checksums in input stream will be verified
|
||||
*/
|
||||
public SnappyFramedInputStream(InputStream in, boolean verifyChecksums)
|
||||
throws IOException {
|
||||
this(Channels.newChannel(in), verifyChecksums);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Snappy input stream to read data from the specified underlying
|
||||
* channel.
|
||||
*
|
||||
* @param in
|
||||
* the underlying readable channel. Must not be {@code null}.
|
||||
*/
|
||||
public SnappyFramedInputStream(ReadableByteChannel in)
|
||||
throws IOException {
|
||||
this(in, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Snappy input stream to read data from the specified underlying
|
||||
* channel.
|
||||
*
|
||||
* @param in
|
||||
* the underlying readable channel. Must not be {@code null}.
|
||||
* @param verifyChecksums
|
||||
* if true, checksums in input stream will be verified
|
||||
*/
|
||||
public SnappyFramedInputStream(ReadableByteChannel in,
|
||||
boolean verifyChecksums) throws IOException {
|
||||
if (in == null) {
|
||||
throw new NullPointerException("in is null");
|
||||
}
|
||||
|
||||
this.rbc = in;
|
||||
this.verifyChecksums = verifyChecksums;
|
||||
|
||||
allocateBuffersBasedOnSize(MAX_BLOCK_SIZE + 5);
|
||||
this.frameHeader = ByteBuffer.allocate(4);
|
||||
|
||||
// stream must begin with stream header
|
||||
final byte[] expectedHeader = HEADER_BYTES;
|
||||
final byte[] actualHeader = new byte[expectedHeader.length];
|
||||
final ByteBuffer actualBuffer = ByteBuffer.wrap(actualHeader);
|
||||
|
||||
// assume that if the input cannot read 4 bytes that something is
|
||||
// wrong.
|
||||
final int read = in.read(actualBuffer);
|
||||
if (read < expectedHeader.length) {
|
||||
throw new EOFException(
|
||||
"encountered EOF while reading stream header");
|
||||
}
|
||||
if (!Arrays.equals(expectedHeader, actualHeader)) {
|
||||
throw new IOException("invalid stream header");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size
|
||||
*/
|
||||
private void allocateBuffersBasedOnSize(int size) {
|
||||
|
||||
input = ByteBuffer.allocateDirect(size);
|
||||
final int maxCompressedLength = Snappy.maxCompressedLength(size);
|
||||
uncompressedDirect = ByteBuffer.allocateDirect(maxCompressedLength);
|
||||
buffer = new byte[maxCompressedLength];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (closed) {
|
||||
return -1;
|
||||
}
|
||||
if (!ensureBuffer()) {
|
||||
return -1;
|
||||
}
|
||||
return buffer[position++] & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] output, int offset, int length) throws IOException {
|
||||
|
||||
if (output == null) {
|
||||
throw new IllegalArgumentException("output is null");
|
||||
}
|
||||
|
||||
if (offset < 0 || length < 0 || offset + length > output.length) {
|
||||
throw new IllegalArgumentException("invalid offset [" + offset
|
||||
+ "] and length [" + length + ']');
|
||||
}
|
||||
|
||||
if (closed) {
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!ensureBuffer()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int size = min(length, available());
|
||||
System.arraycopy(buffer, position, output, offset, size);
|
||||
position += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
if (closed) {
|
||||
return 0;
|
||||
}
|
||||
return valid - position;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
|
||||
if (dst == null) {
|
||||
throw new IllegalArgumentException("dst is null");
|
||||
}
|
||||
|
||||
if (closed) {
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
|
||||
if (dst.remaining() == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!ensureBuffer()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int size = min(dst.remaining(), available());
|
||||
dst.put(buffer, position, size);
|
||||
position += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
rbc.close();
|
||||
} finally {
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static enum FrameAction {
|
||||
RAW, SKIP, UNCOMPRESS;
|
||||
}
|
||||
|
||||
public static final class FrameMetaData {
|
||||
final int length;
|
||||
final FrameAction frameAction;
|
||||
|
||||
/**
|
||||
* @param frameAction
|
||||
* @param length
|
||||
*/
|
||||
public FrameMetaData(FrameAction frameAction, int length) {
|
||||
super();
|
||||
this.frameAction = frameAction;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class FrameData {
|
||||
final int checkSum;
|
||||
final int offset;
|
||||
|
||||
/**
|
||||
* @param checkSum
|
||||
* @param offset
|
||||
*/
|
||||
public FrameData(int checkSum, int offset) {
|
||||
super();
|
||||
this.checkSum = checkSum;
|
||||
this.offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ensureBuffer() throws IOException {
|
||||
if (available() > 0) {
|
||||
return true;
|
||||
}
|
||||
if (eof) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!readBlockHeader()) {
|
||||
eof = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// get action based on header
|
||||
final FrameMetaData frameMetaData = getFrameMetaData(frameHeader);
|
||||
|
||||
if (FrameAction.SKIP == frameMetaData.frameAction) {
|
||||
SnappyFramed.skip(rbc, frameMetaData.length,
|
||||
ByteBuffer.wrap(buffer));
|
||||
return ensureBuffer();
|
||||
}
|
||||
|
||||
if (frameMetaData.length > input.capacity()) {
|
||||
allocateBuffersBasedOnSize(frameMetaData.length);
|
||||
}
|
||||
|
||||
input.clear();
|
||||
input.limit(frameMetaData.length);
|
||||
|
||||
final int actualRead = readBytes(rbc, input);
|
||||
if (actualRead != frameMetaData.length) {
|
||||
throw new EOFException("unexpectd EOF when reading frame");
|
||||
}
|
||||
input.flip();
|
||||
|
||||
final FrameData frameData = getFrameData(input);
|
||||
|
||||
if (FrameAction.UNCOMPRESS == frameMetaData.frameAction) {
|
||||
|
||||
input.position(frameData.offset);
|
||||
|
||||
final int uncompressedLength = Snappy.uncompressedLength(input);
|
||||
|
||||
if (uncompressedLength > uncompressedDirect.capacity()) {
|
||||
uncompressedDirect = ByteBuffer
|
||||
.allocateDirect(uncompressedLength);
|
||||
buffer = new byte[Math.max(input.capacity(), uncompressedLength)];
|
||||
}
|
||||
|
||||
uncompressedDirect.clear();
|
||||
|
||||
this.valid = Snappy.uncompress(input, uncompressedDirect);
|
||||
|
||||
uncompressedDirect.get(buffer, 0, valid);
|
||||
this.position = 0;
|
||||
} else {
|
||||
// we need to start reading at the offset
|
||||
input.position(frameData.offset);
|
||||
this.position = 0;
|
||||
this.valid = input.remaining();
|
||||
this.input.get(buffer, 0, input.remaining());
|
||||
}
|
||||
|
||||
if (verifyChecksums) {
|
||||
final int actualCrc32c = SnappyFramed.maskedCrc32c(buffer,
|
||||
position, valid - position);
|
||||
if (frameData.checkSum != actualCrc32c) {
|
||||
throw new IOException("Corrupt input: invalid checksum");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean readBlockHeader() throws IOException {
|
||||
frameHeader.clear();
|
||||
int read = readBytes(rbc, frameHeader);
|
||||
|
||||
if (read == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (read < frameHeader.capacity()) {
|
||||
throw new EOFException("encountered EOF while reading block header");
|
||||
}
|
||||
frameHeader.flip();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param frameHeader
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private FrameMetaData getFrameMetaData(ByteBuffer frameHeader)
|
||||
throws IOException {
|
||||
|
||||
assert frameHeader.hasArray();
|
||||
|
||||
final byte[] frameHeaderArray = frameHeader.array();
|
||||
|
||||
int length = (frameHeaderArray[1] & 0xFF);
|
||||
length |= (frameHeaderArray[2] & 0xFF) << 8;
|
||||
length |= (frameHeaderArray[3] & 0xFF) << 16;
|
||||
|
||||
int minLength = 0;
|
||||
final FrameAction frameAction;
|
||||
final int flag = frameHeaderArray[0] & 0xFF;
|
||||
switch (flag) {
|
||||
case COMPRESSED_DATA_FLAG:
|
||||
frameAction = FrameAction.UNCOMPRESS;
|
||||
minLength = 5;
|
||||
break;
|
||||
case UNCOMPRESSED_DATA_FLAG:
|
||||
frameAction = FrameAction.RAW;
|
||||
minLength = 5;
|
||||
break;
|
||||
case STREAM_IDENTIFIER_FLAG:
|
||||
if (length != 6) {
|
||||
throw new IOException(
|
||||
"stream identifier chunk with invalid length: "
|
||||
+ length);
|
||||
}
|
||||
frameAction = FrameAction.SKIP;
|
||||
minLength = 6;
|
||||
break;
|
||||
default:
|
||||
// Reserved unskippable chunks (chunk types 0x02-0x7f)
|
||||
if (flag <= 0x7f) {
|
||||
throw new IOException("unsupported unskippable chunk: "
|
||||
+ Integer.toHexString(flag));
|
||||
}
|
||||
|
||||
// all that is left is Reserved skippable chunks (chunk types
|
||||
// 0x80-0xfe)
|
||||
frameAction = FrameAction.SKIP;
|
||||
minLength = 0;
|
||||
}
|
||||
|
||||
if (length < minLength) {
|
||||
throw new IOException("invalid length: " + length
|
||||
+ " for chunk flag: " + Integer.toHexString(flag));
|
||||
}
|
||||
|
||||
return new FrameMetaData(frameAction, length);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param content
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private FrameData getFrameData(ByteBuffer content) throws IOException {
|
||||
return new FrameData(getCrc32c(content), 4);
|
||||
}
|
||||
|
||||
private int getCrc32c(ByteBuffer content) {
|
||||
|
||||
final int position = content.position();
|
||||
|
||||
return ((content.get(position + 3) & 0xFF) << 24)
|
||||
| ((content.get(position + 2) & 0xFF) << 16)
|
||||
| ((content.get(position + 1) & 0xFF) << 8)
|
||||
| (content.get(position) & 0xFF);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Created: Apr 12, 2013
|
||||
*/
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static org.xerial.snappy.SnappyFramed.COMPRESSED_DATA_FLAG;
|
||||
import static org.xerial.snappy.SnappyFramed.HEADER_BYTES;
|
||||
import static org.xerial.snappy.SnappyFramed.UNCOMPRESSED_DATA_FLAG;
|
||||
import static org.xerial.snappy.SnappyFramed.maskedCrc32c;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
/**
|
||||
* Implements the <a
|
||||
* href="http://snappy.googlecode.com/svn/trunk/framing_format.txt"
|
||||
* >x-snappy-framed</a> as an {@link OutputStream} and
|
||||
* {@link WritableByteChannel}.
|
||||
*
|
||||
* @author Brett Okken
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public final class SnappyFramedOutputStream extends OutputStream implements
|
||||
WritableByteChannel {
|
||||
|
||||
/**
|
||||
* The x-snappy-framed specification allows for a chunk size up to
|
||||
* 16,777,211 bytes in length. However, it also goes on to state:
|
||||
* <p>
|
||||
* <code>
|
||||
* We place an additional restriction that the uncompressed data in a chunk
|
||||
* must be no longer than 65536 bytes. This allows consumers to easily use
|
||||
* small fixed-size buffers.
|
||||
* </code>
|
||||
* </p>
|
||||
*/
|
||||
public static final int MAX_BLOCK_SIZE = 64 * 1024;
|
||||
|
||||
/**
|
||||
* The default block size to use.
|
||||
*/
|
||||
public static final int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE;
|
||||
|
||||
/**
|
||||
* The default min compression ratio to use.
|
||||
*/
|
||||
public static final double DEFAULT_MIN_COMPRESSION_RATIO = 0.85d;
|
||||
|
||||
// private final int blockSize;
|
||||
private final ByteBuffer buffer;
|
||||
private final byte[] outputBuffer;
|
||||
private final double minCompressionRatio;
|
||||
|
||||
private final OutputStream out;
|
||||
|
||||
// private int position;
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SnappyFramedOutputStream} using the {@link #DEFAULT_BLOCK_SIZE}
|
||||
* and {@link #DEFAULT_MIN_COMPRESSION_RATIO}.
|
||||
* @param out
|
||||
* The underlying {@link OutputStream} to write to. Must not be
|
||||
* {@code null}.
|
||||
* @throws IOException
|
||||
*/
|
||||
public SnappyFramedOutputStream(OutputStream out) throws IOException {
|
||||
this(out, DEFAULT_BLOCK_SIZE, DEFAULT_MIN_COMPRESSION_RATIO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SnappyFramedOutputStream} instance.
|
||||
*
|
||||
* @param out
|
||||
* The underlying {@link OutputStream} to write to. Must not be
|
||||
* {@code null}.
|
||||
* @param blockSize
|
||||
* The block size (of raw data) to compress before writing frames
|
||||
* to <i>out</i>. Must be in (0, 65536].
|
||||
* @param minCompressionRatio
|
||||
* Defines the minimum compression ratio (
|
||||
* {@code compressedLength / rawLength}) that must be achieved to
|
||||
* write the compressed data. This must be in (0, 1.0].
|
||||
* @throws IOException
|
||||
*/
|
||||
public SnappyFramedOutputStream(OutputStream out, int blockSize,
|
||||
double minCompressionRatio) throws IOException {
|
||||
if (out == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
if (minCompressionRatio <= 0 || minCompressionRatio > 1.0) {
|
||||
throw new IllegalArgumentException("minCompressionRatio "
|
||||
+ minCompressionRatio + " must be in (0,1.0]");
|
||||
}
|
||||
|
||||
if (blockSize <= 0 || blockSize > MAX_BLOCK_SIZE) {
|
||||
throw new IllegalArgumentException("block size " + blockSize
|
||||
+ " must be in (0, 65536]");
|
||||
}
|
||||
|
||||
this.out = out;
|
||||
this.minCompressionRatio = minCompressionRatio;
|
||||
buffer = ByteBuffer.allocate(blockSize);
|
||||
outputBuffer = new byte[Snappy.maxCompressedLength(blockSize)];
|
||||
|
||||
writeHeader(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the implementation specific header or "marker bytes" to
|
||||
* <i>out</i>.
|
||||
*
|
||||
* @param out
|
||||
* The underlying {@link OutputStream}.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void writeHeader(OutputStream out) throws IOException {
|
||||
out.write(HEADER_BYTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return !closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
if (buffer.remaining() <= 0) {
|
||||
flushBuffer();
|
||||
}
|
||||
buffer.put((byte) b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] input, int offset, int length) throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
|
||||
write(ByteBuffer.wrap(input, offset, length));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
if (closed) {
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
|
||||
if (buffer.remaining() <= 0) {
|
||||
flushBuffer();
|
||||
}
|
||||
|
||||
final int srcLength = src.remaining();
|
||||
|
||||
// easy case: enough free space in buffer for entire input
|
||||
if (buffer.remaining() >= src.remaining()) {
|
||||
buffer.put(src);
|
||||
return srcLength;
|
||||
}
|
||||
|
||||
// store current limit
|
||||
final int srcEnd = src.position() + src.remaining();
|
||||
|
||||
while ((src.position() + buffer.remaining()) <= srcEnd) {
|
||||
// fill partial buffer as much as possible and flush
|
||||
src.limit(src.position() + buffer.remaining());
|
||||
buffer.put(src);
|
||||
flushBuffer();
|
||||
}
|
||||
|
||||
// reset original limit
|
||||
src.limit(srcEnd);
|
||||
|
||||
// copy remaining partial block into now-empty buffer
|
||||
buffer.put(src);
|
||||
|
||||
return srcLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void flush() throws IOException {
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
}
|
||||
flushBuffer();
|
||||
out.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
flush();
|
||||
out.close();
|
||||
} finally {
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses and writes out any buffered data. This does nothing if there
|
||||
* is no currently buffered data.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void flushBuffer() throws IOException {
|
||||
if (buffer.position() > 0) {
|
||||
buffer.flip();
|
||||
writeCompressed(buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #calculateCRC32C(byte[], int, int) Calculates} the crc, compresses
|
||||
* the data, determines if the compression ratio is acceptable and calls
|
||||
* {@link #writeBlock(OutputStream, byte[], int, int, boolean, int)} to
|
||||
* actually write the frame.
|
||||
*
|
||||
* @param input
|
||||
* The byte[] containing the raw data to be compressed.
|
||||
* @param offset
|
||||
* The offset into <i>input</i> where the data starts.
|
||||
* @param length
|
||||
* The amount of data in <i>input</i>.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void writeCompressed(ByteBuffer buffer) throws IOException {
|
||||
|
||||
final byte[] input = buffer.array();
|
||||
final int length = buffer.remaining();
|
||||
|
||||
// crc is based on the user supplied input data
|
||||
final int crc32c = calculateCRC32C(input, 0, length);
|
||||
|
||||
final int compressedLength = Snappy.compress(input, 0, length,
|
||||
outputBuffer, 0);
|
||||
|
||||
// only use the compressed data if copmression ratio is <= the
|
||||
// minCompressonRatio
|
||||
if (((double) compressedLength / (double) length) <= minCompressionRatio) {
|
||||
writeBlock(out, outputBuffer, 0, compressedLength, true, crc32c);
|
||||
} else {
|
||||
// otherwise use the uncomprssed data.
|
||||
writeBlock(out, input, 0, length, false, crc32c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a masked CRC32C checksum over the data.
|
||||
*
|
||||
* @param data
|
||||
* @param offset
|
||||
* @param length
|
||||
* @return The CRC32 checksum.
|
||||
*/
|
||||
private int calculateCRC32C(byte[] data, int offset, int length) {
|
||||
return maskedCrc32c(data, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a frame (block) to <i>out</i>.
|
||||
*
|
||||
* @param out
|
||||
* The {@link OutputStream} to write to.
|
||||
* @param data
|
||||
* The data to write.
|
||||
* @param offset
|
||||
* The offset in <i>data</i> to start at.
|
||||
* @param length
|
||||
* The length of <i>data</i> to use.
|
||||
* @param compressed
|
||||
* Indicates if <i>data</i> is the compressed or raw content.
|
||||
* This is based on whether the compression ratio desired is
|
||||
* reached.
|
||||
* @param crc32c
|
||||
* The calculated checksum.
|
||||
* @throws IOException
|
||||
*/
|
||||
private void writeBlock(final OutputStream out, byte[] data, int offset,
|
||||
int length, boolean compressed, int crc32c) throws IOException {
|
||||
out.write(compressed ? COMPRESSED_DATA_FLAG : UNCOMPRESSED_DATA_FLAG);
|
||||
|
||||
// the length written out to the header is both the checksum and the
|
||||
// frame
|
||||
final int headerLength = length + 4;
|
||||
|
||||
// write length
|
||||
out.write(headerLength);
|
||||
out.write(headerLength >>> 8);
|
||||
out.write(headerLength >>> 16);
|
||||
|
||||
// write crc32c of user input data
|
||||
out.write(crc32c);
|
||||
out.write(crc32c >>> 8);
|
||||
out.write(crc32c >>> 16);
|
||||
out.write(crc32c >>> 24);
|
||||
|
||||
// write data
|
||||
out.write(data, offset, length);
|
||||
}
|
||||
}
|
|
@ -24,24 +24,11 @@
|
|||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* <b>Internal only - Do not use this class.</b> This class loads a native
|
||||
|
@ -94,14 +81,21 @@ public class SnappyLoader
|
|||
public static final String KEY_SNAPPY_DISABLE_BUNDLED_LIBS = "org.xerial.snappy.disable.bundled.libs"; // Depreciated, but preserved for backward compatibility
|
||||
|
||||
private static volatile boolean isLoaded = false;
|
||||
private static volatile Object api = null;
|
||||
private static volatile SnappyNative api = null;
|
||||
|
||||
private static File nativeLibFile = null;
|
||||
|
||||
static void cleanUpExtractedNativeLib() {
|
||||
if(nativeLibFile != null && nativeLibFile.exists())
|
||||
nativeLibFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the api instance.
|
||||
*
|
||||
* @param nativeCode
|
||||
*/
|
||||
static synchronized void setApi(Object nativeCode)
|
||||
static synchronized void setApi(SnappyNative nativeCode)
|
||||
{
|
||||
api = nativeCode;
|
||||
}
|
||||
|
@ -142,97 +136,16 @@ public class SnappyLoader
|
|||
loadSnappySystemProperties();
|
||||
}
|
||||
|
||||
private static ClassLoader getRootClassLoader() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
while (cl.getParent() != null) {
|
||||
cl = cl.getParent();
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
|
||||
private static byte[] getByteCode(String resourcePath) throws IOException {
|
||||
|
||||
InputStream in = SnappyLoader.class.getResourceAsStream(resourcePath);
|
||||
if (in == null)
|
||||
throw new IOException(resourcePath + " is not found");
|
||||
byte[] buf = new byte[1024];
|
||||
ByteArrayOutputStream byteCodeBuf = new ByteArrayOutputStream();
|
||||
for (int readLength; (readLength = in.read(buf)) != -1;) {
|
||||
byteCodeBuf.write(buf, 0, readLength);
|
||||
}
|
||||
in.close();
|
||||
|
||||
return byteCodeBuf.toByteArray();
|
||||
}
|
||||
|
||||
public static boolean isNativeLibraryLoaded() {
|
||||
return isLoaded;
|
||||
}
|
||||
|
||||
private static boolean hasInjectedNativeLoader() {
|
||||
try {
|
||||
final String nativeLoaderClassName = "org.xerial.snappy.SnappyNativeLoader";
|
||||
Class< ? > c = Class.forName(nativeLoaderClassName);
|
||||
// If this native loader class is already defined, it means that another class loader already loaded the native library of snappy
|
||||
return true;
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
// do loading
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load SnappyNative and its JNI native implementation using the root class
|
||||
* loader. This hack is for avoiding the JNI multi-loading issue when the
|
||||
* same JNI library is loaded by different class loaders.
|
||||
*
|
||||
* In order to load native code in the root class loader, this method first
|
||||
* inject SnappyNativeLoader class into the root class loader, because
|
||||
* {@link System#load(String)} method uses the class loader of the caller
|
||||
* class when loading native libraries.
|
||||
*
|
||||
* <pre>
|
||||
* (root class loader) -> [SnappyNativeLoader (load JNI code), SnappyNative (has native methods), SnappyNativeAPI, SnappyErrorCode] (injected by this method)
|
||||
* |
|
||||
* |
|
||||
* (child class loader) -> Sees the above classes loaded by the root class loader.
|
||||
* Then creates SnappyNativeAPI implementation by instantiating SnappyNaitive class.
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* (root class loader) -> [SnappyNativeLoader, SnappyNative ...] -> native code is loaded by once in this class loader
|
||||
* | \
|
||||
* | (child2 class loader)
|
||||
* (child1 class loader)
|
||||
*
|
||||
* child1 and child2 share the same SnappyNative code loaded by the root class loader.
|
||||
* </pre>
|
||||
*
|
||||
* Note that Java's class loader first delegates the class lookup to its
|
||||
* parent class loader. So once SnappyNativeLoader is loaded by the root
|
||||
* class loader, no child class loader initialize SnappyNativeLoader again.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static synchronized Object load()
|
||||
static synchronized SnappyNative load()
|
||||
{
|
||||
if (api != null)
|
||||
return api;
|
||||
|
||||
try {
|
||||
if (!hasInjectedNativeLoader()) {
|
||||
// Inject SnappyNativeLoader (src/main/resources/org/xerial/snappy/SnappyNativeLoader.bytecode) to the root class loader
|
||||
Class< ? > nativeLoader = injectSnappyNativeLoader();
|
||||
// Load the JNI code using the injected loader
|
||||
loadNativeLibrary(nativeLoader);
|
||||
}
|
||||
loadNativeLibrary();
|
||||
|
||||
setApi(new SnappyNative());
|
||||
isLoaded = true;
|
||||
// Look up SnappyNative, injected to the root classloder, using reflection in order to avoid the initialization of SnappyNative class in this context class loader.
|
||||
Object nativeCode = Class.forName("org.xerial.snappy.SnappyNative").newInstance();
|
||||
setApi(nativeCode);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -243,119 +156,40 @@ public class SnappyLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Inject SnappyNativeLoader class to the root class loader
|
||||
*
|
||||
* @return native code loader class initialized in the root class loader
|
||||
* Load a native library of snappy-java
|
||||
*/
|
||||
private static Class< ? > injectSnappyNativeLoader() {
|
||||
private static void loadNativeLibrary() {
|
||||
|
||||
try {
|
||||
// Use parent class loader to load SnappyNative, since Tomcat, which uses different class loaders for each webapps, cannot load JNI interface twice
|
||||
|
||||
final String nativeLoaderClassName = "org.xerial.snappy.SnappyNativeLoader";
|
||||
ClassLoader rootClassLoader = getRootClassLoader();
|
||||
// Load a byte code
|
||||
byte[] byteCode = getByteCode("/org/xerial/snappy/SnappyNativeLoader.bytecode");
|
||||
// In addition, we need to load the other dependent classes (e.g., SnappyNative and SnappyException) using the system class loader
|
||||
final String[] classesToPreload = new String[] { "org.xerial.snappy.SnappyNativeAPI",
|
||||
"org.xerial.snappy.SnappyNative", "org.xerial.snappy.SnappyErrorCode" };
|
||||
List<byte[]> preloadClassByteCode = new ArrayList<byte[]>(classesToPreload.length);
|
||||
for (String each : classesToPreload) {
|
||||
preloadClassByteCode.add(getByteCode(String.format("/%s.class", each.replaceAll("\\.", "/"))));
|
||||
}
|
||||
|
||||
// Create SnappyNativeLoader class from a byte code
|
||||
Class< ? > classLoader = Class.forName("java.lang.ClassLoader");
|
||||
Method defineClass = classLoader.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class,
|
||||
int.class, int.class, ProtectionDomain.class });
|
||||
|
||||
ProtectionDomain pd = System.class.getProtectionDomain();
|
||||
|
||||
// ClassLoader.defineClass is a protected method, so we have to make it accessible
|
||||
defineClass.setAccessible(true);
|
||||
try {
|
||||
// Create a new class using a ClassLoader#defineClass
|
||||
defineClass.invoke(rootClassLoader, nativeLoaderClassName, byteCode, 0, byteCode.length, pd);
|
||||
|
||||
// And also define dependent classes in the root class loader
|
||||
for (int i = 0; i < classesToPreload.length; ++i) {
|
||||
byte[] b = preloadClassByteCode.get(i);
|
||||
defineClass.invoke(rootClassLoader, classesToPreload[i], b, 0, b.length, pd);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Reset the accessibility to defineClass method
|
||||
defineClass.setAccessible(false);
|
||||
}
|
||||
|
||||
// Load the SnappyNativeLoader class
|
||||
return rootClassLoader.loadClass(nativeLoaderClassName);
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Load snappy-java's native code using load method of the
|
||||
* SnappyNativeLoader class injected to the root class loader.
|
||||
*
|
||||
* @param loaderClass
|
||||
* @throws SecurityException
|
||||
* @throws NoSuchMethodException
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
private static void loadNativeLibrary(Class< ? > loaderClass) throws SecurityException, NoSuchMethodException,
|
||||
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
|
||||
if (loaderClass == null)
|
||||
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, "missing snappy native loader class");
|
||||
|
||||
File nativeLib = findNativeLibrary();
|
||||
if (nativeLib != null) {
|
||||
nativeLibFile = findNativeLibrary();
|
||||
if (nativeLibFile != null) {
|
||||
// Load extracted or specified snappyjava native library.
|
||||
Method loadMethod = loaderClass.getDeclaredMethod("load", new Class[] { String.class });
|
||||
loadMethod.invoke(null, nativeLib.getAbsolutePath());
|
||||
System.load(nativeLibFile.getAbsolutePath());
|
||||
}
|
||||
else {
|
||||
// Load preinstalled snappyjava (in the path -Djava.library.path)
|
||||
Method loadMethod = loaderClass.getDeclaredMethod("loadLibrary", new Class[] { String.class });
|
||||
loadMethod.invoke(null, "snappyjava");
|
||||
System.loadLibrary("snappyjava");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the MD5 value of the input stream
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
static String md5sum(InputStream input) throws IOException {
|
||||
BufferedInputStream in = new BufferedInputStream(input);
|
||||
try {
|
||||
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
|
||||
DigestInputStream digestInputStream = new DigestInputStream(in, digest);
|
||||
for (; digestInputStream.read() >= 0;) {
|
||||
|
||||
private static boolean contentsEquals(InputStream in1, InputStream in2) throws IOException {
|
||||
if(!(in1 instanceof BufferedInputStream)) {
|
||||
in1 = new BufferedInputStream(in1);
|
||||
}
|
||||
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
|
||||
md5out.write(digest.digest());
|
||||
return md5out.toString();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("MD5 algorithm is not available: " + e);
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
if(!(in2 instanceof BufferedInputStream)) {
|
||||
in2 = new BufferedInputStream(in2);
|
||||
}
|
||||
|
||||
int ch = in1.read();
|
||||
while(ch != -1) {
|
||||
int ch2 = in2.read();
|
||||
if(ch != ch2)
|
||||
return false;
|
||||
ch = in1.read();
|
||||
}
|
||||
int ch2 = in2.read();
|
||||
return ch2 == -1;
|
||||
}
|
||||
/**
|
||||
* Extract the specified library file to the target folder
|
||||
*
|
||||
|
@ -366,50 +200,64 @@ public class SnappyLoader
|
|||
*/
|
||||
private static File extractLibraryFile(String libFolderForCurrentOS, String libraryFileName, String targetFolder) {
|
||||
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
|
||||
final String prefix = "snappy-" + getVersion() + "-";
|
||||
String extractedLibFileName = prefix + libraryFileName;
|
||||
|
||||
// Attach UUID to the native library file to ensure multiple class loaders can read the libsnappy-java multiple times.
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String extractedLibFileName = String.format("snappy-%s-%s-%s", getVersion(), uuid, libraryFileName);
|
||||
File extractedLibFile = new File(targetFolder, extractedLibFileName);
|
||||
|
||||
try {
|
||||
if (extractedLibFile.exists()) {
|
||||
// test md5sum value
|
||||
String md5sum1 = md5sum(SnappyLoader.class.getResourceAsStream(nativeLibraryFilePath));
|
||||
String md5sum2 = md5sum(new FileInputStream(extractedLibFile));
|
||||
|
||||
if (md5sum1.equals(md5sum2)) {
|
||||
return new File(targetFolder, extractedLibFileName);
|
||||
}
|
||||
else {
|
||||
// remove old native library file
|
||||
boolean deletionSucceeded = extractedLibFile.delete();
|
||||
if (!deletionSucceeded) {
|
||||
throw new IOException("failed to remove existing native library file: "
|
||||
+ extractedLibFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract a native library file into the target directory
|
||||
InputStream reader = SnappyLoader.class.getResourceAsStream(nativeLibraryFilePath);
|
||||
FileOutputStream writer = new FileOutputStream(extractedLibFile);
|
||||
try {
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead = 0;
|
||||
while ((bytesRead = reader.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// Delete the extracted lib file on JVM exit.
|
||||
extractedLibFile.deleteOnExit();
|
||||
|
||||
if(writer != null)
|
||||
writer.close();
|
||||
if(reader != null)
|
||||
reader.close();
|
||||
}
|
||||
|
||||
// Set executable (x) flag to enable Java to load the native library
|
||||
if (!System.getProperty("os.name").contains("Windows")) {
|
||||
try {
|
||||
Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
|
||||
.waitFor();
|
||||
|
||||
// Use following methods added since Java6 (If discarding Java5 is acceptable)
|
||||
//extractedLibFile.setReadable(true);
|
||||
//extractedLibFile.setWritable(true, true);
|
||||
//extractedLibFile.setExecutable(true);
|
||||
}
|
||||
catch (Throwable e) {}
|
||||
}
|
||||
|
||||
|
||||
// Check whether the contents are properly copied from the resource folder
|
||||
{
|
||||
InputStream nativeIn = SnappyLoader.class.getResourceAsStream(nativeLibraryFilePath);
|
||||
InputStream extractedLibIn = new FileInputStream(extractedLibFile);
|
||||
try {
|
||||
if(!contentsEquals(nativeIn, extractedLibIn))
|
||||
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, String.format("Failed to write a native library file at %s", extractedLibFile));
|
||||
}
|
||||
finally {
|
||||
if(nativeIn != null)
|
||||
nativeIn.close();
|
||||
if(extractedLibIn != null)
|
||||
extractedLibIn.close();
|
||||
}
|
||||
}
|
||||
|
||||
return new File(targetFolder, extractedLibFileName);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
@ -460,7 +308,7 @@ public class SnappyLoader
|
|||
throw new SnappyError(SnappyErrorCode.FAILED_TO_LOAD_NATIVE_LIBRARY, errorMessage);
|
||||
}
|
||||
|
||||
// Temporary library folder. Use the value of org.xerial.snappy.tempdir or java.io.tmpdir
|
||||
// Temporary folder for the native lib. Use the value of org.xerial.snappy.tempdir or java.io.tmpdir
|
||||
String tempFolder = new File(System.getProperty(KEY_SNAPPY_TEMPDIR,
|
||||
System.getProperty("java.io.tmpdir"))).getAbsolutePath();
|
||||
|
||||
|
@ -475,8 +323,6 @@ public class SnappyLoader
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the snappy-java version by reading pom.properties embedded in jar.
|
||||
* This version data is used as a suffix of a dll file extracted from the
|
||||
|
|
|
@ -33,7 +33,7 @@ void throw_exception(JNIEnv *env, jobject self, int errorCode)
|
|||
JNIEXPORT jstring JNICALL Java_org_xerial_snappy_SnappyNative_nativeLibraryVersion
|
||||
(JNIEnv * env, jobject self)
|
||||
{
|
||||
return env->NewStringUTF("1.0.4");
|
||||
return env->NewStringUTF("1.1.0");
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__JJJ
|
||||
|
@ -90,6 +90,12 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_la
|
|||
char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0);
|
||||
if(in == 0 || out == 0) {
|
||||
// out of memory
|
||||
if(in != 0) {
|
||||
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
|
||||
}
|
||||
if(out != 0) {
|
||||
env->ReleasePrimitiveArrayCritical((jarray) output, out, 0);
|
||||
}
|
||||
throw_exception(env, self, 4);
|
||||
return 0;
|
||||
}
|
||||
|
@ -110,6 +116,12 @@ JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_
|
|||
char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0);
|
||||
if(in == 0 || out == 0) {
|
||||
// out of memory
|
||||
if(in != 0) {
|
||||
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
|
||||
}
|
||||
if(out != 0) {
|
||||
env->ReleasePrimitiveArrayCritical((jarray) output, out, 0);
|
||||
}
|
||||
throw_exception(env, self, 4);
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,6 +270,19 @@ JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressed
|
|||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__JJJ
|
||||
(JNIEnv * env, jobject self, jlong inputAddr, jlong offset, jlong length)
|
||||
{
|
||||
if(inputAddr == 0) {
|
||||
// out of memory
|
||||
throw_exception(env, self, 4);
|
||||
return 0;
|
||||
}
|
||||
bool ret = snappy::IsValidCompressedBuffer((char*) (inputAddr + offset), (size_t) length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_xerial_snappy_SnappyNative_arrayCopy
|
||||
(JNIEnv * env, jobject self, jobject input, jint offset, jint length, jobject output, jint output_offset)
|
||||
{
|
||||
|
@ -265,6 +290,12 @@ JNIEXPORT void JNICALL Java_org_xerial_snappy_SnappyNative_arrayCopy
|
|||
char* dest = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0);
|
||||
if(src == 0 || dest == 0) {
|
||||
// out of memory
|
||||
if(src != 0) {
|
||||
env->ReleasePrimitiveArrayCritical((jarray) input, src, 0);
|
||||
}
|
||||
if(dest != 0) {
|
||||
env->ReleasePrimitiveArrayCritical((jarray) output, dest, 0);
|
||||
}
|
||||
throw_exception(env, self, 4);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,14 @@ JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressed
|
|||
JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_lang_Object_2II
|
||||
(JNIEnv *, jobject, jobject, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: org_xerial_snappy_SnappyNative
|
||||
* Method: isValidCompressedBuffer
|
||||
* Signature: (JJJ)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__JJJ
|
||||
(JNIEnv *, jobject, jlong, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_xerial_snappy_SnappyNative
|
||||
* Method: arrayCopy
|
||||
|
|
|
@ -28,8 +28,7 @@ import java.io.IOException;
|
|||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* <b>Internal only - Do not use this class.</b> JNI interface of the
|
||||
* {@link SnappyNativeAPI} implementation. The native method in this class is
|
||||
* JNI interface of the {@link Snappy} implementation. The native method in this class is
|
||||
* defined in SnappyNative.h (genereted by javah) and SnappyNative.cpp
|
||||
*
|
||||
* <p>
|
||||
|
@ -40,7 +39,7 @@ import java.nio.ByteBuffer;
|
|||
* @author leo
|
||||
*
|
||||
*/
|
||||
public class SnappyNative implements SnappyNativeAPI
|
||||
public class SnappyNative
|
||||
{
|
||||
|
||||
public native String nativeLibraryVersion();
|
||||
|
@ -77,6 +76,8 @@ public class SnappyNative implements SnappyNativeAPI
|
|||
|
||||
public native boolean isValidCompressedBuffer(Object input, int offset, int len) throws IOException;
|
||||
|
||||
public native boolean isValidCompressedBuffer(long inputAddr, long offset, long len) throws IOException;
|
||||
|
||||
public native void arrayCopy(Object src, int offset, int byteLength, Object dest, int dOffset) throws IOException;
|
||||
|
||||
public void throw_error(int errorCode) throws IOException {
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
* Copyright 2011 Taro L. Saito
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*--------------------------------------------------------------------------*/
|
||||
//--------------------------------------
|
||||
// snappy-java Project
|
||||
//
|
||||
// SnappyNative.java
|
||||
// Since: 2011/03/30
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* <b>Internal only - Do not use this class.</b>
|
||||
*
|
||||
* Interface to access the native code of Snappy. Although this class members
|
||||
* are public, do not use them directly. Use {@link Snappy} API instead.
|
||||
*
|
||||
*
|
||||
* @author leo
|
||||
*
|
||||
*/
|
||||
public interface SnappyNativeAPI
|
||||
{
|
||||
|
||||
public String nativeLibraryVersion();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Generic compression/decompression routines.
|
||||
// ------------------------------------------------------------------------
|
||||
public long rawCompress(long inputAddr, long inputSize, long destAddr) throws IOException;
|
||||
public long rawUncompress(long inputAddr, long inputSize, long destAddr) throws IOException;
|
||||
|
||||
public int rawCompress(ByteBuffer input, int inputOffset, int inputLength, ByteBuffer compressed, int outputOffset)
|
||||
throws IOException;
|
||||
|
||||
public int rawCompress(Object input, int inputOffset, int inputByteLength, Object output, int outputOffset) throws IOException;
|
||||
|
||||
public int rawUncompress(ByteBuffer compressed, int inputOffset, int inputLength, ByteBuffer uncompressed,
|
||||
int outputOffset) throws IOException;
|
||||
|
||||
public int rawUncompress(Object input, int inputOffset, int inputLength, Object output, int outputOffset)
|
||||
throws IOException;
|
||||
|
||||
// Returns the maximal size of the compressed representation of
|
||||
// input data that is "source_bytes" bytes in length;
|
||||
public int maxCompressedLength(int source_bytes);
|
||||
|
||||
// This operation takes O(1) time.
|
||||
public int uncompressedLength(ByteBuffer compressed, int offset, int len) throws IOException;
|
||||
|
||||
public int uncompressedLength(Object input, int offset, int len) throws IOException;
|
||||
|
||||
public long uncompressedLength(long inputAddr, long len) throws IOException;
|
||||
|
||||
|
||||
public boolean isValidCompressedBuffer(ByteBuffer compressed, int offset, int len) throws IOException;
|
||||
|
||||
public boolean isValidCompressedBuffer(Object input, int offset, int len) throws IOException;
|
||||
|
||||
public void arrayCopy(Object src, int offset, int byteLength, Object dest, int dOffset) throws IOException;
|
||||
|
||||
public void throw_error(int errorCode) throws IOException;
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -24,14 +24,20 @@
|
|||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.xerial.util.FileResource;
|
||||
import org.xerial.util.log.Logger;
|
||||
|
||||
|
@ -45,6 +51,9 @@ public class CalgaryTest
|
|||
{
|
||||
private static Logger _logger = Logger.getLogger(CalgaryTest.class);
|
||||
|
||||
@Rule
|
||||
public final TemporaryFolder tempFolder = new TemporaryFolder();
|
||||
|
||||
static byte[] readFile(String file) throws IOException {
|
||||
InputStream in = FileResource.find(CalgaryTest.class, file).openStream();
|
||||
if (in == null)
|
||||
|
@ -91,6 +100,83 @@ public class CalgaryTest
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void streamFramed() throws Exception {
|
||||
for (String f : files) {
|
||||
byte[] orig = readFile("testdata/calgary/" + f);
|
||||
|
||||
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
|
||||
SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedBuf);
|
||||
out.write(orig);
|
||||
out.close();
|
||||
|
||||
SnappyFramedInputStream in = new SnappyFramedInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()));
|
||||
|
||||
byte[] uncompressed = new byte[orig.length];
|
||||
int readBytes = readBytes(in, uncompressed, 0, orig.length);
|
||||
|
||||
assertEquals(orig.length, readBytes);
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void streamFramedToFile() throws Exception {
|
||||
for (String f : files) {
|
||||
byte[] orig = readFile("testdata/calgary/" + f);
|
||||
|
||||
final File tempFile = tempFolder.newFile(f);
|
||||
final FileOutputStream compressedFOS = new FileOutputStream(tempFile);
|
||||
try
|
||||
{
|
||||
SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedFOS);
|
||||
out.write(orig);
|
||||
out.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
compressedFOS.close();
|
||||
}
|
||||
|
||||
byte[] uncompressed = new byte[orig.length];
|
||||
|
||||
final FileInputStream compressedFIS = new FileInputStream(tempFile);
|
||||
try
|
||||
{
|
||||
SnappyFramedInputStream in = new SnappyFramedInputStream(compressedFIS.getChannel());
|
||||
int readBytes = readBytes(in, uncompressed, 0, orig.length);
|
||||
|
||||
assertEquals(orig.length, readBytes);
|
||||
}
|
||||
finally
|
||||
{
|
||||
compressedFIS.close();
|
||||
}
|
||||
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void streamFramedNoCRCVerify() throws Exception {
|
||||
for (String f : files) {
|
||||
byte[] orig = readFile("testdata/calgary/" + f);
|
||||
|
||||
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
|
||||
SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedBuf);
|
||||
out.write(orig);
|
||||
out.close();
|
||||
|
||||
SnappyFramedInputStream in = new SnappyFramedInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()), false);
|
||||
|
||||
byte[] uncompressed = new byte[orig.length];
|
||||
int readBytes = readBytes(in, uncompressed, 0, orig.length);
|
||||
|
||||
assertEquals(orig.length, readBytes);
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byteWiseRead() throws Exception {
|
||||
for (String f : files) {
|
||||
|
@ -115,4 +201,28 @@ public class CalgaryTest
|
|||
}
|
||||
}
|
||||
|
||||
static final int readBytes(InputStream source, byte[] dest, int offset, int length) throws IOException
|
||||
{
|
||||
// how many bytes were read.
|
||||
int lastRead = source.read(dest, offset, length);
|
||||
|
||||
int totalRead = lastRead;
|
||||
|
||||
// if we did not read as many bytes as we had hoped, try reading again.
|
||||
if (lastRead < length)
|
||||
{
|
||||
// as long the buffer is not full (remaining() == 0) and we have not reached EOF (lastRead == -1) keep reading.
|
||||
while (totalRead < length && lastRead != -1)
|
||||
{
|
||||
lastRead = source.read(dest, offset + totalRead, length - totalRead);
|
||||
|
||||
// if we got EOF, do not add to total read.
|
||||
if (lastRead != -1)
|
||||
{
|
||||
totalRead += lastRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalRead;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Created: Apr 15, 2013
|
||||
*/
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Generates random data with specific expected snappy performance characteristics.
|
||||
*
|
||||
* <p>
|
||||
* This has been copied from <a href="https://github.com/dain/snappy"> dain's snappy</a> implementation..
|
||||
* </p>
|
||||
*/
|
||||
public class RandomGenerator {
|
||||
|
||||
public final byte[] data;
|
||||
public int position;
|
||||
|
||||
public RandomGenerator(double compressionRatio) {
|
||||
// We use a limited amount of data over and over again and ensure
|
||||
// that it is larger than the compression window (32KB), and also
|
||||
// large enough to serve all typical value sizes we want to write.
|
||||
Random rnd = new Random(301);
|
||||
data = new byte[1048576 + 100];
|
||||
for (int i = 0; i < 1048576; i += 100) {
|
||||
// Add a short fragment that is as compressible as specified ratio
|
||||
System.arraycopy(compressibleData(rnd, compressionRatio, 100), 0,
|
||||
data, i, 100);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNextPosition(int length) {
|
||||
if (position + length > data.length) {
|
||||
position = 0;
|
||||
assert (length < data.length);
|
||||
}
|
||||
int result = position;
|
||||
position += length;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] compressibleData(Random random,
|
||||
double compressionRatio, int length) {
|
||||
int raw = (int) (length * compressionRatio);
|
||||
if (raw < 1) {
|
||||
raw = 1;
|
||||
}
|
||||
byte[] rawData = generateRandomData(random, raw);
|
||||
|
||||
// Duplicate the random data until we have filled "length" bytes
|
||||
byte[] dest = new byte[length];
|
||||
for (int i = 0; i < length;) {
|
||||
int chunkLength = Math.min(rawData.length, length - i);
|
||||
System.arraycopy(rawData, 0, dest, i, chunkLength);
|
||||
i += chunkLength;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
private static byte[] generateRandomData(Random random, int length) {
|
||||
byte[] rawData = new byte[length];
|
||||
for (int i = 0; i < rawData.length; i++) {
|
||||
rawData[i] = (byte) random.nextInt(256);
|
||||
}
|
||||
return rawData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Created: Mar 14, 2013
|
||||
*/
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static org.xerial.snappy.SnappyFramed.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests the functionality of {@link org.xerial.snappy.SnappyFramedInputStream}
|
||||
* and {@link org.xerial.snappy.SnappyFramedOutputStream}.
|
||||
*
|
||||
* @author Brett Okken
|
||||
*/
|
||||
public class SnappyFramedStreamTest {
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
*/
|
||||
protected OutputStream createOutputStream(OutputStream target)
|
||||
throws IOException {
|
||||
return new SnappyFramedOutputStream(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
protected InputStream createInputStream(InputStream source,
|
||||
boolean verifyCheckSums) throws IOException {
|
||||
return new SnappyFramedInputStream(source, verifyCheckSums);
|
||||
}
|
||||
|
||||
protected byte[] getMarkerFrame() {
|
||||
return HEADER_BYTES;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimple() throws Exception {
|
||||
byte[] original = "aaaaaaaaaaaabbbbbbbaaaaaa".getBytes("utf-8");
|
||||
|
||||
byte[] compressed = compress(original);
|
||||
byte[] uncompressed = uncompress(compressed);
|
||||
|
||||
assertArrayEquals(uncompressed, original);
|
||||
// 10 byte stream header, 4 byte block header, 4 byte crc, 19 bytes
|
||||
assertEquals(compressed.length, 37);
|
||||
|
||||
// stream header
|
||||
assertArrayEquals(Arrays.copyOf(compressed, 10), HEADER_BYTES);
|
||||
|
||||
// flag: compressed
|
||||
assertEquals(toInt(compressed[10]), COMPRESSED_DATA_FLAG);
|
||||
|
||||
// length: 23 = 0x000017
|
||||
assertEquals(toInt(compressed[11]), 0x17);
|
||||
assertEquals(toInt(compressed[12]), 0x00);
|
||||
assertEquals(toInt(compressed[13]), 0x00);
|
||||
|
||||
// crc32c: 0x9274cda8
|
||||
assertEquals(toInt(compressed[17]), 0x92);
|
||||
assertEquals(toInt(compressed[16]), 0x74);
|
||||
assertEquals(toInt(compressed[15]), 0xCD);
|
||||
assertEquals(toInt(compressed[14]), 0xA8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUncompressable() throws Exception {
|
||||
byte[] random = getRandom(1, 5000);
|
||||
int crc32c = maskedCrc32c(random);
|
||||
|
||||
byte[] compressed = compress(random);
|
||||
byte[] uncompressed = uncompress(compressed);
|
||||
|
||||
assertArrayEquals(uncompressed, random);
|
||||
assertEquals(compressed.length, random.length + 10 + 4 + 4);
|
||||
|
||||
// flag: uncompressed
|
||||
assertEquals(toInt(compressed[10]), UNCOMPRESSED_DATA_FLAG);
|
||||
|
||||
// length: 5004 = 0x138c
|
||||
assertEquals(toInt(compressed[13]), 0x00);
|
||||
assertEquals(toInt(compressed[12]), 0x13);
|
||||
assertEquals(toInt(compressed[11]), 0x8c);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyCompression() throws Exception {
|
||||
byte[] empty = new byte[0];
|
||||
assertArrayEquals(compress(empty), HEADER_BYTES);
|
||||
assertArrayEquals(uncompress(HEADER_BYTES), empty);
|
||||
}
|
||||
|
||||
@Test(expected = EOFException.class)
|
||||
public void testShortBlockHeader() throws Exception {
|
||||
uncompressBlock(new byte[] { 0 });
|
||||
}
|
||||
|
||||
@Test(expected = EOFException.class)
|
||||
public void testShortBlockData() throws Exception {
|
||||
// flag = 0, size = 8, crc32c = 0, block data= [x, x]
|
||||
uncompressBlock(new byte[] { 1, 8, 0, 0, 0, 0, 0, 0, 'x', 'x' });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnskippableChunkFlags() throws Exception {
|
||||
for (int i = 2; i <= 0x7f; i++) {
|
||||
try {
|
||||
uncompressBlock(new byte[] { (byte) i, 5, 0, 0, 0, 0, 0, 0, 0 });
|
||||
fail("no exception thrown with flag: " + Integer.toHexString(i));
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkippableChunkFlags() throws Exception {
|
||||
for (int i = 0x80; i <= 0xfe; i++) {
|
||||
try {
|
||||
uncompressBlock(new byte[] { (byte) i, 5, 0, 0, 0, 0, 0, 0, 0 });
|
||||
} catch (IOException e) {
|
||||
fail("exception thrown with flag: " + Integer.toHexString(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void testInvalidBlockSizeZero() throws Exception {
|
||||
// flag = '0', block size = 4, crc32c = 0
|
||||
uncompressBlock(new byte[] { 1, 4, 0, 0, 0, 0, 0, 0 });
|
||||
}
|
||||
|
||||
@Test(expected = IOException.class)
|
||||
public void testInvalidChecksum() throws Exception {
|
||||
// flag = 0, size = 5, crc32c = 0, block data = [a]
|
||||
uncompressBlock(new byte[] { 1, 5, 0, 0, 0, 0, 0, 0, 'a' });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidChecksumIgnoredWhenVerificationDisabled()
|
||||
throws Exception {
|
||||
// flag = 0, size = 4, crc32c = 0, block data = [a]
|
||||
byte[] block = { 1, 5, 0, 0, 0, 0, 0, 0, 'a' };
|
||||
ByteArrayInputStream inputData = new ByteArrayInputStream(
|
||||
blockToStream(block));
|
||||
assertArrayEquals(toByteArray(createInputStream(inputData, false)),
|
||||
new byte[] { 'a' });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLargerFrames_raw_() throws IOException {
|
||||
final byte[] random = getRandom(0.5, 100000);
|
||||
|
||||
final byte[] stream = new byte[HEADER_BYTES.length + 8 + random.length];
|
||||
System.arraycopy(HEADER_BYTES, 0, stream, 0, HEADER_BYTES.length);
|
||||
|
||||
stream[10] = UNCOMPRESSED_DATA_FLAG;
|
||||
|
||||
int length = random.length + 4;
|
||||
stream[11] = (byte) length;
|
||||
stream[12] = (byte) (length >>> 8);
|
||||
stream[13] = (byte) (length >>> 16);
|
||||
|
||||
int crc32c = maskedCrc32c(random);
|
||||
stream[14] = (byte) crc32c;
|
||||
stream[15] = (byte) (crc32c >>> 8);
|
||||
stream[16] = (byte) (crc32c >>> 16);
|
||||
stream[17] = (byte) (crc32c >>> 24);
|
||||
|
||||
System.arraycopy(random, 0, stream, 18, random.length);
|
||||
|
||||
final byte[] uncompressed = uncompress(stream);
|
||||
|
||||
assertArrayEquals(random, uncompressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLargerFrames_compressed_() throws IOException {
|
||||
final byte[] random = getRandom(0.5, 500000);
|
||||
|
||||
final byte[] compressed = Snappy.compress(random);
|
||||
|
||||
final byte[] stream = new byte[HEADER_BYTES.length + 8 + compressed.length];
|
||||
System.arraycopy(HEADER_BYTES, 0, stream, 0, HEADER_BYTES.length);
|
||||
|
||||
stream[10] = COMPRESSED_DATA_FLAG;
|
||||
|
||||
int length = compressed.length + 4;
|
||||
stream[11] = (byte) length;
|
||||
stream[12] = (byte) (length >>> 8);
|
||||
stream[13] = (byte) (length >>> 16);
|
||||
|
||||
int crc32c = maskedCrc32c(random);
|
||||
stream[14] = (byte) crc32c;
|
||||
stream[15] = (byte) (crc32c >>> 8);
|
||||
stream[16] = (byte) (crc32c >>> 16);
|
||||
stream[17] = (byte) (crc32c >>> 24);
|
||||
|
||||
System.arraycopy(compressed, 0, stream, 18, compressed.length);
|
||||
|
||||
final byte[] uncompressed = uncompress(stream);
|
||||
|
||||
assertArrayEquals(random, uncompressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLargerFrames_compressed_smaller_raw_larger()
|
||||
throws IOException {
|
||||
final byte[] random = getRandom(0.5, 100000);
|
||||
|
||||
final byte[] compressed = Snappy.compress(random);
|
||||
|
||||
final byte[] stream = new byte[HEADER_BYTES.length + 8
|
||||
+ compressed.length];
|
||||
System.arraycopy(HEADER_BYTES, 0, stream, 0, HEADER_BYTES.length);
|
||||
|
||||
stream[10] = COMPRESSED_DATA_FLAG;
|
||||
|
||||
int length = compressed.length + 4;
|
||||
stream[11] = (byte) length;
|
||||
stream[12] = (byte) (length >>> 8);
|
||||
stream[13] = (byte) (length >>> 16);
|
||||
|
||||
int crc32c = maskedCrc32c(random);
|
||||
stream[14] = (byte) crc32c;
|
||||
stream[15] = (byte) (crc32c >>> 8);
|
||||
stream[16] = (byte) (crc32c >>> 16);
|
||||
stream[17] = (byte) (crc32c >>> 24);
|
||||
|
||||
System.arraycopy(compressed, 0, stream, 18, compressed.length);
|
||||
|
||||
final byte[] uncompressed = uncompress(stream);
|
||||
|
||||
assertArrayEquals(random, uncompressed);
|
||||
}
|
||||
|
||||
private byte[] uncompressBlock(byte[] block) throws IOException {
|
||||
return uncompress(blockToStream(block));
|
||||
}
|
||||
|
||||
private static byte[] blockToStream(byte[] block) {
|
||||
byte[] stream = new byte[HEADER_BYTES.length + block.length];
|
||||
System.arraycopy(HEADER_BYTES, 0, stream, 0, HEADER_BYTES.length);
|
||||
System.arraycopy(block, 0, stream, HEADER_BYTES.length, block.length);
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
protected byte[] compress(byte[] original) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
OutputStream snappyOut = createOutputStream(out);
|
||||
snappyOut.write(original);
|
||||
snappyOut.close();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
protected byte[] uncompress(byte[] compressed) throws IOException {
|
||||
return toByteArray(createInputStream(new ByteArrayInputStream(
|
||||
compressed), true));
|
||||
}
|
||||
|
||||
private static byte[] toByteArray(InputStream createInputStream) throws IOException {
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream(64 * 1024);
|
||||
|
||||
final byte[] buffer = new byte[8 * 1024];
|
||||
|
||||
int read;
|
||||
while((read = createInputStream.read(buffer)) > 0) {
|
||||
baos.write(buffer, 0, read);
|
||||
}
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
static int toInt(byte value) {
|
||||
return value & 0xFF;
|
||||
}
|
||||
|
||||
private byte[] getRandom(double compressionRatio, int length) {
|
||||
RandomGenerator gen = new RandomGenerator(
|
||||
compressionRatio);
|
||||
gen.getNextPosition(length);
|
||||
byte[] random = Arrays.copyOf(gen.data, length);
|
||||
assertEquals(random.length, length);
|
||||
return random;
|
||||
}
|
||||
|
||||
}
|
|
@ -24,23 +24,20 @@
|
|||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||
import org.junit.Test;
|
||||
import org.xerial.util.FileResource;
|
||||
import org.xerial.util.log.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class SnappyLoaderTest
|
||||
{
|
||||
private static Logger _logger = Logger.getLogger(SnappyLoaderTest.class);
|
||||
|
|
Loading…
Reference in New Issue