Merge pull request #109 from xerial/fix-newline

Use LF as newline
This commit is contained in:
Taro L. Saito 2015-05-18 15:53:47 +09:00
commit d6908244a7
17 changed files with 3370 additions and 3370 deletions

View File

@ -1,5 +1,5 @@
#ifndef __CONFIG_H #ifndef __CONFIG_H
#define __CONFIG_H #define __CONFIG_H
#endif // __CONFIG_H #endif // __CONFIG_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,67 +1,67 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyBundleActivator.java // SnappyBundleActivator.java
// Since: 2011/06/22 10:01:46 // Since: 2011/06/22 10:01:46
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import org.osgi.framework.Bundle; import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import java.util.jar.Manifest; import java.util.jar.Manifest;
/** /**
* OSGi bundle entry point * OSGi bundle entry point
* *
* @author leo * @author leo
* *
*/ */
public class SnappyBundleActivator implements BundleActivator public class SnappyBundleActivator implements BundleActivator
{ {
/** /**
* Name of the Snappy native library * Name of the Snappy native library
*/ */
public static final String LIBRARY_NAME = "snappyjava"; public static final String LIBRARY_NAME = "snappyjava";
/** /**
* Make a call to {@link System#loadLibrary(String)} to load the native library which assumes * Make a call to {@link System#loadLibrary(String)} to load the native library which assumes
* that the library is available on the path based on this {@link Bundle}'s {@link Manifest}. * that the library is available on the path based on this {@link Bundle}'s {@link Manifest}.
*/ */
public void start(BundleContext context) throws Exception public void start(BundleContext context) throws Exception
{ {
String library = System.mapLibraryName(LIBRARY_NAME); String library = System.mapLibraryName(LIBRARY_NAME);
if (library.toLowerCase().endsWith(".dylib")) if (library.toLowerCase().endsWith(".dylib"))
{ {
// some MacOS JDK7+ vendors map to dylib instead of jnilib // some MacOS JDK7+ vendors map to dylib instead of jnilib
library = library.replace(".dylib", ".jnilib"); library = library.replace(".dylib", ".jnilib");
} }
System.loadLibrary(library); System.loadLibrary(library);
SnappyLoader.setApi(new SnappyNative()); SnappyLoader.setApi(new SnappyNative());
} }
public void stop(BundleContext context) throws Exception public void stop(BundleContext context) throws Exception
{ {
SnappyLoader.setApi(null); SnappyLoader.setApi(null);
SnappyLoader.cleanUpExtractedNativeLib(); SnappyLoader.cleanUpExtractedNativeLib();
} }
} }

View File

@ -1,124 +1,124 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyCodec.java // SnappyCodec.java
// Since: 2011/04/03 14:50:20 // Since: 2011/04/03 14:50:20
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Arrays; import java.util.Arrays;
/** /**
* Preamble header for {@link SnappyOutputStream}. * Preamble header for {@link SnappyOutputStream}.
* *
* <p> * <p>
* The magic header is the following 8 bytes data: * The magic header is the following 8 bytes data:
* *
* <pre> * <pre>
* -126, 'S', 'N', 'A', 'P', 'P', 'Y', 0 * -126, 'S', 'N', 'A', 'P', 'P', 'Y', 0
* </pre> * </pre>
* *
* </p> * </p>
* *
* @author leo * @author leo
* *
*/ */
public class SnappyCodec public class SnappyCodec
{ {
public static final byte[] MAGIC_HEADER = new byte[] { -126, 'S', 'N', 'A', 'P', 'P', 'Y', 0 }; public static final byte[] MAGIC_HEADER = new byte[] { -126, 'S', 'N', 'A', 'P', 'P', 'Y', 0 };
public static final int MAGIC_LEN = MAGIC_HEADER.length; public static final int MAGIC_LEN = MAGIC_HEADER.length;
public static final int HEADER_SIZE = MAGIC_LEN + 8; public static final int HEADER_SIZE = MAGIC_LEN + 8;
public static final int MAGIC_HEADER_HEAD = SnappyOutputStream.readInt(MAGIC_HEADER, 0); public static final int MAGIC_HEADER_HEAD = SnappyOutputStream.readInt(MAGIC_HEADER, 0);
public static final int MAGIC_HEADER_TAIL = SnappyOutputStream.readInt(MAGIC_HEADER, 4); public static final int MAGIC_HEADER_TAIL = SnappyOutputStream.readInt(MAGIC_HEADER, 4);
static { static {
assert(MAGIC_HEADER_HEAD < 0); assert(MAGIC_HEADER_HEAD < 0);
} }
public static final int DEFAULT_VERSION = 1; public static final int DEFAULT_VERSION = 1;
public static final int MINIMUM_COMPATIBLE_VERSION = 1; public static final int MINIMUM_COMPATIBLE_VERSION = 1;
public final byte[] magic; public final byte[] magic;
public final int version; public final int version;
public final int compatibleVersion; public final int compatibleVersion;
private final byte[] headerArray; private final byte[] headerArray;
private SnappyCodec(byte[] magic, int version, int compatibleVersion) { private SnappyCodec(byte[] magic, int version, int compatibleVersion) {
this.magic = magic; this.magic = magic;
this.version = version; this.version = version;
this.compatibleVersion = compatibleVersion; this.compatibleVersion = compatibleVersion;
ByteArrayOutputStream header = new ByteArrayOutputStream(HEADER_SIZE); ByteArrayOutputStream header = new ByteArrayOutputStream(HEADER_SIZE);
DataOutputStream d = new DataOutputStream(header); DataOutputStream d = new DataOutputStream(header);
try { try {
d.write(magic, 0, MAGIC_LEN); d.write(magic, 0, MAGIC_LEN);
d.writeInt(version); d.writeInt(version);
d.writeInt(compatibleVersion); d.writeInt(compatibleVersion);
d.close(); d.close();
} }
catch(IOException e) { catch(IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
headerArray = header.toByteArray(); headerArray = header.toByteArray();
} }
@Override @Override
public String toString() { public String toString() {
return String.format("version:%d, compatible version:%d", version, compatibleVersion); return String.format("version:%d, compatible version:%d", version, compatibleVersion);
} }
public static int headerSize() { public static int headerSize() {
return HEADER_SIZE; return HEADER_SIZE;
} }
public int writeHeader(byte[] dst, int dstOffset) { public int writeHeader(byte[] dst, int dstOffset) {
System.arraycopy(headerArray, 0, dst, dstOffset, headerArray.length); System.arraycopy(headerArray, 0, dst, dstOffset, headerArray.length);
return headerArray.length; return headerArray.length;
} }
public int writeHeader(OutputStream out) throws IOException { public int writeHeader(OutputStream out) throws IOException {
out.write(headerArray, 0, headerArray.length); out.write(headerArray, 0, headerArray.length);
return headerArray.length; return headerArray.length;
} }
public boolean isValidMagicHeader() { public boolean isValidMagicHeader() {
return Arrays.equals(MAGIC_HEADER, magic); return Arrays.equals(MAGIC_HEADER, magic);
} }
public static SnappyCodec readHeader(InputStream in) throws IOException { public static SnappyCodec readHeader(InputStream in) throws IOException {
DataInputStream d = new DataInputStream(in); DataInputStream d = new DataInputStream(in);
byte[] magic = new byte[MAGIC_LEN]; byte[] magic = new byte[MAGIC_LEN];
d.readFully(magic, 0, MAGIC_LEN); d.readFully(magic, 0, MAGIC_LEN);
int version = d.readInt(); int version = d.readInt();
int compatibleVersion = d.readInt(); int compatibleVersion = d.readInt();
return new SnappyCodec(magic, version, compatibleVersion); return new SnappyCodec(magic, version, compatibleVersion);
} }
public static SnappyCodec currentHeader = new SnappyCodec(MAGIC_HEADER, DEFAULT_VERSION, MINIMUM_COMPATIBLE_VERSION); public static SnappyCodec currentHeader = new SnappyCodec(MAGIC_HEADER, DEFAULT_VERSION, MINIMUM_COMPATIBLE_VERSION);
} }

View File

@ -1,62 +1,62 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyError.java // SnappyError.java
// Since: 2011/03/30 15:22:43 // Since: 2011/03/30 15:22:43
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
/** /**
* Used when serious errors (unchecked exception) are observed. * Used when serious errors (unchecked exception) are observed.
* *
* @author leo * @author leo
* *
*/ */
public class SnappyError extends Error public class SnappyError extends Error
{ {
/** /**
* *
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public final SnappyErrorCode errorCode; public final SnappyErrorCode errorCode;
public SnappyError(SnappyErrorCode code) { public SnappyError(SnappyErrorCode code) {
super(); super();
this.errorCode = code; this.errorCode = code;
} }
public SnappyError(SnappyErrorCode code, Error e) { public SnappyError(SnappyErrorCode code, Error e) {
super(e); super(e);
this.errorCode = code; this.errorCode = code;
} }
public SnappyError(SnappyErrorCode code, String message) { public SnappyError(SnappyErrorCode code, String message) {
super(message); super(message);
this.errorCode = code; this.errorCode = code;
} }
@Override @Override
public String getMessage() { public String getMessage() {
return String.format("[%s] %s", errorCode.name(), super.getMessage()); return String.format("[%s] %s", errorCode.name(), super.getMessage());
} }
} }

View File

@ -1,64 +1,64 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyErrorCode.java // SnappyErrorCode.java
// Since: 2011/03/30 14:56:50 // Since: 2011/03/30 14:56:50
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
/** /**
* Error codes of snappy-java * Error codes of snappy-java
* *
* @author leo * @author leo
* *
*/ */
public enum SnappyErrorCode { public enum SnappyErrorCode {
// DO NOT change these error code IDs because these numbers are used inside SnappyNative.cpp // DO NOT change these error code IDs because these numbers are used inside SnappyNative.cpp
UNKNOWN(0), UNKNOWN(0),
FAILED_TO_LOAD_NATIVE_LIBRARY(1), FAILED_TO_LOAD_NATIVE_LIBRARY(1),
PARSING_ERROR(2), PARSING_ERROR(2),
NOT_A_DIRECT_BUFFER(3), NOT_A_DIRECT_BUFFER(3),
OUT_OF_MEMORY(4), OUT_OF_MEMORY(4),
FAILED_TO_UNCOMPRESS(5), FAILED_TO_UNCOMPRESS(5),
EMPTY_INPUT(6), EMPTY_INPUT(6),
INCOMPATIBLE_VERSION(7), INCOMPATIBLE_VERSION(7),
INVALID_CHUNK_SIZE(8) INVALID_CHUNK_SIZE(8)
; ;
public final int id; public final int id;
private SnappyErrorCode(int id) { private SnappyErrorCode(int id) {
this.id = id; this.id = id;
} }
public static SnappyErrorCode getErrorCode(int id) { public static SnappyErrorCode getErrorCode(int id) {
for (SnappyErrorCode code : SnappyErrorCode.values()) { for (SnappyErrorCode code : SnappyErrorCode.values()) {
if (code.id == id) if (code.id == id)
return code; return code;
} }
return UNKNOWN; return UNKNOWN;
} }
public static String getErrorMessage(int id) { public static String getErrorMessage(int id) {
return getErrorCode(id).name(); return getErrorCode(id).name();
} }
} }

View File

@ -1,74 +1,74 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyException.java // SnappyException.java
// Since: 2011/03/30 14:56:14 // Since: 2011/03/30 14:56:14
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import java.io.IOException; import java.io.IOException;
/** /**
* Exception in snappy-java * Exception in snappy-java
* *
* @deprecated Snappy-java now uses {@link IOException} * @deprecated Snappy-java now uses {@link IOException}
* @author leo * @author leo
* *
*/ */
@Deprecated @Deprecated
public class SnappyException extends Exception public class SnappyException extends Exception
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public final SnappyErrorCode errorCode; public final SnappyErrorCode errorCode;
public SnappyException(int code) { public SnappyException(int code) {
this(SnappyErrorCode.getErrorCode(code)); this(SnappyErrorCode.getErrorCode(code));
} }
public SnappyException(SnappyErrorCode errorCode) { public SnappyException(SnappyErrorCode errorCode) {
super(); super();
this.errorCode = errorCode; this.errorCode = errorCode;
} }
public SnappyException(SnappyErrorCode errorCode, Exception e) { public SnappyException(SnappyErrorCode errorCode, Exception e) {
super(e); super(e);
this.errorCode = errorCode; this.errorCode = errorCode;
} }
public SnappyException(SnappyErrorCode errorCode, String message) { public SnappyException(SnappyErrorCode errorCode, String message) {
super(message); super(message);
this.errorCode = errorCode; this.errorCode = errorCode;
} }
public SnappyErrorCode getErrorCode() { public SnappyErrorCode getErrorCode() {
return errorCode; return errorCode;
} }
public static void throwException(int errorCode) throws SnappyException { public static void throwException(int errorCode) throws SnappyException {
throw new SnappyException(errorCode); throw new SnappyException(errorCode);
} }
@Override @Override
public String getMessage() { public String getMessage() {
return String.format("[%s] %s", errorCode.name(), super.getMessage()); return String.format("[%s] %s", errorCode.name(), super.getMessage());
} }
} }

View File

@ -1,186 +1,186 @@
/* /*
* Created: Apr 12, 2013 * Created: Apr 12, 2013
*/ */
package org.xerial.snappy; package org.xerial.snappy;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* Constants and utilities for implementing x-snappy-framed. * Constants and utilities for implementing x-snappy-framed.
* *
* @author Brett Okken * @author Brett Okken
* @since 1.1.0 * @since 1.1.0
*/ */
final class SnappyFramed { final class SnappyFramed {
public static final int COMPRESSED_DATA_FLAG = 0x00; public static final int COMPRESSED_DATA_FLAG = 0x00;
public static final int UNCOMPRESSED_DATA_FLAG = 0x01; public static final int UNCOMPRESSED_DATA_FLAG = 0x01;
public static final int STREAM_IDENTIFIER_FLAG = 0xff; public static final int STREAM_IDENTIFIER_FLAG = 0xff;
private static final int MASK_DELTA = 0xa282ead8; private static final int MASK_DELTA = 0xa282ead8;
/** /**
* Sun specific mechanisms to clean up resources associated with direct byte buffers. * Sun specific mechanisms to clean up resources associated with direct byte buffers.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static final Class<? extends ByteBuffer> SUN_DIRECT_BUFFER = (Class<? extends ByteBuffer>) lookupClassQuietly("sun.nio.ch.DirectBuffer"); private static final Class<? extends ByteBuffer> SUN_DIRECT_BUFFER = (Class<? extends ByteBuffer>) lookupClassQuietly("sun.nio.ch.DirectBuffer");
private static final Method SUN_BUFFER_CLEANER; private static final Method SUN_BUFFER_CLEANER;
private static final Method SUN_CLEANER_CLEAN; private static final Method SUN_CLEANER_CLEAN;
static static
{ {
Method bufferCleaner = null; Method bufferCleaner = null;
Method cleanerClean = null; Method cleanerClean = null;
try { try {
//operate under the assumption that if the sun direct buffer class exists, //operate under the assumption that if the sun direct buffer class exists,
//all of the sun classes exist //all of the sun classes exist
if (SUN_DIRECT_BUFFER != null) { if (SUN_DIRECT_BUFFER != null) {
bufferCleaner = SUN_DIRECT_BUFFER.getMethod("cleaner", (Class[])null); bufferCleaner = SUN_DIRECT_BUFFER.getMethod("cleaner", (Class[])null);
Class<?> cleanClazz = lookupClassQuietly("sun.misc.Cleaner"); Class<?> cleanClazz = lookupClassQuietly("sun.misc.Cleaner");
cleanerClean = cleanClazz.getMethod("clean", (Class[])null); cleanerClean = cleanClazz.getMethod("clean", (Class[])null);
} }
} catch(Throwable t) { } catch(Throwable t) {
Logger.getLogger(SnappyFramed.class.getName()).log(Level.FINE, "Exception occurred attempting to lookup Sun specific DirectByteBuffer cleaner classes.", t); Logger.getLogger(SnappyFramed.class.getName()).log(Level.FINE, "Exception occurred attempting to lookup Sun specific DirectByteBuffer cleaner classes.", t);
} }
SUN_BUFFER_CLEANER = bufferCleaner; SUN_BUFFER_CLEANER = bufferCleaner;
SUN_CLEANER_CLEAN = cleanerClean; SUN_CLEANER_CLEAN = cleanerClean;
} }
/** /**
* The header consists of the stream identifier flag, 3 bytes indicating a * The header consists of the stream identifier flag, 3 bytes indicating a
* length of 6, and "sNaPpY" in ASCII. * length of 6, and "sNaPpY" in ASCII.
*/ */
public static final byte[] HEADER_BYTES = new byte[] { public static final byte[] HEADER_BYTES = new byte[] {
(byte) STREAM_IDENTIFIER_FLAG, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, (byte) STREAM_IDENTIFIER_FLAG, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61,
0x50, 0x70, 0x59 }; 0x50, 0x70, 0x59 };
public static int maskedCrc32c(byte[] data) public static int maskedCrc32c(byte[] data)
{ {
return maskedCrc32c(data, 0, data.length); return maskedCrc32c(data, 0, data.length);
} }
public static int maskedCrc32c(byte[] data, int offset, int length) public static int maskedCrc32c(byte[] data, int offset, int length)
{ {
final PureJavaCrc32C crc32c = new PureJavaCrc32C(); final PureJavaCrc32C crc32c = new PureJavaCrc32C();
crc32c.update(data, offset, length); crc32c.update(data, offset, length);
return mask(crc32c.getIntegerValue()); return mask(crc32c.getIntegerValue());
} }
/** /**
* Checksums are not stored directly, but masked, as checksumming data and * 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 * 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 * in Apache Hadoop: Rotate the checksum by 15 bits, then add the constant
* 0xa282ead8 (using wraparound as normal for unsigned integers). This is * 0xa282ead8 (using wraparound as normal for unsigned integers). This is
* equivalent to the following C code: * equivalent to the following C code:
* *
* <pre> * <pre>
* uint32_t mask_checksum(uint32_t x) { * uint32_t mask_checksum(uint32_t x) {
* return ((x >> 15) | (x << 17)) + 0xa282ead8; * return ((x >> 15) | (x << 17)) + 0xa282ead8;
* } * }
* </pre> * </pre>
*/ */
public static int mask(int crc) public static int mask(int crc)
{ {
// Rotate right by 15 bits and add a constant. // Rotate right by 15 bits and add a constant.
return ((crc >>> 15) | (crc << 17)) + MASK_DELTA; return ((crc >>> 15) | (crc << 17)) + MASK_DELTA;
} }
static final int readBytes(ReadableByteChannel source, ByteBuffer dest) throws IOException static final int readBytes(ReadableByteChannel source, ByteBuffer dest) throws IOException
{ {
// tells how many bytes to read. // tells how many bytes to read.
final int expectedLength = dest.remaining(); final int expectedLength = dest.remaining();
int totalRead = 0; int totalRead = 0;
// how many bytes were read. // how many bytes were read.
int lastRead = source.read(dest); int lastRead = source.read(dest);
totalRead = lastRead; totalRead = lastRead;
// if we did not read as many bytes as we had hoped, try reading again. // if we did not read as many bytes as we had hoped, try reading again.
if (lastRead < expectedLength) if (lastRead < expectedLength)
{ {
// as long the buffer is not full (remaining() == 0) and we have not reached EOF (lastRead == -1) keep reading. // 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) while (dest.remaining() != 0 && lastRead != -1)
{ {
lastRead = source.read(dest); lastRead = source.read(dest);
// if we got EOF, do not add to total read. // if we got EOF, do not add to total read.
if (lastRead != -1) if (lastRead != -1)
{ {
totalRead += lastRead; totalRead += lastRead;
} }
} }
} }
if (totalRead > 0) if (totalRead > 0)
{ {
dest.limit(dest.position()); dest.limit(dest.position());
} }
else else
{ {
dest.position(dest.limit()); dest.position(dest.limit());
} }
return totalRead; return totalRead;
} }
static int skip(final ReadableByteChannel source, final int skip, final ByteBuffer buffer) throws IOException static int skip(final ReadableByteChannel source, final int skip, final ByteBuffer buffer) throws IOException
{ {
if (skip <= 0) { if (skip <= 0) {
return 0; return 0;
} }
int toSkip = skip; int toSkip = skip;
int skipped = 0; int skipped = 0;
while(toSkip > 0 && skipped != -1) { while(toSkip > 0 && skipped != -1) {
buffer.clear(); buffer.clear();
if (toSkip < buffer.capacity()) { if (toSkip < buffer.capacity()) {
buffer.limit(toSkip); buffer.limit(toSkip);
} }
skipped = source.read(buffer); skipped = source.read(buffer);
if (skipped > 0) { if (skipped > 0) {
toSkip -= skipped; toSkip -= skipped;
} }
} }
buffer.clear(); buffer.clear();
return skip - toSkip; return skip - toSkip;
} }
private static Class<?> lookupClassQuietly(String name) { private static Class<?> lookupClassQuietly(String name) {
try { try {
return SnappyFramed.class.getClassLoader().loadClass(name); return SnappyFramed.class.getClassLoader().loadClass(name);
} catch (Throwable t) { } catch (Throwable t) {
Logger.getLogger(SnappyFramed.class.getName()).log(Level.FINE, "Did not find requested class: " + name, t); Logger.getLogger(SnappyFramed.class.getName()).log(Level.FINE, "Did not find requested class: " + name, t);
} }
return null; return null;
} }
/** /**
* Provides jvm implementation specific operation to aggressively release resources associated with <i>buffer</i>. * Provides jvm implementation specific operation to aggressively release resources associated with <i>buffer</i>.
* @param buffer The {@code ByteBuffer} to release. Must not be {@code null}. Must be {@link ByteBuffer#isDirect() direct}. * @param buffer The {@code ByteBuffer} to release. Must not be {@code null}. Must be {@link ByteBuffer#isDirect() direct}.
*/ */
static void releaseDirectByteBuffer(ByteBuffer buffer) static void releaseDirectByteBuffer(ByteBuffer buffer)
{ {
assert buffer != null && buffer.isDirect(); assert buffer != null && buffer.isDirect();
if (SUN_DIRECT_BUFFER != null && SUN_DIRECT_BUFFER.isAssignableFrom(buffer.getClass())) { if (SUN_DIRECT_BUFFER != null && SUN_DIRECT_BUFFER.isAssignableFrom(buffer.getClass())) {
try { try {
Object cleaner = SUN_BUFFER_CLEANER.invoke(buffer, (Object[]) null); Object cleaner = SUN_BUFFER_CLEANER.invoke(buffer, (Object[]) null);
SUN_CLEANER_CLEAN.invoke(cleaner, (Object[]) null); SUN_CLEANER_CLEAN.invoke(cleaner, (Object[]) null);
} catch (Throwable t) { } catch (Throwable t) {
Logger.getLogger(SnappyFramed.class.getName()).log(Level.FINE, "Exception occurred attempting to clean up Sun specific DirectByteBuffer.", t); Logger.getLogger(SnappyFramed.class.getName()).log(Level.FINE, "Exception occurred attempting to clean up Sun specific DirectByteBuffer.", t);
} }
} }
} }
} }

View File

@ -1,309 +1,309 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <snappy.h> #include <snappy.h>
#include "SnappyNative.h" #include "SnappyNative.h"
void throw_exception(JNIEnv *env, jobject self, int errorCode) void throw_exception(JNIEnv *env, jobject self, int errorCode)
{ {
jclass c = env->FindClass("org/xerial/snappy/SnappyNative"); jclass c = env->FindClass("org/xerial/snappy/SnappyNative");
if(c==0) if(c==0)
return; return;
jmethodID mth_throwex = env->GetMethodID(c, "throw_error", "(I)V"); jmethodID mth_throwex = env->GetMethodID(c, "throw_error", "(I)V");
if(mth_throwex == 0) if(mth_throwex == 0)
return; return;
env->CallVoidMethod(self, mth_throwex, (jint) errorCode); env->CallVoidMethod(self, mth_throwex, (jint) errorCode);
} }
JNIEXPORT jstring JNICALL Java_org_xerial_snappy_SnappyNative_nativeLibraryVersion JNIEXPORT jstring JNICALL Java_org_xerial_snappy_SnappyNative_nativeLibraryVersion
(JNIEnv * env, jobject self) (JNIEnv * env, jobject self)
{ {
return env->NewStringUTF("1.1.0"); return env->NewStringUTF("1.1.0");
} }
JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__JJJ JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__JJJ
(JNIEnv* env, jobject self, jlong srcAddr, jlong length, jlong destAddr) { (JNIEnv* env, jobject self, jlong srcAddr, jlong length, jlong destAddr) {
size_t compressedLength; size_t compressedLength;
snappy::RawCompress((char*) srcAddr, (size_t) length, (char*) destAddr, &compressedLength); snappy::RawCompress((char*) srcAddr, (size_t) length, (char*) destAddr, &compressedLength);
return (jlong) compressedLength; return (jlong) compressedLength;
} }
JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__JJJ JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__JJJ
(JNIEnv* env, jobject self, jlong srcAddr, jlong length, jlong destAddr) { (JNIEnv* env, jobject self, jlong srcAddr, jlong length, jlong destAddr) {
size_t uncompressedLength; size_t uncompressedLength;
snappy::GetUncompressedLength((char*) srcAddr, (size_t) length, &uncompressedLength); snappy::GetUncompressedLength((char*) srcAddr, (size_t) length, &uncompressedLength);
bool ret = snappy::RawUncompress((char*) srcAddr, (size_t) length, (char*) destAddr); bool ret = snappy::RawUncompress((char*) srcAddr, (size_t) length, (char*) destAddr);
if(!ret) { if(!ret) {
throw_exception(env, self, 5); throw_exception(env, self, 5);
return 0; return 0;
} }
return (jlong) uncompressedLength; return (jlong) uncompressedLength;
} }
/* /*
* Class: org_xerial_snappy_Snappy * Class: org_xerial_snappy_Snappy
* Method: compress * Method: compress
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)J * Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)J
*/ */
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_nio_ByteBuffer_2IILjava_nio_ByteBuffer_2I JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_nio_ByteBuffer_2IILjava_nio_ByteBuffer_2I
(JNIEnv* env, jobject self, jobject uncompressed, jint upos, jint ulen, jobject compressed, jint cpos) (JNIEnv* env, jobject self, jobject uncompressed, jint upos, jint ulen, jobject compressed, jint cpos)
{ {
char* uncompressedBuffer = (char*) env->GetDirectBufferAddress(uncompressed); char* uncompressedBuffer = (char*) env->GetDirectBufferAddress(uncompressed);
char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed); char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed);
if(uncompressedBuffer == 0 || compressedBuffer == 0) { if(uncompressedBuffer == 0 || compressedBuffer == 0) {
throw_exception(env, self, 3); throw_exception(env, self, 3);
return (jint) 0; return (jint) 0;
} }
size_t compressedLength; size_t compressedLength;
snappy::RawCompress(uncompressedBuffer + upos, (size_t) ulen, compressedBuffer + cpos, &compressedLength); snappy::RawCompress(uncompressedBuffer + upos, (size_t) ulen, compressedBuffer + cpos, &compressedLength);
return (jint) compressedLength; return (jint) compressedLength;
} }
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_lang_Object_2IILjava_lang_Object_2I JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawCompress__Ljava_lang_Object_2IILjava_lang_Object_2I
(JNIEnv * env, jobject self, jobject input, jint inputOffset, jint inputLen, jobject output, jint outputOffset) (JNIEnv * env, jobject self, jobject input, jint inputOffset, jint inputLen, jobject output, jint outputOffset)
{ {
char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0);
char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0); char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0);
if(in == 0 || out == 0) { if(in == 0 || out == 0) {
// out of memory // out of memory
if(in != 0) { if(in != 0) {
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
} }
if(out != 0) { if(out != 0) {
env->ReleasePrimitiveArrayCritical((jarray) output, out, 0); env->ReleasePrimitiveArrayCritical((jarray) output, out, 0);
} }
throw_exception(env, self, 4); throw_exception(env, self, 4);
return 0; return 0;
} }
size_t compressedLength; size_t compressedLength;
snappy::RawCompress(in + inputOffset, (size_t) inputLen, out + outputOffset, &compressedLength); snappy::RawCompress(in + inputOffset, (size_t) inputLen, out + outputOffset, &compressedLength);
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
env->ReleasePrimitiveArrayCritical((jarray) output, out, 0); env->ReleasePrimitiveArrayCritical((jarray) output, out, 0);
return (jint) compressedLength; return (jint) compressedLength;
} }
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_lang_Object_2IILjava_lang_Object_2I JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_lang_Object_2IILjava_lang_Object_2I
(JNIEnv * env, jobject self, jobject input, jint inputOffset, jint inputLength, jobject output, jint outputOffset) (JNIEnv * env, jobject self, jobject input, jint inputOffset, jint inputLength, jobject output, jint outputOffset)
{ {
char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0);
char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0); char* out = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0);
if(in == 0 || out == 0) { if(in == 0 || out == 0) {
// out of memory // out of memory
if(in != 0) { if(in != 0) {
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
} }
if(out != 0) { if(out != 0) {
env->ReleasePrimitiveArrayCritical((jarray) output, out, 0); env->ReleasePrimitiveArrayCritical((jarray) output, out, 0);
} }
throw_exception(env, self, 4); throw_exception(env, self, 4);
return 0; return 0;
} }
size_t uncompressedLength; size_t uncompressedLength;
snappy::GetUncompressedLength(in + inputOffset, (size_t) inputLength, &uncompressedLength); snappy::GetUncompressedLength(in + inputOffset, (size_t) inputLength, &uncompressedLength);
bool ret = snappy::RawUncompress(in + inputOffset, (size_t) inputLength, out + outputOffset); bool ret = snappy::RawUncompress(in + inputOffset, (size_t) inputLength, out + outputOffset);
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
env->ReleasePrimitiveArrayCritical((jarray) output, out, 0); env->ReleasePrimitiveArrayCritical((jarray) output, out, 0);
if(!ret) { if(!ret) {
throw_exception(env, self, 5); throw_exception(env, self, 5);
return 0; return 0;
} }
return (jint) uncompressedLength; return (jint) uncompressedLength;
} }
/* /*
* Class: org_xerial_snappy_Snappy * Class: org_xerial_snappy_Snappy
* Method: uncompress * Method: uncompress
* Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Z * Signature: (Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;)Z
*/ */
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_nio_ByteBuffer_2IILjava_nio_ByteBuffer_2I JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_rawUncompress__Ljava_nio_ByteBuffer_2IILjava_nio_ByteBuffer_2I
(JNIEnv * env, jobject self, jobject compressed, jint cpos, jint clen, jobject decompressed, jint dpos) (JNIEnv * env, jobject self, jobject compressed, jint cpos, jint clen, jobject decompressed, jint dpos)
{ {
char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed); char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed);
char* decompressedBuffer = (char*) env->GetDirectBufferAddress(decompressed); char* decompressedBuffer = (char*) env->GetDirectBufferAddress(decompressed);
if(compressedBuffer == 0 || decompressedBuffer == 0) { if(compressedBuffer == 0 || decompressedBuffer == 0) {
throw_exception(env, self, 3); throw_exception(env, self, 3);
return (jint) 0; return (jint) 0;
} }
size_t decompressedLength; size_t decompressedLength;
snappy::GetUncompressedLength(compressedBuffer + cpos, (size_t) clen, &decompressedLength); snappy::GetUncompressedLength(compressedBuffer + cpos, (size_t) clen, &decompressedLength);
bool ret = snappy::RawUncompress(compressedBuffer + cpos, (size_t) clen, decompressedBuffer + dpos); bool ret = snappy::RawUncompress(compressedBuffer + cpos, (size_t) clen, decompressedBuffer + dpos);
if(!ret) { if(!ret) {
throw_exception(env, self, 5); throw_exception(env, self, 5);
return 0; return 0;
} }
return (jint) decompressedLength; return (jint) decompressedLength;
} }
/* /*
* Class: org_xerial_snappy_Snappy * Class: org_xerial_snappy_Snappy
* Method: maxCompressedLength * Method: maxCompressedLength
* Signature: (J)J * Signature: (J)J
*/ */
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_maxCompressedLength JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_maxCompressedLength
(JNIEnv *, jobject, jint size) (JNIEnv *, jobject, jint size)
{ {
size_t l = snappy::MaxCompressedLength((size_t) size); size_t l = snappy::MaxCompressedLength((size_t) size);
return (jint) l; return (jint) l;
} }
/* /*
* Class: org_xerial_snappy_Snappy * Class: org_xerial_snappy_Snappy
* Method: getUncompressedLength * Method: getUncompressedLength
* Signature: (Ljava/nio/ByteBuffer;)J * Signature: (Ljava/nio/ByteBuffer;)J
*/ */
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__Ljava_nio_ByteBuffer_2II JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__Ljava_nio_ByteBuffer_2II
(JNIEnv * env, jobject self, jobject compressed, jint cpos, jint clen) (JNIEnv * env, jobject self, jobject compressed, jint cpos, jint clen)
{ {
char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed); char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed);
if(compressedBuffer == 0) { if(compressedBuffer == 0) {
throw_exception(env, self, 3); throw_exception(env, self, 3);
return (jint) 0; return (jint) 0;
} }
size_t result; size_t result;
bool ret = snappy::GetUncompressedLength(compressedBuffer + cpos, (size_t) clen, &result); bool ret = snappy::GetUncompressedLength(compressedBuffer + cpos, (size_t) clen, &result);
if(!ret) { if(!ret) {
throw_exception(env, self, 2); throw_exception(env, self, 2);
return 0; return 0;
} }
return (jint) result; return (jint) result;
} }
JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__Ljava_lang_Object_2II JNIEXPORT jint JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__Ljava_lang_Object_2II
(JNIEnv * env, jobject self, jobject input, jint offset, jint length) (JNIEnv * env, jobject self, jobject input, jint offset, jint length)
{ {
char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0);
if(in == 0) { if(in == 0) {
// out of memory // out of memory
throw_exception(env, self, 4); throw_exception(env, self, 4);
return 0; return 0;
} }
size_t result; size_t result;
bool ret = snappy::GetUncompressedLength(in + offset, (size_t) length, &result); bool ret = snappy::GetUncompressedLength(in + offset, (size_t) length, &result);
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
if(!ret) { if(!ret) {
throw_exception(env, self, 2); throw_exception(env, self, 2);
return 0; return 0;
} }
return (jint) result; return (jint) result;
} }
JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__JJ JNIEXPORT jlong JNICALL Java_org_xerial_snappy_SnappyNative_uncompressedLength__JJ
(JNIEnv *env, jobject self, jlong inputAddr, jlong len) { (JNIEnv *env, jobject self, jlong inputAddr, jlong len) {
size_t result; size_t result;
bool ret = snappy::GetUncompressedLength((char*) inputAddr, (size_t) len, &result); bool ret = snappy::GetUncompressedLength((char*) inputAddr, (size_t) len, &result);
if(!ret) { if(!ret) {
throw_exception(env, self, 2); throw_exception(env, self, 2);
return 0; return 0;
} }
return (jint) result; return (jint) result;
} }
JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_nio_ByteBuffer_2II JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_nio_ByteBuffer_2II
(JNIEnv * env, jobject self, jobject compressed, jint cpos, jint clen) (JNIEnv * env, jobject self, jobject compressed, jint cpos, jint clen)
{ {
char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed); char* compressedBuffer = (char*) env->GetDirectBufferAddress(compressed);
if(compressedBuffer == 0) { if(compressedBuffer == 0) {
throw_exception(env, self, 3); throw_exception(env, self, 3);
return (jint) 0; return (jint) 0;
} }
bool ret = snappy::IsValidCompressedBuffer(compressedBuffer + cpos, (size_t) clen); bool ret = snappy::IsValidCompressedBuffer(compressedBuffer + cpos, (size_t) clen);
return ret; return ret;
} }
JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_lang_Object_2II JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__Ljava_lang_Object_2II
(JNIEnv * env, jobject self, jobject input, jint offset, jint length) (JNIEnv * env, jobject self, jobject input, jint offset, jint length)
{ {
char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); char* in = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0);
if(in == 0) { if(in == 0) {
// out of memory // out of memory
throw_exception(env, self, 4); throw_exception(env, self, 4);
return 0; return 0;
} }
bool ret = snappy::IsValidCompressedBuffer(in + offset, (size_t) length); bool ret = snappy::IsValidCompressedBuffer(in + offset, (size_t) length);
env->ReleasePrimitiveArrayCritical((jarray) input, in, 0); env->ReleasePrimitiveArrayCritical((jarray) input, in, 0);
return ret; return ret;
} }
JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__JJJ JNIEXPORT jboolean JNICALL Java_org_xerial_snappy_SnappyNative_isValidCompressedBuffer__JJJ
(JNIEnv * env, jobject self, jlong inputAddr, jlong offset, jlong length) (JNIEnv * env, jobject self, jlong inputAddr, jlong offset, jlong length)
{ {
if(inputAddr == 0) { if(inputAddr == 0) {
// out of memory // out of memory
throw_exception(env, self, 4); throw_exception(env, self, 4);
return 0; return 0;
} }
bool ret = snappy::IsValidCompressedBuffer((char*) (inputAddr + offset), (size_t) length); bool ret = snappy::IsValidCompressedBuffer((char*) (inputAddr + offset), (size_t) length);
return ret; return ret;
} }
JNIEXPORT void JNICALL Java_org_xerial_snappy_SnappyNative_arrayCopy JNIEXPORT void JNICALL Java_org_xerial_snappy_SnappyNative_arrayCopy
(JNIEnv * env, jobject self, jobject input, jint offset, jint length, jobject output, jint output_offset) (JNIEnv * env, jobject self, jobject input, jint offset, jint length, jobject output, jint output_offset)
{ {
char* src = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0); char* src = (char*) env->GetPrimitiveArrayCritical((jarray) input, 0);
char* dest = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0); char* dest = (char*) env->GetPrimitiveArrayCritical((jarray) output, 0);
if(src == 0 || dest == 0) { if(src == 0 || dest == 0) {
// out of memory // out of memory
if(src != 0) { if(src != 0) {
env->ReleasePrimitiveArrayCritical((jarray) input, src, 0); env->ReleasePrimitiveArrayCritical((jarray) input, src, 0);
} }
if(dest != 0) { if(dest != 0) {
env->ReleasePrimitiveArrayCritical((jarray) output, dest, 0); env->ReleasePrimitiveArrayCritical((jarray) output, dest, 0);
} }
throw_exception(env, self, 4); throw_exception(env, self, 4);
return; return;
} }
memcpy(dest+output_offset, src+offset, (size_t) length); memcpy(dest+output_offset, src+offset, (size_t) length);
env->ReleasePrimitiveArrayCritical((jarray) input, src, 0); env->ReleasePrimitiveArrayCritical((jarray) input, src, 0);
env->ReleasePrimitiveArrayCritical((jarray) output, dest, 0); env->ReleasePrimitiveArrayCritical((jarray) output, dest, 0);
} }

View File

@ -1,87 +1,87 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// snappy-java Project // snappy-java Project
// //
// SnappyNative.java // SnappyNative.java
// Since: 2011/03/30 // Since: 2011/03/30
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
* JNI interface of the {@link Snappy} 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 * defined in SnappyNative.h (genereted by javah) and SnappyNative.cpp
* *
* <p> * <p>
* <b> DO NOT USE THIS CLASS since the direct use of this class might break the * <b> DO NOT USE THIS CLASS since the direct use of this class might break the
* native library code loading in {@link SnappyLoader}. </b> * native library code loading in {@link SnappyLoader}. </b>
* </p> * </p>
* *
* @author leo * @author leo
* *
*/ */
public class SnappyNative public class SnappyNative
{ {
public native String nativeLibraryVersion(); public native String nativeLibraryVersion();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Generic compression/decompression routines. // Generic compression/decompression routines.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
public native long rawCompress(long inputAddr, long inputSize, long destAddr) throws IOException; public native long rawCompress(long inputAddr, long inputSize, long destAddr) throws IOException;
public native long rawUncompress(long inputAddr, long inputSize, long destAddr) throws IOException; public native long rawUncompress(long inputAddr, long inputSize, long destAddr) throws IOException;
public native int rawCompress(ByteBuffer input, int inputOffset, int inputLength, ByteBuffer compressed, public native int rawCompress(ByteBuffer input, int inputOffset, int inputLength, ByteBuffer compressed,
int outputOffset) throws IOException; int outputOffset) throws IOException;
public native int rawCompress(Object input, int inputOffset, int inputByteLength, Object output, int outputOffset) throws IOException; public native int rawCompress(Object input, int inputOffset, int inputByteLength, Object output, int outputOffset) throws IOException;
public native int rawUncompress(ByteBuffer compressed, int inputOffset, int inputLength, ByteBuffer uncompressed, public native int rawUncompress(ByteBuffer compressed, int inputOffset, int inputLength, ByteBuffer uncompressed,
int outputOffset) throws IOException; int outputOffset) throws IOException;
public native int rawUncompress(Object input, int inputOffset, int inputLength, Object output, int outputOffset) public native int rawUncompress(Object input, int inputOffset, int inputLength, Object output, int outputOffset)
throws IOException; throws IOException;
// Returns the maximal size of the compressed representation of // Returns the maximal size of the compressed representation of
// input data that is "source_bytes" bytes in length; // input data that is "source_bytes" bytes in length;
public native int maxCompressedLength(int source_bytes); public native int maxCompressedLength(int source_bytes);
// This operation takes O(1) time. // This operation takes O(1) time.
public native int uncompressedLength(ByteBuffer compressed, int offset, int len) throws IOException; public native int uncompressedLength(ByteBuffer compressed, int offset, int len) throws IOException;
public native int uncompressedLength(Object input, int offset, int len) throws IOException; public native int uncompressedLength(Object input, int offset, int len) throws IOException;
public native long uncompressedLength(long inputAddr, long len) throws IOException; public native long uncompressedLength(long inputAddr, long len) throws IOException;
public native boolean isValidCompressedBuffer(ByteBuffer compressed, int offset, int len) throws IOException; public native boolean isValidCompressedBuffer(ByteBuffer compressed, int offset, int len) throws IOException;
public native boolean isValidCompressedBuffer(Object input, int offset, int len) throws IOException; 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 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 native void arrayCopy(Object src, int offset, int byteLength, Object dest, int dOffset) throws IOException;
public void throw_error(int errorCode) throws IOException { public void throw_error(int errorCode) throws IOException {
throw new IOException(String.format("%s(%d)", SnappyErrorCode.getErrorMessage(errorCode), errorCode)); throw new IOException(String.format("%s(%d)", SnappyErrorCode.getErrorMessage(errorCode), errorCode));
} }
} }

View File

@ -1,44 +1,44 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
/** /**
* Snappy API for compressing/decompressing data. * Snappy API for compressing/decompressing data.
* *
* Usage * Usage
* First, import {@link org.xerial.snappy.Snappy} in your Java code: * First, import {@link org.xerial.snappy.Snappy} in your Java code:
* <code> * <code>
* <pre> * <pre>
* import org.xerial.snappy.Snappy; * import org.xerial.snappy.Snappy;
* </pre> * </pre>
* </code> * </code>
* Then use {@link org.xerial.snappy.Snappy#compress(byte[])} and {@link org.xerial.snappy.Snappy#uncompress(byte[])}: * Then use {@link org.xerial.snappy.Snappy#compress(byte[])} and {@link org.xerial.snappy.Snappy#uncompress(byte[])}:
* <code> * <code>
* <pre> * <pre>
* String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper of Snappy, a fast compresser/decompresser."; * String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper of Snappy, a fast compresser/decompresser.";
* byte[] compressed = Snappy.compress(input.getBytes("UTF-8")); * byte[] compressed = Snappy.compress(input.getBytes("UTF-8"));
* byte[] uncompressed = Snappy.uncompress(compressed); * byte[] uncompressed = Snappy.uncompress(compressed);
* String result = new String(uncompressed, "UTF-8"); * String result = new String(uncompressed, "UTF-8");
* System.out.println(result); * System.out.println(result);
* </pre> * </pre>
* </code> * </code>
* *
* <p>In addition, high-level methods (Snappy.compress(String), Snappy.compress(float[] ..) etc. ) and low-level ones (e.g. Snappy.rawCompress(.. ), Snappy.rawUncompress(..), etc.), which minimize memory copies, can be used. </p> * <p>In addition, high-level methods (Snappy.compress(String), Snappy.compress(float[] ..) etc. ) and low-level ones (e.g. Snappy.rawCompress(.. ), Snappy.rawUncompress(..), etc.), which minimize memory copies, can be used. </p>
* *
* <h3>Stream-based API</h3> * <h3>Stream-based API</h3>
* Stream-based compressor/decompressor SnappyOutputStream, SnappyInputStream are also available for reading/writing large data sets. * Stream-based compressor/decompressor SnappyOutputStream, SnappyInputStream are also available for reading/writing large data sets.
*/ */
package org.xerial.snappy; package org.xerial.snappy;

View File

@ -1,228 +1,228 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// CalgaryTest.java // CalgaryTest.java
// Since: 2011/04/04 12:10:36 // Since: 2011/04/04 12:10:36
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.xerial.util.FileResource; import org.xerial.util.FileResource;
import org.xerial.util.log.Logger; import org.xerial.util.log.Logger;
/** /**
* Benchmark using Calgary data set * Benchmark using Calgary data set
* *
* @author leo * @author leo
* *
*/ */
public class CalgaryTest public class CalgaryTest
{ {
private static Logger _logger = Logger.getLogger(CalgaryTest.class); private static Logger _logger = Logger.getLogger(CalgaryTest.class);
@Rule @Rule
public final TemporaryFolder tempFolder = new TemporaryFolder(); public final TemporaryFolder tempFolder = new TemporaryFolder();
static byte[] readFile(String file) throws IOException { static byte[] readFile(String file) throws IOException {
InputStream in = FileResource.find(CalgaryTest.class, file).openStream(); InputStream in = FileResource.find(CalgaryTest.class, file).openStream();
if (in == null) if (in == null)
throw new IOException("file " + file + " is not found"); throw new IOException("file " + file + " is not found");
try { try {
return SnappyInputStreamTest.readFully(in); return SnappyInputStreamTest.readFully(in);
} }
finally { finally {
if (in != null) if (in != null)
in.close(); in.close();
} }
} }
public static final String[] files = { "bib", "book1", "book2", "geo", "news", "obj1", "obj2", "paper1", "paper2", public static final String[] files = { "bib", "book1", "book2", "geo", "news", "obj1", "obj2", "paper1", "paper2",
"paper3", "paper4", "paper5", "paper6", "pic", "progc", "progl", "progp", "trans" }; "paper3", "paper4", "paper5", "paper6", "pic", "progc", "progl", "progp", "trans" };
@Test @Test
public void block() throws Exception { public void block() throws Exception {
for (String f : files) { for (String f : files) {
byte[] orig = readFile("testdata/calgary/" + f); byte[] orig = readFile("testdata/calgary/" + f);
byte[] compressed = Snappy.compress(orig); byte[] compressed = Snappy.compress(orig);
byte[] uncompressed = Snappy.uncompress(compressed); byte[] uncompressed = Snappy.uncompress(compressed);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
} }
@Test @Test
public void stream() throws Exception { public void stream() throws Exception {
for (String f : files) { for (String f : files) {
byte[] orig = readFile("testdata/calgary/" + f); byte[] orig = readFile("testdata/calgary/" + f);
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream(); ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
SnappyOutputStream out = new SnappyOutputStream(compressedBuf); SnappyOutputStream out = new SnappyOutputStream(compressedBuf);
out.write(orig); out.write(orig);
out.close(); out.close();
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressedBuf.toByteArray())); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()));
byte[] uncompressed = new byte[orig.length]; byte[] uncompressed = new byte[orig.length];
int readBytes = in.read(uncompressed); int readBytes = in.read(uncompressed);
assertEquals(orig.length, readBytes); assertEquals(orig.length, readBytes);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
} }
@Test @Test
public void streamFramed() throws Exception { public void streamFramed() throws Exception {
for (String f : files) { for (String f : files) {
byte[] orig = readFile("testdata/calgary/" + f); byte[] orig = readFile("testdata/calgary/" + f);
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream(); ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedBuf); SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedBuf);
out.write(orig); out.write(orig);
out.close(); out.close();
SnappyFramedInputStream in = new SnappyFramedInputStream(new ByteArrayInputStream(compressedBuf.toByteArray())); SnappyFramedInputStream in = new SnappyFramedInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()));
byte[] uncompressed = new byte[orig.length]; byte[] uncompressed = new byte[orig.length];
int readBytes = readBytes(in, uncompressed, 0, orig.length); int readBytes = readBytes(in, uncompressed, 0, orig.length);
assertEquals(orig.length, readBytes); assertEquals(orig.length, readBytes);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
} }
@Test @Test
public void streamFramedToFile() throws Exception { public void streamFramedToFile() throws Exception {
for (String f : files) { for (String f : files) {
byte[] orig = readFile("testdata/calgary/" + f); byte[] orig = readFile("testdata/calgary/" + f);
final File tempFile = tempFolder.newFile(f); final File tempFile = tempFolder.newFile(f);
final FileOutputStream compressedFOS = new FileOutputStream(tempFile); final FileOutputStream compressedFOS = new FileOutputStream(tempFile);
try try
{ {
SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedFOS); SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedFOS);
out.write(orig); out.write(orig);
out.close(); out.close();
} }
finally finally
{ {
compressedFOS.close(); compressedFOS.close();
} }
byte[] uncompressed = new byte[orig.length]; byte[] uncompressed = new byte[orig.length];
final FileInputStream compressedFIS = new FileInputStream(tempFile); final FileInputStream compressedFIS = new FileInputStream(tempFile);
try try
{ {
SnappyFramedInputStream in = new SnappyFramedInputStream(compressedFIS.getChannel()); SnappyFramedInputStream in = new SnappyFramedInputStream(compressedFIS.getChannel());
int readBytes = readBytes(in, uncompressed, 0, orig.length); int readBytes = readBytes(in, uncompressed, 0, orig.length);
assertEquals(orig.length, readBytes); assertEquals(orig.length, readBytes);
} }
finally finally
{ {
compressedFIS.close(); compressedFIS.close();
} }
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
} }
@Test @Test
public void streamFramedNoCRCVerify() throws Exception { public void streamFramedNoCRCVerify() throws Exception {
for (String f : files) { for (String f : files) {
byte[] orig = readFile("testdata/calgary/" + f); byte[] orig = readFile("testdata/calgary/" + f);
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream(); ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedBuf); SnappyFramedOutputStream out = new SnappyFramedOutputStream(compressedBuf);
out.write(orig); out.write(orig);
out.close(); out.close();
SnappyFramedInputStream in = new SnappyFramedInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()), false); SnappyFramedInputStream in = new SnappyFramedInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()), false);
byte[] uncompressed = new byte[orig.length]; byte[] uncompressed = new byte[orig.length];
int readBytes = readBytes(in, uncompressed, 0, orig.length); int readBytes = readBytes(in, uncompressed, 0, orig.length);
assertEquals(orig.length, readBytes); assertEquals(orig.length, readBytes);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
} }
@Test @Test
public void byteWiseRead() throws Exception { public void byteWiseRead() throws Exception {
for (String f : files) { for (String f : files) {
byte[] orig = readFile("testdata/calgary/" + f); byte[] orig = readFile("testdata/calgary/" + f);
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream(); ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
SnappyOutputStream out = new SnappyOutputStream(compressedBuf); SnappyOutputStream out = new SnappyOutputStream(compressedBuf);
out.write(orig); out.write(orig);
out.close(); out.close();
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressedBuf.toByteArray())); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressedBuf.toByteArray()));
byte[] uncompressed = new byte[orig.length]; byte[] uncompressed = new byte[orig.length];
int cursor = 0; int cursor = 0;
for (;;) { for (;;) {
int b = in.read(); int b = in.read();
if (b == -1) if (b == -1)
break; break;
uncompressed[cursor++] = (byte) b; uncompressed[cursor++] = (byte) b;
} }
assertEquals(orig.length, cursor); assertEquals(orig.length, cursor);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
} }
static final int readBytes(InputStream source, byte[] dest, int offset, int length) throws IOException static final int readBytes(InputStream source, byte[] dest, int offset, int length) throws IOException
{ {
// how many bytes were read. // how many bytes were read.
int lastRead = source.read(dest, offset, length); int lastRead = source.read(dest, offset, length);
int totalRead = lastRead; int totalRead = lastRead;
// if we did not read as many bytes as we had hoped, try reading again. // if we did not read as many bytes as we had hoped, try reading again.
if (lastRead < length) if (lastRead < length)
{ {
// as long the buffer is not full (remaining() == 0) and we have not reached EOF (lastRead == -1) keep reading. // as long the buffer is not full (remaining() == 0) and we have not reached EOF (lastRead == -1) keep reading.
while (totalRead < length && lastRead != -1) while (totalRead < length && lastRead != -1)
{ {
lastRead = source.read(dest, offset + totalRead, length - totalRead); lastRead = source.read(dest, offset + totalRead, length - totalRead);
// if we got EOF, do not add to total read. // if we got EOF, do not add to total read.
if (lastRead != -1) if (lastRead != -1)
{ {
totalRead += lastRead; totalRead += lastRead;
} }
} }
} }
return totalRead; return totalRead;
} }
} }

View File

@ -1,68 +1,68 @@
/* /*
* Created: Apr 15, 2013 * Created: Apr 15, 2013
*/ */
package org.xerial.snappy; package org.xerial.snappy;
import java.util.Random; import java.util.Random;
/** /**
* Generates random data with specific expected snappy performance characteristics. * Generates random data with specific expected snappy performance characteristics.
* *
* <p> * <p>
* This has been copied from <a href="https://github.com/dain/snappy"> dain's snappy</a> implementation.. * This has been copied from <a href="https://github.com/dain/snappy"> dain's snappy</a> implementation..
* </p> * </p>
*/ */
public class RandomGenerator { public class RandomGenerator {
public final byte[] data; public final byte[] data;
public int position; public int position;
public RandomGenerator(double compressionRatio) { public RandomGenerator(double compressionRatio) {
// We use a limited amount of data over and over again and ensure // We use a limited amount of data over and over again and ensure
// that it is larger than the compression window (32KB), and also // that it is larger than the compression window (32KB), and also
// large enough to serve all typical value sizes we want to write. // large enough to serve all typical value sizes we want to write.
Random rnd = new Random(301); Random rnd = new Random(301);
data = new byte[1048576 + 100]; data = new byte[1048576 + 100];
for (int i = 0; i < 1048576; i += 100) { for (int i = 0; i < 1048576; i += 100) {
// Add a short fragment that is as compressible as specified ratio // Add a short fragment that is as compressible as specified ratio
System.arraycopy(compressibleData(rnd, compressionRatio, 100), 0, System.arraycopy(compressibleData(rnd, compressionRatio, 100), 0,
data, i, 100); data, i, 100);
} }
} }
public int getNextPosition(int length) { public int getNextPosition(int length) {
if (position + length > data.length) { if (position + length > data.length) {
position = 0; position = 0;
assert (length < data.length); assert (length < data.length);
} }
int result = position; int result = position;
position += length; position += length;
return result; return result;
} }
private static byte[] compressibleData(Random random, private static byte[] compressibleData(Random random,
double compressionRatio, int length) { double compressionRatio, int length) {
int raw = (int) (length * compressionRatio); int raw = (int) (length * compressionRatio);
if (raw < 1) { if (raw < 1) {
raw = 1; raw = 1;
} }
byte[] rawData = generateRandomData(random, raw); byte[] rawData = generateRandomData(random, raw);
// Duplicate the random data until we have filled "length" bytes // Duplicate the random data until we have filled "length" bytes
byte[] dest = new byte[length]; byte[] dest = new byte[length];
for (int i = 0; i < length;) { for (int i = 0; i < length;) {
int chunkLength = Math.min(rawData.length, length - i); int chunkLength = Math.min(rawData.length, length - i);
System.arraycopy(rawData, 0, dest, i, chunkLength); System.arraycopy(rawData, 0, dest, i, chunkLength);
i += chunkLength; i += chunkLength;
} }
return dest; return dest;
} }
private static byte[] generateRandomData(Random random, int length) { private static byte[] generateRandomData(Random random, int length) {
byte[] rawData = new byte[length]; byte[] rawData = new byte[length];
for (int i = 0; i < rawData.length; i++) { for (int i = 0; i < rawData.length; i++) {
rawData[i] = (byte) random.nextInt(256); rawData[i] = (byte) random.nextInt(256);
} }
return rawData; return rawData;
} }
} }

View File

@ -1,179 +1,179 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyInputStreamTest.java // SnappyInputStreamTest.java
// Since: 2011/03/31 22:31:51 // Since: 2011/03/31 22:31:51
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.junit.Test; import org.junit.Test;
import org.xerial.util.FileResource; import org.xerial.util.FileResource;
import org.xerial.util.log.Logger; import org.xerial.util.log.Logger;
import scala.Array; import scala.Array;
public class SnappyInputStreamTest public class SnappyInputStreamTest
{ {
private static Logger _logger = Logger.getLogger(SnappyInputStreamTest.class); private static Logger _logger = Logger.getLogger(SnappyInputStreamTest.class);
public static byte[] readResourceFile(String fileName) throws IOException { public static byte[] readResourceFile(String fileName) throws IOException {
BufferedInputStream input = new BufferedInputStream(FileResource.find(SnappyOutputStreamTest.class, fileName) BufferedInputStream input = new BufferedInputStream(FileResource.find(SnappyOutputStreamTest.class, fileName)
.openStream()); .openStream());
assertNotNull(input); assertNotNull(input);
return readFully(input); return readFully(input);
} }
public static byte[] readFully(InputStream input) throws IOException { public static byte[] readFully(InputStream input) throws IOException {
try { try {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[4096]; byte[] buf = new byte[4096];
for (int readBytes = 0; (readBytes = input.read(buf)) != -1;) { for (int readBytes = 0; (readBytes = input.read(buf)) != -1;) {
out.write(buf, 0, readBytes); out.write(buf, 0, readBytes);
} }
out.flush(); out.flush();
return out.toByteArray(); return out.toByteArray();
} }
finally { finally {
input.close(); input.close();
} }
} }
public static byte[] byteWiseReadFully(InputStream input) throws IOException { public static byte[] byteWiseReadFully(InputStream input) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[4096]; byte[] buf = new byte[4096];
for (int readData = 0; (readData = input.read()) != -1;) { for (int readData = 0; (readData = input.read()) != -1;) {
out.write(readData); out.write(readData);
} }
out.flush(); out.flush();
return out.toByteArray(); return out.toByteArray();
} }
@Test @Test
public void read() throws Exception { public void read() throws Exception {
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream(); ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
SnappyOutputStream snappyOut = new SnappyOutputStream(compressedBuf); SnappyOutputStream snappyOut = new SnappyOutputStream(compressedBuf);
byte[] orig = readResourceFile("alice29.txt"); byte[] orig = readResourceFile("alice29.txt");
snappyOut.write(orig); snappyOut.write(orig);
snappyOut.close(); snappyOut.close();
byte[] compressed = compressedBuf.toByteArray(); byte[] compressed = compressedBuf.toByteArray();
_logger.debug("compressed size: " + compressed.length); _logger.debug("compressed size: " + compressed.length);
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed)); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed));
byte[] uncompressed = readFully(in); byte[] uncompressed = readFully(in);
assertEquals(orig.length, uncompressed.length); assertEquals(orig.length, uncompressed.length);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
@Test @Test
public void readBlockCompressedData() throws Exception { public void readBlockCompressedData() throws Exception {
byte[] orig = readResourceFile("alice29.txt"); byte[] orig = readResourceFile("alice29.txt");
byte[] compressed = Snappy.compress(orig); byte[] compressed = Snappy.compress(orig);
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed)); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed));
byte[] uncompressed = readFully(in); byte[] uncompressed = readFully(in);
assertEquals(orig.length, uncompressed.length); assertEquals(orig.length, uncompressed.length);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
@Test @Test
public void biteWiseRead() throws Exception { public void biteWiseRead() throws Exception {
byte[] orig = readResourceFile("testdata/calgary/paper6"); byte[] orig = readResourceFile("testdata/calgary/paper6");
byte[] compressed = Snappy.compress(orig); byte[] compressed = Snappy.compress(orig);
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed)); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed));
byte[] uncompressed = byteWiseReadFully(in); byte[] uncompressed = byteWiseReadFully(in);
assertEquals(orig.length, uncompressed.length); assertEquals(orig.length, uncompressed.length);
assertArrayEquals(orig, uncompressed); assertArrayEquals(orig, uncompressed);
} }
@Test @Test
public void available() throws Exception { public void available() throws Exception {
byte[] orig = readResourceFile("testdata/calgary/paper6"); byte[] orig = readResourceFile("testdata/calgary/paper6");
byte[] compressed = Snappy.compress(orig); byte[] compressed = Snappy.compress(orig);
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed)); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed));
byte[] buf = new byte[4]; byte[] buf = new byte[4];
for (int readBytes = 0; (readBytes = in.read(buf)) != -1;) { for (int readBytes = 0; (readBytes = in.read(buf)) != -1;) {
assertTrue(in.available() >= 0); assertTrue(in.available() >= 0);
} }
assertTrue(in.available() == 0); assertTrue(in.available() == 0);
in.close(); in.close();
} }
@Test @Test
public void emptyStream() throws Exception { public void emptyStream() throws Exception {
try { try {
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(new byte[0])); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(new byte[0]));
byte[] uncompressed = readFully(in); byte[] uncompressed = readFully(in);
assertEquals(0, uncompressed.length); assertEquals(0, uncompressed.length);
fail("should not reach here"); fail("should not reach here");
} }
catch(SnappyIOException e) { catch(SnappyIOException e) {
assertEquals(SnappyErrorCode.EMPTY_INPUT, e.getErrorCode()); assertEquals(SnappyErrorCode.EMPTY_INPUT, e.getErrorCode());
} }
} }
public static byte[] compressResource(String resourcePath) throws Exception { public static byte[] compressResource(String resourcePath) throws Exception {
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream(); ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
SnappyOutputStream snappyOut = new SnappyOutputStream(compressedBuf); SnappyOutputStream snappyOut = new SnappyOutputStream(compressedBuf);
byte[] orig = readResourceFile(resourcePath); byte[] orig = readResourceFile(resourcePath);
snappyOut.write(orig); snappyOut.write(orig);
snappyOut.close(); snappyOut.close();
return compressedBuf.toByteArray(); return compressedBuf.toByteArray();
} }
@Test @Test
public void chunkRead() throws Exception { public void chunkRead() throws Exception {
byte[] chunk1 = compressResource("alice29.txt"); byte[] chunk1 = compressResource("alice29.txt");
byte[] chunk2 = compressResource("testdata/calgary/paper6"); byte[] chunk2 = compressResource("testdata/calgary/paper6");
byte[] concatenated = new byte[chunk1.length + chunk2.length]; byte[] concatenated = new byte[chunk1.length + chunk2.length];
System.arraycopy(chunk1, 0, concatenated, 0, chunk1.length); System.arraycopy(chunk1, 0, concatenated, 0, chunk1.length);
System.arraycopy(chunk2, 0, concatenated, chunk1.length, chunk2.length); System.arraycopy(chunk2, 0, concatenated, chunk1.length, chunk2.length);
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(concatenated)); SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(concatenated));
byte[] uncompressed = readFully(in); byte[] uncompressed = readFully(in);
byte[] orig1 = readResourceFile("alice29.txt"); byte[] orig1 = readResourceFile("alice29.txt");
byte[] orig2 = readResourceFile("testdata/calgary/paper6"); byte[] orig2 = readResourceFile("testdata/calgary/paper6");
assertEquals(orig1.length + orig2.length, uncompressed.length); assertEquals(orig1.length + orig2.length, uncompressed.length);
byte[] uncompressed1 = new byte[orig1.length]; byte[] uncompressed1 = new byte[orig1.length];
byte[] uncompressed2 = new byte[orig2.length]; byte[] uncompressed2 = new byte[orig2.length];
System.arraycopy(uncompressed, 0, uncompressed1, 0, orig1.length); System.arraycopy(uncompressed, 0, uncompressed1, 0, orig1.length);
System.arraycopy(uncompressed, orig1.length, uncompressed2, 0, orig2.length); System.arraycopy(uncompressed, orig1.length, uncompressed2, 0, orig2.length);
assertArrayEquals(orig1, uncompressed1); assertArrayEquals(orig1, uncompressed1);
assertArrayEquals(orig2, uncompressed2); assertArrayEquals(orig2, uncompressed2);
} }
} }

View File

@ -1,125 +1,125 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// XerialJ // XerialJ
// //
// SnappyLoaderTest.java // SnappyLoaderTest.java
// Since: 2011/06/22 23:59:47 // Since: 2011/06/22 23:59:47
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import org.codehaus.plexus.classworlds.ClassWorld; import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.junit.Test; import org.junit.Test;
import org.xerial.util.FileResource; import org.xerial.util.FileResource;
import org.xerial.util.log.Logger; import org.xerial.util.log.Logger;
import java.io.*; import java.io.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
public class SnappyLoaderTest public class SnappyLoaderTest
{ {
private static Logger _logger = Logger.getLogger(SnappyLoaderTest.class); private static Logger _logger = Logger.getLogger(SnappyLoaderTest.class);
public static BufferedInputStream openByteStream(Class< ? > referenceClass, String resourceFileName) public static BufferedInputStream openByteStream(Class< ? > referenceClass, String resourceFileName)
throws IOException { throws IOException {
URL url = FileResource.find(referenceClass, resourceFileName); URL url = FileResource.find(referenceClass, resourceFileName);
if (url != null) { if (url != null) {
return new BufferedInputStream(url.openStream()); return new BufferedInputStream(url.openStream());
} }
else else
return null; return null;
} }
public static <T> String loadIntoString(Class<T> referenceClass, String path) throws IOException { public static <T> String loadIntoString(Class<T> referenceClass, String path) throws IOException {
BufferedInputStream in = openByteStream(referenceClass, path); BufferedInputStream in = openByteStream(referenceClass, path);
if (in == null) if (in == null)
throw new FileNotFoundException( throw new FileNotFoundException(
String.format("reference class:%s, path:%s", referenceClass.getName(), path)); String.format("reference class:%s, path:%s", referenceClass.getName(), path));
ByteArrayOutputStream buf = new ByteArrayOutputStream(); ByteArrayOutputStream buf = new ByteArrayOutputStream();
try { try {
byte[] tmp = new byte[4028]; byte[] tmp = new byte[4028];
for (int readBytes = 0; (readBytes = in.read(tmp)) != -1;) { for (int readBytes = 0; (readBytes = in.read(tmp)) != -1;) {
buf.write(tmp, 0, readBytes); buf.write(tmp, 0, readBytes);
} }
buf.flush(); buf.flush();
return buf.toString(); return buf.toString();
} }
finally { finally {
in.close(); in.close();
} }
} }
@Test @Test
public void loadSnappyByDiffentClassloadersInTheSameJVM() throws Exception { public void loadSnappyByDiffentClassloadersInTheSameJVM() throws Exception {
// Parent class loader cannot see Snappy.class // Parent class loader cannot see Snappy.class
ClassLoader parent = this.getClass().getClassLoader().getParent(); ClassLoader parent = this.getClass().getClassLoader().getParent();
ClassWorld cw = new ClassWorld(); ClassWorld cw = new ClassWorld();
ClassRealm P = cw.newRealm("P", parent); ClassRealm P = cw.newRealm("P", parent);
try { try {
P.loadClass("org.xerial.snappy.Snappy"); P.loadClass("org.xerial.snappy.Snappy");
fail("org.xerial.snappy.Snappy is found in the parent"); fail("org.xerial.snappy.Snappy is found in the parent");
} }
catch (ClassNotFoundException e) { catch (ClassNotFoundException e) {
// OK // OK
} }
// Prepare the child class loaders which can load Snappy.class // Prepare the child class loaders which can load Snappy.class
URL classPath = new File("target/classes").toURI().toURL(); URL classPath = new File("target/classes").toURI().toURL();
ClassRealm L1 = cw.newRealm("l1", URLClassLoader.newInstance(new URL[] { classPath }, parent)); ClassRealm L1 = cw.newRealm("l1", URLClassLoader.newInstance(new URL[] { classPath }, parent));
ClassRealm L2 = cw.newRealm("l2", URLClassLoader.newInstance(new URL[] { classPath }, parent)); ClassRealm L2 = cw.newRealm("l2", URLClassLoader.newInstance(new URL[] { classPath }, parent));
// Actually load Snappy.class in a child class loader // Actually load Snappy.class in a child class loader
Class< ? > S1 = L1.loadClass("org.xerial.snappy.Snappy"); Class< ? > S1 = L1.loadClass("org.xerial.snappy.Snappy");
Method m = S1.getMethod("compress", String.class); Method m = S1.getMethod("compress", String.class);
byte[] v = (byte[]) m.invoke(null, "hello world"); byte[] v = (byte[]) m.invoke(null, "hello world");
// Load Snappy.class from another child class loader // Load Snappy.class from another child class loader
Class< ? > S2 = L2.loadClass("org.xerial.snappy.Snappy"); Class< ? > S2 = L2.loadClass("org.xerial.snappy.Snappy");
Method m2 = S2.getMethod("compress", String.class); Method m2 = S2.getMethod("compress", String.class);
byte[] v2 = (byte[]) m2.invoke(null, "hello world"); byte[] v2 = (byte[]) m2.invoke(null, "hello world");
assertArrayEquals(v, v2); assertArrayEquals(v, v2);
} }
@Test @Test
public void load() throws Exception { public void load() throws Exception {
SnappyLoader.load(); SnappyLoader.load();
_logger.debug(Snappy.maxCompressedLength(1024)); _logger.debug(Snappy.maxCompressedLength(1024));
} }
@Test @Test
public void autoLoad() throws Exception { public void autoLoad() throws Exception {
_logger.debug(Snappy.maxCompressedLength(1024)); _logger.debug(Snappy.maxCompressedLength(1024));
} }
public static void main(String[] args) { public static void main(String[] args) {
// Test for loading native library specified in -Djava.library.path // Test for loading native library specified in -Djava.library.path
System.setProperty(SnappyLoader.KEY_SNAPPY_USE_SYSTEMLIB, "true"); System.setProperty(SnappyLoader.KEY_SNAPPY_USE_SYSTEMLIB, "true");
_logger.debug(Snappy.maxCompressedLength(1024)); _logger.debug(Snappy.maxCompressedLength(1024));
} }
} }

View File

@ -1,304 +1,304 @@
/*-------------------------------------------------------------------------- /*--------------------------------------------------------------------------
* Copyright 2011 Taro L. Saito * Copyright 2011 Taro L. Saito
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
//-------------------------------------- //--------------------------------------
// snappy-java Project // snappy-java Project
// //
// SnappyTest.java // SnappyTest.java
// Since: 2011/03/30 // Since: 2011/03/30
// //
// $URL$ // $URL$
// $Author$ // $Author$
//-------------------------------------- //--------------------------------------
package org.xerial.snappy; package org.xerial.snappy;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.xerial.util.log.Logger; import org.xerial.util.log.Logger;
public class SnappyTest public class SnappyTest
{ {
private static Logger _logger = Logger.getLogger(SnappyTest.class); private static Logger _logger = Logger.getLogger(SnappyTest.class);
@Test @Test
public void getVersion() throws Exception { public void getVersion() throws Exception {
String version = Snappy.getNativeLibraryVersion(); String version = Snappy.getNativeLibraryVersion();
_logger.debug("version: " + version); _logger.debug("version: " + version);
} }
@Test @Test
public void directBufferCheck() throws Exception { public void directBufferCheck() throws Exception {
try { try {
ByteBuffer src = ByteBuffer.allocate(1024); ByteBuffer src = ByteBuffer.allocate(1024);
src.put("hello world".getBytes()); src.put("hello world".getBytes());
src.flip(); src.flip();
ByteBuffer dest = ByteBuffer.allocate(1024); ByteBuffer dest = ByteBuffer.allocate(1024);
int maxCompressedLen = Snappy.compress(src, dest); int maxCompressedLen = Snappy.compress(src, dest);
} }
catch (SnappyError e) { catch (SnappyError e) {
Assert.assertTrue(e.errorCode == SnappyErrorCode.NOT_A_DIRECT_BUFFER); Assert.assertTrue(e.errorCode == SnappyErrorCode.NOT_A_DIRECT_BUFFER);
return; return;
} }
fail("shouldn't reach here"); fail("shouldn't reach here");
} }
@Test @Test
public void directBuffer() throws Exception { public void directBuffer() throws Exception {
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
s.append("Hello world!"); s.append("Hello world!");
} }
String origStr = s.toString(); String origStr = s.toString();
byte[] orig = origStr.getBytes(); byte[] orig = origStr.getBytes();
int BUFFER_SIZE = orig.length; int BUFFER_SIZE = orig.length;
ByteBuffer src = ByteBuffer.allocateDirect(orig.length); ByteBuffer src = ByteBuffer.allocateDirect(orig.length);
src.put(orig); src.put(orig);
src.flip(); src.flip();
_logger.debug("input size: " + src.remaining()); _logger.debug("input size: " + src.remaining());
int maxCompressedLen = Snappy.maxCompressedLength(src.remaining()); int maxCompressedLen = Snappy.maxCompressedLength(src.remaining());
_logger.debug("max compressed length:" + maxCompressedLen); _logger.debug("max compressed length:" + maxCompressedLen);
ByteBuffer compressed = ByteBuffer.allocateDirect(maxCompressedLen); ByteBuffer compressed = ByteBuffer.allocateDirect(maxCompressedLen);
int compressedSize = Snappy.compress(src, compressed); int compressedSize = Snappy.compress(src, compressed);
_logger.debug("compressed length: " + compressedSize); _logger.debug("compressed length: " + compressedSize);
assertTrue(Snappy.isValidCompressedBuffer(compressed)); assertTrue(Snappy.isValidCompressedBuffer(compressed));
assertEquals(0, src.position()); assertEquals(0, src.position());
assertEquals(orig.length, src.remaining()); assertEquals(orig.length, src.remaining());
assertEquals(orig.length, src.limit()); assertEquals(orig.length, src.limit());
assertEquals(0, compressed.position()); assertEquals(0, compressed.position());
assertEquals(compressedSize, compressed.limit()); assertEquals(compressedSize, compressed.limit());
assertEquals(compressedSize, compressed.remaining()); assertEquals(compressedSize, compressed.remaining());
int uncompressedLen = Snappy.uncompressedLength(compressed); int uncompressedLen = Snappy.uncompressedLength(compressed);
_logger.debug("uncompressed length: " + uncompressedLen); _logger.debug("uncompressed length: " + uncompressedLen);
ByteBuffer extract = ByteBuffer.allocateDirect(uncompressedLen); ByteBuffer extract = ByteBuffer.allocateDirect(uncompressedLen);
int uncompressedLen2 = Snappy.uncompress(compressed, extract); int uncompressedLen2 = Snappy.uncompress(compressed, extract);
assertEquals(uncompressedLen, uncompressedLen2); assertEquals(uncompressedLen, uncompressedLen2);
assertEquals(uncompressedLen, extract.remaining()); assertEquals(uncompressedLen, extract.remaining());
byte[] b = new byte[uncompressedLen]; byte[] b = new byte[uncompressedLen];
extract.get(b); extract.get(b);
String decompressed = new String(b); String decompressed = new String(b);
_logger.debug(decompressed); _logger.debug(decompressed);
assertEquals(origStr, decompressed); assertEquals(origStr, decompressed);
} }
@Test @Test
public void bufferOffset() throws Exception { public void bufferOffset() throws Exception {
String m = "ACCAGGGGGGGGGGGGGGGGGGGGATAGATATTTCCCGAGATATTTTATATAAAAAAA"; String m = "ACCAGGGGGGGGGGGGGGGGGGGGATAGATATTTCCCGAGATATTTTATATAAAAAAA";
byte[] orig = m.getBytes(); byte[] orig = m.getBytes();
final int offset = 100; final int offset = 100;
ByteBuffer input = ByteBuffer.allocateDirect(orig.length + offset); ByteBuffer input = ByteBuffer.allocateDirect(orig.length + offset);
input.position(offset); input.position(offset);
input.put(orig); input.put(orig);
input.flip(); input.flip();
input.position(offset); input.position(offset);
// compress // compress
int maxCompressedLength = Snappy.maxCompressedLength(input.remaining()); int maxCompressedLength = Snappy.maxCompressedLength(input.remaining());
final int offset2 = 40; final int offset2 = 40;
ByteBuffer compressed = ByteBuffer.allocateDirect(maxCompressedLength + offset2); ByteBuffer compressed = ByteBuffer.allocateDirect(maxCompressedLength + offset2);
compressed.position(offset2); compressed.position(offset2);
Snappy.compress(input, compressed); Snappy.compress(input, compressed);
assertTrue(Snappy.isValidCompressedBuffer(compressed)); assertTrue(Snappy.isValidCompressedBuffer(compressed));
// uncompress // uncompress
final int offset3 = 80; final int offset3 = 80;
int uncompressedLength = Snappy.uncompressedLength(compressed); int uncompressedLength = Snappy.uncompressedLength(compressed);
ByteBuffer uncompressed = ByteBuffer.allocateDirect(uncompressedLength + offset3); ByteBuffer uncompressed = ByteBuffer.allocateDirect(uncompressedLength + offset3);
uncompressed.position(offset3); uncompressed.position(offset3);
Snappy.uncompress(compressed, uncompressed); Snappy.uncompress(compressed, uncompressed);
assertEquals(offset3, uncompressed.position()); assertEquals(offset3, uncompressed.position());
assertEquals(offset3 + uncompressedLength, uncompressed.limit()); assertEquals(offset3 + uncompressedLength, uncompressed.limit());
assertEquals(uncompressedLength, uncompressed.remaining()); assertEquals(uncompressedLength, uncompressed.remaining());
// extract string // extract string
byte[] recovered = new byte[uncompressedLength]; byte[] recovered = new byte[uncompressedLength];
uncompressed.get(recovered); uncompressed.get(recovered);
String m2 = new String(recovered); String m2 = new String(recovered);
assertEquals(m, m2); assertEquals(m, m2);
} }
@Test @Test
public void byteArrayCompress() throws Exception { public void byteArrayCompress() throws Exception {
String m = "ACCAGGGGGGGGGGGGGGGGGGGGATAGATATTTCCCGAGATATTTTATATAAAAAAA"; String m = "ACCAGGGGGGGGGGGGGGGGGGGGATAGATATTTCCCGAGATATTTTATATAAAAAAA";
byte[] input = m.getBytes(); byte[] input = m.getBytes();
byte[] output = new byte[Snappy.maxCompressedLength(input.length)]; byte[] output = new byte[Snappy.maxCompressedLength(input.length)];
int compressedSize = Snappy.compress(input, 0, input.length, output, 0); int compressedSize = Snappy.compress(input, 0, input.length, output, 0);
byte[] uncompressed = new byte[input.length]; byte[] uncompressed = new byte[input.length];
assertTrue(Snappy.isValidCompressedBuffer(output, 0, compressedSize)); assertTrue(Snappy.isValidCompressedBuffer(output, 0, compressedSize));
int uncompressedSize = Snappy.uncompress(output, 0, compressedSize, uncompressed, 0); int uncompressedSize = Snappy.uncompress(output, 0, compressedSize, uncompressed, 0);
String m2 = new String(uncompressed); String m2 = new String(uncompressed);
assertEquals(m, m2); assertEquals(m, m2);
} }
@Test @Test
public void rangeCheck() throws Exception { public void rangeCheck() throws Exception {
String m = "ACCAGGGGGGGGGGGGGGGGGGGGATAGATATTTCCCGAGATATTTTATATAAAAAAA"; String m = "ACCAGGGGGGGGGGGGGGGGGGGGATAGATATTTCCCGAGATATTTTATATAAAAAAA";
byte[] input = m.getBytes(); byte[] input = m.getBytes();
byte[] output = new byte[Snappy.maxCompressedLength(input.length)]; byte[] output = new byte[Snappy.maxCompressedLength(input.length)];
int compressedSize = Snappy.compress(input, 0, input.length, output, 0); int compressedSize = Snappy.compress(input, 0, input.length, output, 0);
assertTrue(Snappy.isValidCompressedBuffer(output, 0, compressedSize)); assertTrue(Snappy.isValidCompressedBuffer(output, 0, compressedSize));
// Intentionally set an invalid range // Intentionally set an invalid range
assertFalse(Snappy.isValidCompressedBuffer(output, 0, compressedSize + 1)); assertFalse(Snappy.isValidCompressedBuffer(output, 0, compressedSize + 1));
assertFalse(Snappy.isValidCompressedBuffer(output, 1, compressedSize)); assertFalse(Snappy.isValidCompressedBuffer(output, 1, compressedSize));
// Test the ByteBuffer API // Test the ByteBuffer API
ByteBuffer bin = ByteBuffer.allocateDirect(input.length); ByteBuffer bin = ByteBuffer.allocateDirect(input.length);
bin.put(input); bin.put(input);
bin.flip(); bin.flip();
ByteBuffer bout = ByteBuffer.allocateDirect(Snappy.maxCompressedLength(bin.remaining())); ByteBuffer bout = ByteBuffer.allocateDirect(Snappy.maxCompressedLength(bin.remaining()));
int compressedSize2 = Snappy.compress(bin, bout); int compressedSize2 = Snappy.compress(bin, bout);
assertEquals(compressedSize, compressedSize2); assertEquals(compressedSize, compressedSize2);
assertTrue(Snappy.isValidCompressedBuffer(bout)); assertTrue(Snappy.isValidCompressedBuffer(bout));
// Intentionally set an invalid range // Intentionally set an invalid range
bout.limit(bout.limit() + 1); bout.limit(bout.limit() + 1);
assertFalse(Snappy.isValidCompressedBuffer(bout)); assertFalse(Snappy.isValidCompressedBuffer(bout));
bout.limit(bout.limit() - 1); bout.limit(bout.limit() - 1);
bout.position(1); bout.position(1);
assertFalse(Snappy.isValidCompressedBuffer(bout)); assertFalse(Snappy.isValidCompressedBuffer(bout));
} }
@Test @Test
public void highLevelAPI() throws Exception { public void highLevelAPI() throws Exception {
String m = "Hello! 01234 ACGDSFSDFJ World. FDSDF02394234 fdsfda03924"; String m = "Hello! 01234 ACGDSFSDFJ World. FDSDF02394234 fdsfda03924";
byte[] input = m.getBytes(); byte[] input = m.getBytes();
byte[] output = Snappy.compress(input); byte[] output = Snappy.compress(input);
byte[] uncompressed = Snappy.uncompress(output); byte[] uncompressed = Snappy.uncompress(output);
String m2 = new String(uncompressed); String m2 = new String(uncompressed);
assertEquals(m, m2); assertEquals(m, m2);
} }
@Test @Test
public void lowLevelAPI() throws Exception { public void lowLevelAPI() throws Exception {
String m = "Hello! 01234 ACGDSFSDFJ World. FDSDF02394234 fdsfda03924"; String m = "Hello! 01234 ACGDSFSDFJ World. FDSDF02394234 fdsfda03924";
byte[] input = m.getBytes(); byte[] input = m.getBytes();
byte[] output = Snappy.rawCompress(input, input.length); byte[] output = Snappy.rawCompress(input, input.length);
byte[] uncompressed = Snappy.uncompress(output); byte[] uncompressed = Snappy.uncompress(output);
String m2 = new String(uncompressed); String m2 = new String(uncompressed);
assertEquals(m, m2); assertEquals(m, m2);
} }
@Test @Test
public void simpleUsage() throws Exception { public void simpleUsage() throws Exception {
String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper" String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper"
+ " for using Snappy from Google (written in C++), a fast compresser/decompresser."; + " for using Snappy from Google (written in C++), a fast compresser/decompresser.";
byte[] compressed = Snappy.compress(input.getBytes("UTF-8")); byte[] compressed = Snappy.compress(input.getBytes("UTF-8"));
byte[] uncompressed = Snappy.uncompress(compressed); byte[] uncompressed = Snappy.uncompress(compressed);
String result = new String(uncompressed, "UTF-8"); String result = new String(uncompressed, "UTF-8");
_logger.debug(result); _logger.debug(result);
} }
@Test @Test
public void floatArray() throws Exception { public void floatArray() throws Exception {
float[] data = new float[] { 1.0f, -0.3f, 1.3f, 234.4f, 34 }; float[] data = new float[] { 1.0f, -0.3f, 1.3f, 234.4f, 34 };
byte[] compressed = Snappy.compress(data); byte[] compressed = Snappy.compress(data);
float[] result = Snappy.uncompressFloatArray(compressed); float[] result = Snappy.uncompressFloatArray(compressed);
assertArrayEquals(data, result, 0.0f); assertArrayEquals(data, result, 0.0f);
} }
@Test @Test
public void doubleArray() throws Exception { public void doubleArray() throws Exception {
double[] data = new double[] { 1.0, -0.3, 1.3, 234.4, 34 }; double[] data = new double[] { 1.0, -0.3, 1.3, 234.4, 34 };
byte[] compressed = Snappy.compress(data); byte[] compressed = Snappy.compress(data);
double[] result = Snappy.uncompressDoubleArray(compressed); double[] result = Snappy.uncompressDoubleArray(compressed);
assertArrayEquals(data, result, 0.0f); assertArrayEquals(data, result, 0.0f);
} }
@Test @Test
public void longArray() throws Exception { public void longArray() throws Exception {
long[] data = new long[] { 2, 3, 15, 4234, 43251531412342342L, 23423422342L }; long[] data = new long[] { 2, 3, 15, 4234, 43251531412342342L, 23423422342L };
byte[] compressed = Snappy.compress(data); byte[] compressed = Snappy.compress(data);
long[] result = Snappy.uncompressLongArray(compressed); long[] result = Snappy.uncompressLongArray(compressed);
assertArrayEquals(data, result); assertArrayEquals(data, result);
} }
@Test @Test
public void shortArray() throws Exception { public void shortArray() throws Exception {
short[] data = new short[] { 432, -32267, 1, 3, 34, 43, 34, Short.MAX_VALUE, -1 }; short[] data = new short[] { 432, -32267, 1, 3, 34, 43, 34, Short.MAX_VALUE, -1 };
byte[] compressed = Snappy.compress(data); byte[] compressed = Snappy.compress(data);
short[] result = Snappy.uncompressShortArray(compressed); short[] result = Snappy.uncompressShortArray(compressed);
assertArrayEquals(data, result); assertArrayEquals(data, result);
} }
@Test @Test
public void intArray() throws Exception { public void intArray() throws Exception {
int[] data = new int[] { 432, -32267, 1, 3, 34, 43, 34, Short.MAX_VALUE, -1, Integer.MAX_VALUE, 3424, 43 }; int[] data = new int[] { 432, -32267, 1, 3, 34, 43, 34, Short.MAX_VALUE, -1, Integer.MAX_VALUE, 3424, 43 };
byte[] compressed = Snappy.compress(data); byte[] compressed = Snappy.compress(data);
int[] result = Snappy.uncompressIntArray(compressed); int[] result = Snappy.uncompressIntArray(compressed);
assertArrayEquals(data, result); assertArrayEquals(data, result);
} }
@Test @Test
public void charArray() throws Exception { public void charArray() throws Exception {
char[] data = new char[] { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' }; char[] data = new char[] { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' };
byte[] compressed = Snappy.compress(data); byte[] compressed = Snappy.compress(data);
char[] result = Snappy.uncompressCharArray(compressed); char[] result = Snappy.uncompressCharArray(compressed);
assertArrayEquals(data, result); assertArrayEquals(data, result);
} }
@Test @Test
public void string() throws Exception { public void string() throws Exception {
String s = "Hello Snappy! Snappy! Snappy!"; String s = "Hello Snappy! Snappy! Snappy!";
byte[] compressed = Snappy.compress(s); byte[] compressed = Snappy.compress(s);
String uncompressedString = Snappy.uncompressString(compressed); String uncompressedString = Snappy.uncompressString(compressed);
assertEquals(s, uncompressedString); assertEquals(s, uncompressedString);
} }
@Test @Test
public void isValidCompressedData() throws Exception { public void isValidCompressedData() throws Exception {
byte[] b = new byte[] { (byte) 91, (byte) 34, (byte) 80, (byte) 73, (byte) 34, (byte) 93 }; byte[] b = new byte[] { (byte) 91, (byte) 34, (byte) 80, (byte) 73, (byte) 34, (byte) 93 };
assertFalse(Snappy.isValidCompressedBuffer(b)); assertFalse(Snappy.isValidCompressedBuffer(b));
try { try {
byte[] uncompressed = Snappy.uncompress(b); byte[] uncompressed = Snappy.uncompress(b);
fail("cannot reach here since the input is invalid data"); fail("cannot reach here since the input is invalid data");
} }
catch (IOException e) { catch (IOException e) {
_logger.debug(e); _logger.debug(e);
} }
} }
} }