pax_global_header00006660000000000000000000000064122226701170014512gustar00rootroot0000000000000052 comment=9d0fcb95caad5f205d849928087b2efa202be4d4 jzlib-1.1.3/000077500000000000000000000000001222267011700126265ustar00rootroot00000000000000jzlib-1.1.3/.gitignore000066400000000000000000000006431222267011700146210ustar00rootroot00000000000000!.gitignore *.gz *.zip *.md5 *.sha1 bin/* build build.eclipse build.properties target dist nbproject/private share latest_source_cache docs/api *.orig *.rej *~ .debug.properties test/testapp/testapp glob_test spaces test .DS_Store *.so *.bundle *.[oa] dev_null .redcar /.externalToolBuilders/ /.settings/ .metadata .idea/workspace.xml shared.iml build_graph.png /.idea/ lib_managed/ project/build/target/ project/boot/ jzlib-1.1.3/ChangeLog000066400000000000000000000125501222267011700144030ustar00rootroot00000000000000ChangeLog of JZlib ==================================================================== Last modified: Mon Feb 20 06:06:07 UTC 2012 Changes since version 1.1.0: - fixed a bug in DeflaterOutputStream#write() with empty data. 9d4616f - fixed a bug in processing unwrapped data with InfalterInputStream. d35db2 - fixed bugs reported in https://github.com/ymnk/jzlib/pull/5 e4aa20 - comments and filename in GZIPHeader must be in ISO-8859-1 encoding - fixing a bug in GZIPHeader#setOS(int os) - some refactoring code. e912088 6900f5 614fdf - improving the performace of Adler32#update method. 6900f5 - constructors of Alder32 and CRC32 become public. 30c4cf - added ZStream#end() and ZStream#finished(). 6b55e3 - exposed useful constants for jruby. e17ad1 - updated pom.xml to delete "souceDirectory" No need to specify sourceDirectory if the project follows maven standard. - updated configurations to use sbt 0.11.1 Changes since version 1.0.7: - supported some new functionalities, which have been introduced since 'zlib' 1.2. - JZlib#{adler32,crc32}_combine, - JZlib can handle gzip file format(RFC1952). - added following classes, - DeflaterOutputStream - InflaterInputStream - GZIPOutputStream - GZIPInputStream - Inflater - Deflater - ZStream has been deprecated. Use Inflater and Deflater instead of it. - GZIPHeader - re-implemented Z{Input,Output}Stream with {Deflater,Inflater}{I/O}Stream - those classes have been deprecated. Use DeflaterOutputStream and InfaterInputStream instead of them. - com/ -> src/main/java/com/ - some tests under src/test/scala/ - pom.xml for mvn, and projects/ for sbt. Changes since version 1.0.6: - change: memory and performance optimisations in the inflate operation. - change: added the nowrap argument to Z{Input,Output}?Stream. Changes since version 1.0.5: - ZInputStream.read(byte[], int, int) method return sometimes zero instead of -1 at the end of stream. - ZOutputStream.end() method should not declare IOException. - It should be possible to call ZOutputStream.end() method more times (because you can call close() method and after it end() method in finally block). - ZOutputStream.finish() method should not ignore IOException from flush(). Many thanks to Matej Kraus at seznam.cz , who pointed out above problems. Changes since version 1.0.4: - a minor bug fix in ZInputStream Changes since version 1.0.3: - fixed a bug in closing ZOutputStream. The inflating and deflating processes were not finished successfully. - added 'finish' and 'end' methods to ZOutputStream.java - added 'example/test_stream_deflate_inflate.java' Changes since version 1.0.2: - enabled pure Java implementation of adler32 and commented out the dependency on J2SE in Adler32.java for J2ME users. Changes since version 1.0.1: - fixed a bug in deflating some trivial data, for example, large data chunk filled with zero. - added 'version' method to JZlib class. Changes since version 1.0.0: - added ZInputStream and ZOutputStream classes. - fixed a typo in LICENSE.txt. Changes since version 0.0.9: - fixed a bug in setting a dictionary in the inflation process. - The license was changed to a BSD style license. - Z{Input,Output}Stream classes were deleted. Changes since version 0.0.8: - fixed a bug in handling a preset dictionary in the inflation process. Changes since version 0.0.7: - added methods to control the window size (the size of the history buffer) and to handle the no-wrap option (no zlib header or check), which is the undocumented functionality of zlib. Changes since version 0.0.6: - updated InfBlocks.java as zlib did to fix the vulnerability related to the 'double free'. Of course, JZlib is free from such a vulnerability like the 'double free', but JZlib had crashed with NullPointerException by a specially-crafted block of invalid deflated data. Changes since version 0.0.5: - added 'flush()' method to com.jcraft.jzlib.ZOutputStream. - fixed to take care when occurring the buffer overflow in com.jcraft.jzlib.ZOutputStream. Many thanks to Tim Bendfelt at cs.wisc.edu , who pointed out above problems. Changes since version 0.0.4: ............................ - fixed a bug in Adler32 class. - fixed a bug in ZInputStream class - modified ZInputStream to be extended from InputStream instead of FileInputStream. - modified ZOutputStream to be extended from OutputStream instead of FileOutputStream. - modified ZStream to be changeable wbits. Give wbits value to the method 'deflateInit' of ZStream. Many thanks to Bryan Keller, who reported bugs and made suggestions. Changes since version 0.0.3: ............................ - fixed a bug in the compression level 0. - modified to be compatible with JIKES's bug. - added Z[Input,Output]Stream written by Lapo Luchini. Changes since version 0.0.2: ............................ - fixed a critical bug, which had arisen in the deflating operation with NO_FLUSH and DEFAULT_COMPRESSION mode. Many thanks to Bryan Keller(keller@neomar.com), who reported this glitch. Changes since version 0.0.1: ............................ - fixed the bad compression ratio problem, which is reported from Martin Smith(martin@spamcop.net). The compression ratio was not so good compared with the compression ration of zlib. Now, this problem has been fixed and, I hope, that deflated files by JZlib and zlib are completely same bit by bit. jzlib-1.1.3/LICENSE.txt000066400000000000000000000031471222267011700144560ustar00rootroot00000000000000JZlib 0.0.* were released under the GNU LGPL license. Later, we have switched over to a BSD-style license. ------------------------------------------------------------------------------ Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jzlib-1.1.3/README000066400000000000000000000120031222267011700135020ustar00rootroot00000000000000 JZlib zlib in pure Java(TM) by ymnk@jcraft.com, JCraft,Inc. http://www.jcraft.com/jzlib/ Last modified: Mon Sep 19 15:28:43 UTC 2011 Description =========== JZlib is a re-implementation of zlib in pure Java. The first and final aim for hacking this stuff is to add the packet compression support to pure Java SSH systems. Documentation ============= * README files all over the source tree have info related to the stuff in the directories. * ChangeLog: what changed from the previous version? * LICENSE.txt Directories & Files in the Source Tree ====================================== * src/main/java has source trees of JZlib. * example/ has some samples, which demonstrate the usages. * misc/ has some stuffs. At present, this directory includes a patch file for MindTerm v.1.2.1, which adds the packet compression functionality. Features ======== * Needless to say, JZlib can inflate data, which is deflated by zlib and JZlib can generate deflated data, which is acceptable and inflated by zlib. * JZlib supports all compression level and all flushing mode in zlib. * JZlib does not support gzip file handling supports. * The performance has not been estimated yet, but it will be not so bad in deflating/inflating data stream on the low bandwidth network. * JZlib is under BSD style license. * Any invention has not been done in developing JZlib. So, if zlib is patent free, JZlib is also not covered by any patents. Why JZlib? ========== Java Platform API provides packages 'java.util.zip.*' for accessing to zlib, but that support is very limited if you need to use the essence of zlib. For example, we needed to full access to zlib to add the packet compression support to pure Java SSH system, but they are useless for our requirements. The Internet draft, SSH Transport Layer Protocol, says in the section '4.2 Compression' as follows, The following compression methods are currently defined: none REQUIRED no compression zlib OPTIONAL GNU ZLIB (LZ77) compression The "zlib" compression is described in [RFC-1950] and in [RFC-1951]. The compression context is initialized after each key exchange, and is passed from one packet to the next with only a partial flush being performed at the end of each packet. A partial flush means that all data will be output, but the next packet will continue using compression tables from the end of the previous packet. To implement this functionality, the Z_PARTIAL_FLUSH mode of zlib must be used, however JDK does not permit us to do so. It seems that this problem has been well known and some people have already reported to JavaSoft's BugParade(for example, BugId:4255743), but any positive response has not been returned from JavaSoft, so this problem will not be solved forever. This is our motivation to hack JZlib. Building Jar File ================= Use 'sbt'(https://github.com/harrah/xsbt/wiki), % sbt package or % mvn package or % cd src/main/java % javac -target 1.5 com/jcraft/jzlib/*.java % jar -cvf jzlib.jar com/jcraft/jzlib/*.class A unofficial patch for MindTerm v.1.2.1 ======================================= A unofficial patch file for MindTerm v.1.2.1 has included in 'misc' directory. It adds the packet compression support to MindTerm. Please refer to 'misc/README' file. Copyrights & Disclaimers ======================== JZlib is copyrighted by ymnk, JCraft,Inc. and is licensed through BSD style license. Read the LICENSE.txt file for the complete license. Credits ======= JZlib has been developed by ymnk@jcraft.com, but he has just re-implemented zlib in pure Java. So, all credit should go to authors Jean-loup Gailly and Mark Adler and contributors of zlib. Here is the copyright notice of zlib version 1.1.3, |Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler | |This software is provided 'as-is', without any express or implied |warranty. In no event will the authors be held liable for any damages |arising from the use of this software. | |Permission is granted to anyone to use this software for any purpose, |including commercial applications, and to alter it and redistribute it |freely, subject to the following restrictions: | |1. The origin of this software must not be misrepresented; you must not | claim that you wrote the original software. If you use this software | in a product, an acknowledgment in the product documentation would be | appreciated but is not required. |2. Altered source versions must be plainly marked as such, and must not be | misrepresented as being the original software. |3. This notice may not be removed or altered from any source distribution. | |Jean-loup Gailly Mark Adler |jloup@gzip.org madler@alumni.caltech.edu If you have any comments, suggestions and questions, write us at jzlib@jcraft.com ``SSH is a registered trademark and Secure Shell is a trademark of SSH Communications Security Corp (www.ssh.com)''. jzlib-1.1.3/example/000077500000000000000000000000001222267011700142615ustar00rootroot00000000000000jzlib-1.1.3/example/README000066400000000000000000000015701222267011700151440ustar00rootroot00000000000000 README of example directory ==================================================================== Last modified: Wed Dec 20 05:54:08 UTC 2000 This directory contains some examples, which demonstrate how to use JZlib. - test_deflate_inflate.java This program tests deflate/inflate with small buffers. - test_large_deflate_inflate.java This program tests deflate/inflate with large buffers and dynamic change of compression level - test_dict_deflate_inflate.java This program tests deflate/inflate with preset dictionary. - test_flush_sync This program tests deflate/inflate with full flush. - test_stream_deflate_inflate.java This program tests deflate/inflate for I/O stream. For example, if you want to compile and run 'test_deflate_inflate.java', try following steps. $ javac -classpath .. test_deflate_inflate.java $ javac -classpath ..:. test_deflate_inflate jzlib-1.1.3/example/test_deflate_inflate.java000066400000000000000000000044171222267011700212770ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ import java.io.*; import com.jcraft.jzlib.*; // Test deflate() with small buffers class test_deflate_inflate{ static final byte[] hello="hello, hello! ".getBytes(); static{ hello[hello.length-1]=0; } public static void main(String[] arg){ int err; int comprLen=40000; int uncomprLen=comprLen; byte[] compr=new byte[comprLen]; byte[] uncompr=new byte[uncomprLen]; Deflater deflater = null; try { deflater = new Deflater(JZlib.Z_DEFAULT_COMPRESSION); } catch(GZIPException e){ // never happen, because argument is valid. } deflater.setInput(hello); deflater.setOutput(compr); while(deflater.total_in!=hello.length && deflater.total_outSSH Connection...' panel. If you add the debug option '--D' in invoking MindTerm, some informations related to the compression ratio will be printed out after the end of each session. ``SSH is a registered trademark and Secure Shell is a trademark of SSH Communications Security Corp (www.ssh.com)''. jzlib-1.1.3/misc/mindtermsrc-v121-compression.patch000066400000000000000000000324531222267011700221660ustar00rootroot00000000000000diff -Naur mindbright/Makefile mindbright-compression/Makefile --- mindbright/Makefile Tue Aug 1 20:37:08 2000 +++ mindbright-compression/Makefile Tue Dec 19 05:49:00 2000 @@ -56,6 +56,7 @@ ssh/SSHTxChannel.class \ ssh/SSHTunnel.class \ ssh/SSHProtocolPlugin.class \ + ssh/SSHCompression.class \ ssh/SSHPdu.class \ ssh/SSHDataInputStream.class \ ssh/SSHDataOutputStream.class \ diff -Naur mindbright/ssh/SSH.java mindbright-compression/ssh/SSH.java --- mindbright/ssh/SSH.java Tue Aug 1 22:30:52 2000 +++ mindbright-compression/ssh/SSH.java Tue Dec 19 05:59:45 2000 @@ -206,6 +206,8 @@ protected Cipher rcvCipher; protected int cipherType; + protected static int compressionLevel=0; + // Server data fields // protected byte[] srvCookie; diff -Naur mindbright/ssh/SSHClient.java mindbright-compression/ssh/SSHClient.java --- mindbright/ssh/SSHClient.java Tue Apr 4 09:34:12 2000 +++ mindbright-compression/ssh/SSHClient.java Tue Dec 19 05:31:57 2000 @@ -481,6 +481,10 @@ protected void disconnect(boolean graceful) { if(!isConnected) return; + if(SSH.compressionLevel!=0){ + SSHCompression.uninit(); + SSH.compressionLevel=0; + } isConnected = false; isOpened = false; gracefulExit = graceful; @@ -897,7 +901,7 @@ void initiateSession() throws IOException { // !!! java.util.zip.Deflater/Inflater can't be used since we can't give // the native inflate/deflate methods the Z_PARTIAL_FLUSH flag - // requestCompression(3); + requestCompression(user.getCompressionLevel()); if(user.wantPTY()) requestPTY(); @@ -939,11 +943,20 @@ } void requestCompression(int level) throws IOException { + if(level==0) return; + if(level<0 || level>9){ + if(interactor!=null) + interactor.report("Error requesting invalid compression level: " + level); + return; + } + SSHPduOutputStream outpdu = new SSHPduOutputStream(CMSG_REQUEST_COMPRESSION, sndCipher); outpdu.writeInt(level); outpdu.writeTo(sshOut); if(!isSuccess() && interactor != null) interactor.report("Error requesting compression level: " + level); + SSH.compressionLevel=level; + SSHCompression.init(level); } void requestMaxPacketSz(int sz) throws IOException { diff -Naur mindbright/ssh/SSHClientUser.java mindbright-compression/ssh/SSHClientUser.java --- mindbright/ssh/SSHClientUser.java Sat Feb 26 12:28:51 2000 +++ mindbright-compression/ssh/SSHClientUser.java Mon Dec 18 05:23:28 2000 @@ -30,6 +30,7 @@ public String getDisplay(); public int getMaxPacketSz(); public int getAliveInterval(); + public int getCompressionLevel(); public boolean wantX11Forward(); public boolean wantPrivileged(); diff -Naur mindbright/ssh/SSHClientUserAdaptor.java mindbright-compression/ssh/SSHClientUserAdaptor.java --- mindbright/ssh/SSHClientUserAdaptor.java Sat Feb 26 12:28:51 2000 +++ mindbright-compression/ssh/SSHClientUserAdaptor.java Mon Dec 18 06:07:33 2000 @@ -62,6 +62,10 @@ return 0; } + public int getCompressionLevel() { + return 0; + } + public boolean wantX11Forward() { return false; } diff -Naur mindbright/ssh/SSHCompression.java mindbright-compression/ssh/SSHCompression.java --- mindbright/ssh/SSHCompression.java Thu Jan 1 00:00:00 1970 +++ mindbright-compression/ssh/SSHCompression.java Wed Dec 20 03:13:52 2000 @@ -0,0 +1,145 @@ +/****************************************************************************** + * + * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden. + * www.mindbright.se, info@mindbright.se + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + ***************************************************************************** + * $Author: ymnk@jcraft.com $ + * $Date: 2000/12/18 17:13:50 $ + * $Name: rel0-0-0 $ + *****************************************************************************/ +package mindbright.ssh; + +import mindbright.ssh.*; +import com.jcraft.jzlib.*; + +final class SSHCompression{ + static private ZStream deflate_stream=null; + static private ZStream inflate_stream=null; + + static void init(int level){ + deflate_stream=new ZStream(); + inflate_stream=new ZStream(); + deflate_stream.deflateInit(level); + inflate_stream.inflateInit(); + } + + static void uninit(){ + if(SSH.DEBUGMORE){ + if(deflate_stream!=null) + System.out.println("compress outgoing: raw data "+deflate_stream.total_in+ + ", compressed "+deflate_stream.total_out+ + ", factor "+(deflate_stream.total_in == 0 ? + 0.0 : + ((double)deflate_stream.total_out) / + ((double)deflate_stream.total_in))); + if(inflate_stream!=null) + System.out.println("compress incoming: raw data "+inflate_stream.total_out+ + ", compressed "+inflate_stream.total_in+ + ", factor "+(inflate_stream.total_out == 0 ? + 0.0 : + ((double)inflate_stream.total_in) / + ((double)inflate_stream.total_out))); + } + if(deflate_stream!=null){ + deflate_stream.deflateEnd(); + deflate_stream.free(); + deflate_stream=null; + } + if(inflate_stream!=null){ + inflate_stream.inflateEnd(); + inflate_stream.free(); + inflate_stream=null; + } + } + + static private final int BUF_SIZE=4096; + static private byte[] d_buf=new byte[BUF_SIZE]; + static private byte[] i_buf=new byte[BUF_SIZE]; + + static int compress(byte[] buf, int len){ + + deflate_stream.next_in=buf; + deflate_stream.next_in_index=8; + deflate_stream.avail_in=len-8; + + int status; + int outputlen=8; + + do{ + deflate_stream.next_out=d_buf; + deflate_stream.next_out_index=0; + deflate_stream.avail_out=BUF_SIZE; + status=deflate_stream.deflate(JZlib.Z_PARTIAL_FLUSH); + switch(status){ + case JZlib.Z_OK: + System.arraycopy(d_buf, 0, + buf, outputlen, + BUF_SIZE-deflate_stream.avail_out); + outputlen+=(BUF_SIZE-deflate_stream.avail_out); + break; + default: + System.err.println("SSHCompression.compress: deflate returnd "+status); + } + } + while(deflate_stream.avail_out==0); + return outputlen; + } + + static private byte[] out_buf = new byte[BUF_SIZE]; + static void uncompress(SSHPduInputStream input){ + int pad=(8-(input.length%8)); + int out_end=0; + + inflate_stream.next_in=input.bytes; + inflate_stream.next_in_index=pad; + inflate_stream.avail_in=input.length - 4; // chop checksum field + + while(true){ + inflate_stream.next_out=i_buf; + inflate_stream.next_out_index=0; + inflate_stream.avail_out=BUF_SIZE; + + int status=inflate_stream.inflate(JZlib.Z_PARTIAL_FLUSH); + switch(status){ + case JZlib.Z_OK: + if(out_buf.lengthinput.bytes.length){ + byte[] foo=new byte[out_end]; + System.arraycopy(out_buf, 0, foo, 0, out_end); + input.bytes=foo; + } + else{ + System.arraycopy(out_buf, 0, input.bytes, 0, out_end); + } + input.length=out_end; + try{ input.reset(); } + catch(Exception e){} + return; + default: + System.err.println("SSHCompression.uncompress: inflate returnd "+status); + return; // humm.. + } + } + } +} diff -Naur mindbright/ssh/SSHMenuHandlerFull.java mindbright-compression/ssh/SSHMenuHandlerFull.java --- mindbright/ssh/SSHMenuHandlerFull.java Tue Aug 1 20:37:08 2000 +++ mindbright-compression/ssh/SSHMenuHandlerFull.java Tue Dec 19 05:26:02 2000 @@ -544,6 +544,7 @@ Dialog settingsDialog = null; Choice choiceCipher, choiceAuthTyp; + Choice choiceCompressionLevel; Checkbox cbX11, cbPrvPrt, cbRemFwd, cbIdHost, cbPortFtp, cbLocHst, cbMTU, cbAlive, cbForcPty; TextField textPort, textUser, textId, textDisp, textMtu, textAlive, textSrv, textRealAddr, textAuthList, textLocHost; @@ -801,6 +802,17 @@ grid2.setConstraints(cbRemFwd, gridc2); ap.add(cbRemFwd); + gridc2.gridy = 7; + lbl = new Label("CompressionLevel:"); + grid2.setConstraints(lbl, gridc2); + ap.add(lbl); + choiceCompressionLevel = new Choice(); + for(i = 0; i < 10; i++) { + choiceCompressionLevel.add(new Integer(i).toString()); + } + grid2.setConstraints(choiceCompressionLevel, gridc2); + ap.add(choiceCompressionLevel); + gridc.gridy = 7; gridc.insets = new Insets(0, 0, 0, 0); gridc.anchor = GridBagConstraints.CENTER; @@ -844,6 +856,8 @@ } else { client.propsHandler.setProperty("authtyp", authType); } + String level = choiceCompressionLevel.getSelectedItem(); + client.propsHandler.setProperty("compression", level); client.propsHandler.setProperty("port", textPort.getText()); client.propsHandler.setProperty("usrname", textUser.getText()); client.propsHandler.setProperty("cipher", cipher[choiceCipher.getSelectedIndex()]); @@ -924,6 +938,9 @@ choiceAuthTyp.select("custom..."); textAuthList.setText(at); } + + at = client.propsHandler.getProperty("compression"); + choiceCompressionLevel.select(at); textId.setText(client.propsHandler.getProperty("idfile")); diff -Naur mindbright/ssh/SSHPduInputStream.java mindbright-compression/ssh/SSHPduInputStream.java --- mindbright/ssh/SSHPduInputStream.java Mon Jul 19 17:13:50 1999 +++ mindbright-compression/ssh/SSHPduInputStream.java Tue Dec 19 05:32:08 2000 @@ -102,6 +102,17 @@ throw new IOException("Invalid checksum in packet"); this.skip(8 - (len % 8)); + + if(SSH.compressionLevel!=0){ + //System.out.print("readFrom: length="+length); + byte[] foo=bytes; + SSHCompression.uncompress(this); + if(foo!=bytes){ + this.in = new PduByteArrayInputStream(bytes); + } + //System.out.println(" -> length="+length); + } + type = (int)this.readByte(); if(type == SSH.MSG_DEBUG) { diff -Naur mindbright/ssh/SSHPduOutputStream.java mindbright-compression/ssh/SSHPduOutputStream.java --- mindbright/ssh/SSHPduOutputStream.java Mon Jul 19 17:13:50 1999 +++ mindbright-compression/ssh/SSHPduOutputStream.java Tue Dec 19 05:32:14 2000 @@ -126,6 +126,13 @@ int padSz; int off = 0; + if(SSH.compressionLevel!=0){ + //System.out.print("writeTo: size="+bytes.size()); + int size=SSHCompression.compress(bytes.getBuf(), bytes.size()); + bytes.setCount(size); + //System.out.println(" -> size="+bytes.size()); + } + iSz = bytes.size(); pad = (iSz + 4) % 8; crc32 = (int)CRC32.getValue(bytes.getBuf(), pad, iSz - pad); diff -Naur mindbright/ssh/SSHPropertyHandler.java mindbright-compression/ssh/SSHPropertyHandler.java --- mindbright/ssh/SSHPropertyHandler.java Tue Aug 1 20:37:08 2000 +++ mindbright-compression/ssh/SSHPropertyHandler.java Tue Dec 19 05:23:39 2000 @@ -84,6 +84,7 @@ { "secrand", "0", "level of security in random seed (for generating session key)", "(0-2, 0=low and 2=high)" }, { "alive", "0", "Connection keep-alive interval in seconds (0 means none)", "(0-600)" }, + { "compression", "0", "Compression Level (0 means none, 1=fast, 9=slow,best )", "(0-9)" }, { "x11fwd", "false", "indicates whether X11 display is forwarded or not", "(true/false)" }, { "prvport", "false", "indicates whether to use a privileged port or not (locally)", "(true/false)" }, { "forcpty", "true", "indicates whether to allocate a pty or not", "(true/false)" }, @@ -295,7 +296,7 @@ if(!(value.equals("true") || value.equals("false"))) throw new IllegalArgumentException("Value for " + key + " must be 'true' or 'false'"); // - } else if(key.equals("port") || key.equals("proxyport") || key.equals("mtu") || + } else if(key.equals("port") || key.equals("proxyport") || key.equals("mtu") || key.equals("compression") || key.equals("secrand") || key.equals("alive")) { try { int val = Integer.valueOf(value).intValue(); @@ -309,6 +310,9 @@ } else if(key.equals("secrand")) { if(val < 0 || val > 2) throw new IllegalArgumentException("Secrand must be 0-2"); + } else if(key.equals("compression")) { + if(val < 0 || val > 9) + throw new IllegalArgumentException("Compression Level must be 0-9"); } } catch (NumberFormatException e) { throw new IllegalArgumentException("Value for " + key + " must be an integer"); @@ -1203,6 +1207,10 @@ public int getAliveInterval() { return Integer.valueOf(getProperty("alive")).intValue(); + } + + public int getCompressionLevel() { + return Integer.valueOf(getProperty("compression")).intValue(); } public boolean wantX11Forward() { jzlib-1.1.3/pom.xml000066400000000000000000000020651222267011700141460ustar00rootroot00000000000000 4.0.0 com.jcraft jzlib 1.1.3 JZlib JZlib is a re-implementation of zlib in pure Java http://www.jcraft.com/jzlib/ jcraft http://www.jcraft.com/ BSD http://www.jcraft.com/jzlib/LICENSE.txt maven-compiler-plugin 2.0 1.5 1.5 true jzlib-1.1.3/project/000077500000000000000000000000001222267011700142745ustar00rootroot00000000000000jzlib-1.1.3/project/Build.scala000066400000000000000000000014601222267011700163410ustar00rootroot00000000000000import sbt._ import Keys._ object BuildSettings { val buildName = "jzlib" val buildOrganization = "JCraft,Inc." val buildVersion = "1.1.3" val buildScalaVersion = "2.10.1" val buildSettings = Defaults.defaultSettings ++ Seq ( organization := buildOrganization, version := buildVersion, scalaVersion := buildScalaVersion, crossPaths := false, javaOptions ++= Seq ( "-target", "1.5" ) ) } object MyBuild extends Build { import BuildSettings._ val scalatest = "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test" private val dependencies = Seq ( scalatest ) lazy val root = Project( buildName, file("."), settings = buildSettings ) .settings( libraryDependencies ++= dependencies ) .settings( parallelExecution in Test := false ) } jzlib-1.1.3/project/build.properties000066400000000000000000000003041222267011700175060ustar00rootroot00000000000000#Project properties #Sun Sep 11 12:01:16 JST 2011 project.organization=JCraft,Inc. project.name=JZlib sbt.version=0.12.3 project.version=1.1.2 build.scala.versions=2.10.1 project.initialize=false jzlib-1.1.3/project/build/000077500000000000000000000000001222267011700153735ustar00rootroot00000000000000jzlib-1.1.3/project/build/MyProject.scala000066400000000000000000000007541222267011700203220ustar00rootroot00000000000000import sbt._ class MyProject(info: ProjectInfo) extends DefaultProject(info) { val scalatest = "org.scalatest" %% "scalatest" % "1.6.1" val junit4 = "junit" % "junit" % "4.8" val junitInterface = "com.novocode" % "junit-interface" % "0.7" override def artifactID = "jzlib" override def compileOptions = super.compileOptions ++compileOptions("-target:jvm-1.5") override def testOptions = super.testOptions ++ Seq(TestArgument(TestFrameworks.JUnit, "-q", "-v")) } jzlib-1.1.3/src/000077500000000000000000000000001222267011700134155ustar00rootroot00000000000000jzlib-1.1.3/src/main/000077500000000000000000000000001222267011700143415ustar00rootroot00000000000000jzlib-1.1.3/src/main/java/000077500000000000000000000000001222267011700152625ustar00rootroot00000000000000jzlib-1.1.3/src/main/java/com/000077500000000000000000000000001222267011700160405ustar00rootroot00000000000000jzlib-1.1.3/src/main/java/com/jcraft/000077500000000000000000000000001222267011700173115ustar00rootroot00000000000000jzlib-1.1.3/src/main/java/com/jcraft/jzlib/000077500000000000000000000000001222267011700204235ustar00rootroot00000000000000jzlib-1.1.3/src/main/java/com/jcraft/jzlib/Adler32.java000066400000000000000000000074731222267011700224750ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final public class Adler32 implements Checksum { // largest prime smaller than 65536 static final private int BASE=65521; // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 static final private int NMAX=5552; private long s1=1L; private long s2=0L; public void reset(long init){ s1=init&0xffff; s2=(init>>16)&0xffff; } public void reset(){ s1=1L; s2=0L; } public long getValue(){ return ((s2<<16)|s1); } public void update(byte[] buf, int index, int len){ if(len==1){ s1+=buf[index++]&0xff; s2+=s1; s1%=BASE; s2%=BASE; return; } int len1 = len/NMAX; int len2 = len%NMAX; while(len1-->0) { int k=NMAX; len-=k; while(k-->0){ s1+=buf[index++]&0xff; s2+=s1; } s1%=BASE; s2%=BASE; } int k=len2; len-=k; while(k-->0){ s1+=buf[index++]&0xff; s2+=s1; } s1%=BASE; s2%=BASE; } public Adler32 copy(){ Adler32 foo = new Adler32(); foo.s1 = this.s1; foo.s2 = this.s2; return foo; } // The following logic has come from zlib.1.2. static long combine(long adler1, long adler2, long len2){ long BASEL = (long)BASE; long sum1; long sum2; long rem; // unsigned int rem = len2 % BASEL; sum1 = adler1 & 0xffffL; sum2 = rem * sum1; sum2 %= BASEL; // MOD(sum2); sum1 += (adler2 & 0xffffL) + BASEL - 1; sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; if (sum1 >= BASEL) sum1 -= BASEL; if (sum1 >= BASEL) sum1 -= BASEL; if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); if (sum2 >= BASEL) sum2 -= BASEL; return sum1 | (sum2 << 16); } /* private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); public void update(byte[] buf, int index, int len){ if(buf==null) {adler.reset();} else{adler.update(buf, index, len);} } public void reset(){ adler.reset(); } public void reset(long init){ if(init==1L){ adler.reset(); } else{ System.err.println("unsupported operation"); } } public long getValue(){ return adler.getValue(); } */ } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/CRC32.java000066400000000000000000000115661222267011700220530ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final public class CRC32 implements Checksum { /* * The following logic has come from RFC1952. */ private int v = 0; private static int[] crc_table = null; static { crc_table = new int[256]; for (int n = 0; n < 256; n++) { int c = n; for (int k = 8; --k >= 0; ) { if ((c & 1) != 0) c = 0xedb88320 ^ (c >>> 1); else c = c >>> 1; } crc_table[n] = c; } } public void update (byte[] buf, int index, int len) { int c = ~v; while (--len >= 0) c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); v = ~c; } public void reset(){ v = 0; } public void reset(long vv){ v = (int)(vv&0xffffffffL); } public long getValue(){ return (long)(v&0xffffffffL); } // The following logic has come from zlib.1.2. private static final int GF2_DIM = 32; static long combine(long crc1, long crc2, long len2){ long row; long[] even = new long[GF2_DIM]; long[] odd = new long[GF2_DIM]; // degenerate case (also disallow negative lengths) if (len2 <= 0) return crc1; // put operator for one zero bit in odd odd[0] = 0xedb88320L; // CRC-32 polynomial row = 1; for (int n = 1; n < GF2_DIM; n++) { odd[n] = row; row <<= 1; } // put operator for two zero bits in even gf2_matrix_square(even, odd); // put operator for four zero bits in odd gf2_matrix_square(odd, even); // apply len2 zeros to crc1 (first square will put the operator for one // zero byte, eight zero bits, in even) do { // apply zeros operator for this bit of len2 gf2_matrix_square(even, odd); if ((len2 & 1)!=0) crc1 = gf2_matrix_times(even, crc1); len2 >>= 1; // if no more bits set, then done if (len2 == 0) break; // another iteration of the loop with odd and even swapped gf2_matrix_square(odd, even); if ((len2 & 1)!=0) crc1 = gf2_matrix_times(odd, crc1); len2 >>= 1; // if no more bits set, then done } while (len2 != 0); /* return combined crc */ crc1 ^= crc2; return crc1; } private static long gf2_matrix_times(long[] mat, long vec){ long sum = 0; int index = 0; while (vec!=0) { if ((vec & 1)!=0) sum ^= mat[index]; vec >>= 1; index++; } return sum; } static final void gf2_matrix_square(long[] square, long[] mat) { for (int n = 0; n < GF2_DIM; n++) square[n] = gf2_matrix_times(mat, mat[n]); } /* private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); public void update(byte[] buf, int index, int len){ if(buf==null) {crc32.reset();} else{crc32.update(buf, index, len);} } public void reset(){ crc32.reset(); } public void reset(long init){ if(init==0L){ crc32.reset(); } else{ System.err.println("unsupported operation"); } } public long getValue(){ return crc32.getValue(); } */ public CRC32 copy(){ CRC32 foo = new CRC32(); foo.v = this.v; return foo; } public static int[] getCRC32Table(){ int[] tmp = new int[crc_table.length]; System.arraycopy(crc_table, 0, tmp, 0, tmp.length); return tmp; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/Checksum.java000066400000000000000000000035001222267011700230260ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; interface Checksum { void update(byte[] buf, int index, int len); void reset(); void reset(long init); long getValue(); Checksum copy(); } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/Deflate.java000066400000000000000000001600731222267011700226410ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; public final class Deflate implements Cloneable { static final private int MAX_MEM_LEVEL=9; static final private int Z_DEFAULT_COMPRESSION=-1; static final private int MAX_WBITS=15; // 32K LZ77 window static final private int DEF_MEM_LEVEL=8; static class Config{ int good_length; // reduce lazy search above this match length int max_lazy; // do not perform lazy search above this match length int nice_length; // quit search above this match length int max_chain; int func; Config(int good_length, int max_lazy, int nice_length, int max_chain, int func){ this.good_length=good_length; this.max_lazy=max_lazy; this.nice_length=nice_length; this.max_chain=max_chain; this.func=func; } } static final private int STORED=0; static final private int FAST=1; static final private int SLOW=2; static final private Config[] config_table; static{ config_table=new Config[10]; // good lazy nice chain config_table[0]=new Config(0, 0, 0, 0, STORED); config_table[1]=new Config(4, 4, 8, 4, FAST); config_table[2]=new Config(4, 5, 16, 8, FAST); config_table[3]=new Config(4, 6, 32, 32, FAST); config_table[4]=new Config(4, 4, 16, 16, SLOW); config_table[5]=new Config(8, 16, 32, 32, SLOW); config_table[6]=new Config(8, 16, 128, 128, SLOW); config_table[7]=new Config(8, 32, 128, 256, SLOW); config_table[8]=new Config(32, 128, 258, 1024, SLOW); config_table[9]=new Config(32, 258, 258, 4096, SLOW); } static final private String[] z_errmsg = { "need dictionary", // Z_NEED_DICT 2 "stream end", // Z_STREAM_END 1 "", // Z_OK 0 "file error", // Z_ERRNO (-1) "stream error", // Z_STREAM_ERROR (-2) "data error", // Z_DATA_ERROR (-3) "insufficient memory", // Z_MEM_ERROR (-4) "buffer error", // Z_BUF_ERROR (-5) "incompatible version",// Z_VERSION_ERROR (-6) "" }; // block not completed, need more input or more output static final private int NeedMore=0; // block flush performed static final private int BlockDone=1; // finish started, need only more output at next deflate static final private int FinishStarted=2; // finish done, accept no more input or output static final private int FinishDone=3; // preset dictionary flag in zlib header static final private int PRESET_DICT=0x20; static final private int Z_FILTERED=1; static final private int Z_HUFFMAN_ONLY=2; static final private int Z_DEFAULT_STRATEGY=0; static final private int Z_NO_FLUSH=0; static final private int Z_PARTIAL_FLUSH=1; static final private int Z_SYNC_FLUSH=2; static final private int Z_FULL_FLUSH=3; static final private int Z_FINISH=4; static final private int Z_OK=0; static final private int Z_STREAM_END=1; static final private int Z_NEED_DICT=2; static final private int Z_ERRNO=-1; static final private int Z_STREAM_ERROR=-2; static final private int Z_DATA_ERROR=-3; static final private int Z_MEM_ERROR=-4; static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; static final private int INIT_STATE=42; static final private int BUSY_STATE=113; static final private int FINISH_STATE=666; // The deflate compression method static final private int Z_DEFLATED=8; static final private int STORED_BLOCK=0; static final private int STATIC_TREES=1; static final private int DYN_TREES=2; // The three kinds of block type static final private int Z_BINARY=0; static final private int Z_ASCII=1; static final private int Z_UNKNOWN=2; static final private int Buf_size=8*2; // repeat previous bit length 3-6 times (2 bits of repeat count) static final private int REP_3_6=16; // repeat a zero length 3-10 times (3 bits of repeat count) static final private int REPZ_3_10=17; // repeat a zero length 11-138 times (7 bits of repeat count) static final private int REPZ_11_138=18; static final private int MIN_MATCH=3; static final private int MAX_MATCH=258; static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); static final private int MAX_BITS=15; static final private int D_CODES=30; static final private int BL_CODES=19; static final private int LENGTH_CODES=29; static final private int LITERALS=256; static final private int L_CODES=(LITERALS+1+LENGTH_CODES); static final private int HEAP_SIZE=(2*L_CODES+1); static final private int END_BLOCK=256; ZStream strm; // pointer back to this zlib stream int status; // as the name implies byte[] pending_buf; // output still pending int pending_buf_size; // size of pending_buf int pending_out; // next pending byte to output to the stream int pending; // nb of bytes in the pending buffer int wrap = 1; byte data_type; // UNKNOWN, BINARY or ASCII byte method; // STORED (for zip only) or DEFLATED int last_flush; // value of flush param for previous deflate call int w_size; // LZ77 window size (32K by default) int w_bits; // log2(w_size) (8..16) int w_mask; // w_size - 1 byte[] window; // Sliding window. Input bytes are read into the second half of the window, // and move to the first half later to keep a dictionary of at least wSize // bytes. With this organization, matches are limited to a distance of // wSize-MAX_MATCH bytes, but this ensures that IO is always // performed with a length multiple of the block size. Also, it limits // the window size to 64K, which is quite useful on MSDOS. // To do: use the user input buffer as sliding window. int window_size; // Actual size of window: 2*wSize, except when the user input buffer // is directly used as sliding window. short[] prev; // Link to older string with same hash index. To limit the size of this // array to 64K, this link is maintained only for the last 32K strings. // An index in this array is thus a window index modulo 32K. short[] head; // Heads of the hash chains or NIL. int ins_h; // hash index of string to be inserted int hash_size; // number of elements in hash table int hash_bits; // log2(hash_size) int hash_mask; // hash_size-1 // Number of bits by which ins_h must be shifted at each input // step. It must be such that after MIN_MATCH steps, the oldest // byte no longer takes part in the hash key, that is: // hash_shift * MIN_MATCH >= hash_bits int hash_shift; // Window position at the beginning of the current output block. Gets // negative when the window is moved backwards. int block_start; int match_length; // length of best match int prev_match; // previous match int match_available; // set if previous match exists int strstart; // start of string to insert int match_start; // start of matching string int lookahead; // number of valid bytes ahead in window // Length of the best match at previous step. Matches not greater than this // are discarded. This is used in the lazy match evaluation. int prev_length; // To speed up deflation, hash chains are never searched beyond this // length. A higher limit improves compression ratio but degrades the speed. int max_chain_length; // Attempt to find a better match only when the current match is strictly // smaller than this value. This mechanism is used only for compression // levels >= 4. int max_lazy_match; // Insert new strings in the hash table only if the match length is not // greater than this length. This saves time but degrades compression. // max_insert_length is used only for compression levels <= 3. int level; // compression level (1..9) int strategy; // favor or force Huffman coding // Use a faster search when the previous match is longer than this int good_match; // Stop searching when current match exceeds this int nice_match; short[] dyn_ltree; // literal and length tree short[] dyn_dtree; // distance tree short[] bl_tree; // Huffman tree for bit lengths Tree l_desc=new Tree(); // desc for literal tree Tree d_desc=new Tree(); // desc for distance tree Tree bl_desc=new Tree(); // desc for bit length tree // number of codes at each bit length for an optimal tree short[] bl_count=new short[MAX_BITS+1]; // working area to be used in Tree#gen_codes() short[] next_code=new short[MAX_BITS+1]; // heap used to build the Huffman trees int[] heap=new int[2*L_CODES+1]; int heap_len; // number of elements in the heap int heap_max; // element of largest frequency // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. // The same heap array is used to build all trees. // Depth of each subtree used as tie breaker for trees of equal frequency byte[] depth=new byte[2*L_CODES+1]; byte[] l_buf; // index for literals or lengths */ // Size of match buffer for literals/lengths. There are 4 reasons for // limiting lit_bufsize to 64K: // - frequencies can be kept in 16 bit counters // - if compression is not successful for the first block, all input // data is still in the window so we can still emit a stored block even // when input comes from standard input. (This can also be done for // all blocks if lit_bufsize is not greater than 32K.) // - if compression is not successful for a file smaller than 64K, we can // even emit a stored file instead of a stored block (saving 5 bytes). // This is applicable only for zip (not gzip or zlib). // - creating new Huffman trees less frequently may not provide fast // adaptation to changes in the input data statistics. (Take for // example a binary file with poorly compressible code followed by // a highly compressible string table.) Smaller buffer sizes give // fast adaptation but have of course the overhead of transmitting // trees more frequently. // - I can't count above 4 int lit_bufsize; int last_lit; // running index in l_buf // Buffer for distances. To simplify the code, d_buf and l_buf have // the same number of elements. To use different lengths, an extra flag // array would be necessary. int d_buf; // index of pendig_buf int opt_len; // bit length of current block with optimal trees int static_len; // bit length of current block with static trees int matches; // number of string matches in current block int last_eob_len; // bit length of EOB code for last block // Output buffer. bits are inserted starting at the bottom (least // significant bits). short bi_buf; // Number of valid bits in bi_buf. All bits above the last valid bit // are always zero. int bi_valid; GZIPHeader gheader = null; Deflate(ZStream strm){ this.strm=strm; dyn_ltree=new short[HEAP_SIZE*2]; dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths } void lm_init() { window_size=2*w_size; head[hash_size-1]=0; for(int i=0; i= 3; max_blindex--) { if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; } // Update opt_len to include the bit length tree and counts opt_len += 3*(max_blindex+1) + 5+5+4; return max_blindex; } // Send the header for a block using dynamic Huffman trees: the counts, the // lengths of the bit length codes, the literal tree and the distance tree. // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. void send_all_trees(int lcodes, int dcodes, int blcodes){ int rank; // index in bl_order send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt send_bits(dcodes-1, 5); send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt for (rank = 0; rank < blcodes; rank++) { send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); } send_tree(dyn_ltree, lcodes-1); // literal tree send_tree(dyn_dtree, dcodes-1); // distance tree } // Send a literal or distance tree in compressed form, using the codes in // bl_tree. void send_tree (short[] tree,// the tree to be sent int max_code // and its largest code of non zero frequency ){ int n; // iterates over all tree elements int prevlen = -1; // last emitted length int curlen; // length of current code int nextlen = tree[0*2+1]; // length of next code int count = 0; // repeat count of the current code int max_count = 7; // max repeat count int min_count = 4; // min repeat count if (nextlen == 0){ max_count = 138; min_count = 3; } for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[(n+1)*2+1]; if(++count < max_count && curlen == nextlen) { continue; } else if(count < min_count) { do { send_code(curlen, bl_tree); } while (--count != 0); } else if(curlen != 0){ if(curlen != prevlen){ send_code(curlen, bl_tree); count--; } send_code(REP_3_6, bl_tree); send_bits(count-3, 2); } else if(count <= 10){ send_code(REPZ_3_10, bl_tree); send_bits(count-3, 3); } else{ send_code(REPZ_11_138, bl_tree); send_bits(count-11, 7); } count = 0; prevlen = curlen; if(nextlen == 0){ max_count = 138; min_count = 3; } else if(curlen == nextlen){ max_count = 6; min_count = 3; } else{ max_count = 7; min_count = 4; } } } // Output a byte on the stream. // IN assertion: there is enough room in pending_buf. final void put_byte(byte[] p, int start, int len){ System.arraycopy(p, start, pending_buf, pending, len); pending+=len; } final void put_byte(byte c){ pending_buf[pending++]=c; } final void put_short(int w) { put_byte((byte)(w/*&0xff*/)); put_byte((byte)(w>>>8)); } final void putShortMSB(int b){ put_byte((byte)(b>>8)); put_byte((byte)(b/*&0xff*/)); } final void send_code(int c, short[] tree){ int c2=c*2; send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); } void send_bits(int value, int length){ int len = length; if (bi_valid > (int)Buf_size - len) { int val = value; // bi_buf |= (val << bi_valid); bi_buf |= ((val << bi_valid)&0xffff); put_short(bi_buf); bi_buf = (short)(val >>> (Buf_size - bi_valid)); bi_valid += len - Buf_size; } else { // bi_buf |= (value) << bi_valid; bi_buf |= (((value) << bi_valid)&0xffff); bi_valid += len; } } // Send one empty static block to give enough lookahead for inflate. // This takes 10 bits, of which 7 may remain in the bit buffer. // The current inflate code requires 9 bits of lookahead. If the // last two codes for the previous block (real code plus EOB) were coded // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode // the last real code. In this case we send two empty static blocks instead // of one. (There are no problems if the previous block is stored or fixed.) // To simplify the code, we assume the worst case of last real code encoded // on one bit only. void _tr_align(){ send_bits(STATIC_TREES<<1, 3); send_code(END_BLOCK, StaticTree.static_ltree); bi_flush(); // Of the 10 bits for the empty block, we have already sent // (10 - bi_valid) bits. The lookahead for the last real code (before // the EOB of the previous block) was thus at least one plus the length // of the EOB plus what we have just sent of the empty static block. if (1 + last_eob_len + 10 - bi_valid < 9) { send_bits(STATIC_TREES<<1, 3); send_code(END_BLOCK, StaticTree.static_ltree); bi_flush(); } last_eob_len = 7; } // Save the match info and tally the frequency counts. Return true if // the current block must be flushed. boolean _tr_tally (int dist, // distance of matched string int lc // match length-MIN_MATCH or unmatched char (if dist==0) ){ pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); pending_buf[d_buf+last_lit*2+1] = (byte)dist; l_buf[last_lit] = (byte)lc; last_lit++; if (dist == 0) { // lc is the unmatched char dyn_ltree[lc*2]++; } else { matches++; // Here, lc is the match length - MIN_MATCH dist--; // dist = match distance - 1 dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; dyn_dtree[Tree.d_code(dist)*2]++; } if ((last_lit & 0x1fff) == 0 && level > 2) { // Compute an upper bound for the compressed length int out_length = last_lit*8; int in_length = strstart - block_start; int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (int)dyn_dtree[dcode*2] * (5L+Tree.extra_dbits[dcode]); } out_length >>>= 3; if ((matches < (last_lit/2)) && out_length < in_length/2) return true; } return (last_lit == lit_bufsize-1); // We avoid equality with lit_bufsize because of wraparound at 64K // on 16 bit machines and because stored blocks are restricted to // 64K-1 bytes. } // Send the block data compressed using the given Huffman trees void compress_block(short[] ltree, short[] dtree){ int dist; // distance of matched string int lc; // match length or unmatched char (if dist == 0) int lx = 0; // running index in l_buf int code; // the code to send int extra; // number of extra bits to send if (last_lit != 0){ do{ dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| (pending_buf[d_buf+lx*2+1]&0xff); lc=(l_buf[lx])&0xff; lx++; if(dist == 0){ send_code(lc, ltree); // send a literal byte } else{ // Here, lc is the match length - MIN_MATCH code = Tree._length_code[lc]; send_code(code+LITERALS+1, ltree); // send the length code extra = Tree.extra_lbits[code]; if(extra != 0){ lc -= Tree.base_length[code]; send_bits(lc, extra); // send the extra length bits } dist--; // dist is now the match distance - 1 code = Tree.d_code(dist); send_code(code, dtree); // send the distance code extra = Tree.extra_dbits[code]; if (extra != 0) { dist -= Tree.base_dist[code]; send_bits(dist, extra); // send the extra distance bits } } // literal or match pair ? // Check that the overlay between pending_buf and d_buf+l_buf is ok: } while (lx < last_lit); } send_code(END_BLOCK, ltree); last_eob_len = ltree[END_BLOCK*2+1]; } // Set the data type to ASCII or BINARY, using a crude approximation: // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. // IN assertion: the fields freq of dyn_ltree are set and the total of all // frequencies does not exceed 64K (to fit in an int on 16 bit machines). void set_data_type(){ int n = 0; int ascii_freq = 0; int bin_freq = 0; while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); } // Flush the bit buffer, keeping at most 7 bits in it. void bi_flush(){ if (bi_valid == 16) { put_short(bi_buf); bi_buf=0; bi_valid=0; } else if (bi_valid >= 8) { put_byte((byte)bi_buf); bi_buf>>>=8; bi_valid-=8; } } // Flush the bit buffer and align the output on a byte boundary void bi_windup(){ if (bi_valid > 8) { put_short(bi_buf); } else if (bi_valid > 0) { put_byte((byte)bi_buf); } bi_buf = 0; bi_valid = 0; } // Copy a stored block, storing first the length and its // one's complement if requested. void copy_block(int buf, // the input data int len, // its length boolean header // true if block header must be written ){ int index=0; bi_windup(); // align on byte boundary last_eob_len = 8; // enough lookahead for inflate if (header) { put_short((short)len); put_short((short)~len); } // while(len--!=0) { // put_byte(window[buf+index]); // index++; // } put_byte(window, buf, len); } void flush_block_only(boolean eof){ _tr_flush_block(block_start>=0 ? block_start : -1, strstart-block_start, eof); block_start=strstart; strm.flush_pending(); } // Copy without compression as much as possible from the input stream, return // the current block state. // This function does not insert new strings in the dictionary since // uncompressible data is probably not useful. This function is used // only for the level=0 compression option. // NOTE: this function should be optimized to avoid extra copying from // window to pending_buf. int deflate_stored(int flush){ // Stored blocks are limited to 0xffff bytes, pending_buf is limited // to pending_buf_size, and each stored block has a 5 byte header: int max_block_size = 0xffff; int max_start; if(max_block_size > pending_buf_size - 5) { max_block_size = pending_buf_size - 5; } // Copy as much as possible from input to output: while(true){ // Fill the window as much as possible: if(lookahead<=1){ fill_window(); if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; if(lookahead==0) break; // flush the current block } strstart+=lookahead; lookahead=0; // Emit a stored block if pending_buf will be full: max_start=block_start+max_block_size; if(strstart==0|| strstart>=max_start) { // strstart == 0 is possible when wraparound on 16-bit machine lookahead = (int)(strstart-max_start); strstart = (int)max_start; flush_block_only(false); if(strm.avail_out==0) return NeedMore; } // Flush if we may have to slide, otherwise block_start may become // negative and the data will be gone: if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { flush_block_only(false); if(strm.avail_out==0) return NeedMore; } } flush_block_only(flush == Z_FINISH); if(strm.avail_out==0) return (flush == Z_FINISH) ? FinishStarted : NeedMore; return flush == Z_FINISH ? FinishDone : BlockDone; } // Send a stored block void _tr_stored_block(int buf, // input block int stored_len, // length of input block boolean eof // true if this is the last block for a file ){ send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type copy_block(buf, stored_len, true); // with header } // Determine the best encoding for the current block: dynamic trees, static // trees or store, and output the encoded block to the zip file. void _tr_flush_block(int buf, // input block, or NULL if too old int stored_len, // length of input block boolean eof // true if this is the last block for a file ) { int opt_lenb, static_lenb;// opt_len and static_len in bytes int max_blindex = 0; // index of last bit length code of non zero freq // Build the Huffman trees unless a stored block is forced if(level > 0) { // Check if the file is ascii or binary if(data_type == Z_UNKNOWN) set_data_type(); // Construct the literal and distance trees l_desc.build_tree(this); d_desc.build_tree(this); // At this point, opt_len and static_len are the total bit lengths of // the compressed block data, excluding the tree representations. // Build the bit length tree for the above two trees, and get the index // in bl_order of the last bit length code to send. max_blindex=build_bl_tree(); // Determine the best encoding. Compute first the block length in bytes opt_lenb=(opt_len+3+7)>>>3; static_lenb=(static_len+3+7)>>>3; if(static_lenb<=opt_lenb) opt_lenb=static_lenb; } else { opt_lenb=static_lenb=stored_len+5; // force a stored block } if(stored_len+4<=opt_lenb && buf != -1){ // 4: two words for the lengths // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. // Otherwise we can't have processed more than WSIZE input bytes since // the last block flush, because compression would have been // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to // transform a block into a stored block. _tr_stored_block(buf, stored_len, eof); } else if(static_lenb == opt_lenb){ send_bits((STATIC_TREES<<1)+(eof?1:0), 3); compress_block(StaticTree.static_ltree, StaticTree.static_dtree); } else{ send_bits((DYN_TREES<<1)+(eof?1:0), 3); send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); compress_block(dyn_ltree, dyn_dtree); } // The above check is made mod 2^32, for files larger than 512 MB // and uLong implemented on 32 bits. init_block(); if(eof){ bi_windup(); } } // Fill the window when the lookahead becomes insufficient. // Updates strstart and lookahead. // // IN assertion: lookahead < MIN_LOOKAHEAD // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD // At least one byte has been read, or avail_in == 0; reads are // performed for at least two bytes (required for the zip translate_eol // option -- not supported here). void fill_window(){ int n, m; int p; int more; // Amount of free space at the end of the window. do{ more = (window_size-lookahead-strstart); // Deal with !@#$% 64K limit: if(more==0 && strstart==0 && lookahead==0){ more = w_size; } else if(more==-1) { // Very unlikely, but possible on 16 bit machine if strstart == 0 // and lookahead == 1 (input done one byte at time) more--; // If the window is almost full and there is insufficient lookahead, // move the upper half to the lower one to make room in the upper half. } else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { System.arraycopy(window, w_size, window, 0, w_size); match_start-=w_size; strstart-=w_size; // we now have strstart >= MAX_DIST block_start-=w_size; // Slide the hash table (could be avoided with 32 bit values // at the expense of memory usage). We slide even when level == 0 // to keep the hash table consistent if we switch back to level > 0 // later. (Using level 0 permanently is not an optimal usage of // zlib, so we don't care about this pathological case.) n = hash_size; p=n; do { m = (head[--p]&0xffff); head[p]=(m>=w_size ? (short)(m-w_size) : 0); } while (--n != 0); n = w_size; p = n; do { m = (prev[--p]&0xffff); prev[p] = (m >= w_size ? (short)(m-w_size) : 0); // If n is not on any hash chain, prev[n] is garbage but // its value will never be used. } while (--n!=0); more += w_size; } if (strm.avail_in == 0) return; // If there was no sliding: // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && // more == window_size - lookahead - strstart // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) // => more >= window_size - 2*WSIZE + 2 // In the BIG_MEM or MMAP case (not yet supported), // window_size == input_size + MIN_LOOKAHEAD && // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. // Otherwise, window_size == 2*WSIZE so more >= 2. // If there was sliding, more >= WSIZE. So in all cases, more >= 2. n = strm.read_buf(window, strstart + lookahead, more); lookahead += n; // Initialize the hash value now that we have some input: if(lookahead >= MIN_MATCH) { ins_h = window[strstart]&0xff; ins_h=(((ins_h)<= MIN_MATCH){ ins_h=(((ins_h)<=MIN_MATCH){ // check_match(strstart, match_start, match_length); bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); lookahead -= match_length; // Insert new strings in the hash table only if the match length // is not too large. This saves time but degrades compression. if(match_length <= max_lazy_match && lookahead >= MIN_MATCH) { match_length--; // string at strstart already in hash table do{ strstart++; ins_h=((ins_h<= MIN_MATCH) { ins_h=(((ins_h)< 4096))) { // If prev_match is also MIN_MATCH, match_start is garbage // but we will ignore the current match anyway. match_length = MIN_MATCH-1; } } // If there was a match at the previous step and the current // match is not better, output the previous match: if(prev_length >= MIN_MATCH && match_length <= prev_length) { int max_insert = strstart + lookahead - MIN_MATCH; // Do not insert strings in hash table beyond this. // check_match(strstart-1, prev_match, prev_length); bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); // Insert in hash table all strings up to the end of the match. // strstart-1 and strstart are already inserted. If there is not // enough lookahead, the last two strings are not inserted in // the hash table. lookahead -= prev_length-1; prev_length -= 2; do{ if(++strstart <= max_insert) { ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? strstart-(w_size-MIN_LOOKAHEAD) : 0; int nice_match=this.nice_match; // Stop when cur_match becomes <= limit. To simplify the code, // we prevent matches with the string of window index 0. int wmask = w_mask; int strend = strstart + MAX_MATCH; byte scan_end1 = window[scan+best_len-1]; byte scan_end = window[scan+best_len]; // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. // It is easy to get rid of this optimization if necessary. // Do not waste too much time if we already have a good match: if (prev_length >= good_match) { chain_length >>= 2; } // Do not look for matches beyond the end of the input. This is necessary // to make deflate deterministic. if (nice_match > lookahead) nice_match = lookahead; do { match = cur_match; // Skip to next match if the match length cannot increase // or if the match length is less than 2: if (window[match+best_len] != scan_end || window[match+best_len-1] != scan_end1 || window[match] != window[scan] || window[++match] != window[scan+1]) continue; // The check at best_len-1 can be removed because it will be made // again later. (This heuristic is not always a win.) // It is not necessary to compare scan[2] and match[2] since they // are always equal when the other bytes match, given that // the hash keys are equal and that HASH_BITS >= 8. scan += 2; match++; // We check for insufficient lookahead only every 8th comparison; // the 256th check will be made at strstart+258. do { } while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; if(len>best_len) { match_start = cur_match; best_len = len; if (len >= nice_match) break; scan_end1 = window[scan+best_len-1]; scan_end = window[scan+best_len]; } } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit && --chain_length != 0); if (best_len <= lookahead) return best_len; return lookahead; } int deflateInit(int level, int bits, int memlevel){ return deflateInit(level, Z_DEFLATED, bits, memlevel, Z_DEFAULT_STRATEGY); } int deflateInit(int level, int bits){ return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); } int deflateInit(int level){ return deflateInit(level, MAX_WBITS); } private int deflateInit(int level, int method, int windowBits, int memLevel, int strategy){ int wrap = 1; // byte[] my_version=ZLIB_VERSION; // // if (version == null || version[0] != my_version[0] // || stream_size != sizeof(z_stream)) { // return Z_VERSION_ERROR; // } strm.msg = null; if (level == Z_DEFAULT_COMPRESSION) level = 6; if (windowBits < 0) { // undocumented feature: suppress zlib header wrap = 0; windowBits = -windowBits; } else if(windowBits > 15){ wrap = 2; windowBits -= 16; strm.adler=new CRC32(); } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } strm.dstate = (Deflate)this; this.wrap = wrap; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; hash_bits = memLevel + 7; hash_size = 1 << hash_bits; hash_mask = hash_size - 1; hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); window = new byte[w_size*2]; prev = new short[w_size]; head = new short[hash_size]; lit_bufsize = 1 << (memLevel + 6); // 16K elements by default // We overlay pending_buf and d_buf+l_buf. This works since the average // output size for (length,distance) codes is <= 24 bits. pending_buf = new byte[lit_bufsize*3]; pending_buf_size = lit_bufsize*3; d_buf = lit_bufsize; l_buf = new byte[lit_bufsize]; this.level = level; this.strategy = strategy; this.method = (byte)method; return deflateReset(); } int deflateReset(){ strm.total_in = strm.total_out = 0; strm.msg = null; // strm.data_type = Z_UNKNOWN; pending = 0; pending_out = 0; if(wrap < 0){ wrap = -wrap; } status = (wrap==0) ? BUSY_STATE : INIT_STATE; strm.adler.reset(); last_flush = Z_NO_FLUSH; tr_init(); lm_init(); return Z_OK; } int deflateEnd(){ if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ return Z_STREAM_ERROR; } // Deallocate in reverse order of allocations: pending_buf=null; l_buf=null; head=null; prev=null; window=null; // free // dstate=null; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } int deflateParams(int _level, int _strategy){ int err=Z_OK; if(_level == Z_DEFAULT_COMPRESSION){ _level = 6; } if(_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } if(config_table[level].func!=config_table[_level].func && strm.total_in != 0) { // Flush the last buffer: err = strm.deflate(Z_PARTIAL_FLUSH); } if(level != _level) { level = _level; max_lazy_match = config_table[level].max_lazy; good_match = config_table[level].good_length; nice_match = config_table[level].nice_length; max_chain_length = config_table[level].max_chain; } strategy = _strategy; return err; } int deflateSetDictionary (byte[] dictionary, int dictLength){ int length = dictLength; int index=0; if(dictionary == null || status != INIT_STATE) return Z_STREAM_ERROR; strm.adler.update(dictionary, 0, dictLength); if(length < MIN_MATCH) return Z_OK; if(length > w_size-MIN_LOOKAHEAD){ length = w_size-MIN_LOOKAHEAD; index=dictLength-length; // use the tail of the dictionary } System.arraycopy(dictionary, index, window, 0, length); strstart = length; block_start = length; // Insert all strings in the hash table (except for the last two bytes). // s->lookahead stays null, so s->ins_h will be recomputed at the next // call of fill_window. ins_h = window[0]&0xff; ins_h=(((ins_h)<Z_FINISH || flush<0){ return Z_STREAM_ERROR; } if(strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == FINISH_STATE && flush != Z_FINISH)) { strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; return Z_STREAM_ERROR; } if(strm.avail_out == 0){ strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; return Z_BUF_ERROR; } old_flush = last_flush; last_flush = flush; // Write the zlib header if(status == INIT_STATE) { if(wrap == 2){ getGZIPHeader().put(this); status=BUSY_STATE; strm.adler.reset(); } else{ int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; int level_flags=((level-1)&0xff)>>1; if(level_flags>3) level_flags=3; header |= (level_flags<<6); if(strstart!=0) header |= PRESET_DICT; header+=31-(header % 31); status=BUSY_STATE; putShortMSB(header); // Save the adler32 of the preset dictionary: if(strstart!=0){ long adler=strm.adler.getValue(); putShortMSB((int)(adler>>>16)); putShortMSB((int)(adler&0xffff)); } strm.adler.reset(); } } // Flush as much pending output as possible if(pending != 0) { strm.flush_pending(); if(strm.avail_out == 0) { // Since avail_out is 0, deflate will be called again with // more output space, but possibly with both pending and // avail_in equal to zero. There won't be anything to do, // but this is not an error situation so make sure we // return OK instead of BUF_ERROR at next call of deflate: last_flush = -1; return Z_OK; } // Make sure there is something to do and avoid duplicate consecutive // flushes. For repeated and useless calls with Z_FINISH, we keep // returning Z_STREAM_END instead of Z_BUFF_ERROR. } else if(strm.avail_in==0 && flush <= old_flush && flush != Z_FINISH) { strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; return Z_BUF_ERROR; } // User must not provide more input after the first FINISH: if(status == FINISH_STATE && strm.avail_in != 0) { strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; return Z_BUF_ERROR; } // Start a new block or continue the current one. if(strm.avail_in!=0 || lookahead!=0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) { int bstate=-1; switch(config_table[level].func){ case STORED: bstate = deflate_stored(flush); break; case FAST: bstate = deflate_fast(flush); break; case SLOW: bstate = deflate_slow(flush); break; default: } if (bstate==FinishStarted || bstate==FinishDone) { status = FINISH_STATE; } if (bstate==NeedMore || bstate==FinishStarted) { if(strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR next call, see above } return Z_OK; // If flush != Z_NO_FLUSH && avail_out == 0, the next call // of deflate should use the same flush parameter to make sure // that the flush is complete. So we don't have to output an // empty block here, this will be done at next call. This also // ensures that for a very small output buffer, we emit at most // one empty block. } if (bstate==BlockDone) { if(flush == Z_PARTIAL_FLUSH) { _tr_align(); } else { // FULL_FLUSH or SYNC_FLUSH _tr_stored_block(0, 0, false); // For a full flush, this empty block will be recognized // as a special marker by inflate_sync(). if(flush == Z_FULL_FLUSH) { //state.head[s.hash_size-1]=0; for(int i=0; i>8)&0xff)); put_byte((byte)((adler>>16)&0xff)); put_byte((byte)((adler>>24)&0xff)); put_byte((byte)(strm.total_in&0xff)); put_byte((byte)((strm.total_in>>8)&0xff)); put_byte((byte)((strm.total_in>>16)&0xff)); put_byte((byte)((strm.total_in>>24)&0xff)); getGZIPHeader().setCRC(adler); } else{ // Write the zlib trailer (adler32) long adler=strm.adler.getValue(); putShortMSB((int)(adler>>>16)); putShortMSB((int)(adler&0xffff)); } strm.flush_pending(); // If avail_out is zero, the application will call deflate again // to flush the rest. if(wrap > 0) wrap = -wrap; // write the trailer only once! return pending != 0 ? Z_OK : Z_STREAM_END; } static int deflateCopy(ZStream dest, ZStream src){ if(src.dstate == null){ return Z_STREAM_ERROR; } if(src.next_in!=null){ dest.next_in = new byte[src.next_in.length]; System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); } dest.next_in_index = src.next_in_index; dest.avail_in = src.avail_in; dest.total_in = src.total_in; if(src.next_out!=null){ dest.next_out = new byte[src.next_out.length]; System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); } dest.next_out_index = src.next_out_index; dest.avail_out = src.avail_out; dest.total_out = src.total_out; dest.msg = src.msg; dest.data_type = src.data_type; dest.adler = src.adler.copy(); try{ dest.dstate = (Deflate)src.dstate.clone(); dest.dstate.strm = dest; } catch(CloneNotSupportedException e){ // } return Z_OK; } public Object clone() throws CloneNotSupportedException { Deflate dest = (Deflate)super.clone(); dest.pending_buf = dup(dest.pending_buf); dest.d_buf = dest.d_buf; dest.l_buf = dup(dest.l_buf); dest.window = dup(dest.window); dest.prev = dup(dest.prev); dest.head = dup(dest.head); dest.dyn_ltree = dup(dest.dyn_ltree); dest.dyn_dtree = dup(dest.dyn_dtree); dest.bl_tree = dup(dest.bl_tree); dest.bl_count = dup(dest.bl_count); dest.next_code = dup(dest.next_code); dest.heap = dup(dest.heap); dest.depth = dup(dest.depth); dest.l_desc.dyn_tree = dest.dyn_ltree; dest.d_desc.dyn_tree = dest.dyn_dtree; dest.bl_desc.dyn_tree = dest.bl_tree; /* dest.l_desc.stat_desc = StaticTree.static_l_desc; dest.d_desc.stat_desc = StaticTree.static_d_desc; dest.bl_desc.stat_desc = StaticTree.static_bl_desc; */ if(dest.gheader!=null){ dest.gheader = (GZIPHeader)dest.gheader.clone(); } return dest; } private byte[] dup(byte[] buf){ byte[] foo = new byte[buf.length]; System.arraycopy(buf, 0, foo, 0, foo.length); return foo; } private short[] dup(short[] buf){ short[] foo = new short[buf.length]; System.arraycopy(buf, 0, foo, 0, foo.length); return foo; } private int[] dup(int[] buf){ int[] foo = new int[buf.length]; System.arraycopy(buf, 0, foo, 0, foo.length); return foo; } synchronized GZIPHeader getGZIPHeader(){ if(gheader==null){ gheader = new GZIPHeader(); } return gheader; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/Deflater.java000066400000000000000000000124761222267011700230260ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final public class Deflater extends ZStream{ static final private int MAX_WBITS=15; // 32K LZ77 window static final private int DEF_WBITS=MAX_WBITS; static final private int Z_NO_FLUSH=0; static final private int Z_PARTIAL_FLUSH=1; static final private int Z_SYNC_FLUSH=2; static final private int Z_FULL_FLUSH=3; static final private int Z_FINISH=4; static final private int MAX_MEM_LEVEL=9; static final private int Z_OK=0; static final private int Z_STREAM_END=1; static final private int Z_NEED_DICT=2; static final private int Z_ERRNO=-1; static final private int Z_STREAM_ERROR=-2; static final private int Z_DATA_ERROR=-3; static final private int Z_MEM_ERROR=-4; static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; private boolean finished = false; public Deflater(){ super(); } public Deflater(int level) throws GZIPException { this(level, MAX_WBITS); } public Deflater(int level, boolean nowrap) throws GZIPException { this(level, MAX_WBITS, nowrap); } public Deflater(int level, int bits) throws GZIPException { this(level, bits, false); } public Deflater(int level, int bits, boolean nowrap) throws GZIPException { super(); int ret = init(level, bits, nowrap); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); } public Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { super(); int ret = init(level, bits, memlevel, wrapperType); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); } public Deflater(int level, int bits, int memlevel) throws GZIPException { super(); int ret = init(level, bits, memlevel); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); } public int init(int level){ return init(level, MAX_WBITS); } public int init(int level, boolean nowrap){ return init(level, MAX_WBITS, nowrap); } public int init(int level, int bits){ return init(level, bits, false); } public int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ if(bits < 9 || bits > 15){ return Z_STREAM_ERROR; } if(wrapperType == JZlib.W_NONE) { bits *= -1; } else if(wrapperType == JZlib.W_GZIP) { bits += 16; } else if(wrapperType == JZlib.W_ANY) { return Z_STREAM_ERROR; } else if(wrapperType == JZlib.W_ZLIB) { } return init(level, bits, memlevel); } public int init(int level, int bits, int memlevel){ finished = false; dstate=new Deflate(this); return dstate.deflateInit(level, bits, memlevel); } public int init(int level, int bits, boolean nowrap){ finished = false; dstate=new Deflate(this); return dstate.deflateInit(level, nowrap?-bits:bits); } public int deflate(int flush){ if(dstate==null){ return Z_STREAM_ERROR; } int ret = dstate.deflate(flush); if(ret == Z_STREAM_END) finished = true; return ret; } public int end(){ finished = true; if(dstate==null) return Z_STREAM_ERROR; int ret=dstate.deflateEnd(); dstate=null; free(); return ret; } public int params(int level, int strategy){ if(dstate==null) return Z_STREAM_ERROR; return dstate.deflateParams(level, strategy); } public int setDictionary (byte[] dictionary, int dictLength){ if(dstate == null) return Z_STREAM_ERROR; return dstate.deflateSetDictionary(dictionary, dictLength); } public boolean finished(){ return finished; } public int copy(Deflater src){ this.finished = src.finished; return Deflate.deflateCopy(this, src); } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/DeflaterOutputStream.java000066400000000000000000000121501222267011700254100ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jzlib; import java.io.*; public class DeflaterOutputStream extends FilterOutputStream { protected final Deflater deflater; protected byte[] buffer; private boolean closed = false; private boolean syncFlush = false; private final byte[] buf1 = new byte[1]; protected boolean mydeflater = false; private boolean close_out = true; protected static final int DEFAULT_BUFSIZE = 512; public DeflaterOutputStream(OutputStream out) throws IOException { this(out, new Deflater(JZlib.Z_DEFAULT_COMPRESSION), DEFAULT_BUFSIZE, true); mydeflater = true; } public DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { this(out, def, DEFAULT_BUFSIZE, true); } public DeflaterOutputStream(OutputStream out, Deflater deflater, int size) throws IOException { this(out, deflater, size, true); } public DeflaterOutputStream(OutputStream out, Deflater deflater, int size, boolean close_out) throws IOException { super(out); if (out == null || deflater == null) { throw new NullPointerException(); } else if (size <= 0) { throw new IllegalArgumentException("buffer size must be greater than 0"); } this.deflater = deflater; buffer = new byte[size]; this.close_out = close_out; } public void write(int b) throws IOException { buf1[0] = (byte)(b & 0xff); write(buf1, 0, 1); } public void write(byte[] b, int off, int len) throws IOException { if (deflater.finished()) { throw new IOException("finished"); } else if (off<0 | len<0 | off+len>b.length) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return; } else { int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; deflater.setInput(b, off, len, true); while (deflater.avail_in>0) { int err = deflate(flush); if (err == JZlib.Z_STREAM_END) break; } } } public void finish() throws IOException { while (!deflater.finished()) { deflate(JZlib.Z_FINISH); } } public void close() throws IOException { if (!closed) { finish(); if (mydeflater){ deflater.end(); } if(close_out) out.close(); closed = true; } } protected int deflate(int flush) throws IOException { deflater.setOutput(buffer, 0, buffer.length); int err = deflater.deflate(flush); switch(err) { case JZlib.Z_OK: case JZlib.Z_STREAM_END: break; case JZlib.Z_BUF_ERROR: if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ // flush() without any data break; } default: throw new IOException("failed to deflate"); } int len = deflater.next_out_index; if (len > 0) { out.write(buffer, 0, len); } return err; } public void flush() throws IOException { if (syncFlush && !deflater.finished()) { while (true) { int err = deflate(JZlib.Z_SYNC_FLUSH); if (deflater.next_out_index < buffer.length) break; if (err == JZlib.Z_STREAM_END) break; } } out.flush(); } public long getTotalIn() { return deflater.getTotalIn(); } public long getTotalOut() { return deflater.getTotalOut(); } public void setSyncFlush(boolean syncFlush){ this.syncFlush = syncFlush; } public boolean getSyncFlush(){ return this.syncFlush; } public Deflater getDeflater(){ return deflater; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/GZIPException.java000066400000000000000000000035071222267011700237230ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; public class GZIPException extends java.io.IOException { public GZIPException() { super(); } public GZIPException(String s) { super(s); } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/GZIPHeader.java000066400000000000000000000135471222267011700231620ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; import java.io.UnsupportedEncodingException; /** * @see "http://www.ietf.org/rfc/rfc1952.txt" */ public class GZIPHeader implements Cloneable { public static final byte OS_MSDOS = (byte) 0x00; public static final byte OS_AMIGA = (byte) 0x01; public static final byte OS_VMS = (byte) 0x02; public static final byte OS_UNIX = (byte) 0x03; public static final byte OS_ATARI = (byte) 0x05; public static final byte OS_OS2 = (byte) 0x06; public static final byte OS_MACOS = (byte) 0x07; public static final byte OS_TOPS20 = (byte) 0x0a; public static final byte OS_WIN32 = (byte) 0x0b; public static final byte OS_VMCMS = (byte) 0x04; public static final byte OS_ZSYSTEM = (byte) 0x08; public static final byte OS_CPM = (byte) 0x09; public static final byte OS_QDOS = (byte) 0x0c; public static final byte OS_RISCOS = (byte) 0x0d; public static final byte OS_UNKNOWN = (byte) 0xff; boolean text = false; private boolean fhcrc = false; long time; int xflags; int os = 255; byte[] extra; byte[] name; byte[] comment; int hcrc; long crc; boolean done = false; long mtime = 0; public void setModifiedTime(long mtime) { this.mtime = mtime; } public long getModifiedTime() { return mtime; } public void setOS(int os) { if((0<=os && os <=13) || os==255) this.os=os; else throw new IllegalArgumentException("os: "+os); } public int getOS(){ return os; } public void setName(String name) { try{ this.name=name.getBytes("ISO-8859-1"); } catch(UnsupportedEncodingException e){ throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); } } public String getName(){ if(name==null) return ""; try { return new String(name, "ISO-8859-1"); } catch (UnsupportedEncodingException e) { throw new InternalError(e.toString()); } } public void setComment(String comment) { try{ this.comment=comment.getBytes("ISO-8859-1"); } catch(UnsupportedEncodingException e){ throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); } } public String getComment(){ if(comment==null) return ""; try { return new String(comment, "ISO-8859-1"); } catch (UnsupportedEncodingException e) { throw new InternalError(e.toString()); } } public void setCRC(long crc){ this.crc = crc; } public long getCRC(){ return crc; } void put(Deflate d){ int flag = 0; if(text){ flag |= 1; // FTEXT } if(fhcrc){ flag |= 2; // FHCRC } if(extra!=null){ flag |= 4; // FEXTRA } if(name!=null){ flag |= 8; // FNAME } if(comment!=null){ flag |= 16; // FCOMMENT } int xfl = 0; if(d.level == JZlib.Z_BEST_SPEED){ xfl |= 4; } else if (d.level == JZlib.Z_BEST_COMPRESSION){ xfl |= 2; } d.put_short((short)0x8b1f); // ID1 ID2 d.put_byte((byte)8); // CM(Compression Method) d.put_byte((byte)flag); d.put_byte((byte)mtime); d.put_byte((byte)(mtime>>8)); d.put_byte((byte)(mtime>>16)); d.put_byte((byte)(mtime>>24)); d.put_byte((byte)xfl); d.put_byte((byte)os); if(extra!=null){ d.put_byte((byte)extra.length); d.put_byte((byte)(extra.length>>8)); d.put_byte(extra, 0, extra.length); } if(name!=null){ d.put_byte(name, 0, name.length); d.put_byte((byte)0); } if(comment!=null){ d.put_byte(comment, 0, comment.length); d.put_byte((byte)0); } } @Override public Object clone() throws CloneNotSupportedException { GZIPHeader gheader = (GZIPHeader)super.clone(); byte[] tmp; if(gheader.extra!=null){ tmp=new byte[gheader.extra.length]; System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); gheader.extra = tmp; } if(gheader.name!=null){ tmp=new byte[gheader.name.length]; System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); gheader.name = tmp; } if(gheader.comment!=null){ tmp=new byte[gheader.comment.length]; System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); gheader.comment = tmp; } return gheader; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/GZIPInputStream.java000066400000000000000000000104621222267011700242360ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jzlib; import java.io.*; public class GZIPInputStream extends InflaterInputStream { public GZIPInputStream(InputStream in) throws IOException { this(in, DEFAULT_BUFSIZE, true); } public GZIPInputStream(InputStream in, int size, boolean close_in) throws IOException { this(in, new Inflater(15+16), size, close_in); myinflater = true; } public GZIPInputStream(InputStream in, Inflater inflater, int size, boolean close_in) throws IOException { super(in, inflater, size, close_in); } public long getModifiedtime() { return inflater.istate.getGZIPHeader().getModifiedTime(); } public int getOS() { return inflater.istate.getGZIPHeader().getOS(); } public String getName() { return inflater.istate.getGZIPHeader().getName(); } public String getComment() { return inflater.istate.getGZIPHeader().getComment(); } public long getCRC() throws GZIPException { if(inflater.istate.mode != 12 /*DONE*/) throw new GZIPException("checksum is not calculated yet."); return inflater.istate.getGZIPHeader().getCRC(); } public void readHeader() throws IOException { byte[] empty = "".getBytes(); inflater.setOutput(empty, 0, 0); inflater.setInput(empty, 0, 0, false); byte[] b = new byte[10]; int n = fill(b); if(n!=10){ if(n>0){ inflater.setInput(b, 0, n, false); //inflater.next_in_index = n; inflater.next_in_index = 0; inflater.avail_in = n; } throw new IOException("no input"); } inflater.setInput(b, 0, n, false); byte[] b1 = new byte[1]; do{ if(inflater.avail_in<=0){ int i = in.read(b1); if(i<=0) throw new IOException("no input"); inflater.setInput(b1, 0, 1, true); } int err = inflater.inflate(JZlib.Z_NO_FLUSH); if(err!=0/*Z_OK*/){ int len = 2048-inflater.next_in.length; if(len>0){ byte[] tmp = new byte[len]; n = fill(tmp); if(n>0){ inflater.avail_in += inflater.next_in_index; inflater.next_in_index = 0; inflater.setInput(tmp, 0, n, true); } } //inflater.next_in_index = inflater.next_in.length; inflater.avail_in += inflater.next_in_index; inflater.next_in_index = 0; throw new IOException(inflater.msg); } } while(inflater.istate.inParsingHeader()); } private int fill(byte[] buf) { int len = buf.length; int n = 0; do{ int i = -1; try { i = in.read(buf, n, buf.length - n); } catch(IOException e){ } if(i == -1){ break; } n+=i; } while(n>> 1){ case 0: // stored {b>>>=(3);k-=(3);} t = k & 7; // go to byte boundary {b>>>=(t);k-=(t);} mode = LENS; // get length of stored block break; case 1: // fixed InfTree.inflate_trees_fixed(bl, bd, tl, td, z); codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); {b>>>=(3);k-=(3);} mode = CODES; break; case 2: // dynamic {b>>>=(3);k-=(3);} mode = TABLE; break; case 3: // illegal {b>>>=(3);k-=(3);} mode = BAD; z.msg = "invalid block type"; r = Z_DATA_ERROR; bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } break; case LENS: while(k<(32)){ if(n!=0){ r=Z_OK; } else{ bitb=b; bitk=k; z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ mode = BAD; z.msg = "invalid stored block lengths"; r = Z_DATA_ERROR; bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } left = (b & 0xffff); b = k = 0; // dump bits mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); break; case STORED: if (n == 0){ bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } if(m==0){ if(q==end&&read!=0){ q=0; m=(int)(qn) t = n; if(t>m) t = m; System.arraycopy(z.next_in, p, window, q, t); p += t; n -= t; q += t; m -= t; if ((left -= t) != 0) break; mode = last!=0 ? DRY : TYPE; break; case TABLE: while(k<(14)){ if(n!=0){ r=Z_OK; } else{ bitb=b; bitk=k; z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) { mode = BAD; z.msg = "too many length or distance symbols"; r = Z_DATA_ERROR; bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if(blens==null || blens.length>>=(14);k-=(14);} index = 0; mode = BTREE; case BTREE: while (index < 4 + (table >>> 10)){ while(k<(3)){ if(n!=0){ r=Z_OK; } else{ bitb=b; bitk=k; z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} } while(index < 19){ blens[border[index++]] = 0; } bb[0] = 7; t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); if (t != Z_OK){ r = t; if (r == Z_DATA_ERROR){ blens=null; mode = BAD; } bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } index = 0; mode = DTREE; case DTREE: while (true){ t = table; if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ break; } int[] h; int i, j, c; t = bb[0]; while(k<(t)){ if(n!=0){ r=Z_OK; } else{ bitb=b; bitk=k; z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); blens[index++] = c; } else { // c == 16..18 i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; while(k<(t+i)){ if(n!=0){ r=Z_OK; } else{ bitb=b; bitk=k; z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); }; n--; b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); j += (b & inflate_mask[i]); b>>>=(i);k-=(i); i = index; t = table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)){ blens=null; mode = BAD; z.msg = "invalid bit length repeat"; r = Z_DATA_ERROR; bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } c = c == 16 ? blens[i-1] : 0; do{ blens[i++] = c; } while (--j!=0); index = i; } } tb[0]=-1; { bl[0] = 9; // must be <= 9 for lookahead assumptions bd[0] = 6; // must be <= 9 for lookahead assumptions t = table; t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tli, tdi, hufts, z); if (t != Z_OK){ if (t == Z_DATA_ERROR){ blens=null; mode = BAD; } r = t; bitb=b; bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; return inflate_flush(r); } codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); } mode = CODES; case CODES: bitb=b; bitk=k; z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; write=q; if ((r = codes.proc(r)) != Z_STREAM_END){ return inflate_flush(r); } r = Z_OK; codes.free(z); p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; q=write;m=(int)(q z.avail_out) n = z.avail_out; if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; // update counters z.avail_out -= n; z.total_out += n; // update check information if(check && n>0){ z.adler.update(window, q, n); } // copy as far as end of window System.arraycopy(window, q, z.next_out, p, n); p += n; q += n; // see if more to copy at beginning of window if (q == end){ // wrap pointers q = 0; if (write == end) write = 0; // compute bytes to copy n = write - q; if (n > z.avail_out) n = z.avail_out; if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; // update counters z.avail_out -= n; z.total_out += n; // update check information if(check && n>0){ z.adler.update(window, q, n); } // copy System.arraycopy(window, q, z.next_out, p, n); p += n; q += n; } // update pointers z.next_out_index = p; read = q; // done return r; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/InfCodes.java000066400000000000000000000373261222267011700227730ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final class InfCodes{ static final private int[] inflate_mask = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff }; static final private int Z_OK=0; static final private int Z_STREAM_END=1; static final private int Z_NEED_DICT=2; static final private int Z_ERRNO=-1; static final private int Z_STREAM_ERROR=-2; static final private int Z_DATA_ERROR=-3; static final private int Z_MEM_ERROR=-4; static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; // waiting for "i:"=input, // "o:"=output, // "x:"=nothing static final private int START=0; // x: set up for LEN static final private int LEN=1; // i: get length/literal/eob next static final private int LENEXT=2; // i: getting length extra (have base) static final private int DIST=3; // i: get distance next static final private int DISTEXT=4;// i: getting distance extra static final private int COPY=5; // o: copying bytes in window, waiting for space static final private int LIT=6; // o: got literal, waiting for output space static final private int WASH=7; // o: got eob, possibly still output waiting static final private int END=8; // x: got eob and all data flushed static final private int BADCODE=9;// x: got error int mode; // current inflate_codes mode // mode dependent information int len; int[] tree; // pointer into tree int tree_index=0; int need; // bits needed int lit; // if EXT or COPY, where and how much int get; // bits to get for extra int dist; // distance back to copy from byte lbits; // ltree bits decoded per branch byte dbits; // dtree bits decoder per branch int[] ltree; // literal/length/eob tree int ltree_index; // literal/length/eob tree int[] dtree; // distance tree int dtree_index; // distance tree private final ZStream z; private final InfBlocks s; InfCodes(ZStream z, InfBlocks s){ this.z=z; this.s=s; } void init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index){ mode=START; lbits=(byte)bl; dbits=(byte)bd; ltree=tl; ltree_index=tl_index; dtree = td; dtree_index=td_index; tree=null; } int proc(int r){ int j; // temporary storage int[] t; // temporary pointer int tindex; // temporary pointer int e; // extra bits or operation int b=0; // bit buffer int k=0; // bits in bit buffer int p=0; // input data pointer int n; // bytes available there int q; // output window write pointer int m; // bytes to end of window or read pointer int f; // pointer to copy strings from // copy input/output information to locals (UPDATE macro restores) p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; q=s.write;m=q= 258 && n >= 10){ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; q=s.write;m=q>>=(tree[tindex+1]); k-=(tree[tindex+1]); e=tree[tindex]; if(e == 0){ // literal lit = tree[tindex+2]; mode = LIT; break; } if((e & 16)!=0 ){ // length get = e & 15; len = tree[tindex+2]; mode = LENEXT; break; } if ((e & 64) == 0){ // next table need = e; tree_index = tindex/3+tree[tindex+2]; break; } if ((e & 32)!=0){ // end of block mode = WASH; break; } mode = BADCODE; // invalid code z.msg = "invalid literal/length code"; r = Z_DATA_ERROR; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(r); case LENEXT: // i: getting length extra (have base) j = get; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(r); } n--; b|=(z.next_in[p++]&0xff)<>=j; k-=j; need = dbits; tree = dtree; tree_index=dtree_index; mode = DIST; case DIST: // i: get distance next j = need; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(r); } n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; k-=tree[tindex+1]; e = (tree[tindex]); if((e & 16)!=0){ // distance get = e & 15; dist = tree[tindex+2]; mode = DISTEXT; break; } if ((e & 64) == 0){ // next table need = e; tree_index = tindex/3 + tree[tindex+2]; break; } mode = BADCODE; // invalid code z.msg = "invalid distance code"; r = Z_DATA_ERROR; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(r); case DISTEXT: // i: getting distance extra j = get; while(k<(j)){ if(n!=0)r=Z_OK; else{ s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return s.inflate_flush(r); } n--; b|=(z.next_in[p++]&0xff)<>=j; k-=j; mode = COPY; case COPY: // o: copying bytes in window, waiting for space f = q - dist; while(f < 0){ // modulo window size-"while" instead f += s.end; // of "if" handles invalid distances } while (len!=0){ if(m==0){ if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any k -= 8; n++; p--; // can always return one } s.write=q; r=s.inflate_flush(r); q=s.write;m=q= 258 && n >= 10 // get literal/length code while(k<(20)){ // max bits for literal/length code n--; b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); s.window[q++] = (byte)tp[tp_index_t_3+2]; m--; continue; } do { b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); if((e&16)!=0){ e &= 15; c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); b>>=e; k-=e; // decode distance base of block to copy while(k<(15)){ // max bits for distance code n--; b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); if((e&16)!=0){ // get extra bits to add to distance base e &= 15; while(k<(e)){ // get extra bits (up to 13) n--; b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); // do the copy m -= c; if (q >= d){ // offset before dest // just copy r=q-d; if(q-r>0 && 2>(q-r)){ s.window[q++]=s.window[r++]; // minimum count is three, s.window[q++]=s.window[r++]; // so unroll loop a little c-=2; } else{ System.arraycopy(s.window, r, s.window, q, 2); q+=2; r+=2; c-=2; } } else{ // else offset after destination r=q-d; do{ r+=s.end; // force pointer in window }while(r<0); // covers invalid distances e=s.end-r; if(c>e){ // if source crosses, c-=e; // wrapped copy if(q-r>0 && e>(q-r)){ do{s.window[q++] = s.window[r++];} while(--e!=0); } else{ System.arraycopy(s.window, r, s.window, q, e); q+=e; r+=e; e=0; } r = 0; // copy rest from start of window } } // copy all or what's left if(q-r>0 && c>(q-r)){ do{s.window[q++] = s.window[r++];} while(--c!=0); } else{ System.arraycopy(s.window, r, s.window, q, c); q+=c; r+=c; c=0; } break; } else if((e&64)==0){ t+=tp[tp_index_t_3+2]; t+=(b&inflate_mask[e]); tp_index_t_3=(tp_index+t)*3; e=tp[tp_index_t_3]; } else{ z.msg = "invalid distance code"; c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_DATA_ERROR; } } while(true); break; } if((e&64)==0){ t+=tp[tp_index_t_3+2]; t+=(b&inflate_mask[e]); tp_index_t_3=(tp_index+t)*3; if((e=tp[tp_index_t_3])==0){ b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); s.window[q++]=(byte)tp[tp_index_t_3+2]; m--; break; } } else if((e&32)!=0){ c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_STREAM_END; } else{ z.msg="invalid literal/length code"; c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_DATA_ERROR; } } while(true); } while(m>=258 && n>= 10); // not enough input or output--restore pointers and return c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; s.bitb=b;s.bitk=k; z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; s.write=q; return Z_OK; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/InfTree.java000066400000000000000000000453261222267011700226340ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final class InfTree{ static final private int MANY=1440; static final private int Z_OK=0; static final private int Z_STREAM_END=1; static final private int Z_NEED_DICT=2; static final private int Z_ERRNO=-1; static final private int Z_STREAM_ERROR=-2; static final private int Z_DATA_ERROR=-3; static final private int Z_MEM_ERROR=-4; static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; static final int fixed_bl = 9; static final int fixed_bd = 5; static final int[] fixed_tl = { 96,7,256, 0,8,80, 0,8,16, 84,8,115, 82,7,31, 0,8,112, 0,8,48, 0,9,192, 80,7,10, 0,8,96, 0,8,32, 0,9,160, 0,8,0, 0,8,128, 0,8,64, 0,9,224, 80,7,6, 0,8,88, 0,8,24, 0,9,144, 83,7,59, 0,8,120, 0,8,56, 0,9,208, 81,7,17, 0,8,104, 0,8,40, 0,9,176, 0,8,8, 0,8,136, 0,8,72, 0,9,240, 80,7,4, 0,8,84, 0,8,20, 85,8,227, 83,7,43, 0,8,116, 0,8,52, 0,9,200, 81,7,13, 0,8,100, 0,8,36, 0,9,168, 0,8,4, 0,8,132, 0,8,68, 0,9,232, 80,7,8, 0,8,92, 0,8,28, 0,9,152, 84,7,83, 0,8,124, 0,8,60, 0,9,216, 82,7,23, 0,8,108, 0,8,44, 0,9,184, 0,8,12, 0,8,140, 0,8,76, 0,9,248, 80,7,3, 0,8,82, 0,8,18, 85,8,163, 83,7,35, 0,8,114, 0,8,50, 0,9,196, 81,7,11, 0,8,98, 0,8,34, 0,9,164, 0,8,2, 0,8,130, 0,8,66, 0,9,228, 80,7,7, 0,8,90, 0,8,26, 0,9,148, 84,7,67, 0,8,122, 0,8,58, 0,9,212, 82,7,19, 0,8,106, 0,8,42, 0,9,180, 0,8,10, 0,8,138, 0,8,74, 0,9,244, 80,7,5, 0,8,86, 0,8,22, 192,8,0, 83,7,51, 0,8,118, 0,8,54, 0,9,204, 81,7,15, 0,8,102, 0,8,38, 0,9,172, 0,8,6, 0,8,134, 0,8,70, 0,9,236, 80,7,9, 0,8,94, 0,8,30, 0,9,156, 84,7,99, 0,8,126, 0,8,62, 0,9,220, 82,7,27, 0,8,110, 0,8,46, 0,9,188, 0,8,14, 0,8,142, 0,8,78, 0,9,252, 96,7,256, 0,8,81, 0,8,17, 85,8,131, 82,7,31, 0,8,113, 0,8,49, 0,9,194, 80,7,10, 0,8,97, 0,8,33, 0,9,162, 0,8,1, 0,8,129, 0,8,65, 0,9,226, 80,7,6, 0,8,89, 0,8,25, 0,9,146, 83,7,59, 0,8,121, 0,8,57, 0,9,210, 81,7,17, 0,8,105, 0,8,41, 0,9,178, 0,8,9, 0,8,137, 0,8,73, 0,9,242, 80,7,4, 0,8,85, 0,8,21, 80,8,258, 83,7,43, 0,8,117, 0,8,53, 0,9,202, 81,7,13, 0,8,101, 0,8,37, 0,9,170, 0,8,5, 0,8,133, 0,8,69, 0,9,234, 80,7,8, 0,8,93, 0,8,29, 0,9,154, 84,7,83, 0,8,125, 0,8,61, 0,9,218, 82,7,23, 0,8,109, 0,8,45, 0,9,186, 0,8,13, 0,8,141, 0,8,77, 0,9,250, 80,7,3, 0,8,83, 0,8,19, 85,8,195, 83,7,35, 0,8,115, 0,8,51, 0,9,198, 81,7,11, 0,8,99, 0,8,35, 0,9,166, 0,8,3, 0,8,131, 0,8,67, 0,9,230, 80,7,7, 0,8,91, 0,8,27, 0,9,150, 84,7,67, 0,8,123, 0,8,59, 0,9,214, 82,7,19, 0,8,107, 0,8,43, 0,9,182, 0,8,11, 0,8,139, 0,8,75, 0,9,246, 80,7,5, 0,8,87, 0,8,23, 192,8,0, 83,7,51, 0,8,119, 0,8,55, 0,9,206, 81,7,15, 0,8,103, 0,8,39, 0,9,174, 0,8,7, 0,8,135, 0,8,71, 0,9,238, 80,7,9, 0,8,95, 0,8,31, 0,9,158, 84,7,99, 0,8,127, 0,8,63, 0,9,222, 82,7,27, 0,8,111, 0,8,47, 0,9,190, 0,8,15, 0,8,143, 0,8,79, 0,9,254, 96,7,256, 0,8,80, 0,8,16, 84,8,115, 82,7,31, 0,8,112, 0,8,48, 0,9,193, 80,7,10, 0,8,96, 0,8,32, 0,9,161, 0,8,0, 0,8,128, 0,8,64, 0,9,225, 80,7,6, 0,8,88, 0,8,24, 0,9,145, 83,7,59, 0,8,120, 0,8,56, 0,9,209, 81,7,17, 0,8,104, 0,8,40, 0,9,177, 0,8,8, 0,8,136, 0,8,72, 0,9,241, 80,7,4, 0,8,84, 0,8,20, 85,8,227, 83,7,43, 0,8,116, 0,8,52, 0,9,201, 81,7,13, 0,8,100, 0,8,36, 0,9,169, 0,8,4, 0,8,132, 0,8,68, 0,9,233, 80,7,8, 0,8,92, 0,8,28, 0,9,153, 84,7,83, 0,8,124, 0,8,60, 0,9,217, 82,7,23, 0,8,108, 0,8,44, 0,9,185, 0,8,12, 0,8,140, 0,8,76, 0,9,249, 80,7,3, 0,8,82, 0,8,18, 85,8,163, 83,7,35, 0,8,114, 0,8,50, 0,9,197, 81,7,11, 0,8,98, 0,8,34, 0,9,165, 0,8,2, 0,8,130, 0,8,66, 0,9,229, 80,7,7, 0,8,90, 0,8,26, 0,9,149, 84,7,67, 0,8,122, 0,8,58, 0,9,213, 82,7,19, 0,8,106, 0,8,42, 0,9,181, 0,8,10, 0,8,138, 0,8,74, 0,9,245, 80,7,5, 0,8,86, 0,8,22, 192,8,0, 83,7,51, 0,8,118, 0,8,54, 0,9,205, 81,7,15, 0,8,102, 0,8,38, 0,9,173, 0,8,6, 0,8,134, 0,8,70, 0,9,237, 80,7,9, 0,8,94, 0,8,30, 0,9,157, 84,7,99, 0,8,126, 0,8,62, 0,9,221, 82,7,27, 0,8,110, 0,8,46, 0,9,189, 0,8,14, 0,8,142, 0,8,78, 0,9,253, 96,7,256, 0,8,81, 0,8,17, 85,8,131, 82,7,31, 0,8,113, 0,8,49, 0,9,195, 80,7,10, 0,8,97, 0,8,33, 0,9,163, 0,8,1, 0,8,129, 0,8,65, 0,9,227, 80,7,6, 0,8,89, 0,8,25, 0,9,147, 83,7,59, 0,8,121, 0,8,57, 0,9,211, 81,7,17, 0,8,105, 0,8,41, 0,9,179, 0,8,9, 0,8,137, 0,8,73, 0,9,243, 80,7,4, 0,8,85, 0,8,21, 80,8,258, 83,7,43, 0,8,117, 0,8,53, 0,9,203, 81,7,13, 0,8,101, 0,8,37, 0,9,171, 0,8,5, 0,8,133, 0,8,69, 0,9,235, 80,7,8, 0,8,93, 0,8,29, 0,9,155, 84,7,83, 0,8,125, 0,8,61, 0,9,219, 82,7,23, 0,8,109, 0,8,45, 0,9,187, 0,8,13, 0,8,141, 0,8,77, 0,9,251, 80,7,3, 0,8,83, 0,8,19, 85,8,195, 83,7,35, 0,8,115, 0,8,51, 0,9,199, 81,7,11, 0,8,99, 0,8,35, 0,9,167, 0,8,3, 0,8,131, 0,8,67, 0,9,231, 80,7,7, 0,8,91, 0,8,27, 0,9,151, 84,7,67, 0,8,123, 0,8,59, 0,9,215, 82,7,19, 0,8,107, 0,8,43, 0,9,183, 0,8,11, 0,8,139, 0,8,75, 0,9,247, 80,7,5, 0,8,87, 0,8,23, 192,8,0, 83,7,51, 0,8,119, 0,8,55, 0,9,207, 81,7,15, 0,8,103, 0,8,39, 0,9,175, 0,8,7, 0,8,135, 0,8,71, 0,9,239, 80,7,9, 0,8,95, 0,8,31, 0,9,159, 84,7,99, 0,8,127, 0,8,63, 0,9,223, 82,7,27, 0,8,111, 0,8,47, 0,9,191, 0,8,15, 0,8,143, 0,8,79, 0,9,255 }; static final int[] fixed_td = { 80,5,1, 87,5,257, 83,5,17, 91,5,4097, 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, 80,5,3, 88,5,513, 84,5,33, 92,5,8193, 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, 80,5,2, 87,5,385, 83,5,25, 91,5,6145, 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, 80,5,4, 88,5,769, 84,5,49, 92,5,12289, 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 }; // Tables for deflate from PKZIP's appnote.txt. static final int[] cplens = { // Copy lengths for literal codes 257..285 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; // see note #13 above about 258 static final int[] cplext = { // Extra bits for literal codes 257..285 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid }; static final int[] cpdist = { // Copy offsets for distance codes 0..29 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 }; static final int[] cpdext = { // Extra bits for distance codes 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; // If BMAX needs to be larger than 16, then h and x[] should be uLong. static final int BMAX=15; // maximum bit length of any code int[] hn = null; // hufts used in space int[] v = null; // work area for huft_build int[] c = null; // bit length count table int[] r = null; // table entry for structure assignment int[] u = null; // table stack int[] x = null; // bit offsets, then code stack private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) int bindex, int n, // number of codes (assumed <= 288) int s, // number of simple-valued codes (0..s-1) int[] d, // list of base values for non-simple codes int[] e, // list of extra bits for non-simple codes int[] t, // result: starting table int[] m, // maximum lookup bits, returns actual int[] hp,// space for trees int[] hn,// hufts used in space int[] v // working area: values in order of bit length ){ // Given a list of code lengths and a maximum table size, make a set of // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR // if the given code set is incomplete (the tables are still built in this // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of // lengths), or Z_MEM_ERROR if not enough memory. int a; // counter for codes of length k int f; // i repeats in table every f entries int g; // maximum code length int h; // table level int i; // counter, current code int j; // counter int k; // number of bits in current code int l; // bits per table (returned in m) int mask; // (1 << w) - 1, to avoid cc -O bug on HP int p; // pointer into c[], b[], or v[] int q; // points to current table int w; // bits before this table == (l * h) int xp; // pointer into x int y; // number of dummy codes added int z; // number of entries in current table // Generate counts for each bit length p = 0; i = n; do { c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX }while(i!=0); if(c[0] == n){ // null input--all zero length codes t[0] = -1; m[0] = 0; return Z_OK; } // Find minimum and maximum length, bound *m by those l = m[0]; for (j = 1; j <= BMAX; j++) if(c[j]!=0) break; k = j; // minimum code length if(l < j){ l = j; } for (i = BMAX; i!=0; i--){ if(c[i]!=0) break; } g = i; // maximum code length if(l > i){ l = i; } m[0] = l; // Adjust last length count to fill out codes, if needed for (y = 1 << j; j < i; j++, y <<= 1){ if ((y -= c[j]) < 0){ return Z_DATA_ERROR; } } if ((y -= c[i]) < 0){ return Z_DATA_ERROR; } c[i] += y; // Generate starting offsets into the value table for each length x[1] = j = 0; p = 1; xp = 2; while (--i!=0) { // note that i == g from above x[xp] = (j += c[p]); xp++; p++; } // Make a table of values in order of bit lengths i = 0; p = 0; do { if ((j = b[bindex+p]) != 0){ v[x[j]++] = i; } p++; } while (++i < n); n = x[g]; // set n to length of v // Generate the Huffman codes and for each, make the table entries x[0] = i = 0; // first Huffman code is zero p = 0; // grab values in bit order h = -1; // no tables yet--level -1 w = -l; // bits decoded == (l * h) u[0] = 0; // just to keep compilers happy q = 0; // ditto z = 0; // ditto // go through the bit lengths (k already is bits in shortest code) for (; k <= g; k++){ a = c[k]; while (a--!=0){ // here i is the Huffman code of length k bits for value *p // make tables up to required level while (k > w + l){ h++; w += l; // previous table always l bits // compute minimum size table less than or equal to l bits z = g - w; z = (z > l) ? l : z; // table size upper limit if((f=1<<(j=k-w))>a+1){ // try a k-w bit table // too few codes for k-w bit table f -= a + 1; // deduct codes from patterns left xp = k; if(j < z){ while (++j < z){ // try smaller tables up to z bits if((f <<= 1) <= c[++xp]) break; // enough codes to use up j bits f -= c[xp]; // else deduct codes from patterns } } } z = 1 << j; // table entries for j-bit table // allocate new table if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) return Z_DATA_ERROR; // overflow of MANY } u[h] = q = /*hp+*/ hn[0]; // DEBUG hn[0] += z; // connect to last table, if there is one if(h!=0){ x[h]=i; // save pattern for backing up r[0]=(byte)j; // bits in this table r[1]=(byte)l; // bits to dump before this table j=i>>>(w - l); r[2] = (int)(q - u[h-1] - j); // offset to this table System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table } else{ t[0] = q; // first table is returned result } } // set up table entry in r r[1] = (byte)(k - w); if (p >= n){ r[0] = 128 + 64; // out of values--invalid code } else if (v[p] < s){ r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block r[2] = v[p++]; // simple code is just the value } else{ r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists r[2]=d[v[p++] - s]; } // fill code-like entries with r f=1<<(k-w); for (j=i>>>w;j>>= 1){ i ^= j; } i ^= j; // backup over finished tables mask = (1 << w) - 1; // needed on HP, cc -O bug while ((i & mask) != x[h]){ h--; // don't need to update q w -= l; mask = (1 << w) - 1; } } } // Return Z_BUF_ERROR if we were given an incomplete table return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } int inflate_trees_bits(int[] c, // 19 code lengths int[] bb, // bits tree desired/actual depth int[] tb, // bits tree result int[] hp, // space for trees ZStream z // for messages ){ int result; initWorkArea(19); hn[0]=0; result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); if(result == Z_DATA_ERROR){ z.msg = "oversubscribed dynamic bit lengths tree"; } else if(result == Z_BUF_ERROR || bb[0] == 0){ z.msg = "incomplete dynamic bit lengths tree"; result = Z_DATA_ERROR; } return result; } int inflate_trees_dynamic(int nl, // number of literal/length codes int nd, // number of distance codes int[] c, // that many (total) code lengths int[] bl, // literal desired/actual bit depth int[] bd, // distance desired/actual bit depth int[] tl, // literal/length tree result int[] td, // distance tree result int[] hp, // space for trees ZStream z // for messages ){ int result; // build literal/length tree initWorkArea(288); hn[0]=0; result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); if (result != Z_OK || bl[0] == 0){ if(result == Z_DATA_ERROR){ z.msg = "oversubscribed literal/length tree"; } else if (result != Z_MEM_ERROR){ z.msg = "incomplete literal/length tree"; result = Z_DATA_ERROR; } return result; } // build distance tree initWorkArea(288); result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); if (result != Z_OK || (bd[0] == 0 && nl > 257)){ if (result == Z_DATA_ERROR){ z.msg = "oversubscribed distance tree"; } else if (result == Z_BUF_ERROR) { z.msg = "incomplete distance tree"; result = Z_DATA_ERROR; } else if (result != Z_MEM_ERROR){ z.msg = "empty distance tree with lengths"; result = Z_DATA_ERROR; } return result; } return Z_OK; } static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth int[] bd, //distance desired/actual bit depth int[][] tl,//literal/length tree result int[][] td,//distance tree result ZStream z //for memory allocation ){ bl[0]=fixed_bl; bd[0]=fixed_bd; tl[0]=fixed_tl; td[0]=fixed_td; return Z_OK; } private void initWorkArea(int vsize){ if(hn==null){ hn=new int[1]; v=new int[vsize]; c=new int[BMAX+1]; r=new int[3]; u=new int[BMAX]; x=new int[BMAX+1]; } if(v.length> 4) + 1; if(w < 48) w &= 15; } if(w<8 ||w>15){ inflateEnd(); return Z_STREAM_ERROR; } if(blocks != null && wbits != w){ blocks.free(); blocks=null; } // set window size wbits=w; this.blocks=new InfBlocks(z, 1<>8))&0xff; if(((wrap&1)==0 || // check if zlib header allowed (((this.method << 8)+b) % 31)!=0) && (this.method&0xf)!=Z_DEFLATED){ if(wrap == 4){ z.next_in_index -= 2; z.avail_in += 2; z.total_in -= 2; wrap = 0; this.mode = BLOCKS; break; } this.mode = BAD; z.msg = "incorrect header check"; // since zlib 1.2, it is allowted to inflateSync for this case. /* this.marker = 5; // can't try inflateSync */ break; } if((this.method&0xf)!=Z_DEFLATED){ this.mode = BAD; z.msg="unknown compression method"; // since zlib 1.2, it is allowted to inflateSync for this case. /* this.marker = 5; // can't try inflateSync */ break; } if(wrap == 4){ wrap = 1; } if((this.method>>4)+8>this.wbits){ this.mode = BAD; z.msg="invalid window size"; // since zlib 1.2, it is allowted to inflateSync for this case. /* this.marker = 5; // can't try inflateSync */ break; } z.adler=new Adler32(); if((b&PRESET_DICT)==0){ this.mode = BLOCKS; break; } this.mode = DICT4; case DICT4: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; this.mode=DICT3; case DICT3: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; this.mode=DICT2; case DICT2: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; this.mode=DICT1; case DICT1: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need += (z.next_in[z.next_in_index++]&0xffL); z.adler.reset(this.need); this.mode = DICT0; return Z_NEED_DICT; case DICT0: this.mode = BAD; z.msg = "need dictionary"; this.marker = 0; // can try inflateSync return Z_STREAM_ERROR; case BLOCKS: r = this.blocks.proc(r); if(r == Z_DATA_ERROR){ this.mode = BAD; this.marker = 0; // can try inflateSync break; } if(r == Z_OK){ r = f; } if(r != Z_STREAM_END){ return r; } r = f; this.was=z.adler.getValue(); this.blocks.reset(); if(this.wrap==0){ this.mode=DONE; break; } this.mode=CHECK4; case CHECK4: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; this.mode=CHECK3; case CHECK3: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; this.mode = CHECK2; case CHECK2: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; this.mode = CHECK1; case CHECK1: if(z.avail_in==0)return r;r=f; z.avail_in--; z.total_in++; this.need+=(z.next_in[z.next_in_index++]&0xffL); if(flags!=0){ // gzip this.need = ((this.need&0xff000000)>>24 | (this.need&0x00ff0000)>>8 | (this.need&0x0000ff00)<<8 | (this.need&0x0000ffff)<<24)&0xffffffffL; } if(((int)(this.was)) != ((int)(this.need))){ z.msg = "incorrect data check"; // chack is delayed /* this.mode = BAD; this.marker = 5; // can't try inflateSync break; */ } else if(flags!=0 && gheader!=null){ gheader.crc = this.need; } this.mode = LENGTH; case LENGTH: if (wrap!=0 && flags!=0) { try { r=readBytes(4, r, f); } catch(Return e){ return e.r; } if(z.msg!=null && z.msg.equals("incorrect data check")){ this.mode = BAD; this.marker = 5; // can't try inflateSync break; } if (this.need != (z.total_out & 0xffffffffL)) { z.msg = "incorrect length check"; this.mode = BAD; break; } z.msg = null; } else { if(z.msg!=null && z.msg.equals("incorrect data check")){ this.mode = BAD; this.marker = 5; // can't try inflateSync break; } } this.mode = DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; case FLAGS: try { r=readBytes(2, r, f); } catch(Return e){ return e.r; } flags = ((int)this.need)&0xffff; if ((flags & 0xff) != Z_DEFLATED) { z.msg = "unknown compression method"; this.mode = BAD; break; } if ((flags & 0xe000)!=0) { z.msg = "unknown header flags set"; this.mode = BAD; break; } if ((flags & 0x0200)!=0){ checksum(2, this.need); } this.mode = TIME; case TIME: try { r=readBytes(4, r, f); } catch(Return e){ return e.r; } if(gheader!=null) gheader.time = this.need; if ((flags & 0x0200)!=0){ checksum(4, this.need); } this.mode = OS; case OS: try { r=readBytes(2, r, f); } catch(Return e){ return e.r; } if(gheader!=null){ gheader.xflags = ((int)this.need)&0xff; gheader.os = (((int)this.need)>>8)&0xff; } if ((flags & 0x0200)!=0){ checksum(2, this.need); } this.mode = EXLEN; case EXLEN: if ((flags & 0x0400)!=0) { try { r=readBytes(2, r, f); } catch(Return e){ return e.r; } if(gheader!=null){ gheader.extra = new byte[((int)this.need)&0xffff]; } if ((flags & 0x0200)!=0){ checksum(2, this.need); } } else if(gheader!=null){ gheader.extra=null; } this.mode = EXTRA; case EXTRA: if ((flags & 0x0400)!=0) { try { r=readBytes(r, f); if(gheader!=null){ byte[] foo = tmp_string.toByteArray(); tmp_string=null; if(foo.length == gheader.extra.length){ System.arraycopy(foo, 0, gheader.extra, 0, foo.length); } else{ z.msg = "bad extra field length"; this.mode = BAD; break; } } } catch(Return e){ return e.r; } } else if(gheader!=null){ gheader.extra=null; } this.mode = NAME; case NAME: if ((flags & 0x0800)!=0) { try { r=readString(r, f); if(gheader!=null){ gheader.name=tmp_string.toByteArray(); } tmp_string=null; } catch(Return e){ return e.r; } } else if(gheader!=null){ gheader.name=null; } this.mode = COMMENT; case COMMENT: if ((flags & 0x1000)!=0) { try { r=readString(r, f); if(gheader!=null){ gheader.comment=tmp_string.toByteArray(); } tmp_string=null; } catch(Return e){ return e.r; } } else if(gheader!=null){ gheader.comment=null; } this.mode = HCRC; case HCRC: if ((flags & 0x0200)!=0) { try { r=readBytes(2, r, f); } catch(Return e){ return e.r; } if(gheader!=null){ gheader.hcrc=(int)(this.need&0xffff); } if(this.need != (z.adler.getValue()&0xffffL)){ this.mode = BAD; z.msg = "header crc mismatch"; this.marker = 5; // can't try inflateSync break; } } z.adler = new CRC32(); this.mode = BLOCKS; break; default: return Z_STREAM_ERROR; } } } int inflateSetDictionary(byte[] dictionary, int dictLength){ if(z==null || (this.mode != DICT0 && this.wrap != 0)){ return Z_STREAM_ERROR; } int index=0; int length = dictLength; if(this.mode==DICT0){ long adler_need=z.adler.getValue(); z.adler.reset(); z.adler.update(dictionary, 0, dictLength); if(z.adler.getValue()!=adler_need){ return Z_DATA_ERROR; } } z.adler.reset(); if(length >= (1<0){ if(z.avail_in==0){ throw new Return(r); }; r=f; z.avail_in--; z.total_in++; this.need = this.need | ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); need_bytes--; } if(n==2){ this.need&=0xffffL; } else if(n==4) { this.need&=0xffffffffL; } need_bytes=-1; return r; } class Return extends Exception{ int r; Return(int r){this.r=r; } } private java.io.ByteArrayOutputStream tmp_string = null; private int readString(int r, int f) throws Return{ if(tmp_string == null){ tmp_string=new java.io.ByteArrayOutputStream(); } int b=0; do { if(z.avail_in==0){ throw new Return(r); }; r=f; z.avail_in--; z.total_in++; b = z.next_in[z.next_in_index]; if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); z.adler.update(z.next_in, z.next_in_index, 1); z.next_in_index++; }while(b!=0); return r; } private int readBytes(int r, int f) throws Return{ if(tmp_string == null){ tmp_string=new java.io.ByteArrayOutputStream(); } int b=0; while(this.need>0){ if(z.avail_in==0){ throw new Return(r); }; r=f; z.avail_in--; z.total_in++; b = z.next_in[z.next_in_index]; tmp_string.write(z.next_in, z.next_in_index, 1); z.adler.update(z.next_in, z.next_in_index, 1); z.next_in_index++; this.need--; } return r; } private void checksum(int n, long v){ for(int i=0; i>=8; } z.adler.update(crcbuf, 0, n); } public GZIPHeader getGZIPHeader(){ return gheader; } boolean inParsingHeader(){ switch(mode){ case HEAD: case DICT4: case DICT3: case DICT2: case DICT1: case FLAGS: case TIME: case OS: case EXLEN: case EXTRA: case NAME: case COMMENT: case HCRC: return true; default: return false; } } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/Inflater.java000066400000000000000000000114411222267011700230330ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final public class Inflater extends ZStream{ static final private int MAX_WBITS=15; // 32K LZ77 window static final private int DEF_WBITS=MAX_WBITS; static final private int Z_NO_FLUSH=0; static final private int Z_PARTIAL_FLUSH=1; static final private int Z_SYNC_FLUSH=2; static final private int Z_FULL_FLUSH=3; static final private int Z_FINISH=4; static final private int MAX_MEM_LEVEL=9; static final private int Z_OK=0; static final private int Z_STREAM_END=1; static final private int Z_NEED_DICT=2; static final private int Z_ERRNO=-1; static final private int Z_STREAM_ERROR=-2; static final private int Z_DATA_ERROR=-3; static final private int Z_MEM_ERROR=-4; static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; public Inflater() { super(); init(); } public Inflater(JZlib.WrapperType wrapperType) throws GZIPException { this(DEF_WBITS, wrapperType); } public Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { super(); int ret = init(w, wrapperType); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); } public Inflater(int w) throws GZIPException { this(w, false); } public Inflater(boolean nowrap) throws GZIPException { this(DEF_WBITS, nowrap); } public Inflater(int w, boolean nowrap) throws GZIPException { super(); int ret = init(w, nowrap); if(ret!=Z_OK) throw new GZIPException(ret+": "+msg); } private boolean finished = false; public int init(){ return init(DEF_WBITS); } public int init(JZlib.WrapperType wrapperType){ return init(DEF_WBITS, wrapperType); } public int init(int w, JZlib.WrapperType wrapperType) { boolean nowrap = false; if(wrapperType == JZlib.W_NONE){ nowrap = true; } else if(wrapperType == JZlib.W_GZIP) { w += 16; } else if(wrapperType == JZlib.W_ANY) { w |= Inflate.INFLATE_ANY; } else if(wrapperType == JZlib.W_ZLIB) { } return init(w, nowrap); } public int init(boolean nowrap){ return init(DEF_WBITS, nowrap); } public int init(int w){ return init(w, false); } public int init(int w, boolean nowrap){ finished = false; istate=new Inflate(this); return istate.inflateInit(nowrap?-w:w); } public int inflate(int f){ if(istate==null) return Z_STREAM_ERROR; int ret = istate.inflate(f); if(ret == Z_STREAM_END) finished = true; return ret; } public int end(){ finished = true; if(istate==null) return Z_STREAM_ERROR; int ret=istate.inflateEnd(); // istate = null; return ret; } public int sync(){ if(istate == null) return Z_STREAM_ERROR; return istate.inflateSync(); } public int syncPoint(){ if(istate == null) return Z_STREAM_ERROR; return istate.inflateSyncPoint(); } public int setDictionary(byte[] dictionary, int dictLength){ if(istate == null) return Z_STREAM_ERROR; return istate.inflateSetDictionary(dictionary, dictLength); } public boolean finished(){ return istate.mode==12 /*DONE*/; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/InflaterInputStream.java000066400000000000000000000153221222267011700252310ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jzlib; import java.io.*; public class InflaterInputStream extends FilterInputStream { protected final Inflater inflater; protected byte[] buf; private boolean closed = false; private boolean eof = false; private boolean close_in = true; protected static final int DEFAULT_BUFSIZE = 512; public InflaterInputStream(InputStream in) throws IOException { this(in, false); } public InflaterInputStream(InputStream in, boolean nowrap) throws IOException { this(in, new Inflater(nowrap)); myinflater = true; } public InflaterInputStream(InputStream in, Inflater inflater) throws IOException { this(in, inflater, DEFAULT_BUFSIZE); } public InflaterInputStream(InputStream in, Inflater inflater, int size) throws IOException { this(in, inflater, size, true); } public InflaterInputStream(InputStream in, Inflater inflater, int size, boolean close_in) throws IOException { super(in); if (in == null || inflater == null) { throw new NullPointerException(); } else if (size <= 0) { throw new IllegalArgumentException("buffer size must be greater than 0"); } this.inflater = inflater; buf = new byte[size]; this.close_in = close_in; } protected boolean myinflater = false; private byte[] byte1 = new byte[1]; public int read() throws IOException { if (closed) { throw new IOException("Stream closed"); } return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; } public int read(byte[] b, int off, int len) throws IOException { if (closed) { throw new IOException("Stream closed"); } if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } else if (eof) { return -1; } int n = 0; inflater.setOutput(b, off, len); while(!eof) { if(inflater.avail_in==0) fill(); int err = inflater.inflate(JZlib.Z_NO_FLUSH); n += inflater.next_out_index - off; off = inflater.next_out_index; switch(err) { case JZlib.Z_DATA_ERROR: throw new IOException(inflater.msg); case JZlib.Z_STREAM_END: case JZlib.Z_NEED_DICT: eof = true; if(err == JZlib.Z_NEED_DICT) return -1; break; default: } if(inflater.avail_out==0) break; } return n; } public int available() throws IOException { if (closed) { throw new IOException("Stream closed"); } if (eof) { return 0; } else { return 1; } } private byte[] b = new byte[512]; public long skip(long n) throws IOException { if (n < 0) { throw new IllegalArgumentException("negative skip length"); } if (closed) { throw new IOException("Stream closed"); } int max = (int)Math.min(n, Integer.MAX_VALUE); int total = 0; while (total < max) { int len = max - total; if (len > b.length) { len = b.length; } len = read(b, 0, len); if (len == -1) { eof = true; break; } total += len; } return total; } public void close() throws IOException { if (!closed) { if (myinflater) inflater.end(); if(close_in) in.close(); closed = true; } } protected void fill() throws IOException { if (closed) { throw new IOException("Stream closed"); } int len = in.read(buf, 0, buf.length); if (len == -1) { if(inflater.istate.wrap == 0 && !inflater.finished()){ buf[0]=0; len=1; } else if(inflater.istate.was != -1){ // in reading trailer throw new IOException("footer is not found"); } else{ throw new EOFException("Unexpected end of ZLIB input stream"); } } inflater.setInput(buf, 0, len, true); } public boolean markSupported() { return false; } public synchronized void mark(int readlimit) { } public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } public long getTotalIn() { return inflater.getTotalIn(); } public long getTotalOut() { return inflater.getTotalOut(); } public byte[] getAvailIn() { if(inflater.avail_in<=0) return null; byte[] tmp = new byte[inflater.avail_in]; System.arraycopy(inflater.next_in, inflater.next_in_index, tmp, 0, inflater.avail_in); return tmp; } public void readHeader() throws IOException { byte[] empty = "".getBytes(); inflater.setInput(empty, 0, 0, false); inflater.setOutput(empty, 0, 0); int err = inflater.inflate(JZlib.Z_NO_FLUSH); if(!inflater.istate.inParsingHeader()){ return; } byte[] b1 = new byte[1]; do{ int i = in.read(b1); if(i<=0) throw new IOException("no input"); inflater.setInput(b1); err = inflater.inflate(JZlib.Z_NO_FLUSH); if(err!=0/*Z_OK*/) throw new IOException(inflater.msg); } while(inflater.istate.inParsingHeader()); } public Inflater getInflater(){ return inflater; } }jzlib-1.1.3/src/main/java/com/jcraft/jzlib/JZlib.java000066400000000000000000000070331222267011700223030ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final public class JZlib{ private static final String version="1.1.0"; public static String version(){return version;} static final public int MAX_WBITS=15; // 32K LZ77 window static final public int DEF_WBITS=MAX_WBITS; public enum WrapperType { NONE, ZLIB, GZIP, ANY } public static final WrapperType W_NONE = WrapperType.NONE; public static final WrapperType W_ZLIB = WrapperType.ZLIB; public static final WrapperType W_GZIP = WrapperType.GZIP; public static final WrapperType W_ANY = WrapperType.ANY; // compression levels static final public int Z_NO_COMPRESSION=0; static final public int Z_BEST_SPEED=1; static final public int Z_BEST_COMPRESSION=9; static final public int Z_DEFAULT_COMPRESSION=(-1); // compression strategy static final public int Z_FILTERED=1; static final public int Z_HUFFMAN_ONLY=2; static final public int Z_DEFAULT_STRATEGY=0; static final public int Z_NO_FLUSH=0; static final public int Z_PARTIAL_FLUSH=1; static final public int Z_SYNC_FLUSH=2; static final public int Z_FULL_FLUSH=3; static final public int Z_FINISH=4; static final public int Z_OK=0; static final public int Z_STREAM_END=1; static final public int Z_NEED_DICT=2; static final public int Z_ERRNO=-1; static final public int Z_STREAM_ERROR=-2; static final public int Z_DATA_ERROR=-3; static final public int Z_MEM_ERROR=-4; static final public int Z_BUF_ERROR=-5; static final public int Z_VERSION_ERROR=-6; // The three kinds of block type static final public byte Z_BINARY = 0; static final public byte Z_ASCII = 1; static final public byte Z_UNKNOWN = 2; public static long adler32_combine(long adler1, long adler2, long len2){ return Adler32.combine(adler1, adler2, len2); } public static long crc32_combine(long crc1, long crc2, long len2){ return CRC32.combine(crc1, crc2, len2); } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/StaticTree.java000066400000000000000000000141211222267011700233340ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final class StaticTree{ static final private int MAX_BITS=15; static final private int BL_CODES=19; static final private int D_CODES=30; static final private int LITERALS=256; static final private int LENGTH_CODES=29; static final private int L_CODES=(LITERALS+1+LENGTH_CODES); // Bit length codes must not exceed MAX_BL_BITS bits static final int MAX_BL_BITS=7; static final short[] static_ltree = { 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8 }; static final short[] static_dtree = { 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 }; static StaticTree static_l_desc = new StaticTree(static_ltree, Tree.extra_lbits, LITERALS+1, L_CODES, MAX_BITS); static StaticTree static_d_desc = new StaticTree(static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS); static StaticTree static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS); short[] static_tree; // static tree or null int[] extra_bits; // extra bits for each code or null int extra_base; // base index for extra_bits int elems; // max number of elements in the tree int max_length; // max bit length for the codes private StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length){ this.static_tree=static_tree; this.extra_bits=extra_bits; this.extra_base=extra_base; this.elems=elems; this.max_length=max_length; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/Tree.java000066400000000000000000000352001222267011700221650ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; final class Tree{ static final private int MAX_BITS=15; static final private int BL_CODES=19; static final private int D_CODES=30; static final private int LITERALS=256; static final private int LENGTH_CODES=29; static final private int L_CODES=(LITERALS+1+LENGTH_CODES); static final private int HEAP_SIZE=(2*L_CODES+1); // Bit length codes must not exceed MAX_BL_BITS bits static final int MAX_BL_BITS=7; // end of block literal code static final int END_BLOCK=256; // repeat previous bit length 3-6 times (2 bits of repeat count) static final int REP_3_6=16; // repeat a zero length 3-10 times (3 bits of repeat count) static final int REPZ_3_10=17; // repeat a zero length 11-138 times (7 bits of repeat count) static final int REPZ_11_138=18; // extra bits for each length code static final int[] extra_lbits={ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 }; // extra bits for each distance code static final int[] extra_dbits={ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; // extra bits for each bit length code static final int[] extra_blbits={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 }; static final byte[] bl_order={ 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; // The lengths of the bit length codes are sent in order of decreasing // probability, to avoid transmitting the lengths for unused bit // length codes. static final int Buf_size=8*2; // see definition of array dist_code below static final int DIST_CODE_LEN=512; static final byte[] _dist_code = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; static final byte[] _length_code={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; static final int[] base_length = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; static final int[] base_dist = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; // Mapping from a distance to a distance code. dist is the distance - 1 and // must not have side effects. _dist_code[256] and _dist_code[257] are never // used. static int d_code(int dist){ return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); } short[] dyn_tree; // the dynamic tree int max_code; // largest code with non zero frequency StaticTree stat_desc; // the corresponding static tree // Compute the optimal bit lengths for a tree and update the total bit length // for the current block. // IN assertion: the fields freq and dad are set, heap[heap_max] and // above are the tree nodes sorted by increasing frequency. // OUT assertions: the field len is set to the optimal bit length, the // array bl_count contains the frequencies for each bit length. // The length opt_len is updated; static_len is also updated if stree is // not null. void gen_bitlen(Deflate s){ short[] tree = dyn_tree; short[] stree = stat_desc.static_tree; int[] extra = stat_desc.extra_bits; int base = stat_desc.extra_base; int max_length = stat_desc.max_length; int h; // heap index int n, m; // iterate over the tree elements int bits; // bit length int xbits; // extra bits short f; // frequency int overflow = 0; // number of elements with bit length too large for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; // In a first pass, compute the optimal bit lengths (which may // overflow in the case of the bit length tree). tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } tree[n*2+1] = (short)bits; // We overwrite tree[n*2+1] which is no longer needed if (n > max_code) continue; // not a leaf node s.bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n*2]; s.opt_len += f * (bits + xbits); if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); } if (overflow == 0) return; // This happens for example on obj2 and pic of the Calgary corpus // Find the first bit length which could increase: do { bits = max_length-1; while(s.bl_count[bits]==0) bits--; s.bl_count[bits]--; // move one leaf down the tree s.bl_count[bits+1]+=2; // move one overflow item as its brother s.bl_count[max_length]--; // The brother of the overflow item also moves one step up, // but this does not affect bl_count[max_length] overflow -= 2; } while (overflow > 0); for (bits = max_length; bits != 0; bits--) { n = s.bl_count[bits]; while (n != 0) { m = s.heap[--h]; if (m > max_code) continue; if (tree[m*2+1] != bits) { s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; tree[m*2+1] = (short)bits; } n--; } } } // Construct one Huffman tree and assigns the code bit strings and lengths. // Update the total bit length for the current block. // IN assertion: the field freq is set for all tree elements. // OUT assertions: the fields len and code are set to the optimal bit length // and corresponding code. The length opt_len is updated; static_len is // also updated if stree is not null. The field max_code is set. void build_tree(Deflate s){ short[] tree=dyn_tree; short[] stree=stat_desc.static_tree; int elems=stat_desc.elems; int n, m; // iterate over heap elements int max_code=-1; // largest code with non zero frequency int node; // new node being created // Construct the initial heap, with least frequent element in // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. // heap[0] is not used. s.heap_len = 0; s.heap_max = HEAP_SIZE; for(n=0; n=1; n--) s.pqdownheap(tree, n); // Construct the Huffman tree by repeatedly combining the least two // frequent nodes. node=elems; // next internal node of the tree do{ // n = node of least frequency n=s.heap[1]; s.heap[1]=s.heap[s.heap_len--]; s.pqdownheap(tree, 1); m=s.heap[1]; // m = node of next least frequency s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency s.heap[--s.heap_max] = m; // Create a new node father of n and m tree[node*2] = (short)(tree[n*2] + tree[m*2]); s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); tree[n*2+1] = tree[m*2+1] = (short)node; // and insert the new node in the heap s.heap[1] = node++; s.pqdownheap(tree, 1); } while(s.heap_len>=2); s.heap[--s.heap_max] = s.heap[1]; // At this point, the fields freq and dad are set. We can now // generate the bit lengths. gen_bitlen(s); // The field len is now set, we can generate the bit codes gen_codes(tree, max_code, s.bl_count, s.next_code); } // Generate the codes for a given tree and bit counts (which need not be // optimal). // IN assertion: the array bl_count contains the bit length statistics for // the given tree and the field len is set for all tree elements. // OUT assertion: the field code is set for all tree elements of non // zero code length. private final static void gen_codes( short[] tree, // the tree to decorate int max_code, // largest code with non zero frequency short[] bl_count, // number of codes at each bit length short[] next_code){ short code = 0; // running code value int bits; // bit index int n; // code index // The distribution counts are first used to generate the code values // without bit reversal. next_code[0]=0; for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); } // Check that the bit counts in bl_count are consistent. The last code // must be all ones. //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; res<<=1; } while(--len>0); return res>>>1; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/ZInputStream.java000066400000000000000000000073371222267011700237050ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jzlib; import java.io.*; /** * ZInputStream * * @deprecated use DeflaterOutputStream or InflaterInputStream */ @Deprecated public class ZInputStream extends FilterInputStream { protected int flush=JZlib.Z_NO_FLUSH; protected boolean compress; protected InputStream in=null; protected Deflater deflater; protected InflaterInputStream iis; public ZInputStream(InputStream in) throws IOException { this(in, false); } public ZInputStream(InputStream in, boolean nowrap) throws IOException { super(in); iis = new InflaterInputStream(in, nowrap); compress=false; } public ZInputStream(InputStream in, int level) throws IOException { super(in); this.in=in; deflater = new Deflater(); deflater.init(level); compress=true; } private byte[] buf1 = new byte[1]; public int read() throws IOException { if(read(buf1, 0, 1)==-1) return -1; return(buf1[0]&0xFF); } private byte[] buf = new byte[512]; public int read(byte[] b, int off, int len) throws IOException { if(compress){ deflater.setOutput(b, off, len); while(true){ int datalen = in.read(buf, 0, buf.length); if(datalen == -1) return -1; deflater.setInput(buf, 0, datalen, true); int err = deflater.deflate(flush); if(deflater.next_out_index>0) return deflater.next_out_index; if(err == JZlib.Z_STREAM_END) return 0; if(err == JZlib.Z_STREAM_ERROR || err == JZlib.Z_DATA_ERROR){ throw new ZStreamException("deflating: "+deflater.msg); } } } else{ return iis.read(b, off, len); } } public long skip(long n) throws IOException { int len=512; if(n0){ inflater.setOutput(buf, 0, buf.length); err = inflater.inflate(flush); if(inflater.next_out_index>0) out.write(buf, 0, inflater.next_out_index); if(err != JZlib.Z_OK) break; } if(err != JZlib.Z_OK) throw new ZStreamException("inflating: "+inflater.msg); return; } } public int getFlushMode() { return flush; } public void setFlushMode(int flush) { this.flush=flush; } public void finish() throws IOException { int err; if(compress){ int tmp = flush; int flush = JZlib.Z_FINISH; try{ write("".getBytes(), 0, 0); } finally { flush = tmp; } } else{ dos.finish(); } flush(); } public synchronized void end() { if(end) return; if(compress){ try { dos.finish(); } catch(Exception e){} } else{ inflater.end(); } end=true; } public void close() throws IOException { try{ try{finish();} catch (IOException ignored) {} } finally{ end(); out.close(); out=null; } } public long getTotalIn() { if(compress) return dos.getTotalIn(); else return inflater.total_in; } public long getTotalOut() { if(compress) return dos.getTotalOut(); else return inflater.total_out; } public void flush() throws IOException { out.flush(); } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/ZStream.java000066400000000000000000000244511222267011700226610ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; /** * ZStream * * @deprecated Not for public use in the future. */ @Deprecated public class ZStream{ static final private int MAX_WBITS=15; // 32K LZ77 window static final private int DEF_WBITS=MAX_WBITS; static final private int Z_NO_FLUSH=0; static final private int Z_PARTIAL_FLUSH=1; static final private int Z_SYNC_FLUSH=2; static final private int Z_FULL_FLUSH=3; static final private int Z_FINISH=4; static final private int MAX_MEM_LEVEL=9; static final private int Z_OK=0; static final private int Z_STREAM_END=1; static final private int Z_NEED_DICT=2; static final private int Z_ERRNO=-1; static final private int Z_STREAM_ERROR=-2; static final private int Z_DATA_ERROR=-3; static final private int Z_MEM_ERROR=-4; static final private int Z_BUF_ERROR=-5; static final private int Z_VERSION_ERROR=-6; public byte[] next_in; // next input byte public int next_in_index; public int avail_in; // number of bytes available at next_in public long total_in; // total nb of input bytes read so far public byte[] next_out; // next output byte should be put there public int next_out_index; public int avail_out; // remaining free space at next_out public long total_out; // total nb of bytes output so far public String msg; Deflate dstate; Inflate istate; int data_type; // best guess about the data type: ascii or binary Checksum adler; public ZStream(){ this(new Adler32()); } public ZStream(Checksum adler){ this.adler=adler; } public int inflateInit(){ return inflateInit(DEF_WBITS); } public int inflateInit(boolean nowrap){ return inflateInit(DEF_WBITS, nowrap); } public int inflateInit(int w){ return inflateInit(w, false); } public int inflateInit(JZlib.WrapperType wrapperType) { return inflateInit(DEF_WBITS, wrapperType); } public int inflateInit(int w, JZlib.WrapperType wrapperType) { boolean nowrap = false; if(wrapperType == JZlib.W_NONE){ nowrap = true; } else if(wrapperType == JZlib.W_GZIP) { w += 16; } else if(wrapperType == JZlib.W_ANY) { w |= Inflate.INFLATE_ANY; } else if(wrapperType == JZlib.W_ZLIB) { } return inflateInit(w, nowrap); } public int inflateInit(int w, boolean nowrap){ istate=new Inflate(this); return istate.inflateInit(nowrap?-w:w); } public int inflate(int f){ if(istate==null) return Z_STREAM_ERROR; return istate.inflate(f); } public int inflateEnd(){ if(istate==null) return Z_STREAM_ERROR; int ret=istate.inflateEnd(); // istate = null; return ret; } public int inflateSync(){ if(istate == null) return Z_STREAM_ERROR; return istate.inflateSync(); } public int inflateSyncPoint(){ if(istate == null) return Z_STREAM_ERROR; return istate.inflateSyncPoint(); } public int inflateSetDictionary(byte[] dictionary, int dictLength){ if(istate == null) return Z_STREAM_ERROR; return istate.inflateSetDictionary(dictionary, dictLength); } public boolean inflateFinished(){ return istate.mode==12 /*DONE*/; } public int deflateInit(int level){ return deflateInit(level, MAX_WBITS); } public int deflateInit(int level, boolean nowrap){ return deflateInit(level, MAX_WBITS, nowrap); } public int deflateInit(int level, int bits){ return deflateInit(level, bits, false); } public int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ if(bits < 9 || bits > 15){ return Z_STREAM_ERROR; } if(wrapperType == JZlib.W_NONE) { bits *= -1; } else if(wrapperType == JZlib.W_GZIP) { bits += 16; } else if(wrapperType == JZlib.W_ANY) { return Z_STREAM_ERROR; } else if(wrapperType == JZlib.W_ZLIB) { } return this.deflateInit(level, bits, memlevel); } public int deflateInit(int level, int bits, int memlevel){ dstate=new Deflate(this); return dstate.deflateInit(level, bits, memlevel); } public int deflateInit(int level, int bits, boolean nowrap){ dstate=new Deflate(this); return dstate.deflateInit(level, nowrap?-bits:bits); } public int deflate(int flush){ if(dstate==null){ return Z_STREAM_ERROR; } return dstate.deflate(flush); } public int deflateEnd(){ if(dstate==null) return Z_STREAM_ERROR; int ret=dstate.deflateEnd(); dstate=null; return ret; } public int deflateParams(int level, int strategy){ if(dstate==null) return Z_STREAM_ERROR; return dstate.deflateParams(level, strategy); } public int deflateSetDictionary (byte[] dictionary, int dictLength){ if(dstate == null) return Z_STREAM_ERROR; return dstate.deflateSetDictionary(dictionary, dictLength); } // Flush as much pending output as possible. All deflate() output goes // through this function so some applications may wish to modify it // to avoid allocating a large strm->next_out buffer and copying into it. // (See also read_buf()). void flush_pending(){ int len=dstate.pending; if(len>avail_out) len=avail_out; if(len==0) return; if(dstate.pending_buf.length<=dstate.pending_out || next_out.length<=next_out_index || dstate.pending_buf.length<(dstate.pending_out+len) || next_out.length<(next_out_index+len)){ //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ // ", "+next_out.length+", "+next_out_index+", "+len); //System.out.println("avail_out="+avail_out); } System.arraycopy(dstate.pending_buf, dstate.pending_out, next_out, next_out_index, len); next_out_index+=len; dstate.pending_out+=len; total_out+=len; avail_out-=len; dstate.pending-=len; if(dstate.pending==0){ dstate.pending_out=0; } } // Read a new buffer from the current input stream, update the adler32 // and total number of bytes read. All deflate() input goes through // this function so some applications may wish to modify it to avoid // allocating a large strm->next_in buffer and copying from it. // (See also flush_pending()). int read_buf(byte[] buf, int start, int size) { int len=avail_in; if(len>size) len=size; if(len==0) return 0; avail_in-=len; if(dstate.wrap!=0) { adler.update(next_in, next_in_index, len); } System.arraycopy(next_in, next_in_index, buf, start, len); next_in_index += len; total_in += len; return len; } public long getAdler(){ return adler.getValue(); } public void free(){ next_in=null; next_out=null; msg=null; } public void setOutput(byte[] buf){ setOutput(buf, 0, buf.length); } public void setOutput(byte[] buf, int off, int len){ next_out = buf; next_out_index = off; avail_out = len; } public void setInput(byte[] buf){ setInput(buf, 0, buf.length, false); } public void setInput(byte[] buf, boolean append){ setInput(buf, 0, buf.length, append); } public void setInput(byte[] buf, int off, int len, boolean append){ if(len<=0 && append && next_in!=null) return; if(avail_in>0 && append){ byte[] tmp = new byte[avail_in+len]; System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); System.arraycopy(buf, off, tmp, avail_in, len); next_in=tmp; next_in_index=0; avail_in+=len; } else{ next_in=buf; next_in_index=off; avail_in=len; } } public byte[] getNextIn(){ return next_in; } public void setNextIn(byte[] next_in){ this.next_in = next_in; } public int getNextInIndex(){ return next_in_index; } public void setNextInIndex(int next_in_index){ this.next_in_index = next_in_index; } public int getAvailIn(){ return avail_in; } public void setAvailIn(int avail_in){ this.avail_in = avail_in; } public byte[] getNextOut(){ return next_out; } public void setNextOut(byte[] next_out){ this.next_out = next_out; } public int getNextOutIndex(){ return next_out_index; } public void setNextOutIndex(int next_out_index){ this.next_out_index = next_out_index; } public int getAvailOut(){ return avail_out; } public void setAvailOut(int avail_out){ this.avail_out = avail_out; } public long getTotalOut(){ return total_out; } public long getTotalIn(){ return total_in; } public String getMessage(){ return msg; } /** * Those methods are expected to be override by Inflater and Deflater. * In the future, they will become abstract methods. */ public int end(){ return Z_OK; } public boolean finished(){ return false; } } jzlib-1.1.3/src/main/java/com/jcraft/jzlib/ZStreamException.java000066400000000000000000000036131222267011700245350ustar00rootroot00000000000000/* -*-mode:java; c-basic-offset:2; -*- */ /* Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * This program is based on zlib-1.1.3, so all credit should go authors * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) * and contributors of zlib. */ package com.jcraft.jzlib; public class ZStreamException extends java.io.IOException { public ZStreamException() { super(); } public ZStreamException(String s) { super(s); } } jzlib-1.1.3/src/test/000077500000000000000000000000001222267011700143745ustar00rootroot00000000000000jzlib-1.1.3/src/test/resources/000077500000000000000000000000001222267011700164065ustar00rootroot00000000000000jzlib-1.1.3/src/test/resources/jzlib.fail.gz000066400000000000000000002376361222267011700210150ustar00rootroot000000000000000RabcdefgݏdIr _>D #<E?,И2h08 HsWCDT]x&f?#"GO?=<㛏O7o_?_/OϿ_۟_<}_o/=o_~oyz_?˿o_~??BD]_>=|z?_}__?/|w??ӗӟ|߿OO~^w߾~/|_?}7~[Ͽ/__??O~_˗__k탾鯿 ?}O?O|?^O_O?շ/?]]˷_}cK;_~/N] v bB OD-'P>ObDynqDžk`1U^q…"Ň7\4޷6j~4^/*oQEOBxP ׼XhzD.BR(qe%N]ƌcEuTfsw:f R˫_XC/tA-W6bDu3<׹*FxT]iɢ;1J6]ތoFH*FxY%<aWSX7MӇH*FxT],$ GW>#+_\I#ߴuswz=4EwRUMHҊh"}s{SeuJɠUZ'4 ,?=$KM{Axq3@9go*cú?9=s{C1F) Y3g?ta?J=L{Mp1Z4s3@*۳Ic߅TX,PK UC1΅h>Xg-n^fc$H^5c%-q.oU1Fpױ#"Ul Q6?=ku }G9o\Q@ǮH+bZX[ ܎*ө~e^ט`dEy^uA"ȕ3*1YN!UyS9NT{3TtSkyXc%gCbKACldp~c0f^lMm[jmĊE]j!>M|";WJT'e{-/K5h>c=ccL$Yq {>SMXF(O,BtUDe+Z=bF(O,Z,?3rF~l}t5]}}kS%{L6sb"" U7GH;WGmwF(O,Zc=c=fL!\ŅŔ !I'!MvXD՗ol>.BZlQq,j+A{-.ڜ-Ι8A}?U=ZsbOY}7j {{cGqgdl"ޙ; =~AsPVn,ݳcGgda";(=~]{H,̱GgԮn"A;F+=~7{HD,8c$r{jFP>1/^,kWK{ VM U]60˫|ZbqVШ.^:.źQoFN\RˊUlDViVڛG&:aY@/{f tt]zq_t ȅSփ:̋$`;kuwrVVΧ֚:zK_8%c#C9܎躎1UIF;M9QAlTcqu#gᐍ-_;/ɮlQ A e{8j=oĊu:E24SF3a!K+XGZ\`t2F%l]q){>TbFh߳pU#Ü!K+ZGD.30Keh>d=䌠cM$yz9^USzɻO*ٻ{NX(QI,RuKXQ]# `I[jm;b B}dM&aa&#JTӵ,kAP_[+*>= Fp"VlRcQ=~m Y{[c0ǏjӞE9v7{(FZ lYcǰǏbt`iܞEܮ=vI{(Sh F|YTch^Ǐ!lҞE|=v"{( J,kwчmPLOK ]ud}L´A-Ugn^X,Q,Uxҽ`gJrE 06b K8Z"+]ZtYk4D#ETb,7cI'dgJnB\p07b K]g "c@B4&8>nVϕ_u_d{`ecv$ q>rg6Χ:KE˗4|6ΰck.]Wk<6H$4#m.*A2+xdloEukh%Y16b̴9[3q$zoZd9bD̆24OuXQ|ZΊᢺuTC3ܠ-8KB׸=*ًv8J,tաH-3bE%_4FҊjwgRY`>#htر#yx]f EO9bD%p:B##VTWXB,Zb6\b {KfvZn5:$}{~1|x3@=g3i?g9(?*{@1V8Z3@ g?mc?ġ=y.{4A&񣴃3@굵gh?J=>{g{>{B\F'Cdr7ŊUCZzކeŊ9 *VM ]|0}V"+hYOF|~kSO ڼXXVxҩ+Y;ڻۗ&K[gu.S0K|Z1YIE T;Ŋ@HɓJ40+WTEYZz>[όtQ).,3FwYu>|?8,9cBbĩBCݐ +*nH6 ` d#7@;Ŏ x]́1eCbĩC +:%}mjxh6\ ՞bL)͈b6ШDxq$i>UVnsb=iZwIoZѺ9SzL]h3rEwF5׸MVV!9#]TJ{gN0Kuh>e=ѝc\TɮYi1g #WTFc,v=&tQZĄY*D)m٤-N4X<y{wMuWg*y{ќX7K(x:obm}LoSݗ"~=v]Q  ]۳wǎj)Ӟ =x7s ZQ سǎ{`eܞ=QI{3iQ@MUسbǎ-l#ӞR="{]Q* ,vՇ6B 'OMJeM0FGYKJ9v4zWǣϋ%S)v+3~m[ZV(O-b$VwF@Z%^nmGܟŀ o]:܌0/ |;1 ts 󡒻dE<·VWkEWP1Kh:fٻQ]K- qa{>V0iqb@EO)oKޙJjgċ}1Kh>f=i{u~y:V+o_-էχ2UwX$Q kb42xDpQEw>V/-KS6(O,Z$G.Ru7X5H jgי"RYomqqƥPɫ96JT"IWT}cLF߳Ҋj-3e/`tmͼgeM0, gn?ϰ=$W{1 񣘿3ղgocd-?!=${1xLK3@Eg?cd?J7=^a{͙13@g_8ǎQǿ@5֣_ij+͋?7ßzy?-ōybDYQeĩ!%knY;xC&gs0}VbFuĀU\@FiuN6\X`U6b(ZUk91昇&}iِ [A#M;:dk\ͮ[RuҚ+K-"tL}Oej/_,n=ִgFta|zI;N |+'7KTcIW%Tݹ!#WTYZz>[-WtQZĄY*D)9d$;>W7p{Q6 ѐcA-Tu#NJňS鷅T,Vt'Tk`-YeL)㈻b6Nc{.^WJFѦ=r69-$/lԊCG{̯M]1,74=2&=ݞۧwuSDFT `Q%ݝ -|=|F(-f,U<6jVjL MG2Du-ZQ͇,S~m|ZVM<Tcۨ-Z)ǿd噘~];MR}d{:cBRXbt1C8}Bj ,kWTBz3 وgmaJ/Tu l(Q]k#[ 8NxHaEwBӯ ka[ 6aA6a0h_|^/h= =~Cjt̉%-:tLlJ܉j6t-NWgX0Kuh:eozfvz| fpu(- gn?=$OW{1 Y3ڲgomdA?I=${1z N3@Ig?dd?JK=~a{ 1:3@g_;ǎQǿ@ :kWO51/V,(kYZ+Iu'"]՚HaRdrFH+ur|c'6\V+L'PJ|S۫FK+_χe0/s1Kh>f=醧>] ƅXɶLa<8UCU *^M6ZZ {>\-3xQ[̈Y*E1{9.fD}՗_ݎVsT*9CߣjXws[0TۢJW)ջ`wPlGkac=~v{H,cGδgKh";ߖ=~O#{H~1,9c G4g4k"~d;d=~sPs,c Gɴgf";F=~Z=:=] ™ ?f~&xf5U 1˿1{ìeEgl>Lԝ3EwN/ΖVɞOW't8_1.,l7kV/Y9_rJG׏/mk\O<2UVX$ѾoT:hvF[4WҎ$,z^آZ59xEWD0|Zu"2Cu.͋ %3'68)G&F`iEhZEuf[Y+&+hTCٖx]:@ZO=<BunҚFimNe}OyX}:xhF=7\6cL A֛Fޠ-uĀUƃJ(-R:>Tݳ![rwX׮gMGmȆkqa I!Sug\5HjeU0Kuh6e^3D8T׸=*3#KTwO*|Źj 0ծrGt-NWgL0Kh>e=MI%Ϭ|߲csGݶTiЃZ %J1,{aEwBϯ  p_ĂldKmaФŚXP՗eC= Z(ڻfauw| ou+clǏbnڞE=v V{( YcqֲǏb_dƞE=v {( vYIcǘGǏ2ckžE|=v>a{( Y7cǏR&gTg>ECQYYjNh1vaBR6hGQ|ELߧuϋu4E'|EVߴ*٪U6]tu\)kU~Fu?]WSuD+K%OL2Y;&K]gֽ""@B47Q%ۣg5uZ \*y tN6b`2Zb%͉ &Kau`(]h:To~;[FK+_χeZb*|zQ"Z<`|d 0Q[@E{{oKޙJjoǫ3ER4v⨕rKVMv~|}muKP՗u?֍-;jX-$%Bh>\9C[x _cǑ \@;D=ym7:~ سkǎm{؞=xM{~Q<@mٳ7ǎ#cūÞ=s{Qf( ͧٳ22uaݞRϰ=M{pQ qس/cǨPe4S<ş̜s7ŊeE )YsX`%*VMpնc Yb4|է,/ZO:"Ru͋%C':8)"Jj'"K[gu"c%@eva>eΘMiO׸=sּXX-Fb [MtulTS֛JH#iѳKk |z?~PK<%?'V,hߵx*DxL2rEuTw"5[-gtQZĄI"V|FċPj|2EwJWӯVžWk1GFbJ|zc2Fw{uYcmܹ-էJ[R5o3X,Ѿntb ԇY\pXiacw=~v{H,݆cGqδgJh";ۖ=~G#{Hn1,9c G4g4k"~j;t=~ sP,c Gi˴gf";F=~R=*=]ʞGug f姦wdJLFIYKJ9vt]F\^W1 ,U}eDXjL 󱒇Ac`zϭ%|7nw=Sw&|Z#v\(TcyȈIv}v`T3A4xzPl<2' t[1zTuG `I;ZG ]kqڣ[I"7X%Lh%lUudqUrE͘Z4޾Q$OEظ=+yGF(O.RtUTwd$-=棙|"X?'=$s{1||x3@gog]?9(o {V,1/ 3@׶g?kc ?ʠ={# A:43@kgEfW?J7=:==];t,8'Ssv 5%+7<}oh301~9Uz\ ? 7/V,(-FoHƊ+/h Yjns1vTf0!kֲFuޥ6^%7LΥyn;s1tU1;bEKZsLV(,^!LZ[YA;N Q|ޑKߧJ|'+K%O t곟;&K[g5Za|zI"<_|d/,QZfFQ;N} n̈́b meXK,Yo ǎan۞=xGW{֙Q  ٳ72bjd8ƞ)=x{Qz KڳNǎ1deœT=a{͙Q 5ٳǎQ2ǏRg >EGwhN/ş \g1 7pԸ^k1 ,/1kI5ʖ/_?_~_~:c{Z%ybDJUdJ.ej-_&[曆aGaVkBVҨOhǣ*3/V,(O-J"L\ѝQEuc7rZaҀ%e#cH:|*{>U99bDylq͇>@,S~q|ZxQ fǬgA5+b36.lJ Z4Ykq$ -=XF3ՙۢ@R)Y.#j[O=w̾S2b%/Ή &kamp^ջ1hFN:Jxp\k3Eyn1#&U0Y+oGJxX^aֆ8*ExPM3EwJ5/ ֆxǷ8-¬##jTWR/?9S+y̜XhU1Ԝ^$+"_8[ڻ|jz拀cwTke8a:1ŊEeC+)Q:f>Ur-+YtT{lit꿛/:VcY46k|ʗ_K[7V?ǖXfźa5Եj ϵ"KR:x-Wk1i GDF U*L]Gi񰪏-gOǃ=OZ,I}gBh:Wa0^m1$o]-/|u8Tss\Qϔ|aUwP+|NX4Q\Du#<ɒ4x*^Xtv'd"a;ކ=0VT{wdfX"!m6MdI<[Y,ZfuXh{6vQ6 3@ngmÏ?=$/M{օ1pY37go'cõ?1=s{1(L3@g?qa?J=L{p1tr3@۳HcuںOf#p7-#+kT}wex*uAU7/V,(.VtoUZRw8\xՊY vH (5AkڲFO qn>XXpVHҩ;EwR7گVОWq&+`]Y*GAkweX/Y V:~|/;w{zF$Zxu4krlTQ]%,YllQX|Ixoi躺1UwxFm-F@SGTw$U-,xdqEyb%16ٔ3w6x~fKڟ8V+JG#N|vzDŽ2]љ"Rc4#hTCqq){>TMFiq3Z8C󑪻'oǪ1:BVV;#\YlY*C!yǀibz|9^9}zJ+r+C%B+JT`N xXH7tdĊjn_,i!Z1jf1VYoQFШ.4 ^JX,u[3Q:ĪX\ {cGqgd'l"޻;A=~B{Hn,ʹ̱G1gda";X=~]{H,gc G0gնn"O;FC=~7{H-E,{8cT$rO*cɧ<2>dcvgc5A-.`ҫd-8+ht:"L=./j:/źYo"Nϔ\Tear@VlV.S0=VS&4qE{>U&ybDu'1gJnc3YZz>[atQ;Vb Y*D){ݤ-Nd~ʗELx]^~}mYK9PFiN:RXխ:: st< d߁وH6Nc{.^W_<8Qi1TZ!նfX-U}{Z=װlpg&YA6bl 4SԛT}IJXX<(yU3nZ YZz>[-sڌtQ;sZ YC)(g$;25hϧJ6,-RuN']h>Su\5Hjj-At-NWgN0Kh>eEIK oeO/ }PlA-U9bRmPP, 2rĕ%-blk&]%+ aaeQ=$v{1܅83@rǴgFh?9("{61183@(g?kcV?@=i{At 3@´gf?J==j=]Lh[QT~3zd%j'z£͋%S )Y\F6YǷF`Q%ݝ -|=ZLV(-f,U:6jZ<`|q 0U(UC>Z,I{gBK+aχ5/*9c'FR4$}FNcnAo?[~-է|BU7vX(QZ8xHF6V c% <`-YYdbL=ƒlĭ)htرOTu(Fp*=j{mJy:ճ[{`&d_8nSSOck١vNX,QZ <*D;'oJ܉jzgb ROYy>#itة9qE{>U&,UGxU3UбZ YZz>[1"ע#R!OYoQFαc{ Ti]ƭ9VcUlZAj=1x`3@goj5?1=$7{[A3@go|`c?=I{Ci1XX3_g/l/?J="{}1Qj v'IeSpuY/Wtu:ރتiq.vbIoxMie8_Hf=QI_Wb6pRz>0'cbJmQTz1juPމ:YFELGو|9vϹ-@o|BCb6(O-JJM8޶=AqEwF/N7_m6(O-b$wb\<Tcߑ5ԨKظ=+yLF(-NtբP7ej_-=x"V_Z d=~ Yěac0Ǐbj4ӞEG=v +8{(n[ YcǰǏ`iܞE0=vI{(i ~YYcifǏ0lӞE|=v#{(] ,we瑩(Xǖ5օM~}w̾3waҦUj:pbł=L5C1ʗ ,3cBbĩ4Cmt +~m^xh<Eyf&nA~&4htUꤊUݵv0J-Jsb`±XɣsbłRXJW)Ua8X΄VW`$#^T!b*|z.8Q+x&ƅXɶLamQ͇Z,I{gBK+aχefZbJ|zQ+/_?_?[_-էJCj;?- JW8>iqE_""ދV59]1aG6e#ޛI+x"xT՝7K Tۢ(T{ja$ٝ,ik[jmQV͈EM¤:|TZşFsb0ۢ͟JW)U}L*v@nVg;{( Y cuǏiɗОE=v -{(F bYscpAǏ2hniמEȤ=v4{(? *YcǏғi͞E|=v>{(r{HuH{CY™ ?f~&xl긊Q f*Q#@gl>Lg==2V+_~~uC~;ǥTi5= &ʃ1,ڻEŇP lxQ[̈6ba6]&jtWE r%'VuG`/js\@bA5 , +/̱lǏbn۞E =v W{( Y[cpǏbrd?ƞE]=v W{( fzYOPcǘSǏ2 dižE|G9va{( zYķcǏR,gTg>e7,xQ5۵]8; 1{RP{']]7 /w%Ճ`e:Xh꭫q{ O\J9\b:[Zmc>]ZV(O.j,|ZUବQ ; T:%̋&ae(L|䎙dQOŖVɞOW++_'5c|zxY7JU6~ ̾S2r%φΉ&ʓnGՇrFΩ2:*xtf3EyrQ3&U89?ddEEUJ"H_#!QUwH՝P:*xt<2EyrQ3&U89ed,循3e2P=K6i@ R|꾌ѢJ*<\Z1{>^-ЌQ]ܐYFAs]UBl\l'qu)]h>Vu/hѝTåղ r4FѝfWi%+|_~ʂ׏/NR}iA-T %s^G,{gaEwBگ  JlpQYbA6khZGYaj߀=xww{Q\ ڳw۴ǎih5Ξ=x#s 3Q\< #سFǎ1keҞҼ= {QZ@۳oԴǎ gȞR=¹=v =]"^x?9?Om,n̋ %ʊ*#N{$Rd-+Vt'Tk`cUEyfv|ńU gH"[>U0}:WźYo-Nϔ\ePj'"K[gu.S0|Z1YI;N |+:wj͋һxVnԻS\Q%ѝ,v=kq:Fb Y*D)=P JGF}o/7;?~P<'?'X,(-JJ Tu `I;ZGHF.m31 Ĥ* f= ⨕b<`Wa+ٓ)#LTPeYXFN)y W.#^1bRbFNSna7\sŢ$JW0OCݚv8YĖVe/{`g|1K(fmqJIqy;+p>#MT7QQUUɢ;*#&liZ:6_`R0 ଷN&#kTR/`~mKڻX?X,(.J=VPob Jpu[.̱Ǐn۞E=v W{(f Yc0Ǐbrd@ƑFa#x cG({iR:Xs$2Hi‘F|=x6bG(i9hp$R=wTt A c-$xQ5-}(;01{Ӓ鲢Fw&(~a, v4w[0(Tr9cE-NKaZmEWw~YLn;T<ܟ0/M|1 tTɍ3,$-@W++_\|YE6kVJL\ɓiQ+ͧm}y8YĖV5aZcQg=o;lw|eGT=X•L2'Mt1ʲ UuϜMdI<[G!SFjrq0&9ed,L]n@d'M4Ն8*FT=7Y%iLll@Z"cL*qسYvU5 VK,tU+U}d9ntq +`Uh-Sղjg2K(ZѝfWe q;,yiqC]HGXWdDZ()TpiZ 6`R8 k&l5k[V@YaOj#xwGڎPl) Y:҈wtatHKΑM#xW${ 3P=) Y'8҈Tw1Heґ8#!GCP)@;҈ot6H1ɑRˇ##x2#]("./ =~~aM(R{'&5TzP]: łc w,SJvK@H/s/(fBF(Vڼ``(ꄠP߬`aKj'B륂 W!+^TbNJ;(fj_l VdO@3O\4ͷ" JW0 >,*)CߙҊtC3Eyr13f)}oy8k$Dظ9y ZT6ETY>Īn*wLhIR<\G=mF(.jȤhweJ(y*Į:7 XUxF(.R VuhIR<\"00Z+2Fulw@&A-iv6J3eT=&KM3'#O7OwdJoZ9W\&edb(\ti%Z[fvYhu>x PvSrwwoóؑ-#$MG1| Xu9R@rAr9cÑw#tG31&- ̲9R@r?ݑJo9MG=r1: z8R@;҈/Y:u!+wmrxԇZZHV誰צ<./FdybDyz2{ՃgeͥbDB52Za#+a7e&VmF@[Y_v^58 >77s=x^X0Q 5o2 6(TrBVߺzfUɊ%KFرhY++jt'U :1U}>/L%P& Tl`ѝRYZZ@z3<0{32w 5*h mgӠ P5~P͕l1'X,(vs+PUw(HUXߙҊts2EǘXYi8k$Dظl:iZ4QQUu7d;cK+dղjޙ`R0 '5:ظ<*y.{ow:JC nEITY6£my9#YTj3ujقgbfL*rYvU5+q%/SHITY6##YtڠrHjHa_IB30$ Bo.(D#cJc>h-!9+lTŲ ΥybDyv"jn-^r*\^pVc2,JwhƅѝfWiϯnHإ7;gJ~S:w v4ݙk*++YTBIgb8-HWoN/_'3cT& g#äX;ˮay[@ii3"Q>\ SwldQ %3 ]=Ol|Q\̌I lfTWKɆclXZ ?Kҙi\RQVuhu¥ղjYe좆R4 ga[RBl\Kn̈:ŁxUT4#Zt'Ue.W6#`g5d|3Fw]gLON1+Od zP l>'؍. VuhQ] %) .i^ WFVΪ&Ҫ|n0:^$YZ᬴Qˮl. beJ79L"`K|zFux{Pf) jIJyv7^o?pҌLgTsU%^D3ÀTEu+x&st&Wً1o#6X{`b:irU-F;Q? UmCldsuZc g#dY+UbOTbR}j. MQ@JW8 nߘ-O~uZv^-sьQ]ԐYF,p3Fw] *UdS8Qi"+S.<#Zt'UspiZf vq@f)[a[R/,Ceo`JKRH$/wwUk6V/`U_OZ-IKZ WkyRFRԻ k&l5+]vy@YHi%#xw{ &ێP\) :҈taxHQΑU#xg$G4P<>)@'8҈Vw1HeґH#"GcP) ;҈o6H1ɑRˇ##x2#](J3$^s~G H4-:@1Ju@H#<#*G HN@4]Wc8[8@q5H#~<Ƽ#.G HS34c;@iuH#GB_X̀JK٠&Y=~ uhSPEybD Ps"|DJ7VX-:2U+bd"Le {*e;1u:}ES`"%"luԬѪ5d"L* Bjڠ&: ugOhYO罹iGư P݊0*y œ`X<y/4YZ:ޘtQZYCVm'M+!k\J޴5C*pK) mp+<+#k{ PŽ4\cf:@&tH#j<#G H4m̛;@u41H#~F<4# G H4{ctk:@鉳qH#Ճjyn[1T3xL}lY0VH d6@jM]m1$QVBVҨ=_WIs̼`X<y*DLɝ\Y;k&(]t-NWp0@HYo^t8iCR`3+Tc%/ v4r(](\kqH hiZZY1c@R$=_ѝd>]ud 0U7e L ZZ;kq:c[ Y E6j&͙?Um[OzTCUwcX(ѾmTZn"ۍuEe+]zjm&B6⯜ 4bOBUwΆR-JKw<ٰ IvxێZ`Ey`ؠ- 8^W^lyz'TS%fiOQS-GŹjj-I!dE1Y8@YHɑݑF=xaG(2i:s$bHȑFs#x G(.&iO:ǘt$2HiǑF#xvG(Î:3iك:r$HrH#T~ׄZyB36A6iH|_:r,7#Ioj}m `VJU]^0837Z[VH쐞nץ4oY sA5U`Xx*l@䎄\ѝQ͝Ku٪5d%L*Rڤ&Y"1u6KTc,2U^@b (]\HKT 7[I[4) ، i/^s0ͷcJW(ۺkq$ hiZ83:#[ YD<2Fףqel\Jյ:XU.#XtT{ehiZ><0ynGM3yϯns[OR5~[s[ <ŀLqE%קJ:ZN3FKdG&maҤ9ʅ^`T#lf6yISO0%=cP&]Lt-ld,k"_oH#<#_{ P4-)cx9@1Xs^H#.U4O =ybDPbJw JⲂEwJ5WJWM$ΊPDz1˛ofBFVԨ`FVڼ`7L-z'|7X`5*p՚zr$.<Ą 7챋Ya&+jT҆d1lw{;]mScA5VybDynQU EEQ5/s1PYo9#j[Šݵ*ۀXavQU=d} W˄$#^1bR=ѝd0nYAX몧>WsӜ`7M([m'KߙҊt6_`R, gʘ5*y]B3Dyrq+PUd-N$3jy+g䋼1K(xFβc@/Ox_K/-r>UZW2BJMqTCC{IB6NŹ[ߑ .3&G0Fd;6U.h0J-;oj/ᚅ!`ȝ4]8X(HŴݑ!#xb{ FP4) :҈7saHȑ#xGP)@ :҈t1He"ȑҰ#vG-ĎP4) 59҈o9HH@Hc(nqf/U] Y᢬vӁB֒貂Ty'>ybD9Cȓ7)+7-6F[ۦap>e[eତQ3_vU箄ybDyj1p`Jn\p@" K+]UJ 2F@@@Yo$/#iHLMnץ}_n_sA5U`X<y*DL3rEFQd5SZaRCFҨ1_WI*م$#K#OeOus\ՇI:J׀l|bzosƵzC]k:eﺔ2Fwztkպjd9nl1+@U`}1O€Ve/s1K(FmqudK0Q] C[ @EPխ3EwJ7/VeC/s1Kh:f{2Fw{uacURݶTiЃj;,K#O`Ldj-_,i#'[]GU:j0cJ·A.f~*-zWaEWs1ˀCffQ]E$u[łܢJW, >|&H hiZv<0 /gD$;L<{KʶixF+y~NX0Q[@"@&;F`2 ɈNHT(M$'#jTWR'lb%6m6ETY.n&Z,I|'B`2x-W{|1PYό1#jTF)ǗKv.A5W;`h\D FTmk3Eu%w&"v]-O|Q\̌YE3Fwv)7MT JW4OMdI<[Z!;|s1f)p[25ظ[Ͽ^~|c\Ov =WDP8FwaHeڑ#xT{ ֔P) Y9҈raHŖő#xG܎Pe)@":҈r1bHeR#\GPz) 8҈Rv$RsK)Iʖy%Y0WtxY/BlĹM]m/Ž/㬤QڜWIPyYzO{;x$|ã !L2%WٲrEwFïMK Z8+]/aGQVBVαYC`!6"Ճj=3łLU.t^`ѝRkUnxw1 f)`֛ݨ-Z6k`%0g}(](l}FZZ;CF..,z$Q;ɎϾx2\4E=`SX^9słܢ,AZ,I|'B`ˈ11bR^FNc.`We+ٓqô8L- r Tu `I;ZGmFDbRrFNSnaT\7~' v4(](+}FĖV2a8_. ,Ţ-d$JW4 )#YȒ$x&Bv]\3:Y[<ƶ G(+) ;҈7vDH՞#xBGqP|) y9҈qH#Y_{ 3P) 9҈pHؑR#8GHP<)@iė+˪GP|2d9:C-%$+kBOM|v}~RM~>S27/ t1 /PɊqV:q"^;Ufdŋ"F(рb֪eE$;MP]{\,LL0( ژP};EwJ6/KZLV߷;@1kuvmP+b}UawS}jGEս>FA`@U}V4#YtTsliEZ̛긏Q0f)p֛aþ%} 0+Y\}r%?d$JW4 KZ,IgbK+d2|-Wg1Kh>g{NY+UgLJށ0+;Qd-zP͕l56'MA.ʲ Uudi%uj4fbfL*rsݬ-Z3vmm3Du3 sqU-g$j._ HW <#_'3cRc}FX+U46JCaNX8Q]H GT-~qZv^31sYc^d8]5Pb[V (Z2pV(,Z6$d^Fw'mPfEӵL̕+*]i:E 4y h6(߳u{1էj*`X<ygjn_,lV!#]/aPe=Sѝc\d,QZL@ v>q-<„PךNeoz <2FwztkC  &c(](`lfqߑ#$hG1P MSrséʑ#$G1| k;R@u?zhdˑ #)Gm1o 49:R@ s߲7‘JڞTuϑƮЖ&+&B PQI /:>] YudQB _:0wbJ\ Յa$ĀVVjˊ~Wb0V98+jLIBϰ|߲ui|ߗ۽n}cj bbZ{d4+-6^נlEyjv,Rj9J9v4h`:HU}R4K#O<0 Sl\ѝQkud7[ZYa e#Hj}YSOslG2'X,(-Jt69;FK^ղpʈEH4ǞXFԨxq̄q];+.#L%PbQTu;ƌ`ѝRkUjYfċ"FR( ggQ[5iy.tUMvjXsłJ nQU~gn~m 6 \-KxQ- ĤB f Q| Xx +yGFh߷:osĂ]}LF߷ВtZ}/K`{|\0zfXDznV 8҈pwaHŎؑի#xoM{ &P) p9҈=ra0HÑE#tGP+)@9҈r1HݑRK#NGrPڑ) z8҈/ۃ)a:e"ⶼ\Z5:t1zP]:+ŢI@,e% OjgbK{+o؏Q0fy U-l'g"l\\]iQ:0*" KjgbK+dUIӞdAȘaF}q8Y#`T_o?pU߭N }A5U>yn[1TN2\-̕uSd7!.*5m@@4 Hs6ҨjɥuL}6(O-FJ@Vtw^l\HEdg)1٤-LZ˫v]5r~Pl4'X,.-tP}mK݉Ҫp6^b@R$ gȸQ[R'l\J6xQbJW, n\ZT ZZ;kq:[ Y E3Ft^|{.z?UZTrو~NX0Q5(:# a8XNb xQ]ۣ[69ba`&#jTF)VJ^x&s[0ꋸfuXxrq>]1V 8@qmwdH#<ͫ#'M{ P&4]co9@8rd H#ޱ<5#sG Hý4) 9@ r4tH#xsŢ$JW0 nИ,s~q"v]-Ќ|Q\̌YE,n3Fwv)=3Dyrq+PU7H9\s8[Z!;S}F(O.f,z2Fww%@U2jTs%i Q=XT=l'Kؒvwڊ4CȚX ;R@@w8בw#$[JG.A Y9R@ roÑ̀#nG#1F Sq?aܑJO#vGGe1x I8R@*A;҈ك߅~ttXZJHV֨vl&®"@ܼ`ht$|J֌ElZAcEWNj1IUu-l.WA v'/SA5X:`p0N^HhQ % .W&+`g5d|޴Fw] *U}‰"EJW< >9-2~qzv^挀Q]ԐY G3Fw]]0w{IiFPTSU7X,Q\<L=Jq+I!hV>']/aU e#OH,yXT DzDyj1T1탗+־:ճht-LW{0Ɏl׵UPSOsj;'X,PBQTu`QNV/s1K([}FԨR'l\Jޞ/>ߴusPշzdB(iDhiZg2Eu Ln1 f)챷)#jTWDiy2]Z_fgXtS-Ct An!>47 80rw$HɆؑF#x kMG(liěp9ǰ:r$b&HɦÑF/#xtG(SF(iϬكr$2HݑF|;#xMG(qڎiķy8(;@)YS T( ''`YH@UK>N2WMˊUC|158AesIc^X0Q (*@R[VN:np/dI6 fVQI_.OM jhA5WޙybDypq+ͧԕ,s~m"v]ɼ|QyNtL(8덏fd,;NP6.op%3ojCFAh@U}>#YTj$3j@dbfR0 gU5ظ ˗_/xS [? 9. J$@ږNJ <ZG+@zvcW{1[#xP'<`W@@`(*8j[fJȐw"檀plm7^ ՞@L0lz9jT_ s\O@u`h}#JW0 nR,s~q"v] zWg1K(ޚѝe] 3i}#JW4OՇBdѝSejmɗc;[Av_8@/HɻݑFW#x ObG(<5i[ڃqs$bHȑF#x G( fi:ǘt$2fOj&ȑF #x^wG(Ďz5iķ9@r$H~H#\i*&*D{ʐa:աaWC-%$+kTPe/3&@}$YTsuEmQ Uf,s~qt Y<d@ZUѝeWUչ #ltU٠Bl\K8-SՊ)](KIFi%% .WC'#`]Y G2FuQ,<#ϿǗߛ8֥ԣjc &ʓ`OmGl`ѝRu ֘ /C:$kN@FEFw]% "XnDETid Uy9XtTkh깂oƫ=Edوs}6Ԩ_8vq.էj'yœ`h 9HՕPߙҊtd`R,ه׽-I3Y;Y,Yk#xtG^ԎP~) 9:҈7tHł͞#x/!G-P<1) 8҈v1AHeFё#i{ S P:) u:҈tmHǑR##x#]f!.Lŕ&rV<EUS@ŋ( .*Yd%u_3UӉ7_|u<(p*fde鼈]d^ßz?\],M''QZH\#>oȖ+GKW'!+_'3cRVfRg"*pruiQe0+Y\|ll@Zs< F7kV6dKר*P?KiRQVu㇍hI*<\Z-;-IFddQh=󜌰ѝfWe q;,i8Nա.tţFcѢJJ<\Z=; lq:c]Y GA{3kE r|ꆄkc8]o&ʣ%m6Ω::\|-W{1ac¬<aWt@NiuqUn$B!YTj$3%mc0_.j8YB5[b~K_,E,NG)R|vD4wb8X=Hݑq#xbGvP7) :҈bHɑ#x;G P) :҈t1HeLȞ#~wGmŎP:7) 59҈ArHHPHch$ ( DQ]!@kIu6ʮr*Ư`ybDu9zq {J.kdE%q86`u<8 hJYa(Ϙ|wbSW xT:7+  'ʳF-JvL"gUk E T87a[RBs%nǩfLFTY>Ī>ޜ-.Bz6 ^Q]ԐI#@za;ͮF*Uɒ]KyoNF”UP'#[TCIK+i{!q^F );ԼnNc-YFγظ@씷yZ S"|M3Eu3y.v_-MuƼH(HYfXj/ɩ+dxվTʜxzzbS%PՍ,J!N6 RmlXѝP XҺ%0zFV8҈7zwaHŰؑ#xMGP )@Ys9҈7Bra7HÑU#tGÿP+) 9҈2HݑR #MGqP) x8҈/;(_:E""Q<^^ ~yՃYfiO[S "Jj!K{`ofy Uؤ&#5fPu % ݪO:0)ԛ+3~iu[.M]1, eFu?Lmnץ!}_n_sA5U羭ybDyj1TP\-Ut Vk"tӵ8]m1¤ eMIH |]%m@,Ռx*DLխ6WsU7Bb (]rt-NWj0@HYg8i|I`T\. 5 v4`(](kq$ hiZvl1 f)cπq8j `vV!hFrC[ @EPՍj3EwJw/Ve/s1K(wFNc3,_~)3cGݶTi/Ѓj%c106W sU*a K'VoSG6n-j[(Y&4sثWnl,QZ<7b1rkW+$+Z8X Hťݑ#xaG殎P4) :҈bHȑu#xGP&) :҈t1He$ȞԸ#vGmĎPZ5) 9҈;rHHDH&nׄ9WvPFH]EȕPMJUBsH4sd2X}p _ŗ%Ճj΢`7L=ҽ@%3Eul"15ڲEyn#fQ0k7jI Xa9n!*ifEV-W++^TrFs1Kh:f_2Fw}&=n}iejW=JiPesF.NQ5`ZbR DFԨOUJ6%E TY.n,S~m 6 \-#xǷ( E2FuE,ri|3erP=Jv,M'Q|권ɒw&"v]-|uF(8fdKZ6avWrF(O.NtEɢ;kfK+d̘`YofmqJU^鷟O-|sw*SOCX,Q kc\ <7;1^5+3~m]`l ͢b]ںc}(LiěL;0u$bHɌґF#x 5G(FVLiě80p$b0HixۑF#xDG(_ji0؃iw$ҍHёF|_#xG(ώ4}wYvb(9?YmyMKJUc@ن (UgYn^X,QZ<]_2@WR5Y/_A٪26]t;3jm4b|nۥT<'\,LTEշ(ܓ,S~mu\~^.,EZ=]5J-q];s`7L=C>#,*!a'ĀV5/s1K(ތFmq$gGvi5jdχ9bDu-9vQU{djn_ W'g8^- ĤB f=/+=gtw2DynQU{mK߉:*؀p3Eu loQ &0{yfD$;5V [^jvA5W`7M(+g$J(LliEZ<8og&l:EAh@U}&kq$ -@Wkkq:c\Y Fv!mgT |vX8SuVn{^n :U4w 80qw$HɆؑF#x {MG(iqك=r$b-HɶÑFM#xqtG(#)iď9r$2aOݑF|W#xMG(qZiwz8(;@Y:Rs9葩Ts"( ]ON̲;Y0XL`I=Dh UEv"@YKBިVesIc^X0Q֜(*4Pɥ`Q R8Z/E7PjexQ[ĈmPZ 5J9Xe@T'ޝ{giDFA`@ԕ,7.>"v]ɼ|Q\̌YE9{qqy;+y9#M''QQUAMdI<[Z!; kq:NdY FJ2Ft^!|¦C0ʪTs%{ &ʓlHUi8YQ8/{`{1`Y/#ktgU`"*pr%4n6ATY6£C@t8YQn/w.>Ƥ g= 挬}`bT˝VgdzP l >'X,(.Rtv1h}o]&nׇ.^e Tc%[  &J\U.#Xt`shl@Zv< Ep}zݳ ͈Ivץlb%[fܢ,BUV)m6ZGwF(-bĤB f=kѝd035n鵼+aNX4Qs+PU_Z,I~gbK+b0/{`g1K(96GʕߑF #x iG(Si[T:t$bHʑF{=xG(N\iOu;ǘu$2HiˑF#xG(riwA:6s$H[‘F|qU,s~mj:qV(O.f,oYY;ˎ ϰ|t6^.SMH:E U+J.fj_*6(\xQ[ĈfFw=(CX{>mWB؅Jn. )Z8Z1E@z<0{32Ĝ 5dFXl8Ćj9bDypq+PU{HŐ$3jydbfR, gY[Rg"l\Jvp4-NSu(](XF߹ t|2Ew(83fd,;6>Jށ02(OzP͕:'MA.ʲUo6ɢR3$ HWc9#_'3cRxFβDUJv4-NSmlHU}e&kq$ -i]}"cҙ⬕|}L`kհ:ŁpU}ALk@֧<ȪG(ni;0u$bHБFa#x c.G(Geix8ǰKp$2HiבFl#x6G(SB0iۃi+v$ҹH)ΑF|#xVG(tG HJG,D[e8%qGN@i&dJ n7ǖTa#*BlY<,N.HކYѢ;[K+qU+e좆̢%* g4Jx~w _췿oޤO=t?ܪ0/ tK2 xP`׺:UkʊE4ȨFmaJQ0# V 0(*'zi`- $u7nZb f#Q+bUa"S}j=JE#MU+2 t9ɢp1j9;e`R, g?Y[Rg"l\J4-NSu(](Q&kq$ -@WEt8_A. ,YngT1>)y.{?UK<'MA.ʲ UuSMdI<[^%0Z#G8/㬷V!#ktgU`"Lƕ##M''Q}`TĐiSBdKut}ڎZ8c]`Vxdfe q}(1)@poFۑQ#$ XG񖛎1  9R@rodrƑ#$G1 Z:R@cs?5c8ÑJ=bG񝜎1 $9R@jp_]wQt$Du\gPAJ+z?. %yn曑q ,eEO K{1&g좆Z6ڕGظֹ6/X,(.RtaVr7+Zt'U{pij YMT7Ú'Q UmldѝS_[G @z$<h91٬-Zۭ"\SPsl4'X,չ.tfcѢ;*#'piZVxuq@f)3lܰ-[S!6r%[nǩ:Łx4OusۍhIJ<\Z=;lq:s]Y G 3F%З3&''UrjSEn˭>ɖs ` Re`X՗)dDZO ֪wBVZo!͆mqJq r'X򊤙896JplDHŋڑ˯#xOUGΕP) 9҈7r%HŮŞ#xGݎPFh) M':҈s1qHeR#\{ Pz) u8҈pQv$Rs)]l5o/JyvVUddve-BlTR}qmzsv4㋁r}6nCџ3D6(O-^$@FK6i Vj<|]]{dcNXbtLdm+3J8a V}lӵ0].$9@F Fu?,ubC| E PUHt8XNVer/K`g1Kh>fozFQ;N Xap1+@U7ՅPމ*p)d bBQfQ;Ɏϣ2/o lA5V9nnQuC U}1kq$-i,\]3:Y҂< G(+);҈wvaGHՑ#xBGpP) 9҈wbH# _GP) 9҈pH؞T#8GGP<) i+ˢSQm8FQNNPKɊ]2AJYiP{Toe8+XTNR8ZWG@jŌxQ[ĈI fFX5؎ jvz{ v4v(@ܚ" KߙҊtfEht(8k5wee\JL\Syip$JW4 >.,sbDV5˜/*Mc>F`4}Fβc3,_~>]&j|ٵ/w2S@?X,(BJJ@$J <ZG@z9jqQ &9$b6b 5+bvĪn4 &sOka$E \=slxQ9. $'N@F DFwvS?P{Xv,M'Q|խ3EwNUfL(Ҋt|3Ew(8gd,;uR6.op%oOaq} (kiT=tH՝P tvdؙ`R0 ଷ)#ktgٱqyPA XtSMC7u An>4 ؃sw$HɏؑF#x MG(F<i[r9p>r$b.cOʷÑFO#xytG(3)iϯ9ǘr$2HݑF|[=xMG( rziķz8Ǩ;@)Z:R$WΚPytօd d^/2!@j拀ckg[*f % WƼ`7M8*e@z[V[Kg(U+gbfL9ku,de,Nn:p8 TkGUV}=4‰"EJW8 Jh%TpiZ3z똒q@f)֛$;&Je q;,y9#NT2FՖ)]h>VSѢJJ<\Z=;'lq:dY GK6lV/izF淟_:E_.էTcUwҹc]@IP6X %Dh=깏eËR-$FLl!/jt'U !Uݱqô0L. JcN@NJ;ZGU@z.<,08Ĝ 5_ \O@u㏲5`h<8{g$-@WkBF sQ0f)p5ԶKAظ&#M''QQUH3r,Xy 2S#3t{ P>ӎ4m}c:@1tH#i<# G H^,4/ 8@v4H#~<̗#G H3 4{c:@wKH#uĪ>-z\G=hF(.jȤ h挰ѝfWi\s}L5dɳsbeJW@ۺ DFΪq ]ZI;K&lq:d$YGt2F\bl\ KwʔUz,#[T$sѥj9e$R@ g6wӦb/O;`IS^O TcU7X0Q]@Pnvu/@]Q m s61՞@Lrq(<jTÔ.OXj qiaj]@A^Z,I'BKZIWokaړ]6?a6&jTF)V+ȖAAQuA5W9bDW(I!`ͪU4c8XAHݞ}#xbGPL7) :҈7saHɑ#x/{ P&) :҈t1He:ȑ؅#6wGĎPZ6)@9҈o?rHHLHcW(q 4|QV]8k u5vr&\yn;Q{O;,:ߖC[Zu#Z-+_'3c1VQxFZQw;v)޹~ßz?ܥ0/X,n52*< Ur&,Igb(dU=mCT075j0v'G7MT3" ,RUiH՝P: ـt3EϪmET0}"#kTR/Y v3OBMɜ`pE_Ėa w}6.j8YY[Rg"QU}G6h߹:o~&YTEdIgbK FWoO, %V_ HݑF=x_G(^l*iĻ:0_s$oH:ȑFS#x C G(ƹi:Qt$2HiƑF0#xqG(MNёF|w=x&G(}JЎ4+~ +d9 "|ˋ+5f:3DzoET67/؍|C/t/XɪqVnR5\7j5Qu 8 H5AتeXdS!6u  'ʳ)ܥ-B~uzv^ `C/,Z^YaS3&-}GeU={8/X,(.R VэhIR<\G=lsFmO/Ȥ h ѝfWi  'ʳ|է[IFJɒOQī奓0`{2pZiö8l8_`>^&Ճjd9bDȔU/#[tgU{ti%Z xPf)sH]Ȓo3Dyz2+"pUd;&$A.W2<#aT+z;c^$Y HIA݋6bѿt}F淟GO췿o1/էJxTsU_p`7MǼ8:$YtaklIk-Xm])g#[Fw]u &E`\z͢ɱn>478}w$mOʳؑFC#x NG(N<i;v9Er$\ֻ.XNF.. VuhѝT \G=lq]$I#@znya(|*zM5* TKɒ ʔU[4#[tgUe.Wv8a/,ţz͛i+z.d]Y D)3HUY,y9_}}]kS?TLsbb,2U Q$a (]rHKT gI[4i HYZڰOe5mFr:J׀l\3Eyj&){g$;FvO>bh~N[ @ ET_,`c-zWk9GF ǝ-,Ez d2FuEgL׵m:XU}LU8jp8=#$kGvA] g:R@2'tvˑ#$GN1, ̝Su?Ec\͑L# G1Z k:R@js|dÑJ!ݑRґ. ѺbVB'0T@EՊױc@r %eEAHz ʔ|]}_nv~KT}걺>jђ'ղψEXm?fozk6jV|3e2T=J1'X,. t f2EwNWگ͖Vh8_. ,Ţz+fv[l> 8҈qwaHŕ؜#xMGfP) q9҈?ra3HÑM#t{ 㿎PF,) 9҈r1HݑR[#6NGrPZ)@{8҈;(b:u":4~ԄΊǼ`hrP%KqYzd"KjgbK{+gbfY5wӾgd~?U޸.S=H:U)d\\p%Re֍.`ۀcVLVα_@[,Mcੜfd=~+۠uOd7.S0i M¤:|j>`S}i.{z ([ieP}BU7y)\l6ZZ:kq:c YD1{dDXjDXɦMa<(ej._-Wn8^-,zfQ"Js&σ2g+ [޷Ọ-e>V9``<(*EPMk3EwJ5ۯQe/s1PY;#jt'ٱ_rmV }F(-JλȰzW_Z,I|'BKZ/WkqGF.- j[0-ɈIvj # O@s;]mGs4 JW0 k&Y5kW ׆ӈtc#vG Hv؎4:@qtdUH#< ##G H624m;c#8@A5H#~<ؚ# G Hc4c;@itH#ms2D$3jy:e끉cbQg=㱌Q$Dظ섗&ʓ(](EcFΩ tC3E23f)p3a>9<(y۬|erYS=X•<'X,h߹*FT3EwN5W/ΖQ W}F߹m.cofmqJUr'W򆏌4Q k\D7=QU_=,*5Cؒwڋ4CȚ` ;R@@w8בw=([JG61 XZ9R@ roÑՀ#1nGSA 9R@q?aܑJO#vGGe1x IS*A;҈9߅%sqE:: ,-%$+ktEk;[ * ='wR>Xgmn^X8Q U8ҽl`%YѢ;KW0.B,RMh[V؈W:ׂqŁNܞ'K!+ZTBIKgU E pZkF[)Ο1z痧Ӣ^_/o}_n[R}q@cA5UybDu3y1Ta2՞6YZ@z#͛j[y1&R62u4fRjKHU"K#O Smol\QiCѼmΦkaړ\ IIp=qvFUPSOk46'X,(-Jtxtw"u\-wƌxQ];\ YDD3FwZu׵m3DynQ+@UwZ]FsMhiZ.<09oGM3y=`A~}}kS:C7'  &*6EyTw"`pdċݢ@z F)~] ʝ`XfȲ2nu4 8ǰpw$bH~ؑF٫=xKMG(io90:r$&HɪÑF7#x!tG((iď9r$2HݑF|;#xMG(qڎiķy؃);@)Y:Rs9S9f?FQ*ON,. mQu U_69dh߽aBc.feZrVz_OaUfLMVTsui &{aՂ(F@\lJ9^q6[Z-Z%8+_)49{jWQJL\gioCFAh@ؕ,;$3jMeJQ0f)p!YvxϯneFǗ<|Hj# &ʃrr}63%)Dh@d b f#V%P"<`W3@9aqQU:$AmZ,I}'BhzWnl0^9. $o9@F,F%mr|*q>U5׍sŢ$JW0 n,s~q"v]-gی|Q\̌YE3Fwv)3Ҕc(](Q}FĖVE!#_T%9. ,=V}dd,;6>JށġOv =J=3'X, Q`T՗"e$j._-ikl6K‘_#$/tGӎ1~ Stou͑#$ G-10 8R@v?;kdFё#G# 1: 4:R@{tfV[gɎ@r$aO~H#\~W{\+CqX{m7YYm({ə^:ˉŢfAATHsg%N(u3u|}VW &$VpFZK^ @>6dՃjεynېq cNCa|h.^ `#2,EZiYab*wXLaFh߻OfDZ()TpiZ똑q@f)s E_o?y e[$'TcUwX0Q\@F%PU6X %DhgdË@Lx3U63VD];eh\4Z,I~'BqW]2^TrF{1Jlѝd0nV4(T-zTs%[ &ʃ(](WtF$xI~gbK+b22̘XYm?#ktg٩mqy;+yCF(O.NtET}%H9x8[Z!;Ҝ|QiA. ,qvZn׊>${Gf1< :R@r$uheϑ#$(G~<1\O J8R@w?!cՑʴ=I*G+1& ta;Rp(]#+u񍐎1 8R@p_Rt$, eCsI+W^ßz?yn{xqU%ĬdY4/VHWM̘ YY#`lf"kru &F욏QZH\J9\8[G!Z/拀cRQKU}?U 5}<  'ʣ)](+9rESղjf*qR4 7ۛ} 1;Y`%[dĉ"EJW< nZ-5~qzv^-KQ]ԐY G2Fw]/_?!ak˷j([^y?D24M tãS"-YTBIgb"HWϿ/_'3c[# g#&X;ˮaWN@ꮧh<8*mjn&K::== وy6>0Vrn_8 T-T%[  'au)](hI*<\Z-;jo %R4ڻ׽:a8Je q;,yiqs]HG7f (vL!<G(̳i{;ǰu$iOБF}#x .G(6H fiy80Mp$2HiבF|=x16G(B0i;h-v$ҽH1ΑF|#xfG(ts XJG,g0=r*5$+`Lu<8 @kIuYa;ͮmyϘ|wb5WY SQExe$,Ә e|2Fw]կoTyS%סT՝,K]l<~L 7W s%)cßƏD`7M([=d$-@Wˇ$#_'3cbQg=⬕<avW{ӦiqC\DFzWd-N$3jyeJqQ0f)p3fYvl}̭/w2S%#XՍB,L%P, Tml`=2%)Dh-~+gË؞@Lrl|0j"OXB !iajs\@A^ L`I;ZҪ90zKXΜ`p]H GXݝ2EwR/V=0ʳ2Kh>h{ya;ͮb*wXgcF(.RtţnѢ;ڋKgE pZϑ9#ltUxI32؏/ۿW/v>U 1Cł4\ ,I'BKWoB6(-bj+0 5>+w'aUD &sBR,>7$ej_-i,\]:[<* G() ;҈vaOH֑#x/C{ qP\) 9҈qaH)#_GPF)@ 9҈pHؑR#8GGP<) i+0t<9fš5~דDa7!S}jvtVEU7CՄ(ݛFUd" KjgbK@W/{`ǂ1JY薕5*yl$g"l\ \,M''Q:U;*=!+Y\|lij3/:cY F9{5[b?c]Zۏ :+y2oNX4Q\De#@#ɒ4x&B6 ]y|QdI#@zCY;ˮaW+bӴ8M5 2ʲ Uu{MdI<[G!wkq\I#@zOY7JU\d}?U e˱9bDyt"+n-~qZv^-ƌQ]ԐYF E7lV*T`quq +`U7_h-SճjYgj3pZ>#ltU(F&|ꆄXa3wKƝԑ,MG'Qz`TW}d#Ė-l|Q\̌նbqfdYR6(߹KV'7 U}{,Z2 ÑFGPL) ;҈uHМg#x.GNHPf) x8҈Mp1Heؑl#I6{ BP&2) ;҈,vѿHCΑR#VGuG(EK{ Yu!Y]Fnw ߙ -WjKWMU'Cۙk(g-yFZW^츊@> e8ƆcyՃjuybDu5:q j+nYѢ3>r*[^zpV(.j,2whQw WGl\G3/X,(.RtţX;EEV50ʳ2K(4mqJq@̾S23T%7  '*fMFTY>Ī>y-JM"g6'#L*s/iv6܀`~:q w U;=eDJҐx*z6 ^-Q]ԐI#<{nya;ͮF* x [Tɒ y?E”U[4#[TCIK+iղHXeQi=挴QKq;,4<#O+S"RWu?lѝUv_u yPf)  i[RZ]vB}&My>Ub6;&jS^@bA=iX5&V$w$bHɅڑF#x gUG(ޕ\i{كqr$%HɥőF'#x G(ݎfi(:ǘs$2kcOjF|˸#x\G(:iķ8p$RvTs)mlR6Q=3緪$xQMm(;@1kt5fl"_A:łɆ[0(Tr9#+XtTkh6@᪕6^x(;ꇠ5b?TaR}jzwO,ML4U(M P%7d%jn_-@WkEWƋ1Kh>g[5JIqy;+yf4[x%|7rݜ]̛ɒ$x&Bv]I|u(8AddT1w.owSQ`S?\$sŢ$,RU7d-N3uj:m=T0g=Y[Rg"*pr%{m6ATY6£Cݤ1#YȒ4x&B6 ]-ь|Q\̌I#@z6Y#^RS. @ê@;,xyNX8@JW8 n -[Sղjo3hZo†mqJe q;,yGFdPRQV4Ѣ; KgZ0ʳ2Kh>h{kfv[m_>V8҈zwaHŶؑ%#xNGFP)@t9҈wEra>HÑu#IuGPf.) 9҈2HޑR#NGmsP) |8҈/;(c:؅"BQX^|ա˒㔉7S_@UkBgc^X4Q5<8@dѝS_[/ott_mO2Ǝo5ʦr&¾\k4M$ R%}7YdI LlA$d=_mO2ƎwPZ3YY2Q*UbUb$S}j~:r  &dH GTˈ[!\Z-;֨hF0v<8 @ 4g4*T`#18}8ݓ ){iX}bU7ȈUﮤSճjYdR3R8 g6b)?c\α?A5XӜ`p2FyzqSf)[Ji[Rbl\ Kޓ'auȋ)]i>W^3:Xقr\F G ;R@v\ ֑#${CGfrA, "9R@qoBʐ#_GÖ1F SpؑJ#8GH1> T) *ie]Hj& iϜPMJU'CǢ2.X6ڛr32;Z~~f|'_nO=VهTsuVEIm*" K$gbJW"mPQIU;yf@Ν Ţ$ZJnd%Llqwer3cgoFFw]UbUb&S}j. GEpU}9#Zt`3.Wk~8`c2,Eza| ظlWqZ-RQVu#hQIOVe0ʳ2K(YFNQbQ]ß*٧ާ,  'J͐|ۺqcFN*y WV4#`]I#@za+y*Į:7 Xiqj]$H#@F"~"KZW>#`g5df`-lK35ڟV1'X,n/ti2EULx.v_I3 X}E2#$tG~Ԏ1l 8:R@2tÊ͑ە=(#!G-11 8R@v?FcXё8#AGc A :R@j|tfǑJ#B##]Z/[rW,cK .d 1Kٴ%, 'Ӌ) GWr-JҾFU+ll{PflHk6mمyޗ_K+kY^.Ss:WQ3"A*qb%*dEj_6(^N `m/Ȏ#PZ^6J}  Xyn| Uda=C -*IC:՛pE 4maJqm{ GUjdk9bDu;|0+ pUw-l-Ζ$sѥjd$6ؙ"R< i[Rbl\ K#<-Su΋)])Sfkq$A.W1#aTFg΋2Ki>i{~i;ϮF;.ٗGy^&+Ճjd 9nz0U3ogKR:ڀ|7abL* HQj\Ȓ.l6yW ٢J<]ZE0Z k6ab^Mⴕ}!}Lhɻ{Qn:4w80w$HؑFa#x [NG(Ƈ,ixكIr$bDHÑF#xuG(S-i϶9 r$2aOݑF|#xfNG(rڐi|8(;@\:R%DCOe!94AA]ĂRXMۈ 1-cZKNΊu4'l2sc^X@Q_PTۆ. /X<1 aǸ3Z!+nt'UxK׏˿o'矞?}UZ1+|N[@"@vw"_`pV)lǫ=EXmfuQ?RV.LJ^?&JR0k6X%DhIej욉!d͊A_8@Y.HɴݑFA#x bG(&3iĻ:ǰs$eOȑF#x G(i:t$2HiȑF=x&wG(Ď4i79h>r$HxH#X~u 8uKɊ]d3FmGOtA5Wgen^X4Q\D4%MYR8[ڷj_1 ,*Mg[V(߹5k6pu L4U(ҩT Yɢ;KfK+dU|1`R0 5iӦW_~1vtxeK_e.է3TcU̻X0Q@xP=F7X %)DhGj 3oƫ>F4}6ԨR'jIU"L%P Tmc `I;ZG@z9zd«=EوS6(߷S?PsAv,MTQQUu dѝSj3fbfR,ٛfmqJIqy;+6#MT9. tEv"~cK+d=3E`Yϰ>#ktgٱqyP]kC0jTs%oP,M\|D7QU_푑,s~q`tdbfr9I,˭ߑF9#x jG(6TiV:t$bHʑF=xG(iOw;ǘu$2Hi ̑FЍ#xG(:si7B:7s$H[‘F|q8d9łRmZ,I'BhWϘ$^Tb f#9P;ɮ`W{!@fNatQUzvB6ՅP߉:ڰ3ˆEvوIFmaJ9X @ǹTƲk`hVǹ(Sng,s6~q"v]-|u(8gdXJL\i<8NHCIgbK+d둑/{`g1K(򙌬ѝeI;vܛ?5ҶԏېEIy+.U5]3:Y˂ېF& {  x;R@voN֑ɦ#$BGfq1, Sqo&(#1_Gc1 9R@pnؑJߦ#8GH1= ) )imUH OPMeՕ1fP5ڑDY9,M''Q0 UrI#+YtTsl @j|Q\̌I*" gpVβQ @>fdßޟ`ic1 By%ږ\w}͕gV$TΒǼ`p"DaI6ZhImTp/xդ⬀Q]۶d$Io Ya;ͮmyT] @%ybDyv"UjX߬hQKmTpl@j Y2Eyr13f)p[F5ԷKAظi&M`5$ !ӈbHņڑ#x;UGPl) 9҈wra!HţŜ#xG܎Pe) ":҈r1`HeR#\{ P) 58҈pQv$Rs)I PT5مʔ! סj]V(O.f,9{RFw}@E/{?:5iAT)R%۲E5*`3uEyr13&I܀:Rg"*prun,M''Qe*++Y\|ll@jY< FH3FUS.Ur%TbT/^@Ep4hu¥ղjAlhZϵdö8l2Oظ죳qZPRQVuhQIOV?G&:c]Y G\2Fw]/_?!a?|r[.էJC6?M.J{N@~ɒx&tnE)23&Yq8Ȝ5*k0v5niZ\Q< UmldQ %-i] juq0V[lQKUp@s]OBGy͜`p EJW8 ))#Zt'UspiZ{f۲nPStwèؑ#$MG񮆎1 s9R@>ro4cÑa#QtG񃿎1+ 9R@ r?ݑJO=vMGq1 y8R@*;҈/X:G+ BKC· ^])`xT_:s8w#@J1wl"@KK W#FE Uz۰V?c\Y޻~(& ՃjybD"UۀXm YѢ;d$z6 ^&QNRC&AkzeXT]un@!8,H*GXG3EEQī5ܜ0.BȤh{#a;ͮF*6JՒuU,bNX<Ѿx12+ pU7,YU>!K+iل-NXgċ2K(ӦmqJq;,ى,#O!+S"RWulѝUv_-njQ*ܔY HF3Fw]߅?ao8T}A5Wui>ATqGՇ)&ka$5o5 ]=|89߬-Z3Vn㪾gaӴ0M/j/F/LlI;mXmW)g#+FUehbR}j. z z q} H 2iį#bHVۑa#x{XG&Pl) 9҈raHvƞ#xG#Pf) W:҈ds1.HeÑR#b{ 훎P:) 59҈pQRw$Rt B U2 ( "ȼТkȩ^It0:dY<%$o`+{˩ \ژǍk.Vr-+ZTKNV V E Eո6*mKإFo2c(ßz?J3/؍tk2 VrWVOQī50ʳ2pZo4#l²܀`#qh{a+y*Ud8U8/Oh-Sճj؀-Xg2K( Ⱅ|ӗ-a?Vеm]O6 =檾nuquތ FU{U,Y86spv=(lG.Ŏ1` m:R@2tàˑ#${GnAL ̥;R@u?ac͑ʬ#1 GM1Z 4oSjs߄ÑJ1ݑRґƮ QAIMLu'hed勲fYK۬V63Y9,MTn5O2o˜T}KYɢ;d$^tmY<;YY;ˮF*{>U 5?}8) v4ߓ)CVrF-IKeUkڀ$R4 7a[RBl\K8-SՓ)](`Fkq$% .Wk~8`O2,}Cdl8w׿{ 6uʀiĪnܸZ-Igղ݀-X{2pZvö8l8_`^SxJՒuU,ُyNX&i+z.dked~ ]ZY;)YF(O/n,zyi+5b]ԽL-dvsO3eT=FK[3'X,(/Zt;6\%idxiZ;f"vYh>xP8R@2~womؑ]#$#NG񶇎1 w9R@2FrBÑ=!uG1. ̵9R@r?ޑJ#MGrAڑ {8R@*;҈/Z:߅!PǨ8d9= D-1dF[]N(@7/ |2t`. /d`FY ff>j[EneEXR_k ~ȇo܄y@cjUyn{quUA6YdI<[/EmPj4/>eG6k<a1@ziyqUNdR!d-L$3u7߼Z?c4; g#CX{dbTWޛL_,B  'ʣ)]h>V%ђTx*Zv^-;Q-Lxq@f)3}ivU6Wm6NT@JW< nZ-IKgղo܀-Xg2K(mqJqxu.|wzJCmoq>ETY>ĪnȼZ-Igղ ߀-X{2pǞmqJq r1X򚅌8Qj"u޷U}HFN*y.i"^4kw@VV Zo҆mqJq4 `>^ß+^suqY8Ԇ Gc8;@qԶTH#<#CG Hq4ͺcx"9@qH#?<Ȕ#9`G H4cL 9@pH#9{ PH4=cT -)yEjQFR!Yf+£.(H # cRFB#i#l1bl2syc^6e$L\}+oql}lM)Kov7auH(6m}A՗_K+~8pс?`;j '.Bʑv@3Т;d%>x"6` v*#L2oodö0l8_, a증@jgA5YΜ`7OH>mgKJ|L6a֙"R< 睷i[Rbl\ Ks<-Su΋)])hF ʒ EVe0Ӌ2K)_mqJXu[_,YTiȄ[ٜMٸֹqa^X@QB Kn !dxijM_Y#RH @՜7*r#o? Q/N7zXjcv4r~Fka$Q P8 ^q €H A1ذ- [)S!v5nc 'JՐүmlhѝT}u4!īg[ d h#&ea+bTcR}'j$}y?E”Uq8[EV8 [ΰ eQi=c܌Q=cbwYWsF(O/VtE6⛭ْy.v_-MuH([ưi[R/DeoJRQ~ v4}ЋH0kb;&$E.WֽWkRF(O/njvH-I!lMPj8R@ZWH#<#{c{ P4-:c :@sdH#,<%#G Hv 4;@t4H#~<#xG HƎ4:c49@NH#H`W+Ee9W}zVΚǼ`7OӍX*oq\rf-Z # mUB HZi#//`@V|UiA5ZBۼ`uJ\p%U5)dEBر+c2ZfF[ӓA6yunja TbRX! pI<^Zu;Flq:e,Y I7nVJ!_ݔ@{{<<dig S WmklI<]G @z% k{P&9~`gӶ0mLՅiajs_,L^\6[ %I\t=m&=BHڈmaJ؇TKe9n}@+$U7p-ɓUk4oG3łZL|8nNOٸlpZ Tb|>ԗ/lKҪlG3łZomqJdsMh&oNՃjJs@Mc үp9p,)تcu#oxG Hێ4 :@1td~H#h<#$G H&44?c*8@[5H#~<ƈ#"G H4c4;@it$H#!eՃjν D7/J7 @X"K :6cuh8Xm答(ؒK7QU50JWT >Z.IgK+r֚ߌ-XŒ3KA)mqJ垬|UU߷ Oßzi~PTnOS[GԧΦja$= Y=lGKdlĢls0g"B _&iajC^Tz"6qT-Lpu$.Dc]%26b;7vyebY!j<`= T`7JIW @nZ+IiKW2p-Wgtk},E鐽}[A[4qd}ƕeQk8T}jq#냥լj-G !d -ȆP) 9;҈wvH1՞#x?GjPl) 9҈7^qmH:D#!X{ Pƺ) M8҈TpH֑Rg#^2G];Pz#)`Ui mU˵~ernTWZ24Bx][_ uhSPEyn;rTa"%K+A`_Ѫ16\p=t@Ze h^W sw^\8 6Rr+ƊmXGZ̆/`RaV4I(8s i? $#OQSЌ\ѝQ+j+oE@8@Yo~8i_vUfiq\eozMIK d}.,}-k>h"3(M"tDmmZ XG?@zji&kB6b A[4im* Tuڍ(p*j['oƪ>FBZkasZI퀐oM+ sZOd-^1,Ez$Q;N} X>9am1+͇]ݿi8X v\-oxuƶ0mGM3)g_~ݗzS%ޡPҽǶpVR]ϔuPD^Z`Q1 d#AfLOBUw(-Rmdja$`I;mGp- W{`ڢ<,ޏؠ- 8^W^lyz'TS%fiOQS-GŹjj-I!dE1Y8@YHɑݑF#x aG(2i:s$bHȑFs#x G(.&iOڃt$2HiǑF#xvG(Î:3i9:r$aOrH#T~ׄhkB1 tMi!_βܼ`7K xҽd0%Y2m}m `VJ]{1,LeZ[VҨҳ{Ԕ捽?=Kßzy?\fiO#asEUt VYfE@W`0@HYkF@dUJ,-RbLT}:ts8Wu $5 [MtM Df7i&"EvO>Ü`7Lm{l1O€V右Zb"|><6j&Θ06k`%{m:XUn8X v\-ƍxuƶ0ynGM3yfϯns[OR5Xs[ <ŀL7W sU*a h9 V{ӵ0]-$cw@F7i &͙0U.a0K-KڱZT YC0z e6] ՞b \GHsX1 #xsGҎPL|) 9:҈H`͑{#x G,P/) 9 8҈v11He*ўė# G P) u:҈o}tcHǑR#=x#]d!.CQ[v>U4O }: 0ͷbJw J6X`5^ઉ/:] Y|0k2Fظչ6/X,(7VS  Y6*p՚6^xu,LuafFd1lw{nUC056TcunigPe*pE$uTj nǫET(Ĭ7Q[R'lb%oETY.nZ,I|'B`2!Ɉ;&]I"@zF9Q;N ag4zP͕4'#Mo6Mw$JoZ9UozT=-6Y%LliEZ~wpQ0f)p3eܬ-Z)36.op%n:EAh@Uݾv8YĖV孼ZcQg=⬕|_.^/ou_^^Ti]Ѓjvv4}r R% w%s`hwl=EXm#doFlTi*tAU_wQZN睷`Hpf m}.c,p$bHۑF#x WG(f i90r$brH@ƑFa#x cG({iQڃWs$2Hi‘F|o#xbG(]iķ9hp$RBUtKB%![(KUjȆ`;(d-nFmGo⛒A5Ugx^c< +^Hdij5M]1,ae2&4qA;sW¼`7Kx 8g,"D@V`ǵ"2F@@@Yo$o8i)ҳԵ}]kS?Tsb-K512 S\ѝQ5Kujom3@T g4dUJv!SY&dnZ0 YGoӦkqZ I"<{bIKjrlu7' -tSFK^ղx-Wgd1K(FmqudK0Ѿo+LFh_4jzlib-1.1.3/src/test/scala/000077500000000000000000000000001222267011700154575ustar00rootroot00000000000000jzlib-1.1.3/src/test/scala/Adler32Test.scala000066400000000000000000000030311222267011700205150ustar00rootroot00000000000000/* -*-mode:scala; c-basic-offset:2; indent-tabs-mode:nil -*- */ package com.jcraft.jzlib import org.scalatest._ import org.scalatest.matchers.ShouldMatchers import java.util.zip.{Adler32 => juzAdler32} class Adler32Test extends FlatSpec with BeforeAndAfter with ShouldMatchers { private var adler: Adler32 = _ before { adler = new Adler32 } after { } behavior of "Adler32" it must "be compatible with java.util.zip.Adler32." in { val buf1 = randombuf(1024) val juza = new juzAdler32 val expected = { juza.update(buf1, 0, buf1.length) juza.getValue } val actual = getValue(List(buf1)); actual should equal (expected) } it can "copy itself." in { val buf1 = randombuf(1024) val buf2 = randombuf(1024) val adler1 = new Adler32 adler1.update(buf1, 0, buf1.length); val adler2 = adler1.copy adler1.update(buf2, 0, buf1.length); adler2.update(buf2, 0, buf1.length); val expected = adler1.getValue val actual = adler2.getValue actual should equal (expected) } it can "combine adler values." in { val buf1 = randombuf(1024) val buf2 = randombuf(1024) val adler1 = getValue(List(buf1)); val adler2 = getValue(List(buf2)); val expected = getValue(List(buf1, buf2)); val actual = Adler32.combine(adler1, adler2, buf2.length) actual should equal (expected) } private def getValue(buf:Seq[Array[Byte]]) = synchronized { adler.reset buf.foreach { b => adler.update(b, 0, b.length) } adler.getValue } } jzlib-1.1.3/src/test/scala/DeflateInflateTest.scala000066400000000000000000000200161222267011700221720ustar00rootroot00000000000000/* -*-mode:scala; c-basic-offset:2; indent-tabs-mode:nil -*- */ package com.jcraft.jzlib import org.scalatest._ import org.scalatest.matchers.ShouldMatchers import JZlib._ class DeflateInflateTest extends FlatSpec with BeforeAndAfter with ShouldMatchers { val comprLen = 40000 val uncomprLen = comprLen var compr:Array[Byte] = _ var uncompr:Array[Byte] = _ var deflater: Deflater = _ var inflater: Inflater = _ var err: Int = _ before { compr = new Array[Byte](comprLen) uncompr = new Array[Byte](uncomprLen) deflater = new Deflater inflater = new Inflater err = Z_OK } after { } behavior of "Deflter and Inflater" it can "deflate and infate data in the large buffer." in { val data = "hello, hello!".getBytes err = deflater.init(Z_BEST_SPEED) err should equal (Z_OK) deflater.setInput(uncompr) deflater.setOutput(compr) err = deflater.deflate(Z_NO_FLUSH) err should equal (Z_OK) deflater.avail_in should equal (0) deflater.params(Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY) deflater.setInput(compr) deflater.avail_in = comprLen/2 err = deflater.deflate(Z_NO_FLUSH) err should equal (Z_OK) deflater.params(Z_BEST_COMPRESSION, Z_FILTERED) deflater.setInput(uncompr) deflater.avail_in = uncomprLen err = deflater.deflate(Z_NO_FLUSH) err should equal (Z_OK) err = deflater.deflate(JZlib.Z_FINISH); err should equal (Z_STREAM_END) err = deflater.end err should equal (Z_OK) inflater.setInput(compr) err = inflater.init err should equal (Z_OK) var loop = true while(loop) { inflater.setOutput(uncompr) err = inflater.inflate(Z_NO_FLUSH) if(err == Z_STREAM_END) loop = false else err should equal (Z_OK) } err = inflater.end err should equal (Z_OK) val total_out = inflater.total_out.asInstanceOf[Int] total_out should equal (2*uncomprLen + comprLen/2) } it can "deflate and infate data in the small buffer." in { val data = "hello, hello!".getBytes err = deflater.init(Z_DEFAULT_COMPRESSION) err should equal (Z_OK) deflater.setInput(data) deflater.setOutput(compr) while(deflater.total_in < data.length && deflater.total_out < comprLen){ deflater.avail_in = 1 deflater.avail_out = 1 err = deflater.deflate(Z_NO_FLUSH) err should equal (Z_OK) } do { deflater.avail_out = 1 err = deflater.deflate(Z_FINISH) } while(err != Z_STREAM_END); err = deflater.end err should equal (Z_OK) inflater.setInput(compr) inflater.setOutput(uncompr) err = inflater.init err should equal (Z_OK) var loop = true while(inflater.total_out loop = false case Z_NEED_DICT => dictID should equal (inflater.getAdler) err = inflater.setDictionary(dictionary, dictionary.length); err should equal (Z_OK) case _ => err should equal (Z_OK) } } while(loop) err = inflater.end err should equal (Z_OK) val total_out = inflater.total_out.asInstanceOf[Int] val actual = new Array[Byte](total_out) System.arraycopy(uncompr, 0, actual, 0, total_out) actual should equal (hello) } it should "support the sync." in { val hello = "hello".getBytes err = deflater.init(Z_DEFAULT_COMPRESSION) err should equal (Z_OK) deflater.setInput(hello) deflater.avail_in = 3; deflater.setOutput(compr) err = deflater.deflate(Z_FULL_FLUSH) err should equal (Z_OK) compr(3) = (compr(3) + 1).asInstanceOf[Byte] deflater.avail_in = hello.length - 3; err = deflater.deflate(Z_FINISH) err should equal (Z_STREAM_END) val comprLen= deflater.total_out.asInstanceOf[Int] err = deflater.end err should equal (Z_OK) err = inflater.init err should equal (Z_OK) inflater.setInput(compr) inflater.avail_in = 2 inflater.setOutput(uncompr) err = inflater.inflate(JZlib.Z_NO_FLUSH) err should equal (Z_OK) inflater.avail_in = comprLen-2 err = inflater.sync err = inflater.inflate(Z_FINISH) err should equal (Z_DATA_ERROR) err = inflater.end err should equal (Z_OK) val total_out = inflater.total_out.asInstanceOf[Int] val actual = new Array[Byte](total_out) System.arraycopy(uncompr, 0, actual, 0, total_out) "hel"+new String(actual) should equal (new String(hello)) } behavior of "Inflater" it can "inflate gzip data." in { val hello = "foo".getBytes val data = List(0x1f, 0x8b, 0x08, 0x18, 0x08, 0xeb, 0x7a, 0x0b, 0x00, 0x0b, 0x58, 0x00, 0x59, 0x00, 0x4b, 0xcb, 0xcf, 0x07, 0x00, 0x21, 0x65, 0x73, 0x8c, 0x03, 0x00, 0x00, 0x00). map(_.asInstanceOf[Byte]). toArray err = inflater.init(15 + 32) err should equal (Z_OK) inflater.setInput(data) inflater.setOutput(uncompr) val comprLen = data.length var loop = true while(inflater.total_out BAOS, ByteArrayInputStream => BAIS} import JZlib._ class DeflaterInflaterStreamTest extends FlatSpec with BeforeAndAfter with ShouldMatchers { before { } after { } behavior of "Deflter and Inflater" it can "deflate and infate data one by one." in { val data1 = randombuf(1024) implicit val buf = new Array[Byte](1) val baos = new BAOS val gos = new DeflaterOutputStream(baos) data1 -> gos gos.close val baos2 = new BAOS new InflaterInputStream(new BAIS(baos.toByteArray)) -> baos2 val data2 = baos2.toByteArray data2.length should equal (data1.length) data2 should equal (data1) } behavior of "DeflterOutputStream and InflaterInputStream" it can "deflate and infate." in { (1 to 100 by 3).foreach { i => implicit val buf = new Array[Byte](i) val data1 = randombuf(10240) val baos = new BAOS val gos = new DeflaterOutputStream(baos) data1 -> gos gos.close val baos2 = new BAOS new InflaterInputStream(new BAIS(baos.toByteArray)) -> baos2 val data2 = baos2.toByteArray data2.length should equal (data1.length) data2 should equal (data1) } } behavior of "Deflter and Inflater" it can "deflate and infate nowrap data." in { (1 to 100 by 3).foreach { i => implicit val buf = new Array[Byte](i) val data1 = randombuf(10240) val baos = new BAOS val deflater = new Deflater(JZlib.Z_DEFAULT_COMPRESSION, JZlib.DEF_WBITS, true) val gos = new DeflaterOutputStream(baos, deflater) data1 -> gos gos.close val baos2 = new BAOS val inflater = new Inflater(JZlib.DEF_WBITS, true) new InflaterInputStream(new BAIS(baos.toByteArray), inflater) -> baos2 val data2 = baos2.toByteArray data2.length should equal (data1.length) data2 should equal (data1) } } it can "deflate and infate nowrap data with MAX_WBITS." in { implicit val buf = new Array[Byte](100) List(randombuf(10240), """{"color":2,"id":"EvLd4UG.CXjnk35o1e8LrYYQfHu0h.d*SqVJPoqmzXM::Ly::Snaps::Store::Commit"}""".getBytes) foreach { data1 => val deflater = new Deflater(JZlib.Z_DEFAULT_COMPRESSION, JZlib.MAX_WBITS, true) val inflater = new Inflater(JZlib.MAX_WBITS, true) val baos = new BAOS val gos = new DeflaterOutputStream(baos, deflater) data1 -> gos gos.close val baos2 = new BAOS new InflaterInputStream(new BAIS(baos.toByteArray), inflater) -> baos2 val data2 = baos2.toByteArray data2.length should equal (data1.length) data2 should equal (data1) } } } jzlib-1.1.3/src/test/scala/GZIPIOStreamTest.scala000066400000000000000000000042271222267011700215060ustar00rootroot00000000000000/* -*-mode:scala; c-basic-offset:2; indent-tabs-mode:nil -*- */ package com.jcraft.jzlib import org.scalatest._ import org.scalatest.matchers.ShouldMatchers import java.io._ import java.util.zip.CheckedOutputStream import java.util.zip.CheckedInputStream import java.util.zip.{GZIPInputStream => juzGZIPInputStream} import java.util.zip.{CRC32 => juzCRC32} import JZlib._ class GZIPIOStreamTest extends FlatSpec with BeforeAndAfter with ShouldMatchers { before { } after { } behavior of "GZIPOutputStream and GZIPInputStream" it can "deflate and infate data." in { val comment = "hi" val name = "/tmp/foo" val content = "hello".getBytes val baos = new ByteArrayOutputStream val gos = new GZIPOutputStream(baos) gos.setComment(comment) gos.setName(name) gos.write(content) gos.close val bais = new ByteArrayInputStream(baos.toByteArray) val gis = new GZIPInputStream(bais) val buf = new Array[Byte](1024) val i = gis.read(buf) content.length should equal(i) (0 until i) foreach { i => content(i).asInstanceOf[Byte] should equal(buf(i).asInstanceOf[Byte]) } comment should equal(gis.getComment) name should equal(gis.getName) val crc32 = new CRC32 crc32.update(content, 0, content.length) crc32.getValue should equal(gis.getCRC.asInstanceOf[Long]) } behavior of "GZIPOutputStream" // https://github.com/ymnk/jzlib/issues/9 // https://github.com/jglick/jzlib-9-demo it can "deflate some file without AIOOBE." in { val pos = new PipedOutputStream() val pis = new PipedInputStream(pos) val csOut = new juzCRC32() val gos = new GZIPOutputStream(pos) val cos = new CheckedOutputStream(gos, csOut) val t = new Thread() { override def run = { val fail = "/jzlib.fail.gz".fromResource val fis = new juzGZIPInputStream(new ByteArrayInputStream(fail)) fis -> cos cos.close() } } t.start(); val gis = new GZIPInputStream(pis) val csIn = new juzCRC32(); new CheckedInputStream(gis, csIn) -> new ByteArrayOutputStream() t.join() csIn.getValue() should equal(csOut.getValue) } } jzlib-1.1.3/src/test/scala/WrapperTypeTest.scala000066400000000000000000000122461222267011700216130ustar00rootroot00000000000000/* -*-mode:scala; c-basic-offset:2; indent-tabs-mode:nil -*- */ package com.jcraft.jzlib import org.scalatest._ import org.scalatest.matchers.ShouldMatchers import java.io.{ByteArrayOutputStream => BAOS, ByteArrayInputStream => BAIS} import JZlib._ class WrapperTypeTest extends FlatSpec with BeforeAndAfter with ShouldMatchers { val data = "hello, hello!".getBytes val comprLen = 40000 val uncomprLen = comprLen var compr:Array[Byte] = _ var uncompr:Array[Byte] = _ var err: Int = _ val cases = /* success */ /* fail */ List((W_ZLIB, (List(W_ZLIB, W_ANY), List(W_GZIP, W_NONE))), (W_GZIP, (List(W_GZIP, W_ANY), List(W_ZLIB, W_NONE))), (W_NONE, (List(W_NONE, W_ANY), List(W_ZLIB, W_GZIP)))) before { compr = new Array[Byte](comprLen) uncompr = new Array[Byte](uncomprLen) err = Z_OK } after { } behavior of "Deflater" it can "detect data type of input." in { implicit val buf = compr cases foreach { case (iflag, (good, bad)) => val baos = new BAOS val deflater = new Deflater(Z_DEFAULT_COMPRESSION, DEF_WBITS, 9, iflag) val gos = new DeflaterOutputStream(baos, deflater) data -> gos gos.close val deflated = baos.toByteArray good map { w => val baos2 = new BAOS val inflater = new Inflater(w) new InflaterInputStream(new BAIS(deflated), inflater) -> baos2 val data1 = baos2.toByteArray data1.length should equal (data.length) data1 should equal (data) import inflater._ (avail_in, avail_out, total_in, total_out) } reduceLeft { (x, y) => x should equal (y); x } bad foreach { w => val baos2 = new BAOS val inflater = new Inflater(w) try { new InflaterInputStream(new BAIS(deflated), inflater) -> baos2 fail("unreachable") } catch { case e:java.io.IOException => } } } } behavior of "ZStream" it can "detect data type of input." in { cases foreach { case (iflag, (good, bad)) => val deflater = new ZStream err = deflater.deflateInit(Z_BEST_SPEED, DEF_WBITS, 9, iflag) err should equal (Z_OK) deflate(deflater, data, compr) good foreach { w => val inflater = inflate(compr, uncompr, w) val total_out = inflater.total_out.asInstanceOf[Int] new String(uncompr, 0, total_out) should equal (new String(data)) } bad foreach { w => inflate_fail(compr, uncompr, w) } } } behavior of "Deflater" it should "support wbits+32." in { var deflater = new Deflater err = deflater.init(Z_BEST_SPEED, DEF_WBITS, 9) err should equal (Z_OK) deflate(deflater, data, compr) var inflater = new Inflater err = inflater.init(DEF_WBITS + 32) err should equal (Z_OK) inflater.setInput(compr) var loop = true while(loop) { inflater.setOutput(uncompr) err = inflater.inflate(Z_NO_FLUSH) if(err == Z_STREAM_END) loop = false else err should equal (Z_OK) } err = inflater.end err should equal (Z_OK) var total_out = inflater.total_out.asInstanceOf[Int] new String(uncompr, 0, total_out) should equal (new String(data)) deflater = new Deflater err = deflater.init(Z_BEST_SPEED, DEF_WBITS + 16, 9) err should equal (Z_OK) deflate(deflater, data, compr) inflater = new Inflater err = inflater.init(DEF_WBITS + 32) err should equal (Z_OK) inflater.setInput(compr) loop = true while(loop) { inflater.setOutput(uncompr) err = inflater.inflate(Z_NO_FLUSH) if(err == Z_STREAM_END) loop = false else err should equal (Z_OK) } err = inflater.end err should equal (Z_OK) total_out = inflater.total_out.asInstanceOf[Int] new String(uncompr, 0, total_out) should equal (new String(data)) } private def deflate(deflater: ZStream, data: Array[Byte], compr: Array[Byte]) = { deflater.setInput(data) deflater.setOutput(compr) err = deflater.deflate(JZlib.Z_FINISH) err should equal (Z_STREAM_END) err = deflater.end err should equal (Z_OK) } private def inflate(compr: Array[Byte], uncompr: Array[Byte], w: WrapperType) = { val inflater = new ZStream err = inflater.inflateInit(w) err should equal (Z_OK) inflater.setInput(compr) var loop = true while(loop) { inflater.setOutput(uncompr) err = inflater.inflate(Z_NO_FLUSH) if(err == Z_STREAM_END) loop = false else err should equal (Z_OK) } err = inflater.end err should equal (Z_OK) inflater } private def inflate_fail(compr: Array[Byte], uncompr: Array[Byte], w: WrapperType) = { val inflater = new ZStream err = inflater.inflateInit(w) err should equal (Z_OK) inflater.setInput(compr) var loop = true while(loop) { inflater.setOutput(uncompr) err = inflater.inflate(Z_NO_FLUSH) if(err == Z_STREAM_END) loop = false else { err should equal (Z_DATA_ERROR) loop = false } } } } jzlib-1.1.3/src/test/scala/ZIOStreamTest.scala000066400000000000000000000026051222267011700211440ustar00rootroot00000000000000/* -*-mode:scala; c-basic-offset:2; indent-tabs-mode:nil -*- */ package com.jcraft.jzlib import org.scalatest._ import org.scalatest.matchers.ShouldMatchers import java.io.{ByteArrayOutputStream => BAOS, ByteArrayInputStream => BAIS} import java.io.{ObjectOutputStream => OOS, ObjectInputStream => OIS} import java.io._ import JZlib._ class ZIOStreamTest extends FlatSpec with BeforeAndAfter with ShouldMatchers { before { } after { } behavior of "ZOutputStream and ZInputStream" it can "deflate and inflate data." in { val hello = "Hello World!" val out = new BAOS() val zOut = new ZOutputStream(out, Z_BEST_COMPRESSION) val objOut = new OOS(zOut) objOut.writeObject(hello) zOut.close val in = new BAIS(out.toByteArray()) val zIn = new ZInputStream(in) val objIn = new OIS(zIn) objIn.readObject.toString should equal (hello) } behavior of "ZOutputStream and ZInputStream" it can "support nowrap data." in { implicit val buf = new Array[Byte](100) val hello = "Hello World!".getBytes val baos = new BAOS val zos = new ZOutputStream(baos, Z_DEFAULT_COMPRESSION, true) hello -> zos zos.close val baos2 = new BAOS val zis = new ZInputStream(new BAIS(baos.toByteArray), true) zis -> baos2 val data2 = baos2.toByteArray data2.length should equal (hello.length) data2 should equal (hello) } } jzlib-1.1.3/src/test/scala/package.scala000066400000000000000000000016441222267011700200640ustar00rootroot00000000000000/* -*-mode:scala; c-basic-offset:2; indent-tabs-mode:nil -*- */ package com.jcraft import java.io._ package object jzlib { implicit def readIS(is: InputStream) = new { def ->(out: OutputStream) (implicit buf: Array[Byte] = new Array[Byte](1024)) = { Stream. continually(is.read(buf)). takeWhile(-1 !=). foreach(i => out.write(buf, 0, i)) is.close } } // reading a resource file implicit def fromResource(str: String ) = new { def fromResource: Array[Byte] = io.Source. fromURL(getClass.getResource(str))(io.Codec.ISO8859). map(_.toByte). toArray } implicit def readArray(is: Array[Byte]) = new { def ->(out: OutputStream)(implicit buf: Array[Byte]) = { new ByteArrayInputStream(is) -> (out) } } def randombuf(n: Int) = (0 to n).map{ _ => util.Random.nextLong.asInstanceOf[Byte] }.toArray }