home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / util / ClassTable.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  42.8 KB  |  1,403 lines  |  [TEXT/CWIE]

  1. // ClassTable.java
  2. // By Ned Etcode
  3. // Copyright 1995, 1996, 1997 Netscape Communications Corp.  All rights reserved.
  4.  
  5. package netscape.util;
  6.  
  7. import java.io.*;
  8.  
  9. /** Object subclass used by an Archive to store the raw data for its encoded
  10.   * objects. Each class in an Archive has a ClassTable that holds the data for
  11.   * instances of that class. The data in a ClassTable is accessed by row and
  12.   * column index, with a row corresponding to an instance of the class and a
  13.   * column corresponding to a field of that class. Field names can be mapped to
  14.   * column indexes through <b>ClassTable.columnForField()</b>; object
  15.   * identifiers can be mapped to row indexes through
  16.   * <b>ClassTable.rowForIdentifier()</b>. New rows are created through
  17.   * <b>ClassTable.newIdentifier()</b>. Only programs that directly manipulate
  18.   * archive data must deal with ClassTables.
  19.   *
  20.   * @see Archive
  21.   * @see ClassInfo
  22.   */
  23. public class ClassTable {
  24.     Archive archive;
  25.     String className;
  26.  
  27.     int classCount;
  28.     String classNames[];
  29.     int classVersions[];
  30.  
  31.     int fieldCount;
  32.     byte fieldTypes[];
  33.     String fieldNames[];
  34.     IdHashtable columnForField;
  35.  
  36.     int rowCapacity;
  37.     int rowCount;
  38.     Object fieldColumns[];
  39.  
  40.     // This is some scratch space used by Archive.read() and Archive.write().
  41.     int tableId;
  42.  
  43.     // This is some scratch space used by the Archiver/Unarchiver.  It is set
  44.     // to true when the Strings in the fieldNames array came directly from
  45.     // describeClassInfo() so that the pointers will be the same.  This is
  46.     // used to speed up Unarchiving.
  47.     boolean uniqueStrings;
  48.  
  49.     /** Constructs a new ClassTable for a given Archive. The ClassTable
  50.       * must be added to the archive by calling <b>Archive.addClassTable()</b>
  51.       * once the ClassTable's class name has been set. This constructor is only
  52.       * useful when reading a ClassTable from a stream.
  53.       * @see #readInfo
  54.       * @see #readData
  55.       * @see Archive#addClassTable
  56.       */
  57.     public ClassTable(Archive archive) {
  58.         super();
  59.         this.archive = archive;
  60.     }
  61.  
  62.     /** Constructs a new ClassTable for the Archive <b>archive</b>. The
  63.       * ClassTable must be added to the Archive by calling
  64.       * <b>Archive.addClassTable()</b>. <b>classInfo</b> helps configure the
  65.       * ClassTable.
  66.       * @see Archive#addClassTable
  67.       */
  68.     public ClassTable(Archive archive, ClassInfo classInfo) {
  69.         this(archive);
  70.  
  71.         className = classInfo.className();
  72.  
  73.         classCount = classInfo.classCount();
  74.         classNames = classInfo.classNames();
  75.         classVersions = classInfo.classVersions();
  76.  
  77.         fieldCount = classInfo.fieldCount();
  78.         fieldTypes = classInfo.fieldTypes();
  79.         fieldNames = classInfo.fieldNames();
  80.  
  81.         fieldColumns = new Object[fieldCount];
  82.     }
  83.  
  84.     /** Returns the archive to which this ClassTable belongs.
  85.       */
  86.     public Archive archive() {
  87.         return archive;
  88.     }
  89.  
  90.     /** Returns the name of the class this ClassTable represents.
  91.       */
  92.     public String className() {
  93.         return className;
  94.     }
  95.  
  96.     /** Returns the chain of superclasses recorded in this ClassTable.
  97.       */
  98.     public String[] classNames() {
  99.         return classNames;
  100.     }
  101.  
  102.     /** Returns the version for a given class name.
  103.       */
  104.     public int versionForClassName(String className) {
  105.         int i, count;
  106.  
  107.         count = classCount;
  108.         for (i = 0; i < count; i++) {
  109.             if (classNames[i].equals(className))
  110.                 return classVersions[i];
  111.         }
  112.  
  113.         return 0;
  114.     }
  115.  
  116.     /** Returns the number of rows in the ClassTable.
  117.       */
  118.     public int rowCount() {
  119.         return rowCount;
  120.     }
  121.  
  122.     private Object newColumn(int fieldType, int length) {
  123.         switch (fieldType) {
  124.             case Codable.BOOLEAN_TYPE:       return new boolean[length];
  125.             case Codable.BOOLEAN_ARRAY_TYPE: return new boolean[length][];
  126.             case Codable.CHAR_TYPE:          return new char[length];
  127.             case Codable.CHAR_ARRAY_TYPE:    return new char[length][];
  128.             case Codable.BYTE_TYPE:          return new byte[length];
  129.             case Codable.BYTE_ARRAY_TYPE:    return new byte[length][];
  130.             case Codable.SHORT_TYPE:         return new short[length];
  131.             case Codable.SHORT_ARRAY_TYPE:   return new short[length][];
  132.             case Codable.INT_TYPE:           return new int[length];
  133.             case Codable.INT_ARRAY_TYPE:     return new int[length][];
  134.             case Codable.LONG_TYPE:          return new long[length];
  135.             case Codable.LONG_ARRAY_TYPE:    return new long[length][];
  136.             case Codable.FLOAT_TYPE:         return new float[length];
  137.             case Codable.FLOAT_ARRAY_TYPE:   return new float[length][];
  138.             case Codable.DOUBLE_TYPE:        return new double[length];
  139.             case Codable.DOUBLE_ARRAY_TYPE:  return new double[length][];
  140.             case Codable.STRING_TYPE:        return new String[length];
  141.             case Codable.STRING_ARRAY_TYPE:  return new String[length][];
  142.             case Codable.OBJECT_TYPE:        return new int[length];
  143.             case Codable.OBJECT_ARRAY_TYPE:  return new int[length][];
  144.             default:
  145.                 throw new InconsistencyException("Unknown field type: " +
  146.                     fieldType);
  147.         }
  148.     }
  149.  
  150.     private void ensureCapacity(int newCapacity) {
  151.         int i;
  152.         Object newColumn;
  153.  
  154.         if (newCapacity <= rowCapacity)
  155.             return;
  156.  
  157.         for (i = 0; i < fieldCount; i++) {
  158.             newColumn = newColumn(fieldTypes[i], newCapacity);
  159.  
  160.             if (rowCapacity > 0)
  161.                 System.arraycopy(fieldColumns[i], 0, newColumn, 0,
  162.                                  rowCapacity);
  163.  
  164.             fieldColumns[i] = newColumn;
  165.         }
  166.  
  167.         rowCapacity = newCapacity;
  168.     }
  169.  
  170.     private void growCapacity() {
  171.         int newCapacity;
  172.  
  173.         if (rowCapacity == 0)
  174.             newCapacity = 8;
  175.         else
  176.             newCapacity = 2 * rowCapacity;
  177.  
  178.         ensureCapacity(newCapacity);
  179.     }
  180.  
  181.     /** Creates a new row in the ClassTable and a new identifier for the
  182.       * archive, returning the new identifier. The new row can be discovered
  183.       * by calling <b>rowForIdentifier()</b>.
  184.       */
  185.     public int newIdentifier() {
  186.         int id;
  187.  
  188.         if (rowCount >= rowCapacity)
  189.             growCapacity();
  190.  
  191.         id = archive.mapIdentifier(this, rowCount);
  192.         rowCount++;
  193.  
  194.         return id;
  195.     }
  196.  
  197.     /** Returns the row index for a given object identifier.
  198.       */
  199.     public int rowForIdentifier(int id) {
  200.         return archive.rowForIdentifier(id);
  201.     }
  202.  
  203.     /** Returns the column index for the given field name.
  204.       */
  205.     public int columnForField(String key) {
  206.         int i;
  207.  
  208.         if (archive.performanceDebug) {
  209.             System.err.println("*** Field " + key + " of class " +
  210.                 className + " was accessed out of order.");
  211.         }
  212.  
  213.         if (columnForField == null) {
  214.             columnForField = new IdHashtable(true);
  215.  
  216.             // We have to add one to the column because the NOT_FOUND
  217.             // constant is 0.  ALERT!
  218.  
  219.             for (i = 0; i < fieldCount; i++) {
  220.                 columnForField.putKnownAbsent(fieldNames[i], i + 1);
  221.             }
  222.         }
  223.  
  224.         i = columnForField.get(key);
  225.  
  226.         return i - 1;
  227.     }
  228.  
  229.     /** This calls describeClassInfo() on the object and replaces equals
  230.       * Strings in the fieldNames array. This method is very opportunistic
  231.       * and bails out at the first sign of trouble.
  232.       */
  233.     void uniqueStrings(ClassInfo info) {
  234.         int i, count;
  235.         String src[], dst[];
  236.  
  237.         // This is set to true even if we fail.  We don't want to keep
  238.         // trying.
  239.  
  240.         setUniqueStrings(true);
  241.  
  242.         if (info.fieldCount != fieldCount) {
  243.             if (archive.performanceDebug) {
  244.                 System.err.println("Failed to unique Strings in class " +
  245.                     info.className());
  246.             }
  247.             return;
  248.         }
  249.  
  250.         // Blow away the columnForField cache so it will benefit too.
  251.  
  252.         columnForField = null;
  253.  
  254.         src = info.fieldNames;
  255.         dst = fieldNames;
  256.         count = fieldCount;
  257.  
  258.         for (i = 0; i < count; i++) {
  259.             if (dst[i].equals(src[i]))
  260.                 dst[i] = src[i];
  261.             else {
  262.                 if (archive.performanceDebug) {
  263.                     System.err.println("Failed to unique Strings in class " +
  264.                         info.className());
  265.                 }
  266.                 return;
  267.             }
  268.         }
  269.  
  270.         // Do the same thing for the classNames.
  271.  
  272.         if (info.classCount != classCount)
  273.             return;
  274.  
  275.         src = info.classNames;
  276.         dst = classNames;
  277.         count = classCount;
  278.  
  279.         for (i = 0; i < count; i++) {
  280.             if (dst[i].equals(src[i]))
  281.                 dst[i] = src[i];
  282.             else
  283.                 return;
  284.         }
  285.     }
  286.  
  287.     void setUniqueStrings(boolean flag) {
  288.         uniqueStrings = flag;
  289.     }
  290.  
  291.     boolean hasUniqueStrings() {
  292.         return uniqueStrings;
  293.     }
  294.  
  295.     /** Returns the boolean value located at <b>row</b>, <b>column</b>.
  296.       * @see #setBooleanAt
  297.       */
  298.     public boolean booleanAt(int row, int column) {
  299.         if (row >= rowCount)
  300.             throw new ArrayIndexOutOfBoundsException(row);
  301.  
  302.         return ((boolean[])fieldColumns[column])[row];
  303.     }
  304.  
  305.     /** Sets the boolean value at <b>row</b>, <b>column</b>.
  306.       */
  307.     public void setBooleanAt(int row, int column, boolean value) {
  308.         if (row >= rowCount)
  309.             throw new ArrayIndexOutOfBoundsException(row);
  310.  
  311.         ((boolean[])fieldColumns[column])[row] = value;
  312.     }
  313.  
  314.     /** Returns the boolean array located at <b>row</b>, <b>column</b>.
  315.       * @see #setBooleanArrayAt
  316.       */
  317.     public boolean[] booleanArrayAt(int row, int column) {
  318.         if (row >= rowCount)
  319.             throw new ArrayIndexOutOfBoundsException(row);
  320.  
  321.         return ((boolean[][])fieldColumns[column])[row];
  322.     }
  323.  
  324.     /** Sets the boolean array at <b>row</b>, <b>column</b>.
  325.       */
  326.     public void setBooleanArrayAt(int row, int column, boolean value[]) {
  327.         if (row >= rowCount)
  328.             throw new ArrayIndexOutOfBoundsException(row);
  329.  
  330.         ((boolean[][])fieldColumns[column])[row] = value;
  331.     }
  332.  
  333.     /** Returns the character value located at <b>row</b>, <b>column</b>.
  334.       * @see #setCharAt
  335.       */
  336.     public char charAt(int row, int column) {
  337.         if (row >= rowCount)
  338.             throw new ArrayIndexOutOfBoundsException(row);
  339.  
  340.         return ((char[])fieldColumns[column])[row];
  341.     }
  342.  
  343.     /** Sets the character value at <b>row</b>, <b>column</b>.
  344.       */
  345.     public void setCharAt(int row, int column, char value) {
  346.         if (row >= rowCount)
  347.             throw new ArrayIndexOutOfBoundsException(row);
  348.  
  349.         ((char[])fieldColumns[column])[row] = value;
  350.     }
  351.  
  352.     /** Returns the character array located at <b>row</b>, <b>column</b>.
  353.       * @see #setCharArrayAt
  354.       */
  355.     public char[] charArrayAt(int row, int column) {
  356.         if (row >= rowCount)
  357.             throw new ArrayIndexOutOfBoundsException(row);
  358.  
  359.         return ((char[][])fieldColumns[column])[row];
  360.     }
  361.  
  362.     /** Sets the character array at <b>row</b>, <b>column</b>.
  363.       */
  364.     public void setCharArrayAt(int row, int column, char value[]) {
  365.         if (row >= rowCount)
  366.             throw new ArrayIndexOutOfBoundsException(row);
  367.  
  368.         ((char[][])fieldColumns[column])[row] = value;
  369.     }
  370.  
  371.     /** Returns the byte value located at <b>row</b>, <b>column</b>.
  372.       * @see #@setByteAt
  373.       */
  374.     public byte byteAt(int row, int column) {
  375.         if (row >= rowCount)
  376.             throw new ArrayIndexOutOfBoundsException(row);
  377.  
  378.         return ((byte[])fieldColumns[column])[row];
  379.     }
  380.  
  381.     /** Sets the byte value at <b>row</b>, <b>column</b>.
  382.       */
  383.     public void setByteAt(int row, int column, byte value) {
  384.         if (row >= rowCount)
  385.             throw new ArrayIndexOutOfBoundsException(row);
  386.  
  387.         ((byte[])fieldColumns[column])[row] = value;
  388.     }
  389.  
  390.     /** Returns the byte array located at <b>row</b>, <b>column</b>.
  391.       * @see #setByteArrayAt
  392.       */
  393.     public byte[] byteArrayAt(int row, int column) {
  394.         if (row >= rowCount)
  395.             throw new ArrayIndexOutOfBoundsException(row);
  396.  
  397.         return ((byte[][])fieldColumns[column])[row];
  398.     }
  399.  
  400.     /** Sets the byte array located at <b>row</b>, <b>column</b>.
  401.       */
  402.     public void setByteArrayAt(int row, int column, byte value[]) {
  403.         if (row >= rowCount)
  404.             throw new ArrayIndexOutOfBoundsException(row);
  405.  
  406.         ((byte[][])fieldColumns[column])[row] = value;
  407.     }
  408.  
  409.     /** Returns the short value located at <b>row</b>, <b>column</b>.
  410.       * @see #setShortAt
  411.       */
  412.     public short shortAt(int row, int column) {
  413.         if (row >= rowCount)
  414.             throw new ArrayIndexOutOfBoundsException(row);
  415.  
  416.         return ((short[])fieldColumns[column])[row];
  417.     }
  418.  
  419.     /** Sets the short value at <b>row</b>, <b>column</b>.
  420.       */
  421.     public void setShortAt(int row, int column, short value) {
  422.         if (row >= rowCount)
  423.             throw new ArrayIndexOutOfBoundsException(row);
  424.  
  425.         ((short[])fieldColumns[column])[row] = value;
  426.     }
  427.  
  428.     /** Returns the short array located at <b>row</b>, <b>column</b>.
  429.       * @see #setShortArrayAt
  430.       */
  431.     public short[] shortArrayAt(int row, int column) {
  432.         if (row >= rowCount)
  433.             throw new ArrayIndexOutOfBoundsException(row);
  434.  
  435.         return ((short[][])fieldColumns[column])[row];
  436.     }
  437.  
  438.     /** Sets the short array at <b>row</b>, <b>column</b>.
  439.       */
  440.     public void setShortArrayAt(int row, int column, short value[]) {
  441.         if (row >= rowCount)
  442.             throw new ArrayIndexOutOfBoundsException(row);
  443.  
  444.         ((short[][])fieldColumns[column])[row] = value;
  445.     }
  446.  
  447.     /** Returns the integer value located at <b>row</b>, <b>column</b>.
  448.       * @see #setIntegerAt
  449.       */
  450.     public int intAt(int row, int column) {
  451.         if (row >= rowCount)
  452.             throw new ArrayIndexOutOfBoundsException(row);
  453.  
  454.         return ((int[])fieldColumns[column])[row];
  455.     }
  456.  
  457.     /** Sets the integer value located at <b>row</b>, <b>column</b>.
  458.       */
  459.     public void setIntAt(int row, int column, int value) {
  460.         if (row >= rowCount)
  461.             throw new ArrayIndexOutOfBoundsException(row);
  462.  
  463.         ((int[])fieldColumns[column])[row] = value;
  464.     }
  465.  
  466.     /** Returns the integer array located at <b>row</b>, <b>column</b>.
  467.       * @see #setIntegerArrayAt
  468.       */
  469.     public int[] intArrayAt(int row, int column) {
  470.         if (row >= rowCount)
  471.             throw new ArrayIndexOutOfBoundsException(row);
  472.  
  473.         return ((int[][])fieldColumns[column])[row];
  474.     }
  475.  
  476.     /** Sets the integer array located at <b>row</b>, <b>column</b>.
  477.       */
  478.     public void setIntArrayAt(int row, int column, int value[]) {
  479.         if (row >= rowCount)
  480.             throw new ArrayIndexOutOfBoundsException(row);
  481.  
  482.         ((int[][])fieldColumns[column])[row] = value;
  483.     }
  484.  
  485.     /** Returns the long value located at <b>row</b>, <b>column</b>.
  486.       * @see #setLongAt
  487.       */
  488.     public long longAt(int row, int column) {
  489.         if (row >= rowCount)
  490.             throw new ArrayIndexOutOfBoundsException(row);
  491.  
  492.         return ((long[])fieldColumns[column])[row];
  493.     }
  494.  
  495.     /** Sets the long value at <b>row</b>, <b>column</b>.
  496.       */
  497.     public void setLongAt(int row, int column, long value) {
  498.         if (row >= rowCount)
  499.             throw new ArrayIndexOutOfBoundsException(row);
  500.  
  501.         ((long[])fieldColumns[column])[row] = value;
  502.     }
  503.  
  504.     /** Returns the long array located at <b>row</b>, <b>column</b>.
  505.       * @see #setLongArrayAt
  506.       */
  507.     public long[] longArrayAt(int row, int column) {
  508.         if (row >= rowCount)
  509.             throw new ArrayIndexOutOfBoundsException(row);
  510.  
  511.         return ((long[][])fieldColumns[column])[row];
  512.     }
  513.  
  514.     /** Sets the long array at <b>row</b>, <b>column</b>.
  515.       */
  516.     public void setLongArrayAt(int row, int column, long value[]) {
  517.         if (row >= rowCount)
  518.             throw new ArrayIndexOutOfBoundsException(row);
  519.  
  520.         ((long[][])fieldColumns[column])[row] = value;
  521.     }
  522.  
  523.     /** Returns the float value located at <b>row</b>, <b>column</b>.
  524.       * @see #setFloatAt
  525.       */
  526.     public float floatAt(int row, int column) {
  527.         if (row >= rowCount)
  528.             throw new ArrayIndexOutOfBoundsException(row);
  529.  
  530.         return ((float[])fieldColumns[column])[row];
  531.     }
  532.  
  533.     /** Sets the float value at <b>row</b>, <b>column</b>.
  534.       */
  535.     public void setFloatAt(int row, int column, float value) {
  536.         if (row >= rowCount)
  537.             throw new ArrayIndexOutOfBoundsException(row);
  538.  
  539.         ((float[])fieldColumns[column])[row] = value;
  540.     }
  541.  
  542.     /** Returns the float array located at <b>row</b>, <b>column</b>.
  543.       * @see #setFloatArrayAt
  544.       */
  545.     public float[] floatArrayAt(int row, int column) {
  546.         if (row >= rowCount)
  547.             throw new ArrayIndexOutOfBoundsException(row);
  548.  
  549.         return ((float[][])fieldColumns[column])[row];
  550.     }
  551.  
  552.     /** Sets the float array at <b>row</b>, <b>column</b>.
  553.       */
  554.     public void setFloatArrayAt(int row, int column, float value[]) {
  555.         if (row >= rowCount)
  556.             throw new ArrayIndexOutOfBoundsException(row);
  557.  
  558.         ((float[][])fieldColumns[column])[row] = value;
  559.     }
  560.  
  561.     /** Returns the double value located at <b>row</b>, <b>column</b>.
  562.       * @see #setDoubleAt
  563.       */
  564.     public double doubleAt(int row, int column) {
  565.         if (row >= rowCount)
  566.             throw new ArrayIndexOutOfBoundsException(row);
  567.  
  568.         return ((double[])fieldColumns[column])[row];
  569.     }
  570.  
  571.     /** Sets the double value at <b>row</b>, <b>column</b>.
  572.       */
  573.     public void setDoubleAt(int row, int column, double value) {
  574.         if (row >= rowCount)
  575.             throw new ArrayIndexOutOfBoundsException(row);
  576.  
  577.         ((double[])fieldColumns[column])[row] = value;
  578.     }
  579.  
  580.     /** Returns the double array located at <b>row</b>, <b>column</b>.
  581.       * @see #setDoubleArrayAt
  582.       */
  583.     public double[] doubleArrayAt(int row, int column) {
  584.         if (row >= rowCount)
  585.             throw new ArrayIndexOutOfBoundsException(row);
  586.  
  587.         return ((double[][])fieldColumns[column])[row];
  588.     }
  589.  
  590.     /** Sets the double array at <b>row</b>, <b>column</b>.
  591.       */
  592.     public void setDoubleArrayAt(int row, int column, double value[]) {
  593.         if (row >= rowCount)
  594.             throw new ArrayIndexOutOfBoundsException(row);
  595.  
  596.         ((double[][])fieldColumns[column])[row] = value;
  597.     }
  598.  
  599.     /** Returns the string value located at <b>row</b>, <b>column</b>.
  600.       * @see #setStringAt
  601.       */
  602.     public String stringAt(int row, int column) {
  603.         if (row >= rowCount)
  604.             throw new ArrayIndexOutOfBoundsException(row);
  605.  
  606.         return ((String[])fieldColumns[column])[row];
  607.     }
  608.  
  609.     /** Sets the string value at <b>row</b>, <b>column</b>.
  610.       */
  611.     public void setStringAt(int row, int column, String value) {
  612.         if (row >= rowCount)
  613.             throw new ArrayIndexOutOfBoundsException(row);
  614.  
  615.         ((String[])fieldColumns[column])[row] = value;
  616.     }
  617.  
  618.     /** Returns the string array located at <b>row</b>, <b>column</b>.
  619.       * @see #setStringArrayAt
  620.       */
  621.     public String[] stringArrayAt(int row, int column) {
  622.         if (row >= rowCount)
  623.             throw new ArrayIndexOutOfBoundsException(row);
  624.  
  625.         return ((String[][])fieldColumns[column])[row];
  626.     }
  627.  
  628.     /** Sets the string array at <b>row</b>, <b>column</b>.
  629.       */
  630.     public void setStringArrayAt(int row, int column, String value[]) {
  631.         if (row >= rowCount)
  632.             throw new ArrayIndexOutOfBoundsException(row);
  633.  
  634.         ((String[][])fieldColumns[column])[row] = value;
  635.     }
  636.  
  637.     /** Returns the identifier at <b>row</b>, <b>column</b>.
  638.       * @see #setIdentifierAt
  639.       */
  640.     public int identifierAt(int row, int column) {
  641.         if (row >= rowCount)
  642.             throw new ArrayIndexOutOfBoundsException(row);
  643.  
  644.         return ((int[])fieldColumns[column])[row];
  645.     }
  646.  
  647.     /** Sets the identifier at <b>row</b>, <b>column</b>.
  648.       */
  649.     public void setIdentifierAt(int row, int column, int value) {
  650.         if (row >= rowCount)
  651.             throw new ArrayIndexOutOfBoundsException(row);
  652.  
  653.         ((int[])fieldColumns[column])[row] = value;
  654.     }
  655.  
  656.     /** Returns the identifier array at <b>row</b>, <b>column</b>.
  657.       * @see #setIdentifierArrayAt
  658.       */
  659.     public int[] identifierArrayAt(int row, int column) {
  660.         if (row >= rowCount)
  661.             throw new ArrayIndexOutOfBoundsException(row);
  662.  
  663.         return ((int[][])fieldColumns[column])[row];
  664.     }
  665.  
  666.     /** Sets the identifier array at <b>row</b>, <b>column</b>.
  667.       */
  668.     public void setIdentifierArrayAt(int row, int column, int value[]) {
  669.         if (row >= rowCount)
  670.             throw new ArrayIndexOutOfBoundsException(row);
  671.  
  672.         ((int[][])fieldColumns[column])[row] = value;
  673.     }
  674.  
  675.     /** Writes the ClassTable's class information to <b>outputStream</b>.
  676.       */
  677.     public void writeInfo(OutputStream outputStream) throws IOException {
  678.         int i, count;
  679.         CompactOutputStream out;
  680.  
  681.         if (outputStream instanceof CompactOutputStream)
  682.             out = (CompactOutputStream)outputStream;
  683.         else
  684.             out = new CompactOutputStream(outputStream);
  685.  
  686.         out.writeCompactUTF(className);
  687.  
  688.         count = fieldCount;
  689.         out.writeCompactInt(count);
  690.  
  691.         for (i = 0; i < count; i++) {
  692.             out.writeCompactUTF(fieldNames[i]);
  693.             out.writeByte(fieldTypes[i]);
  694.         }
  695.  
  696.         count = classCount;
  697.         out.writeCompactInt(count);
  698.  
  699.         for (i = 0; i < count; i++) {
  700.             out.writeCompactUTF(classNames[i]);
  701.             out.writeCompactInt(classVersions[i]);
  702.         }
  703.  
  704.         // Leave room for expansion.
  705.  
  706.         out.writeCompactInt(0);
  707.     }
  708.  
  709.     /** Writes the ClassTable's instance data to <b>outputStream</b>.
  710.       */
  711.     public void writeData(OutputStream outputStream) throws IOException {
  712.         int i, count;
  713.         Object column;
  714.         CompactOutputStream out;
  715.  
  716.         if (outputStream instanceof CompactOutputStream)
  717.             out = (CompactOutputStream)outputStream;
  718.         else
  719.             out = new CompactOutputStream(outputStream);
  720.  
  721.         out.writeCompactInt(rowCount);
  722.  
  723.         count = fieldCount;
  724.  
  725.         // Write out all the boolean columns first so they get compacted
  726.         // better.  The boolean arrays don't matter since they do a
  727.         // writeCompactInt() which flushes the boolean buffer.
  728.  
  729.         for (i = 0; i < count; i++) {
  730.             if (fieldTypes[i] == Codable.BOOLEAN_TYPE)
  731.                 writeBooleanColumn(out, (boolean[])fieldColumns[i], rowCount);
  732.         }
  733.  
  734.         // Write out the rest of the columns.
  735.  
  736.         for (i = 0; i < count; i++) {
  737.             column = fieldColumns[i];
  738.  
  739.             switch (fieldTypes[i]) {
  740.                 case Codable.BOOLEAN_TYPE:
  741.                     break;
  742.                 case Codable.BOOLEAN_ARRAY_TYPE:
  743.                     writeBooleanArrayColumn(out,(boolean[][])column, rowCount);
  744.                     break;
  745.                 case Codable.CHAR_TYPE:
  746.                     writeCharColumn(out, (char[])column, rowCount);
  747.                     break;
  748.                 case Codable.CHAR_ARRAY_TYPE:
  749.                     writeCharArrayColumn(out, (char[][])column, rowCount);
  750.                     break;
  751.                 case Codable.BYTE_TYPE:
  752.                     writeByteColumn(out, (byte[])column, rowCount);
  753.                     break;
  754.                 case Codable.BYTE_ARRAY_TYPE:
  755.                     writeByteArrayColumn(out, (byte[][])column, rowCount);
  756.                     break;
  757.                 case Codable.SHORT_TYPE:
  758.                     writeShortColumn(out, (short[])column, rowCount);
  759.                     break;
  760.                 case Codable.SHORT_ARRAY_TYPE:
  761.                     writeShortArrayColumn(out, (short[][])column, rowCount);
  762.                     break;
  763.                 case Codable.INT_TYPE:
  764.                     writeIntColumn(out, (int[])column, rowCount);
  765.                     break;
  766.                 case Codable.INT_ARRAY_TYPE:
  767.                     writeIntArrayColumn(out, (int[][])column, rowCount);
  768.                     break;
  769.                 case Codable.LONG_TYPE:
  770.                     writeLongColumn(out, (long[])column, rowCount);
  771.                     break;
  772.                 case Codable.LONG_ARRAY_TYPE:
  773.                     writeLongArrayColumn(out, (long[][])column, rowCount);
  774.                     break;
  775.                 case Codable.FLOAT_TYPE:
  776.                     writeFloatColumn(out, (float[])column, rowCount);
  777.                     break;
  778.                 case Codable.FLOAT_ARRAY_TYPE:
  779.                     writeFloatArrayColumn(out, (float[][])column, rowCount);
  780.                     break;
  781.                 case Codable.DOUBLE_TYPE:
  782.                     writeDoubleColumn(out, (double[])column, rowCount);
  783.                     break;
  784.                 case Codable.DOUBLE_ARRAY_TYPE:
  785.                     writeDoubleArrayColumn(out, (double[][])column, rowCount);
  786.                     break;
  787.                 case Codable.STRING_TYPE:
  788.                     writeStringColumn(out, (String[])column, rowCount);
  789.                     break;
  790.                 case Codable.STRING_ARRAY_TYPE:
  791.                     writeStringArrayColumn(out, (String[][])column, rowCount);
  792.                     break;
  793.                 case Codable.OBJECT_TYPE:
  794.                     writeIntColumn(out, (int[])column, rowCount);
  795.                     break;
  796.                 case Codable.OBJECT_ARRAY_TYPE:
  797.                     writeIntArrayColumn(out, (int[][])column, rowCount);
  798.                     break;
  799.                 default:
  800.                     throw new InconsistencyException("Unknown field type: " +
  801.                         fieldTypes[i]);
  802.             }
  803.         }
  804.  
  805.         // Leave room for expansion.
  806.  
  807.         out.writeCompactInt(0);
  808.     }
  809.  
  810.     private void writeBooleanColumn(CompactOutputStream out,
  811.         boolean column[], int count) throws IOException {
  812.         int i;
  813.  
  814.         for (i = 0; i < count; i++) {
  815.             out.writeCompactBoolean(column[i]);
  816.         }
  817.     }
  818.  
  819.     private void writeBooleanArrayColumn(CompactOutputStream out,
  820.         boolean column[][], int count) throws IOException {
  821.         int i;
  822.         boolean array[];
  823.  
  824.         for (i = 0; i < count; i++) {
  825.             array = column[i];
  826.             if (array == null)
  827.                 out.writeCompactInt(-1);
  828.             else {
  829.                 out.writeCompactInt(array.length);
  830.                 writeBooleanColumn(out, array, array.length);
  831.             }
  832.         }
  833.     }
  834.  
  835.     private void writeCharColumn(CompactOutputStream out,
  836.         char column[], int count) throws IOException {
  837.         int i;
  838.  
  839.         for (i = 0; i < count; i++) {
  840.             out.writeChar(column[i]);
  841.         }
  842.     }
  843.  
  844.     private void writeCharArrayColumn(CompactOutputStream out,
  845.         char column[][], int count) throws IOException {
  846.         int i;
  847.         char array[];
  848.  
  849.         for (i = 0; i < count; i++) {
  850.             array = column[i];
  851.             if (array == null)
  852.                 out.writeCompactInt(-1);
  853.             else {
  854.                 out.writeCompactInt(array.length);
  855.                 writeCharColumn(out, array, array.length);
  856.             }
  857.         }
  858.     }
  859.  
  860.     private void writeByteColumn(CompactOutputStream out,
  861.         byte column[], int count) throws IOException {
  862.         out.write(column, 0, count);
  863.     }
  864.  
  865.     private void writeByteArrayColumn(CompactOutputStream out,
  866.         byte column[][], int count) throws IOException {
  867.         int i;
  868.         byte array[];
  869.  
  870.         for (i = 0; i < count; i++) {
  871.             array = column[i];
  872.             if (array == null)
  873.                 out.writeCompactInt(-1);
  874.             else {
  875.                 out.writeCompactInt(array.length);
  876.                 writeByteColumn(out, array, array.length);
  877.             }
  878.         }
  879.     }
  880.  
  881.     private void writeShortColumn(CompactOutputStream out,
  882.         short column[], int count) throws IOException {
  883.         int i;
  884.  
  885.         for (i = 0; i < count; i++) {
  886.             out.writeShort(column[i]);
  887.         }
  888.     }
  889.  
  890.     private void writeShortArrayColumn(CompactOutputStream out,
  891.         short column[][], int count) throws IOException {
  892.         int i;
  893.         short array[];
  894.  
  895.         for (i = 0; i < count; i++) {
  896.             array = column[i];
  897.             if (array == null)
  898.                 out.writeCompactInt(-1);
  899.             else {
  900.                 out.writeCompactInt(array.length);
  901.                 writeShortColumn(out, array, array.length);
  902.             }
  903.         }
  904.     }
  905.  
  906.     private void writeIntColumn(CompactOutputStream out,
  907.         int column[], int count) throws IOException {
  908.         int i;
  909.  
  910.         for (i = 0; i < count; i++) {
  911.             out.writeCompactInt(column[i]);
  912.         }
  913.     }
  914.  
  915.     private void writeIntArrayColumn(CompactOutputStream out,
  916.         int column[][], int count) throws IOException {
  917.         int i, j, length;
  918.         int array[];
  919.  
  920.         for (i = 0; i < count; i++) {
  921.             array = column[i];
  922.             if (array == null)
  923.                 out.writeCompactInt(-1);
  924.             else {
  925.                 length = array.length;
  926.                 out.writeCompactInt(length);
  927.  
  928.                 // Arrays of ints often contain big values (like pixel values)
  929.                 // so we don't write them out in compact form since they would
  930.                 // get slightly bigger.  ALERT!
  931.  
  932.                 for (j = 0; j < length; j++) {
  933.                     out.writeInt(array[j]);
  934.                 }
  935.             }
  936.         }
  937.     }
  938.  
  939.     private void writeLongColumn(CompactOutputStream out,
  940.         long column[], int count) throws IOException {
  941.         int i;
  942.  
  943.         for (i = 0; i < count; i++) {
  944.             out.writeLong(column[i]);
  945.         }
  946.     }
  947.  
  948.     private void writeLongArrayColumn(CompactOutputStream out,
  949.         long column[][], int count) throws IOException {
  950.         int i;
  951.         long array[];
  952.  
  953.         for (i = 0; i < count; i++) {
  954.             array = column[i];
  955.             if (array == null)
  956.                 out.writeCompactInt(-1);
  957.             else {
  958.                 out.writeCompactInt(array.length);
  959.                 writeLongColumn(out, array, array.length);
  960.             }
  961.         }
  962.     }
  963.  
  964.     private void writeFloatColumn(CompactOutputStream out,
  965.         float column[], int count) throws IOException {
  966.         int i;
  967.  
  968.         for (i = 0; i < count; i++) {
  969.             out.writeFloat(column[i]);
  970.         }
  971.     }
  972.  
  973.     private void writeFloatArrayColumn(CompactOutputStream out,
  974.         float column[][], int count) throws IOException {
  975.         int i;
  976.         float array[];
  977.  
  978.         for (i = 0; i < count; i++) {
  979.             array = column[i];
  980.             if (array == null)
  981.                 out.writeCompactInt(-1);
  982.             else {
  983.                 out.writeCompactInt(array.length);
  984.                 writeFloatColumn(out, array, array.length);
  985.             }
  986.         }
  987.     }
  988.  
  989.     private void writeDoubleColumn(CompactOutputStream out,
  990.         double column[], int count) throws IOException {
  991.         int i;
  992.  
  993.         for (i = 0; i < count; i++) {
  994.             out.writeDouble(column[i]);
  995.         }
  996.     }
  997.  
  998.     private void writeDoubleArrayColumn(CompactOutputStream out,
  999.         double column[][], int count) throws IOException {
  1000.         int i;
  1001.         double array[];
  1002.  
  1003.         for (i = 0; i < count; i++) {
  1004.             array = column[i];
  1005.             if (array == null)
  1006.                 out.writeCompactInt(-1);
  1007.             else {
  1008.                 out.writeCompactInt(array.length);
  1009.                 writeDoubleColumn(out, array, array.length);
  1010.             }
  1011.         }
  1012.     }
  1013.  
  1014.     private void writeStringColumn(CompactOutputStream out,
  1015.         String column[], int count) throws IOException {
  1016.         int i;
  1017.  
  1018.         for (i = 0; i < count; i++) {
  1019.             out.writeCompactUTF(column[i]);
  1020.         }
  1021.     }
  1022.  
  1023.     private void writeStringArrayColumn(CompactOutputStream out,
  1024.         String column[][], int count) throws IOException {
  1025.         int i;
  1026.         String array[];
  1027.  
  1028.         for (i = 0; i < count; i++) {
  1029.             array = column[i];
  1030.             if (array == null)
  1031.                 out.writeCompactInt(-1);
  1032.             else {
  1033.                 out.writeCompactInt(array.length);
  1034.                 writeStringColumn(out, array, array.length);
  1035.             }
  1036.         }
  1037.     }
  1038.  
  1039.     /** Reads class information from <b>inputStream</b>.
  1040.       */
  1041.     public void readInfo(InputStream inputStream) throws IOException {
  1042.         int i, count;
  1043.         CompactInputStream in;
  1044.  
  1045.         if (inputStream instanceof CompactInputStream)
  1046.             in = (CompactInputStream)inputStream;
  1047.         else
  1048.             in = new CompactInputStream(inputStream);
  1049.  
  1050.         className = in.readCompactUTF();
  1051.  
  1052.         count = in.readCompactInt();
  1053.         fieldCount = count;
  1054.  
  1055.         fieldNames = new String[count];
  1056.         fieldTypes = new byte[count];
  1057.         fieldColumns = new Object[count];
  1058.  
  1059.         for (i = 0; i < count; i++) {
  1060.             fieldNames[i] = in.readCompactUTF();
  1061.             fieldTypes[i] = in.readByte();
  1062.         }
  1063.  
  1064.         count = in.readCompactInt();
  1065.         classCount = count;
  1066.  
  1067.         classNames = new String[count];
  1068.         classVersions = new int[count];
  1069.  
  1070.         for (i = 0; i < count; i++) {
  1071.             classNames[i] = in.readCompactUTF();
  1072.             classVersions[i] = in.readCompactInt();
  1073.         }
  1074.  
  1075.         // Leave room for expansion.
  1076.  
  1077.         count = in.readCompactInt();
  1078.         if (count > 0)
  1079.             in.skipBytes(count);
  1080.     }
  1081.  
  1082.     /** Reads instance data from <b>input</b>.
  1083.       */
  1084.     public void readData(InputStream inputStream) throws IOException {
  1085.         int i, count;
  1086.         Object column;
  1087.         CompactInputStream in;
  1088.  
  1089.         if (inputStream instanceof CompactInputStream)
  1090.             in = (CompactInputStream)inputStream;
  1091.         else
  1092.             in = new CompactInputStream(inputStream);
  1093.  
  1094.         rowCount = in.readCompactInt();
  1095.         ensureCapacity(rowCount);
  1096.  
  1097.         count = fieldCount;
  1098.  
  1099.         // Read in all the boolean columns first.
  1100.  
  1101.         for (i = 0; i < count; i++) {
  1102.             if (fieldTypes[i] == Codable.BOOLEAN_TYPE)
  1103.                 readBooleanColumn(in, (boolean[])fieldColumns[i], rowCount);
  1104.         }
  1105.  
  1106.         // Write out the rest of the columns.
  1107.  
  1108.         for (i = 0; i < count; i++) {
  1109.             column = fieldColumns[i];
  1110.  
  1111.             switch (fieldTypes[i]) {
  1112.                 case Codable.BOOLEAN_TYPE:
  1113.                     break;
  1114.                 case Codable.BOOLEAN_ARRAY_TYPE:
  1115.                     readBooleanArrayColumn(in,(boolean[][])column, rowCount);
  1116.                     break;
  1117.                 case Codable.CHAR_TYPE:
  1118.                     readCharColumn(in, (char[])column, rowCount);
  1119.                     break;
  1120.                 case Codable.CHAR_ARRAY_TYPE:
  1121.                     readCharArrayColumn(in, (char[][])column, rowCount);
  1122.                     break;
  1123.                 case Codable.BYTE_TYPE:
  1124.                     readByteColumn(in, (byte[])column, rowCount);
  1125.                     break;
  1126.                 case Codable.BYTE_ARRAY_TYPE:
  1127.                     readByteArrayColumn(in, (byte[][])column, rowCount);
  1128.                     break;
  1129.                 case Codable.SHORT_TYPE:
  1130.                     readShortColumn(in, (short[])column, rowCount);
  1131.                     break;
  1132.                 case Codable.SHORT_ARRAY_TYPE:
  1133.                     readShortArrayColumn(in, (short[][])column, rowCount);
  1134.                     break;
  1135.                 case Codable.INT_TYPE:
  1136.                     readIntColumn(in, (int[])column, rowCount);
  1137.                     break;
  1138.                 case Codable.INT_ARRAY_TYPE:
  1139.                     readIntArrayColumn(in, (int[][])column, rowCount);
  1140.                     break;
  1141.                 case Codable.LONG_TYPE:
  1142.                     readLongColumn(in, (long[])column, rowCount);
  1143.                     break;
  1144.                 case Codable.LONG_ARRAY_TYPE:
  1145.                     readLongArrayColumn(in, (long[][])column, rowCount);
  1146.                     break;
  1147.                 case Codable.FLOAT_TYPE:
  1148.                     readFloatColumn(in, (float[])column, rowCount);
  1149.                     break;
  1150.                 case Codable.FLOAT_ARRAY_TYPE:
  1151.                     readFloatArrayColumn(in, (float[][])column, rowCount);
  1152.                     break;
  1153.                 case Codable.DOUBLE_TYPE:
  1154.                     readDoubleColumn(in, (double[])column, rowCount);
  1155.                     break;
  1156.                 case Codable.DOUBLE_ARRAY_TYPE:
  1157.                     readDoubleArrayColumn(in, (double[][])column, rowCount);
  1158.                     break;
  1159.                 case Codable.STRING_TYPE:
  1160.                     readStringColumn(in, (String[])column, rowCount);
  1161.                     break;
  1162.                 case Codable.STRING_ARRAY_TYPE:
  1163.                     readStringArrayColumn(in, (String[][])column, rowCount);
  1164.                     break;
  1165.                 case Codable.OBJECT_TYPE:
  1166.                     readIntColumn(in, (int[])column, rowCount);
  1167.                     break;
  1168.                 case Codable.OBJECT_ARRAY_TYPE:
  1169.                     readIntArrayColumn(in, (int[][])column, rowCount);
  1170.                     break;
  1171.                 default:
  1172.                     throw new InconsistencyException("Unknown field type: " +
  1173.                         fieldTypes[i]);
  1174.             }
  1175.         }
  1176.  
  1177.         // Leave room for expansion.
  1178.  
  1179.         count = in.readCompactInt();
  1180.         if (count > 0)
  1181.             in.skipBytes(count);
  1182.     }
  1183.  
  1184.     private void readBooleanColumn(CompactInputStream in,
  1185.         boolean column[], int count) throws IOException {
  1186.         int i;
  1187.  
  1188.         for (i = 0; i < count; i++) {
  1189.             column[i] = in.readCompactBoolean();
  1190.         }
  1191.     }
  1192.  
  1193.     private void readBooleanArrayColumn(CompactInputStream in,
  1194.         boolean column[][], int count) throws IOException {
  1195.         int i, length;
  1196.         boolean array[];
  1197.  
  1198.         for (i = 0; i < count; i++) {
  1199.             length = in.readCompactInt();
  1200.             if (length >= 0) {
  1201.                 array = new boolean[length];
  1202.                 column[i] = array;
  1203.                 readBooleanColumn(in, array, length);
  1204.             }
  1205.         }
  1206.     }
  1207.  
  1208.     private void readCharColumn(CompactInputStream in,
  1209.         char column[], int count) throws IOException {
  1210.         int i;
  1211.  
  1212.         for (i = 0; i < count; i++) {
  1213.             column[i] = in.readChar();
  1214.         }
  1215.     }
  1216.  
  1217.     private void readCharArrayColumn(CompactInputStream in,
  1218.         char column[][], int count) throws IOException {
  1219.         int i, length;
  1220.         char array[];
  1221.  
  1222.         for (i = 0; i < count; i++) {
  1223.             length = in.readCompactInt();
  1224.             if (length >= 0) {
  1225.                 array = new char[length];
  1226.                 column[i] = array;
  1227.                 readCharColumn(in, array, length);
  1228.             }
  1229.         }
  1230.     }
  1231.  
  1232.     private void readByteColumn(CompactInputStream in,
  1233.         byte column[], int count) throws IOException {
  1234.         in.readFully(column, 0, count);
  1235.     }
  1236.  
  1237.     private void readByteArrayColumn(CompactInputStream in,
  1238.         byte column[][], int count) throws IOException {
  1239.         int i, length;
  1240.         byte array[];
  1241.  
  1242.         for (i = 0; i < count; i++) {
  1243.             length = in.readCompactInt();
  1244.             if (length >= 0) {
  1245.                 array = new byte[length];
  1246.                 column[i] = array;
  1247.                 readByteColumn(in, array, length);
  1248.             }
  1249.         }
  1250.     }
  1251.  
  1252.     private void readShortColumn(CompactInputStream in,
  1253.         short column[], int count) throws IOException {
  1254.         int i;
  1255.  
  1256.         for (i = 0; i < count; i++) {
  1257.             column[i] = in.readShort();
  1258.         }
  1259.     }
  1260.  
  1261.     private void readShortArrayColumn(CompactInputStream in,
  1262.         short column[][], int count) throws IOException {
  1263.         int i, length;
  1264.         short array[];
  1265.  
  1266.         for (i = 0; i < count; i++) {
  1267.             length = in.readCompactInt();
  1268.             if (length >= 0) {
  1269.                 array = new short[length];
  1270.                 column[i] = array;
  1271.                 readShortColumn(in, array, length);
  1272.             }
  1273.         }
  1274.     }
  1275.  
  1276.     private void readIntColumn(CompactInputStream in,
  1277.         int column[], int count) throws IOException {
  1278.         int i;
  1279.  
  1280.         for (i = 0; i < count; i++) {
  1281.             column[i] = in.readCompactInt();
  1282.         }
  1283.     }
  1284.  
  1285.     private void readIntArrayColumn(CompactInputStream in,
  1286.         int column[][], int count) throws IOException {
  1287.         int i, j, length;
  1288.         int array[];
  1289.  
  1290.         for (i = 0; i < count; i++) {
  1291.             length = in.readCompactInt();
  1292.             if (length >= 0) {
  1293.  
  1294.                 // Arrays of ints often contain big values (like pixel values)
  1295.                 // so we don't write them out in compact form since they would
  1296.                 // get slightly bigger.  ALERT!
  1297.  
  1298.                 array = new int[length];
  1299.                 column[i] = array;
  1300.                 for (j = 0; j < length; j++) {
  1301.                     array[j] = in.readInt();
  1302.                 }
  1303.             }
  1304.         }
  1305.     }
  1306.  
  1307.     private void readLongColumn(CompactInputStream in,
  1308.         long column[], int count) throws IOException {
  1309.         int i;
  1310.  
  1311.         for (i = 0; i < count; i++) {
  1312.             column[i] = in.readLong();
  1313.         }
  1314.     }
  1315.  
  1316.     private void readLongArrayColumn(CompactInputStream in,
  1317.         long column[][], int count) throws IOException {
  1318.         int i, length;
  1319.         long array[];
  1320.  
  1321.         for (i = 0; i < count; i++) {
  1322.             length = in.readCompactInt();
  1323.             if (length >= 0) {
  1324.                 array = new long[length];
  1325.                 column[i] = array;
  1326.                 readLongColumn(in, array, length);
  1327.             }
  1328.         }
  1329.     }
  1330.  
  1331.     private void readFloatColumn(CompactInputStream in,
  1332.         float column[], int count) throws IOException {
  1333.         int i;
  1334.  
  1335.         for (i = 0; i < count; i++) {
  1336.             column[i] = in.readFloat();
  1337.         }
  1338.     }
  1339.  
  1340.     private void readFloatArrayColumn(CompactInputStream in,
  1341.         float column[][], int count) throws IOException {
  1342.         int i, length;
  1343.         float array[];
  1344.  
  1345.         for (i = 0; i < count; i++) {
  1346.             length = in.readCompactInt();
  1347.             if (length >= 0) {
  1348.                 array = new float[length];
  1349.                 column[i] = array;
  1350.                 readFloatColumn(in, array, length);
  1351.             }
  1352.         }
  1353.     }
  1354.  
  1355.     private void readDoubleColumn(CompactInputStream in,
  1356.         double column[], int count) throws IOException {
  1357.         int i;
  1358.  
  1359.         for (i = 0; i < count; i++) {
  1360.             column[i] = in.readDouble();
  1361.         }
  1362.     }
  1363.  
  1364.     private void readDoubleArrayColumn(CompactInputStream in,
  1365.         double column[][], int count) throws IOException {
  1366.         int i, length;
  1367.         double array[];
  1368.  
  1369.         for (i = 0; i < count; i++) {
  1370.             length = in.readCompactInt();
  1371.             if (length >= 0) {
  1372.                 array = new double[length];
  1373.                 column[i] = array;
  1374.                 readDoubleColumn(in, array, length);
  1375.             }
  1376.         }
  1377.     }
  1378.  
  1379.     private void readStringColumn(CompactInputStream in,
  1380.         String column[], int count) throws IOException {
  1381.         int i;
  1382.  
  1383.         for (i = 0; i < count; i++) {
  1384.             column[i] = in.readCompactUTF();
  1385.         }
  1386.     }
  1387.  
  1388.     private void readStringArrayColumn(CompactInputStream in,
  1389.         String column[][], int count) throws IOException {
  1390.         int i, length;
  1391.         String array[];
  1392.  
  1393.         for (i = 0; i < count; i++) {
  1394.             length = in.readCompactInt();
  1395.             if (length >= 0) {
  1396.                 array = new String[length];
  1397.                 column[i] = array;
  1398.                 readStringColumn(in, array, length);
  1399.             }
  1400.         }
  1401.     }
  1402. }
  1403.