Author: mturk Date: Mon Aug 15 07:48:54 2011 New Revision: 1157733 URL: http://svn.apache.org/viewvc?rev=1157733&view=rev Log: Add initial bzip2 api
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Bzip2.java (with props) commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Local.java (with props) commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/LocalStrings.properties (with props) commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestBzip2.java (with props) Modified: commons/sandbox/runtime/trunk/src/main/native/shared/bzip2.c commons/sandbox/runtime/trunk/src/main/native/shared/error.c Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Bzip2.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Bzip2.java?rev=1157733&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Bzip2.java (added) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Bzip2.java Mon Aug 15 07:48:54 2011 @@ -0,0 +1,603 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.runtime.util.bzip2; + +import java.io.Closeable; +import java.io.IOException; +import java.nio.ByteBuffer; +import org.apache.commons.runtime.InvalidArgumentException; +import org.apache.commons.runtime.InvalidDataException; +import org.apache.commons.runtime.InvalidRangeException; +import org.apache.commons.runtime.OverflowException; +import org.apache.commons.runtime.Pointer; +import org.apache.commons.runtime.util.StringManager; + +/** + * Primitive array helper routines. + * + * @author Mladen Turk + * @since Runtime 1.0 + */ +public final class Bzip2 implements Closeable +{ + /** + * Bzip2 library version string. + */ + public static final String VERSION; + + /** + * Indicates that the stream is in the {@code running} state. + */ + public static final int BZ_RUN = 0; + /** + * Indicates that the stream is in the {@code flushing} state. + */ + public static final int BZ_FLUSH = 1; + /** + * Indicates that the stream is in the {@code finishing} state. + */ + public static final int BZ_FINISH = 2; + + /** + * The requested action was completed successfully. + */ + public static final int BZ_OK = 0; + /** + * The {@code run} sequence compleced successfully. + */ + public static final int BZ_RUN_OK = 1; + /** + * The {@code flush} sequence compleced successfully. + */ + public static final int BZ_FLUSH_OK = 2; + /** + * The {@code finis} sequence compleced successfully. + */ + public static final int BZ_FINISH_OK = 3; + /** + * Compression of data was completed, or the logical stream end was + * detected during decompression. + */ + public static final int BZ_STREAM_END = 4; + + + + /** + * Pointer to the native bz_stream structure. + */ + private final byte[] stream; + + private static native String sver0(); + private static native int size0(); + private static native void init0(byte[] stream, int bufferSize); + private static native int end0(byte[] stream); + private static native int bzinit0(byte[] stream, int blockSize100k, int workFactor); + private static native int bzinit1(byte[] stream, boolean small); + + private static native int nextinp0(byte[] stream, byte[] buf, int off, int len); + private static native int nextinp1(byte[] stream, ByteBuffer buf, int off, int len); + private static native int nextinp2(byte[] stream, long buf, long off, long len); + private static native int nextout0(byte[] stream, byte[] buf, int off, int len); + private static native int nextout1(byte[] stream, ByteBuffer buf, int off, int len); + private static native int nextout2(byte[] stream, long buf, long off, long len); + + private static native void nextinp3(byte[] stream); + private static native void nextout3(byte[] stream); + + private static final int DEFAULT_BUFFER_SIZE = 4096; + private static final int DEFAULT_WORK_FACTOR = 30; + + private static final int SIZEOF_BZ_STREAM; + + /* Error codes */ + private static final int BZ_SEQUENCE_ERROR = -1; + private static final int BZ_PARAM_ERROR = -2; + private static final int BZ_MEM_ERROR = -3; + private static final int BZ_DATA_ERROR = -4; + private static final int BZ_DATA_ERROR_MAGIC = -5; + private static final int BZ_IO_ERROR = -6; + private static final int BZ_UNEXPECTED_EOF = -7; + private static final int BZ_OUTBUFF_FULL = -8; + private static final int BZ_CONFIG_ERROR = -9; + + static { + VERSION = sver0(); + SIZEOF_BZ_STREAM = size0(); + } + + private static native int compress0(byte[] src, int spos, + byte[] dst, int dpos, int dlen, + int len, int blockSize100k, + int workFactor) + throws InvalidArgumentException, + OverflowException; + private static native int compress1(ByteBuffer src, int spos, + ByteBuffer dst, int dpos, int dlen, + int len, int blockSize100k, + int workFactor) + throws InvalidArgumentException, + OverflowException; + private static native long compress2(long src, long dst, long dlen, + long len, int blockSize100k, + int workFactor) + throws InvalidArgumentException, + InvalidRangeException, + OverflowException; + private static native int decompress0(byte[] src, int spos, + byte[] dst, int dpos, int dlen, + int len, boolean small) + throws InvalidArgumentException, + InvalidDataException, + OverflowException; + private static native int decompress1(ByteBuffer src, int spos, + ByteBuffer dst, int dpos, int dlen, + int len, boolean small) + throws InvalidArgumentException, + InvalidDataException, + OverflowException; + private static native long decompress2(long src,long dst, long dlen, + long len, boolean small) + throws InvalidArgumentException, + InvalidDataException, + OverflowException; + + + /** + * Compress data buffer. + * <p> + * Compression in this manner is a one-shot event, done with a single call + * to this function. The resulting compressed data is a complete bzip2 + * format data stream. There is no mechanism for making additional calls + * to provide extra input data. If you want that kind of mechanism, use + * the low-level interface. + * </p> + * + * @param src the source data buffer. + * @param srcPos starting position in the source buffer. + * @param dest destination buffer that will hold compressed data. + * @param destPos stating position in the destination buffer. + * @param length number of bytes to compress. + * @param blockSize100k the block size to be used for compression. It + * should be a value between {@code 1} and {@code 9} inclusive. + * @param workFactor controls how the compression phase behaves when + * presented with worst case. Allowable values range from + * {@code 0} to {@code 250} inclusive. + * @return the size of the compressed data. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws OverflowException if the size of the compressed data exceeds + * the size of the destination buffer. + */ + public static int buffToBuffCompress(byte[] src, + int srcPos, + byte[] dest, + int destPos, + int length, + int blockSize100k, + int workFactor) + throws InvalidArgumentException, + OverflowException + { + /* TODO: Check for param validity */ + return compress0(src, srcPos, dest, destPos, dest.length - destPos, + length, blockSize100k, workFactor); + } + + /** + * Compress data buffer. + * <p> + * Compression in this manner is a one-shot event, done with a single call + * to this function. The resulting compressed data is a complete bzip2 + * format data stream. There is no mechanism for making additional calls + * to provide extra input data. If you want that kind of mechanism, use + * the low-level interface. + * </p> + * + * @param src the source data buffer. + * @param dest destination buffer that will hold compressed data. + * @param blockSize100k the block size to be used for compression. It + * should be a value between {@code 1} and {@code 9} inclusive. + * @param workFactor controls how the compression phase behaves when + * presented with worst case. Allowable values range from + * {@code 0} to {@code 250} inclusive. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws OverflowException if the size of the compressed data exceeds + * the size of the destination buffer. + */ + public static void buffToBuffCompress(ByteBuffer src, + ByteBuffer dest, + int blockSize100k, + int workFactor) + throws InvalidArgumentException, + OverflowException + { + /* TODO: Check for param validity */ + int s = compress1(src, src.position(), dest, dest.position(), + dest.limit(), src.limit(), + blockSize100k, workFactor); + dest.position(s); + } + + /** + * Compress data buffer. + * <p> + * Compression in this manner is a one-shot event, done with a single call + * to this function. The resulting compressed data is a complete bzip2 + * format data stream. There is no mechanism for making additional calls + * to provide extra input data. If you want that kind of mechanism, use + * the low-level interface. + * </p> + * + * @param src the source data buffer. + * @param srcPos starting position in the source buffer. + * @param dest destination buffer that will hold compressed data. + * @param destPos stating position in the destination buffer. + * @param length number of bytes to compress. + * @param blockSize100k the block size to be used for compression. It + * should be a value between {@code 1} and {@code 9} inclusive. + * @param workFactor controls how the compression phase behaves when + * presented with worst case. Allowable values range from + * {@code 0} to {@code 250} inclusive. + * @return the size of the compressed data. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws OverflowException if the size of the compressed data exceeds + * the size of the destination buffer. + */ + public static long buffToBuffCompress(Pointer src, + long srcPos, + Pointer dst, + long dstPos, + long length, + int blockSize100k, + int workFactor) + throws InvalidArgumentException, + InvalidRangeException, + OverflowException + { + long srca = src.address() + srcPos; + long dsta = dst.address() + dstPos; + /* TODO: Check for param validity */ + return compress2(srca, dsta, dst.sizeof() - dstPos, length, + blockSize100k, workFactor); + } + + /** + * Decompress data buffer. + * <p> + * Because the compression ratio of the compressed data cannot be known + * in advance, there is no easy way to guarantee that the output buffer + * will be big enough. You may of course make arrangements in your code + * to record the size of the uncompressed data, but such a mechanism is + * beyond the scope of this library. + * </p> + * + * @param src the source data buffer. + * @param srcPos starting position in the source buffer. + * @param dest destination buffer that will hold uncompressed data. + * @param destPos stating position in the destination buffer. + * @param length number of bytes to uncompress. + * @param small if {@code true} the library will use an alternative + * decompression algorithm which uses less memory but at the cost + * of decompressing more slowly. + * @return the size of the uncompressed data. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws InvalidDataException if provided data is corrupt or contains + * invalid bzip2 data. + * @throws OverflowException if the size of the uncompressed data exceeds + * the size of the destination buffer. + */ + public static int buffToBuffDecompress(byte[] src, + int srcPos, + byte[] dest, + int destPos, + int length, + boolean small) + throws InvalidArgumentException, + InvalidDataException, + OverflowException + { + /* TODO: Check for param validity */ + return decompress0(src, srcPos, dest, destPos, dest.length - destPos, + length, small); + } + + /** + * Decompress data buffer. + * <p> + * Because the compression ratio of the compressed data cannot be known + * in advance, there is no easy way to guarantee that the output buffer + * will be big enough. You may of course make arrangements in your code + * to record the size of the uncompressed data, but such a mechanism is + * beyond the scope of this library. + * </p> + * + * @param src the source data buffer. + * @param dest destination buffer that will hold uncompressed data. + * @param small if {@code true} the library will use an alternative + * decompression algorithm which uses less memory but at the cost + * of decompressing more slowly. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws InvalidDataException if provided data is corrupt or contains + * invalid bzip2 data. + * @throws OverflowException if the size of the uncompressed data exceeds + * the size of the destination buffer. + */ + public static void buffToBuffDecompress(ByteBuffer src, + ByteBuffer dest, + boolean small) + throws InvalidArgumentException, + InvalidDataException, + OverflowException + { + /* TODO: Check for param validity */ + int p = decompress1(src, src.position(), dest, dest.position(), + dest.limit(), src.limit(), small); + dest.position(p); + } + + /** + * Decompress data buffer. + * <p> + * Because the compression ratio of the compressed data cannot be known + * in advance, there is no easy way to guarantee that the output buffer + * will be big enough. You may of course make arrangements in your code + * to record the size of the uncompressed data, but such a mechanism is + * beyond the scope of this library. + * </p> + * + * @param src the source data buffer. + * @param srcPos starting position in the source buffer. + * @param dst destination buffer that will hold uncompressed data. + * @param dstPos stating position in the destination buffer. + * @param length number of bytes to uncompress. + * @param small if {@code true} the library will use an alternative + * decompression algorithm which uses less memory but at the cost + * of decompressing more slowly. + * @return the size of the uncompressed data. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws InvalidDataException if provided data is corrupt or contains + * invalid bzip2 data. + * @throws OverflowException if the size of the uncompressed data exceeds + * the size of the destination buffer. + */ + public static long buffToBuffDecompress(Pointer src, + long srcPos, + Pointer dst, + long dstPos, + long length, + boolean small) + throws InvalidArgumentException, + InvalidDataException, + OverflowException + { + long srca = src.address() + srcPos; + long dsta = dst.address() + dstPos; + /* TODO: Check for param validity */ + return decompress2(srca, dsta, dst.sizeof() - dstPos, length, small); + } + + /** + * Initialize this Bzip2 instance for compression. + * + * @param blockSize100k the block size to be used for compression. It + * should be a value between {@code 1} and {@code 9} inclusive. + * @param workFactor controls how the compression phase behaves when + * presented with worst case. Allowable values range from + * {@code 0} to {@code 250} inclusive. + * @return the size of the uncompressed data. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws OutOfMemoryError if there was not enough memory. + */ + public void compressInit(int blockSize100k, int workFactor) + throws InvalidArgumentException, + OutOfMemoryError + { + if (blockSize100k < 1) + blockSize100k = 1; + if (blockSize100k > 9) + blockSize100k = 9; + int rc = bzinit0(stream, blockSize100k, workFactor); + if (rc != BZ_OK) { + if (rc == BZ_MEM_ERROR) + throw new OutOfMemoryError(); + else + throw new InvalidArgumentException(); + } + + } + + /** + * Initialize this Bzip2 instance for decompression. + * + * @param small if {@code true} the library will use an alternative + * decompression algorithm which uses less memory but at the cost + * of decompressing more slowly. + * @return the size of the uncompressed data. + * + * @throws InvalidArgumentException if any of the argumets is invalid. + * @throws OutOfMemoryError if there was not enough memory. + */ + public void decompressInit(boolean small) + throws InvalidArgumentException, + OutOfMemoryError + { + int rc = bzinit1(stream, small); + if (rc != BZ_OK) { + if (rc == BZ_MEM_ERROR) + throw new OutOfMemoryError(); + else + throw new InvalidArgumentException(); + } + + } + + /** + * Create Bzip2 instance + */ + public Bzip2() + { + stream = new byte[SIZEOF_BZ_STREAM + DEFAULT_BUFFER_SIZE]; + init0(stream, DEFAULT_BUFFER_SIZE); + } + + /** + * Create Bzip2 instance + * + * @param bufferSize internal buffer size. + */ + public Bzip2(int bufferSize) + { + stream = new byte[SIZEOF_BZ_STREAM + bufferSize]; + init0(stream, bufferSize); + } + + /** + * Create compressor Bzip2 instance + * @param blockSize100k the block size to be used for compression. It + * should be a value between {@code 1} and {@code 9} inclusive. + * @param workFactor controls how the compression phase behaves when + * presented with worst case. Allowable values range from + * {@code 0} to {@code 250} inclusive. + * @param bufferSize internal buffer size. + */ + public Bzip2(int blockSize100k, int workFactor, int bufferSize) + { + stream = new byte[SIZEOF_BZ_STREAM + bufferSize]; + init0(stream, bufferSize); + if (workFactor < 0 || workFactor > 250) + workFactor = DEFAULT_WORK_FACTOR; + compressInit(blockSize100k, workFactor); + } + + /** + * Create compressor Bzip2 instance + * @param blockSize100k the block size to be used for compression. It + * should be a value between {@code 1} and {@code 9} inclusive. + * @param workFactor controls how the compression phase behaves when + * presented with worst case. Allowable values range from + * {@code 0} to {@code 250} inclusive. + */ + public Bzip2(int blockSize100k, int workFactor) + { + stream = new byte[SIZEOF_BZ_STREAM + DEFAULT_BUFFER_SIZE]; + init0(stream, DEFAULT_BUFFER_SIZE); + compressInit(blockSize100k, workFactor); + } + + /** + * Create decompressor Bzip2 instance + * + * @param small if {@code true} the library will use an alternative + * decompression algorithm which uses less memory but at the cost + * of decompressing more slowly. + * @param bufferSize internal buffer size. + */ + public Bzip2(boolean small, int bufferSize) + { + stream = new byte[SIZEOF_BZ_STREAM + bufferSize]; + init0(stream, bufferSize); + decompressInit(small); + } + + /** + * Create decompressor Bzip2 instance + * + * @param small if {@code true} the library will use an alternative + * decompression algorithm which uses less memory but at the cost + * of decompressing more slowly. + */ + public Bzip2(boolean small) + { + stream = new byte[SIZEOF_BZ_STREAM + DEFAULT_BUFFER_SIZE]; + init0(stream, DEFAULT_BUFFER_SIZE); + decompressInit(small); + } + + /** + * Releases all memory associated with this stream. + * <p> + * Note that {@code Object.finalize()} method will call + * this function. However explicit call to {@code close()} + * allows better memory management. + * </p> + * @see java.io.Closeable#close() + * @throws IOException if an I/O error occurs. + */ + public void close() + throws IOException + { + int rc = end0(stream); + if (rc != BZ_OK) { + /* TODO: Use descriptions from localstrings + */ + throw new IOException(); + } + } + + /** + * Called by the garbage collector when the object is destroyed. + * The class will free internal resources allocated by the + * Operating system only if there are no additional references + * to this object. + * @see Object#finalize() + * @throws Throwable the {@code Exception} raised by this method. + */ + @Override + protected final void finalize() + throws Throwable + { + end0(stream); + } + + public void setNextIn(byte[] buff, int off, int len) + throws InvalidArgumentException + { + if (buff == null || len < 1) + throw new InvalidArgumentException(); + int rc = nextinp0(stream, buff, off, len); + if (rc != BZ_OK) + throw new InvalidArgumentException(); + } + + public void setNextIn(ByteBuffer buff) + throws InvalidArgumentException + { + if (buff == null || buff.capacity() < 1) + throw new InvalidArgumentException(); + int rc = nextinp1(stream, buff, buff.position(), buff.limit()); + if (rc != BZ_OK) + throw new InvalidArgumentException(); + } + + public void setNextIn(Pointer buff, long off, long len) + throws InvalidArgumentException + { + if (buff == null || len < 1L) + throw new InvalidArgumentException(); + int rc = nextinp2(stream, buff.address(), off, len); + if (rc != BZ_OK) + throw new InvalidArgumentException(); + } + +} + Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Bzip2.java ------------------------------------------------------------------------------ svn:eol-style = native Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Local.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Local.java?rev=1157733&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Local.java (added) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Local.java Mon Aug 15 07:48:54 2011 @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.apache.commons.runtime.util.bzip2; +import org.apache.commons.runtime.util.StringManager; + +/** Util package private constants + */ +class Local +{ + + public static final String Package = "org.apache.commons.runtime.util.bzip2"; + public static final StringManager sm; + + static { + sm = StringManager.getManager(Package); + } +} + Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/Local.java ------------------------------------------------------------------------------ svn:eol-style = native Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/LocalStrings.properties URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/LocalStrings.properties?rev=1157733&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/LocalStrings.properties (added) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/LocalStrings.properties Mon Aug 15 07:48:54 2011 @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +BZ_PARAM_ERROR=Invalid parameter +BZ_DATA_ERROR=Data integrity error is detected in the compressed stream +BZ_DATA_ERROR_MAGIC=Compressed stream doesn't begin with the right magic bytes +BZ_SEQUENCE_ERROR=Invalid library call sequence + Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/bzip2/LocalStrings.properties ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/sandbox/runtime/trunk/src/main/native/shared/bzip2.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/bzip2.c?rev=1157733&r1=1157732&r2=1157733&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/bzip2.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/bzip2.c Mon Aug 15 07:48:54 2011 @@ -21,13 +21,30 @@ #include "bzip2/bzlib.h" +#define ACR_BZIP2_EXPORT(RT, CL, MN) \ + ACR_JNIEXPORT RT JNICALL Java_org_apache_commons_runtime_util_bzip2_##CL##_##MN +#define ACR_BZBUFF(S) ((char *)(S) + ACR_BZSIZE) + +static int ACR_BZSIZE; + void _cr_bz_internal_error(int errorcode) { - /* TODO: Make this as configurable callback - * So that those messages can pop up in loggers. - */ + char b[100]; + snprintf(b, sizeof(b), "Internal Bzip2 error number %d", errorcode); + AcrThrow(0, ACR_EX_ERUNTIME, b); } +typedef struct acr_bzstream { + bz_stream bz; + int compressing; + unsigned int blen; + jbyteArray nia; + jbyte *nip; + jbyteArray noa; + jbyte *nop; +} acr_bzstream; + + static const char *bz_errmsg(int err) { switch (err) { @@ -46,23 +63,22 @@ static const char *bz_errmsg(int err) return "Unknown Bzip2 error"; } - -ACR_UTIL_EXPORT(jstring, Bzip2, sver0)(JNI_STDARGS) +ACR_BZIP2_EXPORT(jstring, Bzip2, sver0)(JNI_STDARGS) { return AcrNewJavaStringU(env, BZ2_bzlibVersion()); } -ACR_UTIL_EXPORT(jlong, Bzip2, compress0)(JNI_STDARGS, jbyteArray dst, - jbyteArray src, jint off, jint len, - jint blockSize100k, - jint workFactor) +ACR_BZIP2_EXPORT(jlong, Bzip2, compress0)(JNI_STDARGS, jbyteArray src, jint spos, + jbyteArray dst, jint dpos, jint dlen, + jint len, jint blockSize100k, + jint workFactor) { unsigned int dstLen; char *scp; char *dcp; int rc; - dstLen = (unsigned int)(*env)->GetArrayLength(env, dst); + dstLen = dlen; scp = JARRAY_CRITICAL(char, src); dcp = JARRAY_CRITICAL(char, dst); if (dcp == 0 || scp == 0) { @@ -72,7 +88,7 @@ ACR_UTIL_EXPORT(jlong, Bzip2, compress0) return 0; } - rc = BZ2_bzBuffToBuffCompress(dcp, &dstLen, scp + off, len, + rc = BZ2_bzBuffToBuffCompress(dcp + dpos, &dstLen, scp + spos, len, blockSize100k, 0, workFactor); RELEASE_CRITICAL(src, scp); RELEASE_CRITICAL(dst, dcp); @@ -87,16 +103,75 @@ ACR_UTIL_EXPORT(jlong, Bzip2, compress0) return 0; } -ACR_UTIL_EXPORT(jlong, Bzip2, decompress0)(JNI_STDARGS, jbyteArray dst, - jbyteArray src, jint off, jint len, - jboolean small) +ACR_BZIP2_EXPORT(jint, Bzip2, compress1)(JNI_STDARGS, jobject src, jint spos, + jobject dst, jint dpos, jint dlen, + jint len, jint blockSize100k, + jint workFactor) { unsigned int dstLen; char *scp; char *dcp; int rc; - dstLen = (unsigned int)(*env)->GetArrayLength(env, dst); + dstLen = dlen; + if ((scp = (char *)(*env)->GetDirectBufferAddress(env, src)) == 0) { + ACR_THROW(ACR_EX_ENULL, 0); + return 0; + } + if ((dcp = (char *)(*env)->GetDirectBufferAddress(env, dst)) == 0) { + ACR_THROW(ACR_EX_ENULL, 0); + return 0; + } + rc = BZ2_bzBuffToBuffCompress(dcp + dpos, &dstLen, scp + spos, len, + blockSize100k, 0, workFactor); + if (rc == BZ_OK) + return dstLen; + else if (rc == BZ_OUTBUFF_FULL) + ACR_THROW(ACR_EX_EOVERFLOW, 0); + else if (rc == BZ_MEM_ERROR) + ACR_THROW(ACR_EX_ENOMEM, 0); + else + ACR_THROW(ACR_EX_EINVAL, 0); + return 0; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, compress2)(JNI_STDARGS, jlong src, jlong dst, + jlong dlen, jlong len, jint blockSize100k, + jint workFactor) +{ + unsigned int dstLen; + char *scp = J2P(src, char *); + char *dcp = J2P(dst, char *); + int rc; + + if (dlen > UINT_MAX || len > UINT_MAX) { + ACR_THROW(ACR_EX_ERANGE, 0); + return 0; + } + dstLen = (unsigned int)dlen; + rc = BZ2_bzBuffToBuffCompress(dcp, &dstLen, scp, (unsigned int)len, + blockSize100k, 0, workFactor); + if (rc == BZ_OK) + return (jlong)dstLen; + else if (rc == BZ_OUTBUFF_FULL) + ACR_THROW(ACR_EX_EOVERFLOW, 0); + else if (rc == BZ_MEM_ERROR) + ACR_THROW(ACR_EX_ENOMEM, 0); + else + ACR_THROW(ACR_EX_EINVAL, 0); + return 0; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, decompress0)(JNI_STDARGS, jbyteArray src, jint spos, + jbyteArray dst, jint dpos, jint dlen, + jint len, jboolean small) +{ + unsigned int dstLen; + char *scp; + char *dcp; + int rc; + + dstLen = dlen; scp = JARRAY_CRITICAL(char, src); dcp = JARRAY_CRITICAL(char, dst); if (dcp == 0 || scp == 0) { @@ -106,10 +181,73 @@ ACR_UTIL_EXPORT(jlong, Bzip2, decompress return 0; } - rc = BZ2_bzBuffToBuffDecompress(dcp, &dstLen, scp + off, len, small, 0); + rc = BZ2_bzBuffToBuffDecompress(dcp + dpos, &dstLen, scp + spos, len, small, 0); RELEASE_CRITICAL(src, scp); RELEASE_CRITICAL(dst, dcp); if (rc == BZ_OK) + return dstLen; + else if (rc == BZ_OUTBUFF_FULL) + ACR_THROW(ACR_EX_EOVERFLOW, 0); + else if (rc == BZ_MEM_ERROR) + ACR_THROW(ACR_EX_ENOMEM, 0); + else if (rc == BZ_PARAM_ERROR) + ACR_THROW(ACR_EX_EINVAL, 0); + else + ACR_THROW_MSG(ACR_EX_EILSEQ, bz_errmsg(rc)); + return 0; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, decompress1)(JNI_STDARGS, jobject src, jint spos, + jobject dst, jint dpos, jint dlen, + jint len, jboolean small) +{ + unsigned int dstLen; + char *scp; + char *dcp; + int rc; + + dstLen = dlen; + if ((scp = (char *)(*env)->GetDirectBufferAddress(env, src)) == 0) { + ACR_THROW(ACR_EX_ENULL, 0); + return 0; + } + if ((dcp = (char *)(*env)->GetDirectBufferAddress(env, dst)) == 0) { + ACR_THROW(ACR_EX_ENULL, 0); + return 0; + } + + rc = BZ2_bzBuffToBuffDecompress(dcp + dpos, &dstLen, scp + spos, len, small, 0); + if (rc == BZ_OK) + return dstLen; + else if (rc == BZ_OUTBUFF_FULL) + ACR_THROW(ACR_EX_EOVERFLOW, 0); + else if (rc == BZ_MEM_ERROR) + ACR_THROW(ACR_EX_ENOMEM, 0); + else if (rc == BZ_PARAM_ERROR) + ACR_THROW(ACR_EX_EINVAL, 0); + else + ACR_THROW_MSG(ACR_EX_EILSEQ, bz_errmsg(rc)); + return 0; +} + +ACR_BZIP2_EXPORT(jlong, Bzip2, decompress2)(JNI_STDARGS, jlong src, + jlong dst, jlong dlen, + jlong len, jboolean small) +{ + unsigned int dstLen; + char *scp = J2P(src, char *); + char *dcp = J2P(dst, char *); + int rc; + + if (dlen > UINT_MAX || len > UINT_MAX) { + ACR_THROW(ACR_EX_ERANGE, 0); + return 0; + } + dstLen = (unsigned int)dlen; + + rc = BZ2_bzBuffToBuffDecompress(dcp, &dstLen, scp, (unsigned int)len, + small, 0); + if (rc == BZ_OK) return (jlong)dstLen; else if (rc == BZ_OUTBUFF_FULL) ACR_THROW(ACR_EX_EOVERFLOW, 0); @@ -121,3 +259,180 @@ ACR_UTIL_EXPORT(jlong, Bzip2, decompress ACR_THROW_MSG(ACR_EX_EILSEQ, bz_errmsg(rc)); return 0; } + +ACR_BZIP2_EXPORT(jint, Bzip2, size0)(JNI_STDARGS) +{ + int ssize = ISIZEOF(acr_bzstream); + ACR_BZSIZE = ACR_ALIGN_DEFAULT(ssize); + return ACR_BZSIZE; +} + +ACR_BZIP2_EXPORT(void, Bzip2, init0)(JNI_STDARGS, jbyteArray stream, + jint bsize) +{ + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + memset(&s->bz, 0, sizeof(bz_stream)); + s->blen = bsize; + RELEASE_CRITICAL(stream, s); +} + +ACR_BZIP2_EXPORT(jint, Bzip2, bzinit0)(JNI_STDARGS, jbyteArray stream, + jint blockSize100k, + jint workFactor) +{ + int rc; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + rc = BZ2_bzCompressInit((bz_stream *)s, blockSize100k, 0, workFactor); + s->compressing = 1; + RELEASE_CRITICAL(stream, s); + return rc; +} + +ACR_BZIP2_EXPORT(jlong, Bzip2, bzinit1)(JNI_STDARGS, jbyteArray stream, + jboolean small) +{ + int rc; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + rc = BZ2_bzDecompressInit((bz_stream *)s, 0, small); + s->compressing = 0; + RELEASE_CRITICAL(stream, s); + return rc; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, end0)(JNI_STDARGS, jbyteArray stream) +{ + int rc; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->compressing) + rc = BZ2_bzCompressEnd((bz_stream *)s); + else + rc = BZ2_bzDecompressEnd((bz_stream *)s); + if (s->nip != 0 && s->nia != 0) + (*env)->ReleaseByteArrayElements(env, s->nia, s->nip, 0); + if (s->nop != 0 && s->noa != 0) + (*env)->ReleaseByteArrayElements(env, s->noa, s->nop, 0); + memset(&s->bz, 0, sizeof(bz_stream)); + RELEASE_CRITICAL(stream, s); + return rc; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, nextinp0)(JNI_STDARGS, jbyteArray stream, + jbyteArray src, jint off, jint len) +{ + int rc = BZ_PARAM_ERROR; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nip != 0 && s->nia != 0) + (*env)->ReleaseByteArrayElements(env, s->nia, s->nip, 0); + s->nia = 0; + s->nip = (*env)->GetByteArrayElements(env, src, 0); + if (s->nip != 0) { + s->nia = src; + s->bz.next_in = (char *)s->nip + off; + s->bz.avail_in = len; + rc = BZ_OK; + } + return rc; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, nextinp1)(JNI_STDARGS, jbyteArray stream, + jobject src, jint off, jint len) +{ + int rc = BZ_PARAM_ERROR; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nip != 0 && s->nia != 0) + (*env)->ReleaseByteArrayElements(env, s->nia, s->nip, 0); + s->nia = 0; + s->nip = (*env)->GetDirectBufferAddress(env, src); + if (s->nip != 0) { + s->bz.next_in = (char *)s->nip + off; + s->bz.avail_in = len; + rc = BZ_OK; + } + return rc; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, nextinp2)(JNI_STDARGS, jbyteArray stream, + jlong src, jlong off, jlong len) +{ + int rc = BZ_PARAM_ERROR; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nip != 0 && s->nia != 0) + (*env)->ReleaseByteArrayElements(env, s->nia, s->nip, 0); + s->nia = 0; + s->nip = J2P(src, jbyte*); + if (s->nip != 0) { + s->bz.next_in = (char *)s->nip + (ptrdiff_t)off; + s->bz.avail_in = (unsigned int)len; + rc = BZ_OK; + } + return rc; +} + +ACR_BZIP2_EXPORT(void, Bzip2, nextinp3)(JNI_STDARGS, jbyteArray stream) +{ + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nip != 0 && s->nia != 0) + (*env)->ReleaseByteArrayElements(env, s->nia, s->nip, 0); + s->nia = 0; + s->nip = 0; + /* Use internal buffer */ + s->bz.next_in = ACR_BZBUFF(s); + s->bz.avail_in = ACR_BZSIZE; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, nextout1)(JNI_STDARGS, jbyteArray stream, + jobject src, jint off, jint len) +{ + int rc = BZ_PARAM_ERROR; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nop != 0 && s->noa != 0) + (*env)->ReleaseByteArrayElements(env, s->noa, s->nop, 0); + s->noa = 0; + s->nop = (*env)->GetDirectBufferAddress(env, src); + if (s->nop != 0) { + s->bz.next_out = (char *)s->nop + off; + s->bz.avail_out = len; + rc = BZ_OK; + } + return rc; +} + +ACR_BZIP2_EXPORT(jint, Bzip2, nextout2)(JNI_STDARGS, jbyteArray stream, + jlong src, jlong off, jlong len) +{ + int rc = BZ_PARAM_ERROR; + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nop != 0 && s->noa != 0) + (*env)->ReleaseByteArrayElements(env, s->noa, s->nop, 0); + s->noa = 0; + s->nop = J2P(src, jbyte*); + if (s->nop != 0) { + s->bz.next_out = (char *)s->nop + (ptrdiff_t)off; + s->bz.avail_out = (unsigned int)len; + rc = BZ_OK; + } + return rc; +} + +ACR_BZIP2_EXPORT(void, Bzip2, nextout3)(JNI_STDARGS, jbyteArray stream) +{ + acr_bzstream *s = JARRAY_CRITICAL(acr_bzstream, stream); + + if (s->nop != 0 && s->noa != 0) + (*env)->ReleaseByteArrayElements(env, s->noa, s->nop, 0); + s->noa = 0; + s->nop = 0; + /* Use internal buffer */ + s->bz.next_out = ACR_BZBUFF(s); + s->bz.avail_out = ACR_BZSIZE; +} Modified: commons/sandbox/runtime/trunk/src/main/native/shared/error.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/error.c?rev=1157733&r1=1157732&r2=1157733&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/error.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/error.c Mon Aug 15 07:48:54 2011 @@ -638,10 +638,12 @@ AcrThrow(JNI_STDENV, int cls, const char { jclass ec; + if (cls < 0 && cls >= ACR_EX_LEN) { + AcrThrowByName(env, 0, msg); + return; + } if (env == 0) env = AcrGetJNIEnv(); - if (cls < 0 && cls >= ACR_EX_LEN) - cls = 0; if (IS_INVALID_HANDLE(env)) { ACR_DEBUG_TRACE("JNI Environment is invalid or unavailable. Throwing '%s'", _throw_classes[cls].name); if (msg) { @@ -759,7 +761,9 @@ AcrThrowByError(JNI_STDENV, int def, int char buf[ACR_MBUFF_SIZ] = ""; const char *str = 0; - if (ACR_STATUS_IS_EEXIST(err)) + if (err == 0) + return; + else if (ACR_STATUS_IS_EEXIST(err)) cls = ACR_EX_EEXIST; else if (ACR_STATUS_IS_ENOENT(err)) cls = ACR_EX_ENOENT; Added: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestBzip2.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestBzip2.java?rev=1157733&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestBzip2.java (added) +++ commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestBzip2.java Mon Aug 15 07:48:54 2011 @@ -0,0 +1,43 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.runtime.util.bzip2; + +import java.io.IOException; +import java.io.File; +import org.testng.annotations.*; +import org.testng.Assert; + +public class TestBzip2 extends Assert +{ + + @Test(groups = { "core" }) + public void bufToBuffCompressing() + { + byte[] cd = new byte[1000]; + byte[] dd = new byte[1000]; + byte[] dc = new byte[1000]; + + for (int i = 0; i < 1000; i++) + cd[i] = (byte)(i % 10); + + int sc = Bzip2.buffToBuffCompress(cd, 0, dd, 0, 1000, 9, 30); + assertTrue(sc != 0); + int sd = Bzip2.buffToBuffDecompress(dd, 0, dc, 0, sc, false); + assertEquals(sd, 1000); + } + +} Propchange: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestBzip2.java ------------------------------------------------------------------------------ svn:eol-style = native