You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by do...@apache.org on 2002/03/24 08:02:32 UTC

cvs commit: jakarta-avalon-excalibur/bzip2/src/test/org/apache/avalon/excalibur/bzip2/test BzipTestCase.java asf-logo-huge.tar asf-logo-huge.tar.bz2

donaldp     02/03/23 23:02:32

  Added:       bzip2    .cvsignore BUILDING.txt README.txt
                        ant.properties.sample build.bat build.sh build.xml
                        project.properties
               bzip2/examples README.txt
               bzip2/src/java/org/apache/avalon/excalibur/bzip2
                        BZip2Constants.java CBZip2InputStream.java
                        CBZip2OutputStream.java CRC.java
               bzip2/src/test/org/apache/avalon/excalibur/bzip2/test
                        BzipTestCase.java asf-logo-huge.tar
                        asf-logo-huge.tar.bz2
  Log:
  Add bzip component from Ant
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/bzip2/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  ant.properties
  build
  checkstyle.cache
  distributions
  dist
  excalibur-*
  *.el
  *.ipr
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/BUILDING.txt
  
  Index: BUILDING.txt
  ===================================================================
  
                 Building The Component
                 ======================
  
  Building from CVS
  -----------------
  
  Assuming:
   - You have a JDK installed, $JAVA_HOME set and 'java -version' works
   - Your directory structure follows standard CVS layout:
  
  jakarta-avalon/                   # jakarta-avalon CVS module, containing Ant
  jakarta-avalon-excalibur/              # contains build.sh, build.bat
  jakarta-avalon-excalibur/<component>   # you are here
  
  Then to build, you need only customize ant.properties (see step 6 below) and
  type './build.sh' (Unix) or 'build' (DOS). The '-projecthelp' option will
  list the available targets.
  
  
  Building from source distribution
  ---------------------------------
  
  In order to build a binary distribution version of the component from a 
  source  distribution,  you must have  a Java Development Kit (JDK)  for 
  version  1.1 (or  later)  downloaded  and  installed  (version  1.3.1 
  recommended), and do the following:
  
  (0) Download and Install a Java Development Kit
  
  * Download a Java Development Kit (JDK) release (version 1.1 or later) 
    from:
  
      http://java.sun.com/j2se/
  
  * Install the JDK according to the instructions included with the release.
  
  * Set an environment variable JAVA_HOME to the pathname of the directory
    into which you installed the JDK release.
  
  
  (1) Download and Install the Ant Binary Distribution
  
  * Download a binary distribution of Ant 1.4.1 from:
  
      http://jakarta.apache.org/builds/jakarta-ant/release/v1.4.1/bin/
  
    On a Windows platform, you will need:
      jakarta-ant-1.4.1-bin.zip
      jakarta-ant-1.4.1-optional.jar
  
    On a Unix platform, you will need:
      jakarta-ant-1.4.1-bin.tar.gz
      jakarta-ant-1.4.1-optional.jar
  
  * Unpack the binary distribution into a convenient location so that the
    Ant release resides in its own directory (conventionally named
    "jakarta-ant-1.4.1").  For the purposes of the remainder of this document,
    the symbolic name "${ant.home}" is used to refer to the full pathname of
    the release directory.
  
  * Copy the file "jakarta-ant-1.4.1-optional.jar", downloaded above, into
    the directory "${ant.home}/lib".  This makes available several Ant
    extension commands that are commonly required when building Jakarta
    based projects.
  
  * Modify the PATH environment variable to include directory
    "${ant.home}/bin" in its list.  This makes the "ant" command line script
    available, which will be used to actually perform the build.
  
  (2) Download and Install the JUnit Testing Package (OPTIONAL)
  
  NOTE: This is only required if you wish to run the unit tests for 
  this component
  
  * Download the JUnit unit test package (version 3.7 or later) from:
  
      http://www.junit.org/
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  * Copy the file "junit.jar", downloaded above, into the directory 
    "${ant.home}/lib".  This makes available the unit testing tasks that are 
    commonly required when building Jakarta based projects.
  
  (3) Download and Install the JDepend 2.2, Dependency Analysis Package (OPTIONAL)
  
  NOTE: This is only required if you wish to run dependency analysis for 
  this component. 
  
  * Download the JDepend package (version 2.2 or later) from:
  
      http://www.clarkware.com/software/JDepend.html
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  * Copy the file "jdepend.jar", downloaded above, into the directory 
    "${ant.home}/lib".  This makes available the dependency analysis tasks.
  
  
  (4) Download and Install Checkstyle, 2.1 or later (OPTIONAL)
  
  NOTE: This is only required if you wish to generate reports regarding code style.
  
  * Download the Checkstyle package (version 2.1 or later) from:
  
      http://checkstyle.sourceforge.net/
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  (5) Download and Install the Xalan, XSLT engine (OPTIONAL)
  
  NOTE: This is only required if you wish to generate reports for the dependency 
  analysis, checkstyle and unit testing results.
  
  * Download the Xalan package (version 2.3.1 or later) from:
  
      http://xml.apache.org/xalan-j/
  
  * Unpack the package into a convenient location so that it resides in its
    own subdirectory.
  
  * Copy the files "xalan.jar", and "xml-apis.jar", downloaded above, into 
    the directory "${ant.home}/lib".  This makes available the XSLT reporting
    capabilities.
  
  (6) Customize Build Properties For This Subproject
  
  Most Jakarta subprojects allow you to customize Ant properties (with default
  values defined in the "build.xml" file.  This is done by creating a text file
  named "ant.properties" in the source distribution directory (for property
  definitions local to this subproject) and/or your user home directory (for
  property definitions shared across subprojects).  You can use the included
  "ant.properties.sample" file as a starting point for this.
  
  External dependencies are satisfied by configuring appropriate values in your 
  ant.properties file.  The easiest way to satisfy these dependencies is to copy 
  the "ant.properties.sample" file (in the top-level directory) to "ant.properties", 
  and then edit it to suit your environment.  On Unix, this would be done as:
  
    cd @dist.name@
    cp ant.properties.sample ant.properties
    emacs ant.properties
  
  NOTE:  Be *sure* that you do not check "ant.properties" in to the CVS
  repository.  This file is local to your own development environment, and
  each developer will have their own version.
  
  (7) Build A Binary Distribution
  
  Open a command line shell, and issue the following commands:
  
    cd @dist.name@
    ant -projecthelp
  
  If everything is installed correctly, you should see a list of the Ant
  "targets" that represent different commands you might wish to build.  By
  convention, the "jar" target creates the jar of the component. To execute 
  it, type the following commands:
  
    cd @dist.name@
    ant jar
  
  This will create a jar in the @dist.name@/build/lib directory that contains 
  the component.
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/README.txt
  
  Index: README.txt
  ===================================================================
                    Avalons Excalibur Bzip2
                    -----------------------
  
  Add description here...
  
  Getting Started:
  ----------------
  
  If you downloaded a source release of the component then you
  will need to build the component. Directions for building the
  component are located in BUILDING.txt
  
  If you downloaded a binary release, or a release with both binary
  and source then it is recomended you look over the documentation
  in docs/index.html - and then look into the examples/ directory
  for examples of the component in action.
  
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/ant.properties.sample
  
  Index: ant.properties.sample
  ===================================================================
  # -----------------------------------------------------------------------------
  # Component ant.properties.sample
  #
  # This is an example "ant.properties" file, used to customize the building of
  # the component for your local environment.  It defines the location of all
  # external modules that this component depend on.  Copy this file to
  # "ant.properties" in the source directory, and customize it as needed.
  #
  # The ant.properties values in this directory apply only to this component, and
  # override the defaults in ../ant.properties.
  #
  # $Id: ant.properties.sample,v 1.1 2002/03/24 07:02:31 donaldp Exp $
  # -----------------------------------------------------------------------------
  
  # --------------------------------------------------
  #      COMPONENT-SPECIFIC REQUIRED LIBRARIES
  # --------------------------------------------------
  
  
  # ----- Compile Control Flags -----
  build.debug=on
  build.optimize=off
  build.deprecation=off
  
  # ----- Base Directory in which all the packages are stored -----
  base.path=/opt
  
  # --------------------------------------------------
  #                REQUIRED LIBRARIES
  # --------------------------------------------------
  
  
  # ----- JUnit Unit Test Suite, version 3.7 or later -----
  junit.home=${base.path}/junit3.7
  junit.lib=${junit.home}
  junit.jar=${junit.lib}/junit.jar
  
  
  
  # --------------------------------------------------
  #                OPTIONAL LIBRARIES
  # --------------------------------------------------
  
  # ----- Checkstyle, version 2.1 or later -----
  
  # Uncomment the 'do.checkstyle' flag property to enable checkstyle
  # do.checkstyle=
  checkstyle.home=${base.path}/checkstyle-2.1
  checkstyle.lib=${checkstyle.home}
  checkstyle.jar=${checkstyle.lib}/checkstyle-all-2.1.jar
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/build.bat
  
  Index: build.bat
  ===================================================================
  @echo off
  
  set BASE=..
  call %BASE%\build.bat %1 %2 %3 %4 %5 %6 %7 %8
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/build.sh
  
  Index: build.sh
  ===================================================================
  #!/bin/sh
  
  BASE=`dirname $0`  # Directory containing this script. Not the same as $PWD.
  
  $BASE/../build.sh -f $BASE/build.xml $@
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <project name="Excalibur Bzip2" default="main" basedir=".">
  
      <!-- load per-project properties -->
      <property file="project.properties"/>
  
      <!--
        Give user a chance to override without editing this file
        (and without typing -D each time he compiles it)
      -->
      <property file="ant.properties"/>
      <property file="../ant.properties"/>
      <property file="${user.home}/.ant.properties"/>
  
      <!-- Settings used to configure compile environment -->
      <property name="build.debug" value="on"/>
      <property name="build.optimize" value="off"/>
      <property name="build.deprecation" value="off"/>
      <property name="build.compress" value="false"/>
      <property name="junit.failonerror" value="false"/>
  
      <!-- location of intermediate products -->
      <property name="build.dir" value="build"/>
      <property name="build.lib" value="${build.dir}/lib"/>
      <property name="build.classes" value="${build.dir}/classes"/>
      <property name="build.tests" value="${build.dir}/tests"/>
      <property name="build.reports" value="${build.dir}/reports"/>
  
      <!-- Set the properties for source directories -->
      <property name="src.dir" value="src"/>
      <property name="java.dir" value="${src.dir}/java"/>
      <property name="test.dir" value="${src.dir}/test"/>
  
      <!-- Set the properties for distribution directories -->
      <property name="dist.dir" value="dist"/>
      <property name="dist.javadocs" value="${dist.dir}/docs/api"/>
  
      <!-- property to specify name of zip/jar files -->
      <property name="dist.name" value="excalibur-${name}-${version}"/>
  
      <!-- property indicating directory where all distribution archives are placed -->
      <property name="dist.base" value="distributions"/>
  
      <!-- Classpath for product -->
      <path id="project.class.path">
          <pathelement path="${java.class.path}"/>
          <pathelement location="${build.classes}"/>
          <pathelement location="${junit.jar}"/>
          <pathelement location="${checkstyle.jar}"/>
      </path>
  
      <target name="main" depends="dist" description="Build the project"/>
      <target name="rebuild" depends="clean,main" description="Rebuild the project"/>
  
      <!-- Compiles the source code -->
      <target name="compile" description="Compiles the source code">
  
          <mkdir dir="${build.classes}"/>
  
          <!-- Compile all classes including the tests. -->
          <javac srcdir="${java.dir}"
              destdir="${build.classes}"
              debug="${build.debug}"
              optimize="${build.optimize}"
              deprecation="${build.deprecation}"
              target="1.2">
              <classpath refid="project.class.path" />
              <src path="${test.dir}"/>
              <include name="**/*.java"/>
          </javac>
  
          <!-- copy resources to same location as .class files -->
          <copy todir="${build.classes}">
              <fileset dir="${java.dir}">
                  <exclude name="**/*.java"/>
              </fileset>
          </copy>
  
          <copy todir="${build.classes}">
              <fileset dir="${test.dir}">
                  <exclude name="**/*.java"/>
              </fileset>
          </copy>
  
      </target>
  
      <!-- Creates all the .jar file -->
      <target name="jar" depends="compile" description="Generates the jar files">
  
          <mkdir dir="${build.lib}"/>
  
          <jar jarfile="${build.lib}/${dist.name}.jar"
              basedir="${build.classes}"
              compress="${build.compress}">
              <exclude name="**/test/**"/>
              <zipfileset dir=".." prefix="META-INF/">
                  <include name="LICENSE.txt"/>
              </zipfileset>
          </jar>
      </target>
  
      <!-- Creates all the Javadocs -->
      <target name="javadocs" depends="compile" description="Generates the javadocs">
  
          <mkdir dir="${dist.javadocs}"/>
          <javadoc packagenames="org.apache.*"
              sourcepath="${java.dir}"
              destdir="${dist.javadocs}">
              <classpath refid="project.class.path" />
              <doclet name="com.sun.tools.doclets.standard.Standard">
                  <param name="-author"/>
                  <param name="-version"/>
                  <param name="-doctitle" value="${Name}"/>
                  <param name="-windowtitle" value="${Name} API"/>
                  <param name="-link" value="http://java.sun.com/j2se/1.4/docs/api/"/>
                  <param name="-link" value="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/"/>
                  <param name="-link" value="http://jakarta.apache.org/avalon/api/"/>
                  <param name="-bottom"
                      value="&quot;Copyright &#169; ${year} Apache Jakarta Project. All Rights Reserved.&quot;"/>
              </doclet>
          </javadoc>
      </target>
  
      <target name="test" depends="compile" description="Perform the unit tests">
  
          <echo message="Performing Unit Tests" />
  
          <mkdir dir="${build.tests}"/>
  
          <junit fork="true"
              haltonfailure="${junit.failonerror}"
              printsummary="yes"
              dir="${build.tests}">
              <classpath refid="project.class.path"/>
  
              <formatter type="xml"/>    <!-- xml reports for junitreport -->
              <formatter type="plain"/>  <!-- text reports for humans     -->
  
              <batchtest todir="${build.tests}">
                  <fileset dir="${build.classes}">
                      <include name="**/test/*TestCase.class"/>
                      <exclude name="**/Abstract*"/>
                  </fileset>
              </batchtest>
          </junit>
  
      </target>
  
      <target name="test-reports" depends="test" description="Generate Reports for the unit tests">
  
          <mkdir dir="${build.reports}/junit"/>
  
          <junitreport todir="${build.reports}/junit">
              <fileset dir="${build.tests}">
                  <include name="TEST-*.xml"/>
              </fileset>
              <report format="frames" todir="${build.reports}/junit"/>
          </junitreport>
  
          <!-- Clean up the xml reports used by the junitreport task -->
          <!--
          <delete>
              <fileset dir="${build.tests}" includes="TEST-*.xml"/>
              <fileset dir="${build.tests}" includes="TESTS-*.xml"/>
          </delete>
          -->
  
      </target>
  
      <target name="jdepend" if="do.jdepend" description="Generate Dependency Analysis Report">
  
          <!-- this invocation of jdepend requires the CVS version of ant for the xml format -->
          <!-- thats why you are required to define do.jdepend property to generate the report -->
          <jdepend outputfile="${build.dir}/jdepend-results.xml" format="xml" fork="yes">
              <classpath refid="project.class.path"/>
              <sourcespath>
                  <pathelement location="src/java" />
              </sourcespath>
          </jdepend>
  
          <mkdir dir="${build.reports}/jdepend"/>
          <style in="${build.dir}/jdepend-results.xml"
              processor="trax"
              out="${build.reports}/jdepend/delete-me.txt"
              style="${ant.home}/etc/jdepend-frames.xsl"/>
      </target>
  
      <target name="checkstyle" if="do.checkstyle" description="Checkstyle">
  
          <!-- this invocation of checkstyle requires that checkstyle be downloaded and setup -->
          <!-- thats why you are required to define do.checkstyle property to generate the report -->
          <taskdef name="checkstyle"
              classname="com.puppycrawl.tools.checkstyle.CheckStyleTask">
              <classpath refid="project.class.path"/>
          </taskdef>
          <checkstyle
              lcurlyType="nl"
              lcurlyMethod="nl"
              lcurlyOther="nl"
              rcurly="ignore"
              allowProtected="false"
              allowPackage="false"
              allowNoAuthor="false"
              maxLineLen="100"
              maxMethodLen="100"
              maxConstructorLen="100"
              memberPattern="^m_[a-z][a-zA-Z0-9]*$"
              staticPattern="^c_[a-z][a-zA-Z0-9]*$"
              constPattern="(^c_[a-z][a-zA-Z0-9]*$)|([A-Z_]*$)"
              ignoreImportLen="true"
              allowTabs="false"
              javadocScope="protected"
              ignoreWhitespace="true"
              cacheFile="checkstyle.cache"
              failOnViolation="false"
              ignoreCastWhitespace="true">
              <fileset dir="${java.dir}">
                  <include name="**/*.java"/>
              </fileset>
              <formatter type="plain"/>
              <formatter type="xml" toFile="build/checkstyle-results.xml"/>
          </checkstyle>
      </target>
  
      <target name="checkstyle-report"
          depends="checkstyle"
          if="do.checkstyle"
          description="Generate Checkstyle Report">
  
          <mkdir dir="${build.reports}/checkstyle"/>
          <style style="../tools/etc/checkstyle-frames.xsl" in="build/checkstyle-results.xml"
              out="${build.reports}/checkstyle/delete-me.html"/>
  
      </target>
  
      <!-- Creates the distribution -->
      <target name="dist"
          depends="jar, test-reports, jdepend, checkstyle-report, javadocs"
          description="Generates the jar files">
  
          <mkdir dir="${dist.dir}"/>
          <copy file="${build.lib}/${dist.name}.jar" todir="${dist.dir}"/>
          <copy file="../LICENSE.txt" todir="${dist.dir}"/>
          <copy file="../KEYS" todir="${dist.dir}"/>
          <copy file="README.txt" todir="${dist.dir}"/>
  
          <mkdir dir="${dist.base}"/>
  
          <zip zipfile="${dist.base}/${dist.name}-bin.zip" compress="true">
              <zipfileset dir="${dist.dir}" prefix="${dist.name}"/>
          </zip>
  
          <!--
            Not supported by released ant but when it is we should enable this across
            all of the products
          <tar longfile="gnu" tarfile="${dist.base}/${dist.name}-bin.tar">
            <tarfileset dir="${dist.dir}"
                        prefix="${dist.name}"
                        username="avalon"
                        group="avalon"/>
          </tar>
  
          <gzip zipfile="${dist.base}/${dist.name}-bin.tar.gz"
                src="${dist.name}-bin.tar"/>
          <bzip2 zipfile="${dist.base}/${dist.name}-bin.tar.gz"
                 src="${dist.name}-bin.tar"/>
  
          <delete file="${dist.base}/${dist.name}-bin.tar"/>
  
          <checksum fileext=".md5">
            <fileset dir="${dist.base}" />
          </checksum>
          -->
          <delete dir="${dist.dir}" />
  
      </target>
  
      <!-- Cleans up build and distribution directories -->
      <target name="clean" description="Cleans up the project">
          <delete file="checkstyle.cache"/>
          <delete dir="${build.dir}" />
          <delete dir="${dist.dir}" />
          <delete dir="test" /> <!-- unit testing output directory -->
          <delete>
              <fileset dir="." includes="**/*~" defaultexcludes="no"/>
          </delete>
      </target>
  
      <target name="real-clean" depends="clean" description="Cleans up the project, including distributions">
          <delete dir="${dist.base}" />
      </target>
  
  </project>
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/project.properties
  
  Index: project.properties
  ===================================================================
  name=bzip2
  Name=BZip2
  version=1.0a
  year=2000-2002
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/examples/README.txt
  
  Index: README.txt
  ===================================================================
  This directory contains a number of examples for the component.
  They are;
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/java/org/apache/avalon/excalibur/bzip2/BZip2Constants.java
  
  Index: BZip2Constants.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.bzip2;
  
  /**
   * Base class for both the compress and decompress classes. Holds common arrays,
   * and static data.
   *
   * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
   */
  interface BZip2Constants
  {
      int BASE_BLOCK_SIZE = 100000;
      int MAX_ALPHA_SIZE = 258;
      int MAX_CODE_LEN = 23;
      int RUNA = 0;
      int RUNB = 1;
      int N_GROUPS = 6;
      int G_SIZE = 50;
      int N_ITERS = 4;
      int MAX_SELECTORS = ( 2 + ( 900000 / G_SIZE ) );
      int NUM_OVERSHOOT_BYTES = 20;
  
      int[] RAND_NUMS = new int[]
      {
          619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
          985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
          733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
          419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
          878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
          862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
          150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
          170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
          73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
          909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
          641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
          161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
          382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
          98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
          227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
          469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
          184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
          715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
          951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
          652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
          645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
          609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
          653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
          411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
          170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
          857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
          669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
          944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
          344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
          897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
          433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
          686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
          946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
          978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
          680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
          707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
          297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
          134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
          343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
          140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
          170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
          369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
          804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
          896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
          661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
          768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
          61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
          372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
          780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
          920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
          645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
          936, 638
      };
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/java/org/apache/avalon/excalibur/bzip2/CBZip2InputStream.java
  
  Index: CBZip2InputStream.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.bzip2;
  
  import java.io.IOException;
  import java.io.InputStream;
  import org.apache.avalon.excalibur.bzip2.BZip2Constants;
  
  /**
   * An input stream that decompresses from the BZip2 format (without the file
   * header chars) to be read as any other stream.
   *
   * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
   */
  public class CBZip2InputStream
      extends InputStream
      implements BZip2Constants
  {
      private final static int START_BLOCK_STATE = 1;
      private final static int RAND_PART_A_STATE = 2;
      private final static int RAND_PART_B_STATE = 3;
      private final static int RAND_PART_C_STATE = 4;
      private final static int NO_RAND_PART_A_STATE = 5;
      private final static int NO_RAND_PART_B_STATE = 6;
      private final static int NO_RAND_PART_C_STATE = 7;
  
      private CRC m_crc = new CRC();
      private boolean[] m_inUse = new boolean[ 256 ];
      private char[] m_seqToUnseq = new char[ 256 ];
      private char[] m_unseqToSeq = new char[ 256 ];
      private char[] m_selector = new char[ MAX_SELECTORS ];
      private char[] m_selectorMtf = new char[ MAX_SELECTORS ];
  
      /*
       * freq table collected to save a pass over the data
       * during decompression.
       */
      private int[] m_unzftab = new int[ 256 ];
  
      private int[][] m_limit = new int[ N_GROUPS ][ MAX_ALPHA_SIZE ];
      private int[][] m_base = new int[ N_GROUPS ][ MAX_ALPHA_SIZE ];
      private int[][] m_perm = new int[ N_GROUPS ][ MAX_ALPHA_SIZE ];
      private int[] m_minLens = new int[ N_GROUPS ];
  
      private boolean m_streamEnd;
      private int m_currentChar = -1;
  
      private int m_currentState = START_BLOCK_STATE;
      private int m_rNToGo;
      private int m_rTPos;
      private int m_tPos;
  
      private int i2;
      private int count;
      private int chPrev;
      private int ch2;
      private int j2;
      private char z;
  
      private boolean m_blockRandomised;
  
      /*
       * always: in the range 0 .. 9.
       * The current block size is 100000 * this number.
       */
      private int m_blockSize100k;
      private int m_bsBuff;
      private int m_bsLive;
  
      private InputStream m_input;
  
      private int m_computedBlockCRC;
      private int m_computedCombinedCRC;
  
      /*
       * index of the last char in the block, so
       * the block size == last + 1.
       */
      private int m_last;
      private char[] m_ll8;
      private int m_nInUse;
  
      /*
       * index in zptr[] of original string after sorting.
       */
      private int m_origPtr;
  
      private int m_storedBlockCRC;
      private int m_storedCombinedCRC;
      private int[] m_tt;
  
      public CBZip2InputStream( final InputStream input )
      {
          bsSetStream( input );
          initialize();
          initBlock();
          setupBlock();
      }
  
      private static void badBlockHeader()
      {
          cadvise();
      }
  
      private static void blockOverrun()
      {
          cadvise();
      }
  
      private static void cadvise()
      {
          System.out.println( "CRC Error" );
          //throw new CCoruptionError();
      }
  
      private static void compressedStreamEOF()
      {
          cadvise();
      }
  
      private static void crcError()
      {
          cadvise();
      }
  
      public int read()
      {
          if( m_streamEnd )
          {
              return -1;
          }
          else
          {
              int retChar = m_currentChar;
              switch( m_currentState )
              {
                  case START_BLOCK_STATE:
                      break;
                  case RAND_PART_A_STATE:
                      break;
                  case RAND_PART_B_STATE:
                      setupRandPartB();
                      break;
                  case RAND_PART_C_STATE:
                      setupRandPartC();
                      break;
                  case NO_RAND_PART_A_STATE:
                      break;
                  case NO_RAND_PART_B_STATE:
                      setupNoRandPartB();
                      break;
                  case NO_RAND_PART_C_STATE:
                      setupNoRandPartC();
                      break;
                  default:
                      break;
              }
              return retChar;
          }
      }
  
      private void setDecompressStructureSizes( int newSize100k )
      {
          if( !( 0 <= newSize100k && newSize100k <= 9 && 0 <= m_blockSize100k
              && m_blockSize100k <= 9 ) )
          {
              // throw new IOException("Invalid block size");
          }
  
          m_blockSize100k = newSize100k;
  
          if( newSize100k == 0 )
          {
              return;
          }
  
          int n = BASE_BLOCK_SIZE * newSize100k;
          m_ll8 = new char[ n ];
          m_tt = new int[ n ];
      }
  
      private void setupBlock()
      {
          int[] cftab = new int[ 257 ];
          char ch;
  
          cftab[ 0 ] = 0;
          for( int i = 1; i <= 256; i++ )
          {
              cftab[ i ] = m_unzftab[ i - 1 ];
          }
          for( int i = 1; i <= 256; i++ )
          {
              cftab[ i ] += cftab[ i - 1 ];
          }
  
          for( int i = 0; i <= m_last; i++ )
          {
              ch = m_ll8[ i ];
              m_tt[ cftab[ ch ] ] = i;
              cftab[ ch ]++;
          }
          cftab = null;
  
          m_tPos = m_tt[ m_origPtr ];
  
          count = 0;
          i2 = 0;
          ch2 = 256;
          /*
           * not a char and not EOF
           */
          if( m_blockRandomised )
          {
              m_rNToGo = 0;
              m_rTPos = 0;
              setupRandPartA();
          }
          else
          {
              setupNoRandPartA();
          }
      }
  
      private void setupNoRandPartA()
      {
          if( i2 <= m_last )
          {
              chPrev = ch2;
              ch2 = m_ll8[ m_tPos ];
              m_tPos = m_tt[ m_tPos ];
              i2++;
  
              m_currentChar = ch2;
              m_currentState = NO_RAND_PART_B_STATE;
              m_crc.updateCRC( ch2 );
          }
          else
          {
              endBlock();
              initBlock();
              setupBlock();
          }
      }
  
      private void setupNoRandPartB()
      {
          if( ch2 != chPrev )
          {
              m_currentState = NO_RAND_PART_A_STATE;
              count = 1;
              setupNoRandPartA();
          }
          else
          {
              count++;
              if( count >= 4 )
              {
                  z = m_ll8[ m_tPos ];
                  m_tPos = m_tt[ m_tPos ];
                  m_currentState = NO_RAND_PART_C_STATE;
                  j2 = 0;
                  setupNoRandPartC();
              }
              else
              {
                  m_currentState = NO_RAND_PART_A_STATE;
                  setupNoRandPartA();
              }
          }
      }
  
      private void setupNoRandPartC()
      {
          if( j2 < z )
          {
              m_currentChar = ch2;
              m_crc.updateCRC( ch2 );
              j2++;
          }
          else
          {
              m_currentState = NO_RAND_PART_A_STATE;
              i2++;
              count = 0;
              setupNoRandPartA();
          }
      }
  
      private void setupRandPartA()
      {
          if( i2 <= m_last )
          {
              chPrev = ch2;
              ch2 = m_ll8[ m_tPos ];
              m_tPos = m_tt[ m_tPos ];
              if( m_rNToGo == 0 )
              {
                  m_rNToGo = RAND_NUMS[ m_rTPos ];
                  m_rTPos++;
                  if( m_rTPos == 512 )
                  {
                      m_rTPos = 0;
                  }
              }
              m_rNToGo--;
              ch2 ^= ( ( m_rNToGo == 1 ) ? 1 : 0 );
              i2++;
  
              m_currentChar = ch2;
              m_currentState = RAND_PART_B_STATE;
              m_crc.updateCRC( ch2 );
          }
          else
          {
              endBlock();
              initBlock();
              setupBlock();
          }
      }
  
      private void setupRandPartB()
      {
          if( ch2 != chPrev )
          {
              m_currentState = RAND_PART_A_STATE;
              count = 1;
              setupRandPartA();
          }
          else
          {
              count++;
              if( count >= 4 )
              {
                  z = m_ll8[ m_tPos ];
                  m_tPos = m_tt[ m_tPos ];
                  if( m_rNToGo == 0 )
                  {
                      m_rNToGo = RAND_NUMS[ m_rTPos ];
                      m_rTPos++;
                      if( m_rTPos == 512 )
                      {
                          m_rTPos = 0;
                      }
                  }
                  m_rNToGo--;
                  z ^= ( ( m_rNToGo == 1 ) ? 1 : 0 );
                  j2 = 0;
                  m_currentState = RAND_PART_C_STATE;
                  setupRandPartC();
              }
              else
              {
                  m_currentState = RAND_PART_A_STATE;
                  setupRandPartA();
              }
          }
      }
  
      private void setupRandPartC()
      {
          if( j2 < z )
          {
              m_currentChar = ch2;
              m_crc.updateCRC( ch2 );
              j2++;
          }
          else
          {
              m_currentState = RAND_PART_A_STATE;
              i2++;
              count = 0;
              setupRandPartA();
          }
      }
  
      private void getAndMoveToFrontDecode()
      {
          int nextSym;
  
          int limitLast = BASE_BLOCK_SIZE * m_blockSize100k;
          m_origPtr = readVariableSizedInt( 24 );
  
          recvDecodingTables();
          int EOB = m_nInUse + 1;
          int groupNo = -1;
          int groupPos = 0;
  
          /*
           * Setting up the unzftab entries here is not strictly
           * necessary, but it does save having to do it later
           * in a separate pass, and so saves a block's worth of
           * cache misses.
           */
          for( int i = 0; i <= 255; i++ )
          {
              m_unzftab[ i ] = 0;
          }
  
          final char[] yy = new char[ 256 ];
          for( int i = 0; i <= 255; i++ )
          {
              yy[ i ] = (char)i;
          }
  
          m_last = -1;
          int zt;
          int zn;
          int zvec;
          int zj;
          if( groupPos == 0 )
          {
              groupNo++;
              groupPos = G_SIZE;
          }
          groupPos--;
  
          zt = m_selector[ groupNo ];
          zn = m_minLens[ zt ];
          zvec = bsR( zn );
          while( zvec > m_limit[ zt ][ zn ] )
          {
              zn++;
  
              while( m_bsLive < 1 )
              {
                  int zzi;
                  char thech = 0;
                  try
                  {
                      thech = (char)m_input.read();
                  }
                  catch( IOException e )
                  {
                      compressedStreamEOF();
                  }
                  if( thech == -1 )
                  {
                      compressedStreamEOF();
                  }
                  zzi = thech;
                  m_bsBuff = ( m_bsBuff << 8 ) | ( zzi & 0xff );
                  m_bsLive += 8;
              }
  
              zj = ( m_bsBuff >> ( m_bsLive - 1 ) ) & 1;
              m_bsLive--;
  
              zvec = ( zvec << 1 ) | zj;
          }
          nextSym = m_perm[ zt ][ zvec - m_base[ zt ][ zn ] ];
  
          while( true )
          {
              if( nextSym == EOB )
              {
                  break;
              }
  
              if( nextSym == RUNA || nextSym == RUNB )
              {
                  char ch;
                  int s = -1;
                  int N = 1;
                  do
                  {
                      if( nextSym == RUNA )
                      {
                          s = s + ( 0 + 1 ) * N;
                      }
                      else if( nextSym == RUNB )
                      {
                          s = s + ( 1 + 1 ) * N;
                      }
                      N = N * 2;
  
                      if( groupPos == 0 )
                      {
                          groupNo++;
                          groupPos = G_SIZE;
                      }
                      groupPos--;
                      zt = m_selector[ groupNo ];
                      zn = m_minLens[ zt ];
                      zvec = bsR( zn );
                      while( zvec > m_limit[ zt ][ zn ] )
                      {
                          zn++;
  
                          while( m_bsLive < 1 )
                          {
                              int zzi;
                              char thech = 0;
                              try
                              {
                                  thech = (char)m_input.read();
                              }
                              catch( IOException e )
                              {
                                  compressedStreamEOF();
                              }
                              if( thech == -1 )
                              {
                                  compressedStreamEOF();
                              }
                              zzi = thech;
                              m_bsBuff = ( m_bsBuff << 8 ) | ( zzi & 0xff );
                              m_bsLive += 8;
                          }
  
                          zj = ( m_bsBuff >> ( m_bsLive - 1 ) ) & 1;
                          m_bsLive--;
                          zvec = ( zvec << 1 ) | zj;
                      }
  
                      nextSym = m_perm[ zt ][ zvec - m_base[ zt ][ zn ] ];
  
                  } while( nextSym == RUNA || nextSym == RUNB );
  
                  s++;
                  ch = m_seqToUnseq[ yy[ 0 ] ];
                  m_unzftab[ ch ] += s;
  
                  while( s > 0 )
                  {
                      m_last++;
                      m_ll8[ m_last ] = ch;
                      s--;
                  }
  
                  if( m_last >= limitLast )
                  {
                      blockOverrun();
                  }
                  continue;
              }
              else
              {
                  char tmp;
                  m_last++;
                  if( m_last >= limitLast )
                  {
                      blockOverrun();
                  }
  
                  tmp = yy[ nextSym - 1 ];
                  m_unzftab[ m_seqToUnseq[ tmp ] ]++;
                  m_ll8[ m_last ] = m_seqToUnseq[ tmp ];
  
                  /*
                   * This loop is hammered during decompression,
                   * hence the unrolling.
                   * for (j = nextSym-1; j > 0; j--) yy[j] = yy[j-1];
                   */
                  int j = nextSym - 1;
                  for( ; j > 3; j -= 4 )
                  {
                      yy[ j ] = yy[ j - 1 ];
                      yy[ j - 1 ] = yy[ j - 2 ];
                      yy[ j - 2 ] = yy[ j - 3 ];
                      yy[ j - 3 ] = yy[ j - 4 ];
                  }
                  for( ; j > 0; j-- )
                  {
                      yy[ j ] = yy[ j - 1 ];
                  }
  
                  yy[ 0 ] = tmp;
  
                  if( groupPos == 0 )
                  {
                      groupNo++;
                      groupPos = G_SIZE;
                  }
                  groupPos--;
                  zt = m_selector[ groupNo ];
                  zn = m_minLens[ zt ];
                  zvec = bsR( zn );
                  while( zvec > m_limit[ zt ][ zn ] )
                  {
                      zn++;
  
                      while( m_bsLive < 1 )
                      {
                          char ch = 0;
                          try
                          {
                              ch = (char)m_input.read();
                          }
                          catch( IOException e )
                          {
                              compressedStreamEOF();
                          }
  
                          m_bsBuff = ( m_bsBuff << 8 ) | ( ch & 0xff );
                          m_bsLive += 8;
                      }
  
                      zj = ( m_bsBuff >> ( m_bsLive - 1 ) ) & 1;
                      m_bsLive--;
  
                      zvec = ( zvec << 1 ) | zj;
                  }
                  nextSym = m_perm[ zt ][ zvec - m_base[ zt ][ zn ] ];
  
                  continue;
              }
          }
      }
  
      private void bsFinishedWithStream()
      {
          m_input = null;
      }
  
      private int readVariableSizedInt( final int numBits )
      {
          return bsR( numBits );
      }
  
      private char readUnsignedChar()
      {
          return (char)bsR( 8 );
      }
  
      private int readInt()
      {
          int u = 0;
          u = ( u << 8 ) | bsR( 8 );
          u = ( u << 8 ) | bsR( 8 );
          u = ( u << 8 ) | bsR( 8 );
          u = ( u << 8 ) | bsR( 8 );
          return u;
      }
  
      private int bsR( final int n )
      {
          while( m_bsLive < n )
          {
              char ch = 0;
              try
              {
                  ch = (char)m_input.read();
              }
              catch( final IOException ioe )
              {
                  compressedStreamEOF();
              }
  
              if( ch == -1 )
              {
                  compressedStreamEOF();
              }
  
              m_bsBuff = ( m_bsBuff << 8 ) | ( ch & 0xff );
              m_bsLive += 8;
          }
  
          final int result = ( m_bsBuff >> ( m_bsLive - n ) ) & ( ( 1 << n ) - 1 );
          m_bsLive -= n;
          return result;
      }
  
      private void bsSetStream( final InputStream input )
      {
          m_input = input;
          m_bsLive = 0;
          m_bsBuff = 0;
      }
  
      private void complete()
      {
          m_storedCombinedCRC = readInt();
          if( m_storedCombinedCRC != m_computedCombinedCRC )
          {
              crcError();
          }
  
          bsFinishedWithStream();
          m_streamEnd = true;
      }
  
      private void endBlock()
      {
          m_computedBlockCRC = m_crc.getFinalCRC();
          /*
           * A bad CRC is considered a fatal error.
           */
          if( m_storedBlockCRC != m_computedBlockCRC )
          {
              crcError();
          }
  
          m_computedCombinedCRC = ( m_computedCombinedCRC << 1 )
              | ( m_computedCombinedCRC >>> 31 );
          m_computedCombinedCRC ^= m_computedBlockCRC;
      }
  
      private void hbCreateDecodeTables( final int[] limit,
                                         final int[] base,
                                         final int[] perm,
                                         final char[] length,
                                         final int minLen,
                                         final int maxLen,
                                         final int alphaSize )
      {
          int pp = 0;
          for( int i = minLen; i <= maxLen; i++ )
          {
              for( int j = 0; j < alphaSize; j++ )
              {
                  if( length[ j ] == i )
                  {
                      perm[ pp ] = j;
                      pp++;
                  }
              }
          }
  
          for( int i = 0; i < MAX_CODE_LEN; i++ )
          {
              base[ i ] = 0;
          }
  
          for( int i = 0; i < alphaSize; i++ )
          {
              base[ length[ i ] + 1 ]++;
          }
  
          for( int i = 1; i < MAX_CODE_LEN; i++ )
          {
              base[ i ] += base[ i - 1 ];
          }
  
          for( int i = 0; i < MAX_CODE_LEN; i++ )
          {
              limit[ i ] = 0;
          }
  
          int vec = 0;
          for( int i = minLen; i <= maxLen; i++ )
          {
              vec += ( base[ i + 1 ] - base[ i ] );
              limit[ i ] = vec - 1;
              vec <<= 1;
          }
  
          for( int i = minLen + 1; i <= maxLen; i++ )
          {
              base[ i ] = ( ( limit[ i - 1 ] + 1 ) << 1 ) - base[ i ];
          }
      }
  
      private void initBlock()
      {
          final char magic1 = readUnsignedChar();
          final char magic2 = readUnsignedChar();
          final char magic3 = readUnsignedChar();
          final char magic4 = readUnsignedChar();
          final char magic5 = readUnsignedChar();
          final char magic6 = readUnsignedChar();
          if( magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 &&
              magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90 )
          {
              complete();
              return;
          }
  
          if( magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 ||
              magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59 )
          {
              badBlockHeader();
              m_streamEnd = true;
              return;
          }
  
          m_storedBlockCRC = readInt();
  
          if( bsR( 1 ) == 1 )
          {
              m_blockRandomised = true;
          }
          else
          {
              m_blockRandomised = false;
          }
  
          //        currBlockNo++;
          getAndMoveToFrontDecode();
  
          m_crc.initialiseCRC();
          m_currentState = START_BLOCK_STATE;
      }
  
      private void initialize()
      {
          final char magic3 = readUnsignedChar();
          final char magic4 = readUnsignedChar();
          if( magic3 != 'h' || magic4 < '1' || magic4 > '9' )
          {
              bsFinishedWithStream();
              m_streamEnd = true;
              return;
          }
  
          setDecompressStructureSizes( magic4 - '0' );
          m_computedCombinedCRC = 0;
      }
  
      private void makeMaps()
      {
          m_nInUse = 0;
          for( int i = 0; i < 256; i++ )
          {
              if( m_inUse[ i ] )
              {
                  m_seqToUnseq[ m_nInUse ] = (char)i;
                  m_unseqToSeq[ i ] = (char)m_nInUse;
                  m_nInUse++;
              }
          }
      }
  
      private void recvDecodingTables()
      {
          buildInUseTable();
          makeMaps();
          final int alphaSize = m_nInUse + 2;
  
          /*
           * Now the selectors
           */
          final int groupCount = bsR( 3 );
          final int selectorCount = bsR( 15 );
          for( int i = 0; i < selectorCount; i++ )
          {
              int run = 0;
              while( bsR( 1 ) == 1 )
              {
                  run++;
              }
              m_selectorMtf[ i ] = (char)run;
          }
  
          /*
           * Undo the MTF values for the selectors.
           */
          final char[] pos = new char[ N_GROUPS ];
          for( char v = 0; v < groupCount; v++ )
          {
              pos[ v ] = v;
          }
  
          for( int i = 0; i < selectorCount; i++ )
          {
              int v = m_selectorMtf[ i ];
              final char tmp = pos[ v ];
              while( v > 0 )
              {
                  pos[ v ] = pos[ v - 1 ];
                  v--;
              }
              pos[ 0 ] = tmp;
              m_selector[ i ] = tmp;
          }
  
          final char[][] len = new char[ N_GROUPS ][ MAX_ALPHA_SIZE ];
          /*
           * Now the coding tables
           */
          for( int i = 0; i < groupCount; i++ )
          {
              int curr = bsR( 5 );
              for( int j = 0; j < alphaSize; j++ )
              {
                  while( bsR( 1 ) == 1 )
                  {
                      if( bsR( 1 ) == 0 )
                      {
                          curr++;
                      }
                      else
                      {
                          curr--;
                      }
                  }
                  len[ i ][ j ] = (char)curr;
              }
          }
  
          /*
           * Create the Huffman decoding tables
           */
          for( int k = 0; k < groupCount; k++ )
          {
              int minLen = 32;
              int maxLen = 0;
              for( int i = 0; i < alphaSize; i++ )
              {
                  if( len[ k ][ i ] > maxLen )
                  {
                      maxLen = len[ k ][ i ];
                  }
                  if( len[ k ][ i ] < minLen )
                  {
                      minLen = len[ k ][ i ];
                  }
              }
              hbCreateDecodeTables( m_limit[ k ], m_base[ k ], m_perm[ k ], len[ k ], minLen,
                                    maxLen, alphaSize );
              m_minLens[ k ] = minLen;
          }
      }
  
      private void buildInUseTable()
      {
          final boolean[] inUse16 = new boolean[ 16 ];
  
          /*
           * Receive the mapping table
           */
          for( int i = 0; i < 16; i++ )
          {
              if( bsR( 1 ) == 1 )
              {
                  inUse16[ i ] = true;
              }
              else
              {
                  inUse16[ i ] = false;
              }
          }
  
          for( int i = 0; i < 256; i++ )
          {
              m_inUse[ i ] = false;
          }
  
          for( int i = 0; i < 16; i++ )
          {
              if( inUse16[ i ] )
              {
                  for( int j = 0; j < 16; j++ )
                  {
                      if( bsR( 1 ) == 1 )
                      {
                          m_inUse[ i * 16 + j ] = true;
                      }
                  }
              }
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/java/org/apache/avalon/excalibur/bzip2/CBZip2OutputStream.java
  
  Index: CBZip2OutputStream.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.bzip2;
  
  import java.io.IOException;
  import java.io.OutputStream;
  import org.apache.avalon.excalibur.bzip2.BZip2Constants;
  
  /**
   * An output stream that compresses into the BZip2 format (without the file
   * header chars) into another stream. TODO: Update to BZip2 1.0.1
   *
   * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
   */
  public class CBZip2OutputStream
      extends OutputStream
      implements BZip2Constants
  {
      private final static int LOWER_BYTE_MASK = 0x000000ff;
      private final static int UPPER_BYTE_MASK = 0xffffff00;
      private final static int SETMASK = ( 1 << 21 );
      private final static int CLEARMASK = ( ~SETMASK );
      private final static int GREATER_ICOST = 15;
      private final static int LESSER_ICOST = 0;
      private final static int SMALL_THRESH = 20;
      private final static int DEPTH_THRESH = 10;
  
      /*
       * If you are ever unlucky/improbable enough
       * to get a stack overflow whilst sorting,
       * increase the following constant and try
       * again.  In practice I have never seen the
       * stack go above 27 elems, so the following
       * limit seems very generous.
       */
      private final static int QSORT_STACK_SIZE = 1000;
  
      private CRC m_crc = new CRC();
  
      private boolean[] m_inUse = new boolean[ 256 ];
  
      private char[] m_seqToUnseq = new char[ 256 ];
      private char[] m_unseqToSeq = new char[ 256 ];
  
      private char[] m_selector = new char[ MAX_SELECTORS ];
      private char[] m_selectorMtf = new char[ MAX_SELECTORS ];
  
      private int[] m_mtfFreq = new int[ MAX_ALPHA_SIZE ];
  
      private int m_currentChar = -1;
      private int m_runLength;
  
      private boolean m_closed;
  
      /*
       * Knuth's increments seem to work better
       * than Incerpi-Sedgewick here.  Possibly
       * because the number of elems to sort is
       * usually small, typically <= 20.
       */
      private int[] m_incs = new int[]
      {
          1, 4, 13, 40, 121, 364, 1093, 3280,
          9841, 29524, 88573, 265720,
          797161, 2391484
      };
  
      private boolean m_blockRandomised;
  
      /*
       * always: in the range 0 .. 9.
       * The current block size is 100000 * this number.
       */
      private int m_blockSize100k;
      private int m_bsBuff;
      private int m_bsLive;
  
      private int m_bytesIn;
      private int m_bytesOut;
  
      /*
       * index of the last char in the block, so
       * the block size == last + 1.
       */
      private int m_last;
  
      /*
       * index in zptr[] of original string after sorting.
       */
      private int m_origPtr;
  
      private int m_allowableBlockSize;
  
      private char[] m_block;
  
      private int m_blockCRC;
      private int m_combinedCRC;
  
      private OutputStream m_bsStream;
      private boolean m_firstAttempt;
      private int[] m_ftab;
      private int m_nBlocksRandomised;
      private int m_nInUse;
  
      private int m_nMTF;
      private int[] m_quadrant;
      private short[] m_szptr;
      private int m_workDone;
  
      /*
       * Used when sorting.  If too many long comparisons
       * happen, we stop sorting, randomise the block
       * slightly, and try again.
       */
      private int m_workFactor;
      private int m_workLimit;
      private int[] m_zptr;
  
      public CBZip2OutputStream( final OutputStream output )
          throws IOException
      {
          this( output, 9 );
      }
  
      public CBZip2OutputStream( final OutputStream output, final int blockSize )
          throws IOException
      {
          bsSetStream( output );
          m_workFactor = 50;
  
          int outBlockSize = blockSize;
          if( outBlockSize > 9 )
          {
              outBlockSize = 9;
          }
          if( outBlockSize < 1 )
          {
              outBlockSize = 1;
          }
          m_blockSize100k = outBlockSize;
          allocateCompressStructures();
          initialize();
          initBlock();
      }
  
      protected static void hbMakeCodeLengths( char[] len, int[] freq,
                                               int alphaSize, int maxLen )
      {
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int nNodes;
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int nHeap;
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int n1;
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int n2;
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int i;
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int j;
          /*
           * Nodes and heap entries run from 1.  Entry 0
           * for both the heap and nodes is a sentinel.
           */
          int k;
          boolean tooLong;
  
          int[] heap = new int[ MAX_ALPHA_SIZE + 2 ];
          int[] weights = new int[ MAX_ALPHA_SIZE * 2 ];
          int[] parent = new int[ MAX_ALPHA_SIZE * 2 ];
  
          for( i = 0; i < alphaSize; i++ )
          {
              weights[ i + 1 ] = ( freq[ i ] == 0 ? 1 : freq[ i ] ) << 8;
          }
  
          while( true )
          {
              nNodes = alphaSize;
              nHeap = 0;
  
              heap[ 0 ] = 0;
              weights[ 0 ] = 0;
              parent[ 0 ] = -2;
  
              for( i = 1; i <= alphaSize; i++ )
              {
                  parent[ i ] = -1;
                  nHeap++;
                  heap[ nHeap ] = i;
                  {
                      int zz;
                      int tmp;
                      zz = nHeap;
                      tmp = heap[ zz ];
                      while( weights[ tmp ] < weights[ heap[ zz >> 1 ] ] )
                      {
                          heap[ zz ] = heap[ zz >> 1 ];
                          zz >>= 1;
                      }
                      heap[ zz ] = tmp;
                  }
              }
              if( !( nHeap < ( MAX_ALPHA_SIZE + 2 ) ) )
              {
                  panic();
              }
  
              while( nHeap > 1 )
              {
                  n1 = heap[ 1 ];
                  heap[ 1 ] = heap[ nHeap ];
                  nHeap--;
                  {
                      int zz = 0;
                      int yy = 0;
                      int tmp = 0;
                      zz = 1;
                      tmp = heap[ zz ];
                      while( true )
                      {
                          yy = zz << 1;
                          if( yy > nHeap )
                          {
                              break;
                          }
                          if( yy < nHeap &&
                              weights[ heap[ yy + 1 ] ] < weights[ heap[ yy ] ] )
                          {
                              yy++;
                          }
                          if( weights[ tmp ] < weights[ heap[ yy ] ] )
                          {
                              break;
                          }
                          heap[ zz ] = heap[ yy ];
                          zz = yy;
                      }
                      heap[ zz ] = tmp;
                  }
                  n2 = heap[ 1 ];
                  heap[ 1 ] = heap[ nHeap ];
                  nHeap--;
                  {
                      int zz = 0;
                      int yy = 0;
                      int tmp = 0;
                      zz = 1;
                      tmp = heap[ zz ];
                      while( true )
                      {
                          yy = zz << 1;
                          if( yy > nHeap )
                          {
                              break;
                          }
                          if( yy < nHeap &&
                              weights[ heap[ yy + 1 ] ] < weights[ heap[ yy ] ] )
                          {
                              yy++;
                          }
                          if( weights[ tmp ] < weights[ heap[ yy ] ] )
                          {
                              break;
                          }
                          heap[ zz ] = heap[ yy ];
                          zz = yy;
                      }
                      heap[ zz ] = tmp;
                  }
                  nNodes++;
                  parent[ n1 ] = nNodes;
                  parent[ n2 ] = nNodes;
  
                  final int v1 = weights[ n1 ];
                  final int v2 = weights[ n2 ];
                  final int weight = calculateWeight( v1, v2 );
                  weights[ nNodes ] = weight;
  
                  parent[ nNodes ] = -1;
                  nHeap++;
                  heap[ nHeap ] = nNodes;
                  {
                      int zz = 0;
                      int tmp = 0;
                      zz = nHeap;
                      tmp = heap[ zz ];
                      while( weights[ tmp ] < weights[ heap[ zz >> 1 ] ] )
                      {
                          heap[ zz ] = heap[ zz >> 1 ];
                          zz >>= 1;
                      }
                      heap[ zz ] = tmp;
                  }
              }
              if( !( nNodes < ( MAX_ALPHA_SIZE * 2 ) ) )
              {
                  panic();
              }
  
              tooLong = false;
              for( i = 1; i <= alphaSize; i++ )
              {
                  j = 0;
                  k = i;
                  while( parent[ k ] >= 0 )
                  {
                      k = parent[ k ];
                      j++;
                  }
                  len[ i - 1 ] = (char)j;
                  if( j > maxLen )
                  {
                      tooLong = true;
                  }
              }
  
              if( !tooLong )
              {
                  break;
              }
  
              for( i = 1; i < alphaSize; i++ )
              {
                  j = weights[ i ] >> 8;
                  j = 1 + ( j / 2 );
                  weights[ i ] = j << 8;
              }
          }
      }
  
      private static int calculateWeight( final int v1, final int v2 )
      {
          final int upper = ( v1 & UPPER_BYTE_MASK ) + ( v2 & UPPER_BYTE_MASK );
          final int v1Lower = ( v1 & LOWER_BYTE_MASK );
          final int v2Lower = ( v2 & LOWER_BYTE_MASK );
          final int nnnn = ( v1Lower > v2Lower ) ? v1Lower : v2Lower;
          return upper | ( 1 + nnnn );
      }
  
      private static void panic()
      {
          System.out.println( "panic" );
          //throw new CError();
      }
  
      public void close()
          throws IOException
      {
          if( m_closed )
          {
              return;
          }
  
          if( m_runLength > 0 )
          {
              writeRun();
          }
          m_currentChar = -1;
          endBlock();
          endCompression();
          m_closed = true;
          super.close();
          m_bsStream.close();
      }
  
      public void finalize()
          throws Throwable
      {
          close();
      }
  
      public void flush()
          throws IOException
      {
          super.flush();
          m_bsStream.flush();
      }
  
      /**
       * modified by Oliver Merkel, 010128
       *
       * @param bv Description of Parameter
       * @exception java.io.IOException Description of Exception
       */
      public void write( int bv )
          throws IOException
      {
          int b = ( 256 + bv ) % 256;
          if( m_currentChar != -1 )
          {
              if( m_currentChar == b )
              {
                  m_runLength++;
                  if( m_runLength > 254 )
                  {
                      writeRun();
                      m_currentChar = -1;
                      m_runLength = 0;
                  }
              }
              else
              {
                  writeRun();
                  m_runLength = 1;
                  m_currentChar = b;
              }
          }
          else
          {
              m_currentChar = b;
              m_runLength++;
          }
      }
  
      private void allocateCompressStructures()
      {
          int n = BASE_BLOCK_SIZE * m_blockSize100k;
          m_block = new char[ ( n + 1 + NUM_OVERSHOOT_BYTES ) ];
          m_quadrant = new int[ ( n + NUM_OVERSHOOT_BYTES ) ];
          m_zptr = new int[ n ];
          m_ftab = new int[ 65537 ];
  
          if( m_block == null || m_quadrant == null || m_zptr == null
              || m_ftab == null )
          {
              //int totalDraw = (n + 1 + NUM_OVERSHOOT_BYTES) + (n + NUM_OVERSHOOT_BYTES) + n + 65537;
              //compressOutOfMemory ( totalDraw, n );
          }
  
          /*
           * The back end needs a place to store the MTF values
           * whilst it calculates the coding tables.  We could
           * put them in the zptr array.  However, these values
           * will fit in a short, so we overlay szptr at the
           * start of zptr, in the hope of reducing the number
           * of cache misses induced by the multiple traversals
           * of the MTF values when calculating coding tables.
           * Seems to improve compression speed by about 1%.
           */
          //    szptr = zptr;
  
          m_szptr = new short[ 2 * n ];
      }
  
      private void bsFinishedWithStream()
          throws IOException
      {
          while( m_bsLive > 0 )
          {
              int ch = ( m_bsBuff >> 24 );
              try
              {
                  m_bsStream.write( ch );// write 8-bit
              }
              catch( IOException e )
              {
                  throw e;
              }
              m_bsBuff <<= 8;
              m_bsLive -= 8;
              m_bytesOut++;
          }
      }
  
      private void bsPutIntVS( int numBits, int c )
          throws IOException
      {
          bsW( numBits, c );
      }
  
      private void bsPutUChar( int c )
          throws IOException
      {
          bsW( 8, c );
      }
  
      private void bsPutint( int u )
          throws IOException
      {
          bsW( 8, ( u >> 24 ) & 0xff );
          bsW( 8, ( u >> 16 ) & 0xff );
          bsW( 8, ( u >> 8 ) & 0xff );
          bsW( 8, u & 0xff );
      }
  
      private void bsSetStream( OutputStream f )
      {
          m_bsStream = f;
          m_bsLive = 0;
          m_bsBuff = 0;
          m_bytesOut = 0;
          m_bytesIn = 0;
      }
  
      private void bsW( int n, int v )
          throws IOException
      {
          while( m_bsLive >= 8 )
          {
              int ch = ( m_bsBuff >> 24 );
              try
              {
                  m_bsStream.write( ch );// write 8-bit
              }
              catch( IOException e )
              {
                  throw e;
              }
              m_bsBuff <<= 8;
              m_bsLive -= 8;
              m_bytesOut++;
          }
          m_bsBuff |= ( v << ( 32 - m_bsLive - n ) );
          m_bsLive += n;
      }
  
      private void doReversibleTransformation()
      {
          int i;
  
          m_workLimit = m_workFactor * m_last;
          m_workDone = 0;
          m_blockRandomised = false;
          m_firstAttempt = true;
  
          mainSort();
  
          if( m_workDone > m_workLimit && m_firstAttempt )
          {
              randomiseBlock();
              m_workLimit = 0;
              m_workDone = 0;
              m_blockRandomised = true;
              m_firstAttempt = false;
              mainSort();
          }
  
          m_origPtr = -1;
          for( i = 0; i <= m_last; i++ )
          {
              if( m_zptr[ i ] == 0 )
              {
                  m_origPtr = i;
                  break;
              }
          }
          ;
  
          if( m_origPtr == -1 )
          {
              panic();
          }
      }
  
      private void endBlock()
          throws IOException
      {
          m_blockCRC = m_crc.getFinalCRC();
          m_combinedCRC = ( m_combinedCRC << 1 ) | ( m_combinedCRC >>> 31 );
          m_combinedCRC ^= m_blockCRC;
  
          /*
           * sort the block and establish posn of original string
           */
          doReversibleTransformation();
  
          /*
           * A 6-byte block header, the value chosen arbitrarily
           * as 0x314159265359 :-).  A 32 bit value does not really
           * give a strong enough guarantee that the value will not
           * appear by chance in the compressed datastream.  Worst-case
           * probability of this event, for a 900k block, is about
           * 2.0e-3 for 32 bits, 1.0e-5 for 40 bits and 4.0e-8 for 48 bits.
           * For a compressed file of size 100Gb -- about 100000 blocks --
           * only a 48-bit marker will do.  NB: normal compression/
           * decompression do *not* rely on these statistical properties.
           * They are only important when trying to recover blocks from
           * damaged files.
           */
          bsPutUChar( 0x31 );
          bsPutUChar( 0x41 );
          bsPutUChar( 0x59 );
          bsPutUChar( 0x26 );
          bsPutUChar( 0x53 );
          bsPutUChar( 0x59 );
  
          /*
           * Now the block's CRC, so it is in a known place.
           */
          bsPutint( m_blockCRC );
  
          /*
           * Now a single bit indicating randomisation.
           */
          if( m_blockRandomised )
          {
              bsW( 1, 1 );
              m_nBlocksRandomised++;
          }
          else
          {
              bsW( 1, 0 );
          }
  
          /*
           * Finally, block's contents proper.
           */
          moveToFrontCodeAndSend();
      }
  
      private void endCompression()
          throws IOException
      {
          /*
           * Now another magic 48-bit number, 0x177245385090, to
           * indicate the end of the last block.  (sqrt(pi), if
           * you want to know.  I did want to use e, but it contains
           * too much repetition -- 27 18 28 18 28 46 -- for me
           * to feel statistically comfortable.  Call me paranoid.)
           */
          bsPutUChar( 0x17 );
          bsPutUChar( 0x72 );
          bsPutUChar( 0x45 );
          bsPutUChar( 0x38 );
          bsPutUChar( 0x50 );
          bsPutUChar( 0x90 );
  
          bsPutint( m_combinedCRC );
  
          bsFinishedWithStream();
      }
  
      private boolean fullGtU( int i1, int i2 )
      {
          int k;
          char c1;
          char c2;
          int s1;
          int s2;
  
          c1 = m_block[ i1 + 1 ];
          c2 = m_block[ i2 + 1 ];
          if( c1 != c2 )
          {
              return ( c1 > c2 );
          }
          i1++;
          i2++;
  
          c1 = m_block[ i1 + 1 ];
          c2 = m_block[ i2 + 1 ];
          if( c1 != c2 )
          {
              return ( c1 > c2 );
          }
          i1++;
          i2++;
  
          c1 = m_block[ i1 + 1 ];
          c2 = m_block[ i2 + 1 ];
          if( c1 != c2 )
          {
              return ( c1 > c2 );
          }
          i1++;
          i2++;
  
          c1 = m_block[ i1 + 1 ];
          c2 = m_block[ i2 + 1 ];
          if( c1 != c2 )
          {
              return ( c1 > c2 );
          }
          i1++;
          i2++;
  
          c1 = m_block[ i1 + 1 ];
          c2 = m_block[ i2 + 1 ];
          if( c1 != c2 )
          {
              return ( c1 > c2 );
          }
          i1++;
          i2++;
  
          c1 = m_block[ i1 + 1 ];
          c2 = m_block[ i2 + 1 ];
          if( c1 != c2 )
          {
              return ( c1 > c2 );
          }
          i1++;
          i2++;
  
          k = m_last + 1;
  
          do
          {
              c1 = m_block[ i1 + 1 ];
              c2 = m_block[ i2 + 1 ];
              if( c1 != c2 )
              {
                  return ( c1 > c2 );
              }
              s1 = m_quadrant[ i1 ];
              s2 = m_quadrant[ i2 ];
              if( s1 != s2 )
              {
                  return ( s1 > s2 );
              }
              i1++;
              i2++;
  
              c1 = m_block[ i1 + 1 ];
              c2 = m_block[ i2 + 1 ];
              if( c1 != c2 )
              {
                  return ( c1 > c2 );
              }
              s1 = m_quadrant[ i1 ];
              s2 = m_quadrant[ i2 ];
              if( s1 != s2 )
              {
                  return ( s1 > s2 );
              }
              i1++;
              i2++;
  
              c1 = m_block[ i1 + 1 ];
              c2 = m_block[ i2 + 1 ];
              if( c1 != c2 )
              {
                  return ( c1 > c2 );
              }
              s1 = m_quadrant[ i1 ];
              s2 = m_quadrant[ i2 ];
              if( s1 != s2 )
              {
                  return ( s1 > s2 );
              }
              i1++;
              i2++;
  
              c1 = m_block[ i1 + 1 ];
              c2 = m_block[ i2 + 1 ];
              if( c1 != c2 )
              {
                  return ( c1 > c2 );
              }
              s1 = m_quadrant[ i1 ];
              s2 = m_quadrant[ i2 ];
              if( s1 != s2 )
              {
                  return ( s1 > s2 );
              }
              i1++;
              i2++;
  
              if( i1 > m_last )
              {
                  i1 -= m_last;
                  i1--;
              }
              ;
              if( i2 > m_last )
              {
                  i2 -= m_last;
                  i2--;
              }
              ;
  
              k -= 4;
              m_workDone++;
          } while( k >= 0 );
  
          return false;
      }
  
      private void generateMTFValues()
      {
          char[] yy = new char[ 256 ];
          int i;
          int j;
          char tmp;
          char tmp2;
          int zPend;
          int wr;
          int EOB;
  
          makeMaps();
          EOB = m_nInUse + 1;
  
          for( i = 0; i <= EOB; i++ )
          {
              m_mtfFreq[ i ] = 0;
          }
  
          wr = 0;
          zPend = 0;
          for( i = 0; i < m_nInUse; i++ )
          {
              yy[ i ] = (char)i;
          }
  
          for( i = 0; i <= m_last; i++ )
          {
              char ll_i;
  
              ll_i = m_unseqToSeq[ m_block[ m_zptr[ i ] ] ];
  
              j = 0;
              tmp = yy[ j ];
              while( ll_i != tmp )
              {
                  j++;
                  tmp2 = tmp;
                  tmp = yy[ j ];
                  yy[ j ] = tmp2;
              }
              ;
              yy[ 0 ] = tmp;
  
              if( j == 0 )
              {
                  zPend++;
              }
              else
              {
                  if( zPend > 0 )
                  {
                      zPend--;
                      while( true )
                      {
                          switch( zPend % 2 )
                          {
                              case 0:
                                  m_szptr[ wr ] = (short)RUNA;
                                  wr++;
                                  m_mtfFreq[ RUNA ]++;
                                  break;
                              case 1:
                                  m_szptr[ wr ] = (short)RUNB;
                                  wr++;
                                  m_mtfFreq[ RUNB ]++;
                                  break;
                          }
                          ;
                          if( zPend < 2 )
                          {
                              break;
                          }
                          zPend = ( zPend - 2 ) / 2;
                      }
                      ;
                      zPend = 0;
                  }
                  m_szptr[ wr ] = (short)( j + 1 );
                  wr++;
                  m_mtfFreq[ j + 1 ]++;
              }
          }
  
          if( zPend > 0 )
          {
              zPend--;
              while( true )
              {
                  switch( zPend % 2 )
                  {
                      case 0:
                          m_szptr[ wr ] = (short)RUNA;
                          wr++;
                          m_mtfFreq[ RUNA ]++;
                          break;
                      case 1:
                          m_szptr[ wr ] = (short)RUNB;
                          wr++;
                          m_mtfFreq[ RUNB ]++;
                          break;
                  }
                  if( zPend < 2 )
                  {
                      break;
                  }
                  zPend = ( zPend - 2 ) / 2;
              }
          }
  
          m_szptr[ wr ] = (short)EOB;
          wr++;
          m_mtfFreq[ EOB ]++;
  
          m_nMTF = wr;
      }
  
      private void hbAssignCodes( int[] code, char[] length, int minLen,
                                  int maxLen, int alphaSize )
      {
          int n;
          int vec;
          int i;
  
          vec = 0;
          for( n = minLen; n <= maxLen; n++ )
          {
              for( i = 0; i < alphaSize; i++ )
              {
                  if( length[ i ] == n )
                  {
                      code[ i ] = vec;
                      vec++;
                  }
              }
              ;
              vec <<= 1;
          }
      }
  
      private void initBlock()
      {
          //        blockNo++;
          m_crc.initialiseCRC();
          m_last = -1;
          //        ch = 0;
  
          for( int i = 0; i < 256; i++ )
          {
              m_inUse[ i ] = false;
          }
  
          /*
           * 20 is just a paranoia constant
           */
          m_allowableBlockSize = BASE_BLOCK_SIZE * m_blockSize100k - 20;
      }
  
      private void initialize()
          throws IOException
      {
          m_bytesIn = 0;
          m_bytesOut = 0;
          m_nBlocksRandomised = 0;
  
          /*
           * Write `magic' bytes h indicating file-format == huffmanised,
           * followed by a digit indicating blockSize100k.
           */
          bsPutUChar( 'h' );
          bsPutUChar( '0' + m_blockSize100k );
  
          m_combinedCRC = 0;
      }
  
      private void mainSort()
      {
          int i;
          int j;
          int ss;
          int sb;
          int[] runningOrder = new int[ 256 ];
          int[] copy = new int[ 256 ];
          boolean[] bigDone = new boolean[ 256 ];
          int c1;
          int c2;
          int numQSorted;
  
          /*
           * In the various block-sized structures, live data runs
           * from 0 to last+NUM_OVERSHOOT_BYTES inclusive.  First,
           * set up the overshoot area for block.
           */
          //   if (verbosity >= 4) fprintf ( stderr, "        sort initialise ...\n" );
          for( i = 0; i < NUM_OVERSHOOT_BYTES; i++ )
          {
              m_block[ m_last + i + 2 ] = m_block[ ( i % ( m_last + 1 ) ) + 1 ];
          }
          for( i = 0; i <= m_last + NUM_OVERSHOOT_BYTES; i++ )
          {
              m_quadrant[ i ] = 0;
          }
  
          m_block[ 0 ] = m_block[ m_last + 1 ];
  
          if( m_last < 4000 )
          {
              /*
               * Use simpleSort(), since the full sorting mechanism
               * has quite a large constant overhead.
               */
              for( i = 0; i <= m_last; i++ )
              {
                  m_zptr[ i ] = i;
              }
              m_firstAttempt = false;
              m_workDone = 0;
              m_workLimit = 0;
              simpleSort( 0, m_last, 0 );
          }
          else
          {
              numQSorted = 0;
              for( i = 0; i <= 255; i++ )
              {
                  bigDone[ i ] = false;
              }
  
              for( i = 0; i <= 65536; i++ )
              {
                  m_ftab[ i ] = 0;
              }
  
              c1 = m_block[ 0 ];
              for( i = 0; i <= m_last; i++ )
              {
                  c2 = m_block[ i + 1 ];
                  m_ftab[ ( c1 << 8 ) + c2 ]++;
                  c1 = c2;
              }
  
              for( i = 1; i <= 65536; i++ )
              {
                  m_ftab[ i ] += m_ftab[ i - 1 ];
              }
  
              c1 = m_block[ 1 ];
              for( i = 0; i < m_last; i++ )
              {
                  c2 = m_block[ i + 2 ];
                  j = ( c1 << 8 ) + c2;
                  c1 = c2;
                  m_ftab[ j ]--;
                  m_zptr[ m_ftab[ j ] ] = i;
              }
  
              j = ( ( m_block[ m_last + 1 ] ) << 8 ) + ( m_block[ 1 ] );
              m_ftab[ j ]--;
              m_zptr[ m_ftab[ j ] ] = m_last;
  
              /*
               * Now ftab contains the first loc of every small bucket.
               * Calculate the running order, from smallest to largest
               * big bucket.
               */
              for( i = 0; i <= 255; i++ )
              {
                  runningOrder[ i ] = i;
              }
              {
                  int vv;
                  int h = 1;
                  do
                  {
                      h = 3 * h + 1;
                  } while( h <= 256 );
                  do
                  {
                      h = h / 3;
                      for( i = h; i <= 255; i++ )
                      {
                          vv = runningOrder[ i ];
                          j = i;
                          while( ( m_ftab[ ( ( runningOrder[ j - h ] ) + 1 ) << 8 ]
                              - m_ftab[ ( runningOrder[ j - h ] ) << 8 ] ) >
                              ( m_ftab[ ( ( vv ) + 1 ) << 8 ] - m_ftab[ ( vv ) << 8 ] ) )
                          {
                              runningOrder[ j ] = runningOrder[ j - h ];
                              j = j - h;
                              if( j <= ( h - 1 ) )
                              {
                                  break;
                              }
                          }
                          runningOrder[ j ] = vv;
                      }
                  } while( h != 1 );
              }
  
              /*
               * The main sorting loop.
               */
              for( i = 0; i <= 255; i++ )
              {
  
                  /*
                   * Process big buckets, starting with the least full.
                   */
                  ss = runningOrder[ i ];
  
                  /*
                   * Complete the big bucket [ss] by quicksorting
                   * any unsorted small buckets [ss, j].  Hopefully
                   * previous pointer-scanning phases have already
                   * completed many of the small buckets [ss, j], so
                   * we don't have to sort them at all.
                   */
                  for( j = 0; j <= 255; j++ )
                  {
                      sb = ( ss << 8 ) + j;
                      if( !( ( m_ftab[ sb ] & SETMASK ) == SETMASK ) )
                      {
                          int lo = m_ftab[ sb ] & CLEARMASK;
                          int hi = ( m_ftab[ sb + 1 ] & CLEARMASK ) - 1;
                          if( hi > lo )
                          {
                              qSort3( lo, hi, 2 );
                              numQSorted += ( hi - lo + 1 );
                              if( m_workDone > m_workLimit && m_firstAttempt )
                              {
                                  return;
                              }
                          }
                          m_ftab[ sb ] |= SETMASK;
                      }
                  }
  
                  /*
                   * The ss big bucket is now done.  Record this fact,
                   * and update the quadrant descriptors.  Remember to
                   * update quadrants in the overshoot area too, if
                   * necessary.  The "if (i < 255)" test merely skips
                   * this updating for the last bucket processed, since
                   * updating for the last bucket is pointless.
                   */
                  bigDone[ ss ] = true;
  
                  if( i < 255 )
                  {
                      int bbStart = m_ftab[ ss << 8 ] & CLEARMASK;
                      int bbSize = ( m_ftab[ ( ss + 1 ) << 8 ] & CLEARMASK ) - bbStart;
                      int shifts = 0;
  
                      while( ( bbSize >> shifts ) > 65534 )
                      {
                          shifts++;
                      }
  
                      for( j = 0; j < bbSize; j++ )
                      {
                          int a2update = m_zptr[ bbStart + j ];
                          int qVal = ( j >> shifts );
                          m_quadrant[ a2update ] = qVal;
                          if( a2update < NUM_OVERSHOOT_BYTES )
                          {
                              m_quadrant[ a2update + m_last + 1 ] = qVal;
                          }
                      }
  
                      if( !( ( ( bbSize - 1 ) >> shifts ) <= 65535 ) )
                      {
                          panic();
                      }
                  }
  
                  /*
                   * Now scan this big bucket so as to synthesise the
                   * sorted order for small buckets [t, ss] for all t != ss.
                   */
                  for( j = 0; j <= 255; j++ )
                  {
                      copy[ j ] = m_ftab[ ( j << 8 ) + ss ] & CLEARMASK;
                  }
  
                  for( j = m_ftab[ ss << 8 ] & CLEARMASK;
                       j < ( m_ftab[ ( ss + 1 ) << 8 ] & CLEARMASK ); j++ )
                  {
                      c1 = m_block[ m_zptr[ j ] ];
                      if( !bigDone[ c1 ] )
                      {
                          m_zptr[ copy[ c1 ] ] = m_zptr[ j ] == 0 ? m_last : m_zptr[ j ] - 1;
                          copy[ c1 ]++;
                      }
                  }
  
                  for( j = 0; j <= 255; j++ )
                  {
                      m_ftab[ ( j << 8 ) + ss ] |= SETMASK;
                  }
              }
          }
      }
  
      private void makeMaps()
      {
          int i;
          m_nInUse = 0;
          for( i = 0; i < 256; i++ )
          {
              if( m_inUse[ i ] )
              {
                  m_seqToUnseq[ m_nInUse ] = (char)i;
                  m_unseqToSeq[ i ] = (char)m_nInUse;
                  m_nInUse++;
              }
          }
      }
  
      private char med3( char a, char b, char c )
      {
          char t;
          if( a > b )
          {
              t = a;
              a = b;
              b = t;
          }
          if( b > c )
          {
              t = b;
              b = c;
              c = t;
          }
          if( a > b )
          {
              b = a;
          }
          return b;
      }
  
      private void moveToFrontCodeAndSend()
          throws IOException
      {
          bsPutIntVS( 24, m_origPtr );
          generateMTFValues();
          sendMTFValues();
      }
  
      private void qSort3( int loSt, int hiSt, int dSt )
      {
          int unLo;
          int unHi;
          int ltLo;
          int gtHi;
          int med;
          int n;
          int m;
          int sp;
          int lo;
          int hi;
          int d;
          StackElem[] stack = new StackElem[ QSORT_STACK_SIZE ];
          for( int count = 0; count < QSORT_STACK_SIZE; count++ )
          {
              stack[ count ] = new StackElem();
          }
  
          sp = 0;
  
          stack[ sp ].ll = loSt;
          stack[ sp ].hh = hiSt;
          stack[ sp ].dd = dSt;
          sp++;
  
          while( sp > 0 )
          {
              if( sp >= QSORT_STACK_SIZE )
              {
                  panic();
              }
  
              sp--;
              lo = stack[ sp ].ll;
              hi = stack[ sp ].hh;
              d = stack[ sp ].dd;
  
              if( hi - lo < SMALL_THRESH || d > DEPTH_THRESH )
              {
                  simpleSort( lo, hi, d );
                  if( m_workDone > m_workLimit && m_firstAttempt )
                  {
                      return;
                  }
                  continue;
              }
  
              med = med3( m_block[ m_zptr[ lo ] + d + 1 ],
                          m_block[ m_zptr[ hi ] + d + 1 ],
                          m_block[ m_zptr[ ( lo + hi ) >> 1 ] + d + 1 ] );
  
              unLo = lo;
              ltLo = lo;
              unHi = hi;
              gtHi = hi;
  
              while( true )
              {
                  while( true )
                  {
                      if( unLo > unHi )
                      {
                          break;
                      }
                      n = m_block[ m_zptr[ unLo ] + d + 1 ] - med;
                      if( n == 0 )
                      {
                          int temp = 0;
                          temp = m_zptr[ unLo ];
                          m_zptr[ unLo ] = m_zptr[ ltLo ];
                          m_zptr[ ltLo ] = temp;
                          ltLo++;
                          unLo++;
                          continue;
                      }
                      ;
                      if( n > 0 )
                      {
                          break;
                      }
                      unLo++;
                  }
                  while( true )
                  {
                      if( unLo > unHi )
                      {
                          break;
                      }
                      n = m_block[ m_zptr[ unHi ] + d + 1 ] - med;
                      if( n == 0 )
                      {
                          int temp = 0;
                          temp = m_zptr[ unHi ];
                          m_zptr[ unHi ] = m_zptr[ gtHi ];
                          m_zptr[ gtHi ] = temp;
                          gtHi--;
                          unHi--;
                          continue;
                      }
                      ;
                      if( n < 0 )
                      {
                          break;
                      }
                      unHi--;
                  }
                  if( unLo > unHi )
                  {
                      break;
                  }
                  int temp = 0;
                  temp = m_zptr[ unLo ];
                  m_zptr[ unLo ] = m_zptr[ unHi ];
                  m_zptr[ unHi ] = temp;
                  unLo++;
                  unHi--;
              }
  
              if( gtHi < ltLo )
              {
                  stack[ sp ].ll = lo;
                  stack[ sp ].hh = hi;
                  stack[ sp ].dd = d + 1;
                  sp++;
                  continue;
              }
  
              n = ( ( ltLo - lo ) < ( unLo - ltLo ) ) ? ( ltLo - lo ) : ( unLo - ltLo );
              vswap( lo, unLo - n, n );
              m = ( ( hi - gtHi ) < ( gtHi - unHi ) ) ? ( hi - gtHi ) : ( gtHi - unHi );
              vswap( unLo, hi - m + 1, m );
  
              n = lo + unLo - ltLo - 1;
              m = hi - ( gtHi - unHi ) + 1;
  
              stack[ sp ].ll = lo;
              stack[ sp ].hh = n;
              stack[ sp ].dd = d;
              sp++;
  
              stack[ sp ].ll = n + 1;
              stack[ sp ].hh = m - 1;
              stack[ sp ].dd = d + 1;
              sp++;
  
              stack[ sp ].ll = m;
              stack[ sp ].hh = hi;
              stack[ sp ].dd = d;
              sp++;
          }
      }
  
      private void randomiseBlock()
      {
          int i;
          int rNToGo = 0;
          int rTPos = 0;
          for( i = 0; i < 256; i++ )
          {
              m_inUse[ i ] = false;
          }
  
          for( i = 0; i <= m_last; i++ )
          {
              if( rNToGo == 0 )
              {
                  rNToGo = (char)RAND_NUMS[ rTPos ];
                  rTPos++;
                  if( rTPos == 512 )
                  {
                      rTPos = 0;
                  }
              }
              rNToGo--;
              m_block[ i + 1 ] ^= ( ( rNToGo == 1 ) ? 1 : 0 );
              // handle 16 bit signed numbers
              m_block[ i + 1 ] &= 0xFF;
  
              m_inUse[ m_block[ i + 1 ] ] = true;
          }
      }
  
      private void sendMTFValues()
          throws IOException
      {
          char[][] len = new char[ N_GROUPS ][ MAX_ALPHA_SIZE ];
  
          int v;
  
          int t;
  
          int i;
  
          int j;
  
          int gs;
  
          int ge;
  
          int totc;
  
          int bt;
  
          int bc;
  
          int iter;
          int nSelectors = 0;
          int alphaSize;
          int minLen;
          int maxLen;
          int selCtr;
          int nGroups;
          int nBytes;
  
          alphaSize = m_nInUse + 2;
          for( t = 0; t < N_GROUPS; t++ )
          {
              for( v = 0; v < alphaSize; v++ )
              {
                  len[ t ][ v ] = (char)GREATER_ICOST;
              }
          }
  
          /*
           * Decide how many coding tables to use
           */
          if( m_nMTF <= 0 )
          {
              panic();
          }
  
          if( m_nMTF < 200 )
          {
              nGroups = 2;
          }
          else if( m_nMTF < 600 )
          {
              nGroups = 3;
          }
          else if( m_nMTF < 1200 )
          {
              nGroups = 4;
          }
          else if( m_nMTF < 2400 )
          {
              nGroups = 5;
          }
          else
          {
              nGroups = 6;
          }
          {
              /*
               * Generate an initial set of coding tables
               */
              int nPart;
              int remF;
              int tFreq;
              int aFreq;
  
              nPart = nGroups;
              remF = m_nMTF;
              gs = 0;
              while( nPart > 0 )
              {
                  tFreq = remF / nPart;
                  ge = gs - 1;
                  aFreq = 0;
                  while( aFreq < tFreq && ge < alphaSize - 1 )
                  {
                      ge++;
                      aFreq += m_mtfFreq[ ge ];
                  }
  
                  if( ge > gs && nPart != nGroups && nPart != 1
                      && ( ( nGroups - nPart ) % 2 == 1 ) )
                  {
                      aFreq -= m_mtfFreq[ ge ];
                      ge--;
                  }
  
                  for( v = 0; v < alphaSize; v++ )
                  {
                      if( v >= gs && v <= ge )
                      {
                          len[ nPart - 1 ][ v ] = (char)LESSER_ICOST;
                      }
                      else
                      {
                          len[ nPart - 1 ][ v ] = (char)GREATER_ICOST;
                      }
                  }
  
                  nPart--;
                  gs = ge + 1;
                  remF -= aFreq;
              }
          }
  
          int[][] rfreq = new int[ N_GROUPS ][ MAX_ALPHA_SIZE ];
          int[] fave = new int[ N_GROUPS ];
          short[] cost = new short[ N_GROUPS ];
          /*
           * Iterate up to N_ITERS times to improve the tables.
           */
          for( iter = 0; iter < N_ITERS; iter++ )
          {
              for( t = 0; t < nGroups; t++ )
              {
                  fave[ t ] = 0;
              }
  
              for( t = 0; t < nGroups; t++ )
              {
                  for( v = 0; v < alphaSize; v++ )
                  {
                      rfreq[ t ][ v ] = 0;
                  }
              }
  
              nSelectors = 0;
              totc = 0;
              gs = 0;
              while( true )
              {
  
                  /*
                   * Set group start & end marks.
                   */
                  if( gs >= m_nMTF )
                  {
                      break;
                  }
                  ge = gs + G_SIZE - 1;
                  if( ge >= m_nMTF )
                  {
                      ge = m_nMTF - 1;
                  }
  
                  /*
                   * Calculate the cost of this group as coded
                   * by each of the coding tables.
                   */
                  for( t = 0; t < nGroups; t++ )
                  {
                      cost[ t ] = 0;
                  }
  
                  if( nGroups == 6 )
                  {
                      short cost0 = 0;
                      short cost1 = 0;
                      short cost2 = 0;
                      short cost3 = 0;
                      short cost4 = 0;
                      short cost5 = 0;
  
                      for( i = gs; i <= ge; i++ )
                      {
                          short icv = m_szptr[ i ];
                          cost0 += len[ 0 ][ icv ];
                          cost1 += len[ 1 ][ icv ];
                          cost2 += len[ 2 ][ icv ];
                          cost3 += len[ 3 ][ icv ];
                          cost4 += len[ 4 ][ icv ];
                          cost5 += len[ 5 ][ icv ];
                      }
                      cost[ 0 ] = cost0;
                      cost[ 1 ] = cost1;
                      cost[ 2 ] = cost2;
                      cost[ 3 ] = cost3;
                      cost[ 4 ] = cost4;
                      cost[ 5 ] = cost5;
                  }
                  else
                  {
                      for( i = gs; i <= ge; i++ )
                      {
                          short icv = m_szptr[ i ];
                          for( t = 0; t < nGroups; t++ )
                          {
                              cost[ t ] += len[ t ][ icv ];
                          }
                      }
                  }
  
                  /*
                   * Find the coding table which is best for this group,
                   * and record its identity in the selector table.
                   */
                  bc = 999999999;
                  bt = -1;
                  for( t = 0; t < nGroups; t++ )
                  {
                      if( cost[ t ] < bc )
                      {
                          bc = cost[ t ];
                          bt = t;
                      }
                  }
                  ;
                  totc += bc;
                  fave[ bt ]++;
                  m_selector[ nSelectors ] = (char)bt;
                  nSelectors++;
  
                  /*
                   * Increment the symbol frequencies for the selected table.
                   */
                  for( i = gs; i <= ge; i++ )
                  {
                      rfreq[ bt ][ m_szptr[ i ] ]++;
                  }
  
                  gs = ge + 1;
              }
  
              /*
               * Recompute the tables based on the accumulated frequencies.
               */
              for( t = 0; t < nGroups; t++ )
              {
                  hbMakeCodeLengths( len[ t ], rfreq[ t ], alphaSize, 20 );
              }
          }
  
          rfreq = null;
          fave = null;
          cost = null;
  
          if( !( nGroups < 8 ) )
          {
              panic();
          }
          if( !( nSelectors < 32768 && nSelectors <= ( 2 + ( 900000 / G_SIZE ) ) ) )
          {
              panic();
          }
          {
              /*
               * Compute MTF values for the selectors.
               */
              char[] pos = new char[ N_GROUPS ];
              char ll_i;
              char tmp2;
              char tmp;
              for( i = 0; i < nGroups; i++ )
              {
                  pos[ i ] = (char)i;
              }
              for( i = 0; i < nSelectors; i++ )
              {
                  ll_i = m_selector[ i ];
                  j = 0;
                  tmp = pos[ j ];
                  while( ll_i != tmp )
                  {
                      j++;
                      tmp2 = tmp;
                      tmp = pos[ j ];
                      pos[ j ] = tmp2;
                  }
                  pos[ 0 ] = tmp;
                  m_selectorMtf[ i ] = (char)j;
              }
          }
  
          int[][] code = new int[ N_GROUPS ][ MAX_ALPHA_SIZE ];
  
          /*
           * Assign actual codes for the tables.
           */
          for( t = 0; t < nGroups; t++ )
          {
              minLen = 32;
              maxLen = 0;
              for( i = 0; i < alphaSize; i++ )
              {
                  if( len[ t ][ i ] > maxLen )
                  {
                      maxLen = len[ t ][ i ];
                  }
                  if( len[ t ][ i ] < minLen )
                  {
                      minLen = len[ t ][ i ];
                  }
              }
              if( maxLen > 20 )
              {
                  panic();
              }
              if( minLen < 1 )
              {
                  panic();
              }
              hbAssignCodes( code[ t ], len[ t ], minLen, maxLen, alphaSize );
          }
          {
              /*
               * Transmit the mapping table.
               */
              boolean[] inUse16 = new boolean[ 16 ];
              for( i = 0; i < 16; i++ )
              {
                  inUse16[ i ] = false;
                  for( j = 0; j < 16; j++ )
                  {
                      if( m_inUse[ i * 16 + j ] )
                      {
                          inUse16[ i ] = true;
                      }
                  }
              }
  
              nBytes = m_bytesOut;
              for( i = 0; i < 16; i++ )
              {
                  if( inUse16[ i ] )
                  {
                      bsW( 1, 1 );
                  }
                  else
                  {
                      bsW( 1, 0 );
                  }
              }
  
              for( i = 0; i < 16; i++ )
              {
                  if( inUse16[ i ] )
                  {
                      for( j = 0; j < 16; j++ )
                      {
                          if( m_inUse[ i * 16 + j ] )
                          {
                              bsW( 1, 1 );
                          }
                          else
                          {
                              bsW( 1, 0 );
                          }
                      }
                  }
              }
  
          }
  
          /*
           * Now the selectors.
           */
          nBytes = m_bytesOut;
          bsW( 3, nGroups );
          bsW( 15, nSelectors );
          for( i = 0; i < nSelectors; i++ )
          {
              for( j = 0; j < m_selectorMtf[ i ]; j++ )
              {
                  bsW( 1, 1 );
              }
              bsW( 1, 0 );
          }
  
          /*
           * Now the coding tables.
           */
          nBytes = m_bytesOut;
  
          for( t = 0; t < nGroups; t++ )
          {
              int curr = len[ t ][ 0 ];
              bsW( 5, curr );
              for( i = 0; i < alphaSize; i++ )
              {
                  while( curr < len[ t ][ i ] )
                  {
                      bsW( 2, 2 );
                      curr++;
                      /*
                       * 10
                       */
                  }
                  while( curr > len[ t ][ i ] )
                  {
                      bsW( 2, 3 );
                      curr--;
                      /*
                       * 11
                       */
                  }
                  bsW( 1, 0 );
              }
          }
  
          /*
           * And finally, the block data proper
           */
          nBytes = m_bytesOut;
          selCtr = 0;
          gs = 0;
          while( true )
          {
              if( gs >= m_nMTF )
              {
                  break;
              }
              ge = gs + G_SIZE - 1;
              if( ge >= m_nMTF )
              {
                  ge = m_nMTF - 1;
              }
              for( i = gs; i <= ge; i++ )
              {
                  bsW( len[ m_selector[ selCtr ] ][ m_szptr[ i ] ],
                       code[ m_selector[ selCtr ] ][ m_szptr[ i ] ] );
              }
  
              gs = ge + 1;
              selCtr++;
          }
          if( !( selCtr == nSelectors ) )
          {
              panic();
          }
      }
  
      private void simpleSort( int lo, int hi, int d )
      {
          int i;
          int j;
          int h;
          int bigN;
          int hp;
          int v;
  
          bigN = hi - lo + 1;
          if( bigN < 2 )
          {
              return;
          }
  
          hp = 0;
          while( m_incs[ hp ] < bigN )
          {
              hp++;
          }
          hp--;
  
          for( ; hp >= 0; hp-- )
          {
              h = m_incs[ hp ];
  
              i = lo + h;
              while( true )
              {
                  /*
                   * copy 1
                   */
                  if( i > hi )
                  {
                      break;
                  }
                  v = m_zptr[ i ];
                  j = i;
                  while( fullGtU( m_zptr[ j - h ] + d, v + d ) )
                  {
                      m_zptr[ j ] = m_zptr[ j - h ];
                      j = j - h;
                      if( j <= ( lo + h - 1 ) )
                      {
                          break;
                      }
                  }
                  m_zptr[ j ] = v;
                  i++;
  
                  /*
                   * copy 2
                   */
                  if( i > hi )
                  {
                      break;
                  }
                  v = m_zptr[ i ];
                  j = i;
                  while( fullGtU( m_zptr[ j - h ] + d, v + d ) )
                  {
                      m_zptr[ j ] = m_zptr[ j - h ];
                      j = j - h;
                      if( j <= ( lo + h - 1 ) )
                      {
                          break;
                      }
                  }
                  m_zptr[ j ] = v;
                  i++;
  
                  /*
                   * copy 3
                   */
                  if( i > hi )
                  {
                      break;
                  }
                  v = m_zptr[ i ];
                  j = i;
                  while( fullGtU( m_zptr[ j - h ] + d, v + d ) )
                  {
                      m_zptr[ j ] = m_zptr[ j - h ];
                      j = j - h;
                      if( j <= ( lo + h - 1 ) )
                      {
                          break;
                      }
                  }
                  m_zptr[ j ] = v;
                  i++;
  
                  if( m_workDone > m_workLimit && m_firstAttempt )
                  {
                      return;
                  }
              }
          }
      }
  
      private void vswap( int p1, int p2, int n )
      {
          int temp = 0;
          while( n > 0 )
          {
              temp = m_zptr[ p1 ];
              m_zptr[ p1 ] = m_zptr[ p2 ];
              m_zptr[ p2 ] = temp;
              p1++;
              p2++;
              n--;
          }
      }
  
      private void writeRun()
          throws IOException
      {
          if( m_last < m_allowableBlockSize )
          {
              m_inUse[ m_currentChar ] = true;
              for( int i = 0; i < m_runLength; i++ )
              {
                  m_crc.updateCRC( (char)m_currentChar );
              }
              switch( m_runLength )
              {
                  case 1:
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      break;
                  case 2:
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      break;
                  case 3:
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      break;
                  default:
                      m_inUse[ m_runLength - 4 ] = true;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)m_currentChar;
                      m_last++;
                      m_block[ m_last + 1 ] = (char)( m_runLength - 4 );
                      break;
              }
          }
          else
          {
              endBlock();
              initBlock();
              writeRun();
          }
      }
  
      private class StackElem
      {
          int dd;
          int hh;
          int ll;
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/java/org/apache/avalon/excalibur/bzip2/CRC.java
  
  Index: CRC.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.bzip2;
  
  /**
   * A simple class the hold and calculate the CRC for sanity checking of the
   * data.
   *
   * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
   */
  class CRC
  {
      private static int[] CRC32_TABLE = new int[]
      {
          0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
          0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
          0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
          0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
          0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
          0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
          0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
          0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
          0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
          0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
          0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
          0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
          0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
          0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
          0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
          0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
          0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
          0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
          0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
          0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
          0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
          0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
          0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
          0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
          0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
          0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
          0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
          0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
          0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
          0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
          0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
          0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
          0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
          0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
          0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
          0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
          0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
          0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
          0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
          0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
          0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
          0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
          0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
          0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
          0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
          0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
          0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
          0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
          0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
          0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
          0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
          0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
          0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
          0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
          0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
          0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
          0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
          0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
          0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
          0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
          0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
          0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
          0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
          0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
      };
  
      private int m_globalCrc;
  
      protected CRC()
      {
          initialiseCRC();
      }
  
      void setGlobalCRC( final int newCrc )
      {
          m_globalCrc = newCrc;
      }
  
      int getFinalCRC()
      {
          return ~m_globalCrc;
      }
  
      int getGlobalCRC()
      {
          return m_globalCrc;
      }
  
      void initialiseCRC()
      {
          m_globalCrc = 0xffffffff;
      }
  
      void updateCRC( final int inCh )
      {
          int temp = ( m_globalCrc >> 24 ) ^ inCh;
          if( temp < 0 )
          {
              temp = 256 + temp;
          }
          m_globalCrc = ( m_globalCrc << 8 ) ^ CRC32_TABLE[ temp ];
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/test/org/apache/avalon/excalibur/bzip2/test/BzipTestCase.java
  
  Index: BzipTestCase.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.bzip2.test;
  
  import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import junit.framework.TestCase;
  import org.apache.avalon.excalibur.bzip2.CBZip2InputStream;
  import org.apache.avalon.excalibur.bzip2.CBZip2OutputStream;
  
  /**
   * A test the stress tested the BZip implementation to verify
   * that it behaves correctly.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/24 07:02:31 $
   */
  public class BzipTestCase
      extends TestCase
  {
      private static final byte[] HEADER = new byte[]{(byte)'B', (byte)'Z'};
  
      public BzipTestCase( final String name )
      {
          super( name );
      }
  
      public void testBzipOutputStream()
          throws Exception
      {
          final InputStream input = getInputStream( "asf-logo-huge.tar" );
          final File outputFile = getOutputFile( ".tar.bz2" );
          final OutputStream output = new FileOutputStream( outputFile );
          final CBZip2OutputStream packedOutput = getPackedOutput( output );
          copy( input, packedOutput );
          shutdownStream( input );
          shutdownStream( packedOutput );
          shutdownStream( output );
          compareContents( "asf-logo-huge.tar.bz2", outputFile );
          forceDelete( outputFile );
      }
  
      private void forceDelete( final File outputFile ) throws IOException
      {
          if( !outputFile.delete() )
          {
              final String message = "File " + outputFile + " unable to be deleted.";
              throw new IOException( message );
          }
      }
  
      public void testBzipInputStream()
          throws Exception
      {
          final InputStream input = getInputStream( "asf-logo-huge.tar.bz2" );
          final File outputFile = getOutputFile( ".tar" );
          final OutputStream output = new FileOutputStream( outputFile );
          final CBZip2InputStream packedInput = getPackedInput( input );
          copy( packedInput, output );
          shutdownStream( input );
          shutdownStream( packedInput );
          shutdownStream( output );
          compareContents( "asf-logo-huge.tar", outputFile );
          forceDelete( outputFile );
      }
  
      /**
       * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
       */
      private void copy( final InputStream input,
                         final OutputStream output )
          throws IOException
      {
          final byte[] buffer = new byte[ 8024 ];
          int n = 0;
          while( -1 != ( n = input.read( buffer ) ) )
          {
              output.write( buffer, 0, n );
          }
      }
  
      private void compareContents( final String initial, final File generated )
          throws Exception
      {
          final InputStream input1 = getInputStream( initial );
          final InputStream input2 = new FileInputStream( generated );
          final boolean test = contentEquals( input1, input2 );
          shutdownStream( input1 );
          shutdownStream( input2 );
          assertTrue( "Contents of " + initial + " matches generated version " + generated, test );
      }
  
      private CBZip2InputStream getPackedInput( final InputStream input )
          throws IOException
      {
          final int b1 = input.read();
          final int b2 = input.read();
          assertEquals( "Equal header byte1", b1, 'B' );
          assertEquals( "Equal header byte2", b2, 'Z' );
          return new CBZip2InputStream( input );
      }
  
      private CBZip2OutputStream getPackedOutput( final OutputStream output )
          throws IOException
      {
          output.write( HEADER );
          return new CBZip2OutputStream( output );
      }
  
      private File getOutputFile( final String postfix )
          throws IOException
      {
          final File cwd = new File( "." );
          return File.createTempFile( "ant-test", postfix, cwd );
      }
  
      private InputStream getInputStream( final String resource )
          throws Exception
      {
          final String filename = ".." + File.separator + ".." + File.separator +
              "src" + File.separator + "test" + File.separator +
              getClass().getName().replace( '.', File.separatorChar );
          final String path = getPath( filename );
          final File input = new File( path, resource );
          return new FileInputStream( input );
          //final ClassLoader loader = getClass().getClassLoader();
          //return loader.getResourceAsStream( resource );
      }
  
      /**
       * Compare the contents of two Streams to determine if they are equal or not.
       *
       * @param input1 the first stream
       * @param input2 the second stream
       * @return true if the content of the streams are equal or they both don't exist, false otherwise
       */
      private boolean contentEquals( final InputStream input1,
                                     final InputStream input2 )
          throws IOException
      {
          final InputStream bufferedInput1 = new BufferedInputStream( input1 );
          final InputStream bufferedInput2 = new BufferedInputStream( input2 );
  
          int ch = bufferedInput1.read();
          while( -1 != ch )
          {
              final int ch2 = bufferedInput2.read();
              if( ch != ch2 )
              {
                  return false;
              }
              ch = bufferedInput1.read();
          }
  
          final int ch2 = bufferedInput2.read();
          if( -1 != ch2 )
          {
              return false;
          }
          else
          {
              return true;
          }
      }
  
      private String getPath( final String filepath )
      {
          final int index = filepath.lastIndexOf( File.separatorChar );
          if( -1 == index )
          {
              return "";
          }
          else
          {
              return filepath.substring( 0, index );
          }
      }
  
      /**
       * Unconditionally close an <code>OutputStream</code>.
       * Equivalent to {@link java.io.OutputStream#close()}, except any exceptions will be ignored.
       * @param output A (possibly null) OutputStream
       */
      private static void shutdownStream( final OutputStream output )
      {
          if( null == output )
          {
              return;
          }
  
          try
          {
              output.close();
          }
          catch( final IOException ioe )
          {
          }
      }
  
      /**
       * Unconditionally close an <code>InputStream</code>.
       * Equivalent to {@link java.io.InputStream#close()}, except any exceptions will be ignored.
       * @param input A (possibly null) InputStream
       */
      private static void shutdownStream( final InputStream input )
      {
          if( null == input )
          {
              return;
          }
  
          try
          {
              input.close();
          }
          catch( final IOException ioe )
          {
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/test/org/apache/avalon/excalibur/bzip2/test/asf-logo-huge.tar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/bzip2/src/test/org/apache/avalon/excalibur/bzip2/test/asf-logo-huge.tar.bz2
  
  	<<Binary file>>
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>