From 30da09694b77a86b0790f9480cf934120c5258d3 Mon Sep 17 00:00:00 2001 From: "Aaron M. Renn" Date: Mon, 7 Apr 2003 12:25:08 +0000 Subject: 2003-04-07 Aaron M. Renn (arenn@urbanophile.com) * java/io/ObjectStreamException * java/io/FileFilter * java/io/FilenameFilter * java/io/ObjectInput * java/io/ObjectOutput * java/io/ObjectStreamConstants Minor doc fixes, format fixes, spelling corrections, etc. * java/io/DataInput Corrected code samples in Javadocs to match reality * java/io/DataOutput * java/io/ObjectInputValidation Major documentation fixes - all Javadocs re-written or updated From-SVN: r65329 --- libjava/java/io/DataInput.java | 63 ++++++----- libjava/java/io/DataOutput.java | 175 +++++++++++++++++++++++++---- libjava/java/io/FileFilter.java | 6 +- libjava/java/io/FilenameFilter.java | 9 +- libjava/java/io/ObjectInput.java | 19 ++-- libjava/java/io/ObjectInputValidation.java | 19 +++- libjava/java/io/ObjectOutput.java | 3 +- libjava/java/io/ObjectStreamConstants.java | 16 +-- libjava/java/io/ObjectStreamException.java | 4 +- 9 files changed, 241 insertions(+), 73 deletions(-) (limited to 'libjava/java/io') diff --git a/libjava/java/io/DataInput.java b/libjava/java/io/DataInput.java index bf7c478..95f5a3c 100644 --- a/libjava/java/io/DataInput.java +++ b/libjava/java/io/DataInput.java @@ -84,7 +84,7 @@ public interface DataInput * @exception EOFException If end of file is reached before reading the byte * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeBoolean */ byte readByte() throws EOFException, IOException; @@ -94,7 +94,7 @@ public interface DataInput *

* This method can read an unsigned byte written by an object * implementing the - * writeUnsignedByte() method in the DataOutput + * writeByte() method in the DataOutput * interface. * * @return The unsigned bytes value read as a Java int. @@ -102,7 +102,7 @@ public interface DataInput * @exception EOFException If end of file is reached before reading the value * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeByte */ int readUnsignedByte() throws EOFException, IOException; @@ -128,7 +128,7 @@ public interface DataInput * @exception EOFException If end of file is reached before reading the char * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeChar */ char readChar() throws EOFException, IOException; @@ -143,7 +143,7 @@ public interface DataInput * first and second byte read from the stream respectively, they will be * transformed to a short in the following manner: *

- * (short)((byte1 << 8) + byte2) + * (short)((byte1 << 8) + (byte2 & 0xFF)) *

* The value returned is in the range of -32768 to 32767. *

@@ -157,7 +157,7 @@ public interface DataInput * @exception EOFException If end of file is reached before reading the value * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeShort */ short readShort() throws EOFException, IOException; @@ -172,12 +172,12 @@ public interface DataInput * first and second byte read from the stream respectively, they will be * transformed to an int in the following manner: *

- * (int)((byte1 << 8) + byte2) + * (int)(((byte1 0xFF) << 8) + (byte2 & 0xFF)) *

* The value returned is in the range of 0 to 65535. *

* This method can read an unsigned short written by an object implementing - * the writeUnsignedShort() method in the + * the writeShort() method in the * DataOutput * interface. * @@ -186,6 +186,8 @@ public interface DataInput * @exception EOFException If end of file is reached before reading * the value * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort */ int readUnsignedShort() throws EOFException, IOException; @@ -200,7 +202,8 @@ public interface DataInput * the first four bytes read from the stream, they will be * transformed to an int in the following manner: *

- * (int)((byte1 << 24) + (byte2 << 16) + (byte3 << 8) + byte4)) + * (int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF))) *

* The value returned is in the range of -2147483648 to 2147483647. *

@@ -213,7 +216,7 @@ public interface DataInput * @exception EOFException If end of file is reached before reading the int * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeInt */ int readInt() throws EOFException, IOException; @@ -228,8 +231,10 @@ public interface DataInput * the first eight bytes read from the stream, they will be * transformed to an long in the following manner: *

- * (long)((byte1 << 56) + (byte2 << 48) + (byte3 << 40) + - * (byte4 << 32) + (byte5 << 24) + (byte6 << 16) + (byte7 << 8) + byte9)) + * (long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + + * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + + * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + + * ((byte7 & 0xFF) << 8) + (byte9 & 0xFF))) * *

* The value returned is in the range of -9223372036854775808 to @@ -244,7 +249,7 @@ public interface DataInput * @exception EOFException If end of file is reached before reading the long * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeLong */ long readLong() throws EOFException, IOException; @@ -267,8 +272,8 @@ public interface DataInput * float * @exception IOException If any other error occurs * - * @see java.lang.Float - * @see DataOutput + * @see DataOutput#writeFloat + * @see java.lang.Float#intBitsToFloat */ float readFloat() throws EOFException, IOException; @@ -290,8 +295,8 @@ public interface DataInput * double * @exception IOException If any other error occurs * - * @see java.lang.Double - * @see DataOutput + * @see DataOutput#writeDouble + * @see java.lang.Double#longBitsToDouble */ double readDouble() throws EOFException, IOException; @@ -309,6 +314,7 @@ public interface DataInput * A line terminator is a byte sequence consisting of either * \r, \n or \r\n. These termination * charaters are discarded and are not returned as part of the string. + * A line is also terminated by an end of file condition. *

* This method can read data that was written by an object implementing the * writeLine() method in DataOutput. @@ -317,7 +323,7 @@ public interface DataInput * * @exception IOException If an error occurs * - * @see DataOutput + * @see DataOutput#writeLine */ String readLine() throws IOException; @@ -390,7 +396,7 @@ public interface DataInput * @exception UTFDataFormatException If the data is not in UTF-8 format * @exception IOException If any other error occurs * - * @see DataOutput + * @see DataOutput#writeUTF */ String readUTF() throws EOFException, UTFDataFormatException, IOException; @@ -398,7 +404,9 @@ public interface DataInput * This method reads raw bytes into the passed array until the array is * full. Note that this method blocks until the data is available and * throws an exception if there is not enough data left in the stream to - * fill the buffer + * fill the buffer. Note also that zero length buffers are permitted. + * In this case, the method will return immediately without reading any + * bytes from the stream. * * @param buf The buffer into which to read the data * @@ -414,8 +422,10 @@ public interface DataInput * offset bytes into the buffer. The number of bytes read * will be * exactly len. Note that this method blocks until the data is - * available and * throws an exception if there is not enough data left in - * the stream to read len bytes. + * available and throws an exception if there is not enough data left in + * the stream to read len bytes. Note also that zero length + * buffers are permitted. In this case, the method will return immediately + * without reading any bytes from the stream. * * @param buf The buffer into which to read the data * @param offset The offset into the buffer to start storing data @@ -430,17 +440,18 @@ public interface DataInput /** * This method skips and discards the specified number of bytes in an - * input stream + * input stream. Note that this method may skip less than the requested + * number of bytes. The actual number of bytes skipped is returned. * - * @param num_bytes The number of bytes to skip + * @param numBytes The number of bytes to skip * * @return The number of bytes actually skipped, which will always be - * num_bytes + * numBytes * * @exception EOFException If end of file is reached before all bytes can be * skipped * @exception IOException If any other error occurs */ - int skipBytes(int n) throws EOFException, IOException; + int skipBytes(int numBytes) throws EOFException, IOException; } // interface DataInput diff --git a/libjava/java/io/DataOutput.java b/libjava/java/io/DataOutput.java index 5c626f5e..462889d 100644 --- a/libjava/java/io/DataOutput.java +++ b/libjava/java/io/DataOutput.java @@ -1,5 +1,5 @@ /* DataOutput.java -- Interface for writing data from a stream - Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -45,119 +45,254 @@ package java.io; /** * This interface is implemented by classes that can wrte data to streams - * from Java primitive types. + * from Java primitive types. This data can subsequently be read back + * by classes implementing the DataInput interface. * * @author Aaron M. Renn (arenn@urbanophile.com) * @author Tom Tromey + * + * @see DataInput */ public interface DataOutput { - /** - * This method writes a Java boolean value to an output stream + * This method writes a Java boolean value to an output stream. If + * value is true, a byte with the value of + * 1 will be written, otherwise a byte with the value of 0 will be + * written. + * + * The value written can be read using the readBoolean + * method in DataInput. * * @param value The boolean value to write * * @exception IOException If an error occurs + * + * @see DataInput#readBoolean */ void writeBoolean(boolean value) throws IOException; /** - * This method writes a Java byte value to an output stream + * This method writes a Java byte value to an output stream. The + * byte to be written will be in the lowest 8 bits of the + * int value passed. + * + * The value written can be read using the readByte or + * readUnsignedByte methods in DataInput. * * @param value The int value to write * * @exception IOException If an error occurs + * + * @see DataInput#readByte + * @see DataInput#readUnsignedByte */ void writeByte(int value) throws IOException; /** - * This method writes a Java char value to an output stream + * This method writes a Java char value to an output stream. The + * char to be written will be in the lowest 16 bits of the int + * value passed. These bytes will be written "big endian". That is, + * with the high byte written first in the following manner: + *

+ * byte0 = (byte)((value & 0xFF00) >> 8);
+ * byte1 = (byte)(value & 0x00FF);
+ *

+ * + * The value written can be read using the readChar + * method in DataInput. * * @param value The char value to write * * @exception IOException If an error occurs + * + * @see DataInput#readChar */ void writeChar(int value) throws IOException; /** - * This method writes a Java int value to an output stream as a 16 bit value + * This method writes a Java char value to an output stream. The + * char to be written will be in the lowest 16 bits of the int + * value passed. These bytes will be written "big endian". That is, + * with the high byte written first in the following manner: + *

+ * byte0 = (byte)((value & 0xFF00) >> 8);
+ * byte1 = (byte)(value & 0x00FF);
+ *

+ * + * The value written can be read using the readShort and + * readUnsignedShort methods in DataInput. * * @param value The int value to write as a 16-bit value * * @exception IOException If an error occurs + * + * @see DataInput#readShort + * @see DataInput#readUnsignedShort */ void writeShort(int value) throws IOException; /** - * This method writes a Java int value to an output stream + * This method writes a Java int value to an output stream. The 4 bytes + * of the passed value will be written "big endian". That is, with + * the high byte written first in the following manner: + *

+ * byte0 = (byte)((value & 0xFF000000) >> 24);
+ * byte1 = (byte)((value & 0x00FF0000) >> 16);
+ * byte2 = (byte)((value & 0x0000FF00) >> 8);
+ * byte3 = (byte)(value & 0x000000FF);
+ *

+ * + * The value written can be read using the readInt + * method in DataInput. * * @param value The int value to write * * @exception IOException If an error occurs + * + * @see DataInput#readInt */ void writeInt(int value) throws IOException; /** - * This method writes a Java long value to an output stream + * This method writes a Java long value to an output stream. The 8 bytes + * of the passed value will be written "big endian". That is, with + * the high byte written first in the following manner: + *

+ * byte0 = (byte)((value & 0xFF00000000000000L) >> 56);
+ * byte1 = (byte)((value & 0x00FF000000000000L) >> 48);
+ * byte2 = (byte)((value & 0x0000FF0000000000L) >> 40);
+ * byte3 = (byte)((value & 0x000000FF00000000L) >> 32);
+ * byte4 = (byte)((value & 0x00000000FF000000L) >> 24);
+ * byte5 = (byte)((value & 0x0000000000FF0000L) >> 16);
+ * byte6 = (byte)((value & 0x000000000000FF00L) >> 8);
+ * byte7 = (byte)(value & 0x00000000000000FFL);
+ *

+ * + * The value written can be read using the readLong + * method in DataInput. * * @param value The long value to write * * @exception IOException If an error occurs + * + * @see DataInput#readLong */ void writeLong(long value) throws IOException; /** - * This method writes a Java float value to an output stream + * This method writes a Java float value to the stream. This + * value is written by first calling the method + * Float.floatToIntBits + * to retrieve an int representing the floating point number, + * then writing this int value to the stream exactly the same + * as the writeInt() method does. + * + * The value written can be read using the readFloat + * method in DataInput. * * @param value The float value to write * * @exception IOException If an error occurs + * + * @see writeInt + * @see DataInput#readFloat + * @see Float#floatToIntBits */ void writeFloat(float value) throws IOException; /** - * This method writes a Java double value to an output stream + * This method writes a Java double value to the stream. This + * value is written by first calling the method + * Double.doubleToLongBits + * to retrieve an long representing the floating point number, + * then writing this long value to the stream exactly the same + * as the writeLong() method does. + * + * The value written can be read using the readDouble + * method in DataInput. * * @param value The double value to write * * @exception IOException If any other error occurs + * + * @see writeLong + * @see DataInput#readDouble + * @see Double#doubleToLongBits */ void writeDouble(double value) throws IOException; /** - * This method writes a String to an output stream as an array of bytes + * This method writes all the bytes in a String out to the + * stream. One byte is written for each character in the + * String. + * The high eight bits of each character are discarded, thus this + * method is inappropriate for completely representing Unicode characters. * - * @param value The String to write + * @param value The String to write * * @exception IOException If an error occurs */ void writeBytes(String value) throws IOException; /** - * This method writes a String to an output stream as an array of char's + * This method writes all the bytes of a String to an + * output stream as an array of char's. Each character + * is written using the method specified in the writeChar + * method. * * @param value The String to write * * @exception IOException If an error occurs + * + * @see writeChar */ void writeChars(String value) throws IOException; /** - * This method writes a String to an output stream encoded in - * UTF-8 format. + * This method writes a Java String to the stream in a modified + * UTF-8 format. First, two bytes are written to the stream indicating the + * number of bytes to follow. This is written in the form of a Java + * short value in the same manner used by the + * writeShort method. Note that this is the number of + * bytes in the + * encoded String not the String length. Next + * come the encoded characters. Each character in the String + * is encoded as either one, two or three bytes. For characters in the + * range of \u0001 to \u007F, one byte is used. + * The character + * value goes into bits 0-7 and bit eight is 0. For characters in the range + * of \u0080 to \u007FF, two bytes are used. Bits + * 6-10 of the character value are encoded bits 0-4 of the first byte, with + * the high bytes having a value of "110". Bits 0-5 of the character value + * are stored in bits 0-5 of the second byte, with the high bits set to + * "10". This type of encoding is also done for the null character + * \u0000. This eliminates any C style NUL character values + * in the output. All remaining characters are stored as three bytes. + * Bits 12-15 of the character value are stored in bits 0-3 of the first + * byte. The high bits of the first bytes are set to "1110". Bits 6-11 + * of the character value are stored in bits 0-5 of the second byte. The + * high bits of the second byte are set to "10". And bits 0-5 of the + * character value are stored in bits 0-5 of byte three, with the high bits + * of that byte set to "10". * - * @param value The String to write + * The value written can be read using the readUTF + * method in DataInput. + * + * @param value The String to write * * @exception IOException If an error occurs + * + * @see DataInput#readUTF */ void writeUTF(String value) throws IOException; /** * This method writes an 8-bit value (passed into the method as a Java - * int) to an output stream. + * int) to an output stream. The low 8 bits of the + * passed value are written. * - * @param value The byte to write to the output stream + * @param value The byte to write to the output stream * * @exception IOException If an error occurs */ @@ -176,7 +311,7 @@ public interface DataOutput * This method writes raw bytes from the passed array buf * starting * offset bytes into the buffer. The number of bytes - * written will be * exactly len. + * written will be exactly len. * * @param buf The buffer from which to write the data * @param offset The offset into the buffer to start writing data from diff --git a/libjava/java/io/FileFilter.java b/libjava/java/io/FileFilter.java index 68950d3..de6feb1 100644 --- a/libjava/java/io/FileFilter.java +++ b/libjava/java/io/FileFilter.java @@ -1,5 +1,5 @@ /* FileFilter.java -- Filter a list of pathnames - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998,2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,12 +41,14 @@ package java.io; /** * This interface has one method which is used for filtering pathnames * returned in a pathname listing. It is currently used by the - * File.listFiles() method. + * File.listFiles(FileFilter) method. *

* The method in this interface determines if a particular pathname should * or should not be included in the pathname listing. * * @author Aaron M. Renn (arenn@urbanophile.com) + * + * @see File#listFiles(java.io.FileFilter) */ public interface FileFilter { diff --git a/libjava/java/io/FilenameFilter.java b/libjava/java/io/FilenameFilter.java index 9e95b1e..e3b004d 100644 --- a/libjava/java/io/FilenameFilter.java +++ b/libjava/java/io/FilenameFilter.java @@ -1,5 +1,5 @@ /* FilenameFilter.java -- Filter a list of filenames - Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -46,17 +46,20 @@ package java.io; /** * This interface has one method which is used for filtering filenames * returned in a directory listing. It is currently used by the - * File.list() method and by the filename dialog in AWT. + * File.list(FilenameFilter) method and by the filename + * dialog in AWT. *

* The method in this interface determines if a particular file should * or should not be included in the file listing. * * @author Aaron M. Renn (arenn@urbanophile.com) * @author Tom Tromey + * + * @see File#listFiles(java.io.FilenameFilter) + * @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter) */ public interface FilenameFilter { - /** * This method determines whether or not a given file should be included * in a directory listing. diff --git a/libjava/java/io/ObjectInput.java b/libjava/java/io/ObjectInput.java index 831203a..44cfb93 100644 --- a/libjava/java/io/ObjectInput.java +++ b/libjava/java/io/ObjectInput.java @@ -45,6 +45,8 @@ package java.io; * InputStream * * @author Aaron M. Renn (arenn@urbanophile.com) + * + * @see DataInput */ public interface ObjectInput extends DataInput { @@ -60,7 +62,8 @@ public interface ObjectInput extends DataInput /** * This method reading a byte of data from a stream. It returns that byte - * as an int. This method blocks if no data is available to be read. + * as an int. This method blocks if no data is available + * to be read. * * @return The byte of data read * @@ -76,7 +79,7 @@ public interface ObjectInput extends DataInput * * @param buf The byte array to receive the data read * - * @return The actual number fo bytes read or -1 if end of stream + * @return The actual number of bytes read or -1 if end of stream * * @exception IOException If an error occurs */ @@ -92,10 +95,10 @@ public interface ObjectInput extends DataInput * possible. * * @param buf The byte array to receive the data read - * @param offset The offset into @code{buf} to start storing data + * @param offset The offset into buf to start storing data * @param len The maximum number of bytes to read * - * @return The actual number fo bytes read or -1 if end of stream + * @return The actual number of bytes read or -1 if end of stream * * @exception IOException If an error occurs */ @@ -103,14 +106,14 @@ public interface ObjectInput extends DataInput /** * Reads an object instance and returns it. If the class for the object - * being read cannot be found, then a ClassNotFoundException will - * be thrown. + * being read cannot be found, then a ClassNotFoundException + * will be thrown. * * @return The object instance that was read * * @exception ClassNotFoundException If a class for the object cannot be * found - * @exception IOException If an error occurs + * @exception IOException If any other error occurs */ public abstract Object readObject() throws ClassNotFoundException, IOException; @@ -126,7 +129,7 @@ public interface ObjectInput extends DataInput * * @exception IOException If an error occurs */ - public abstract long skip(long num_bytes) throws IOException; + public abstract long skip(long numBytes) throws IOException; /** * This method closes the input source diff --git a/libjava/java/io/ObjectInputValidation.java b/libjava/java/io/ObjectInputValidation.java index 2259eb8..af9da5f 100644 --- a/libjava/java/io/ObjectInputValidation.java +++ b/libjava/java/io/ObjectInputValidation.java @@ -39,16 +39,27 @@ exception statement from your version. */ package java.io; /** - * What does this interface really do? + * This class allows an object to validate that it is valid after + * deserialization has run completely for it and all dependent objects. + * This allows an object to determine if it is invalid even if all + * state data was correctly deserialized from the stream. It can also + * be used to perform re-initialization type activities on an object + * after it has been completely deserialized. + * + * Since this method functions as a type of callback, it must be + * registered through ObjectInputStream.registerValidation + * in order to be invoked. This is typically done in the + * readObject method. * * @author Aaron M. Renn (arenn@urbanophile.com) + * + * @see ObjectInputStream#registerValidation */ public interface ObjectInputValidation { - /** - * This method is called to validate an object. If the object is invalid - * an exception is thrown. + * This method is called to validate an object after serialization + * is complete. If the object is invalid an exception is thrown. * * @exception InvalidObjectException If the object is invalid */ diff --git a/libjava/java/io/ObjectOutput.java b/libjava/java/io/ObjectOutput.java index f9e923b..5a02add 100644 --- a/libjava/java/io/ObjectOutput.java +++ b/libjava/java/io/ObjectOutput.java @@ -45,10 +45,11 @@ package java.io; * OutputStream like. * * @author Aaron M. Renn (arenn@urbanophile.com) + * + * @see DataOutput */ public interface ObjectOutput extends DataOutput { - /** * This method writes the specified byte to the output stream. * diff --git a/libjava/java/io/ObjectStreamConstants.java b/libjava/java/io/ObjectStreamConstants.java index 980b04d..1cddd2e 100644 --- a/libjava/java/io/ObjectStreamConstants.java +++ b/libjava/java/io/ObjectStreamConstants.java @@ -1,6 +1,6 @@ /* ObjectStreamConstants.java -- Interface containing constant values used in reading and writing serialized objects - Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,14 +40,15 @@ exception statement from your version. */ package java.io; /** - This interface contains constants that are used in object - serialization. This interface is used by ObjectOutputStream, - ObjectInputStream, ObjectStreamClass, and possibly other classes. - The values for these constants are specified in Javasoft's "Object - Serialization Specification" TODO: add reference -*/ + * This interface contains constants that are used in object + * serialization. This interface is used by ObjectOutputStream, + * ObjectInputStream, and ObjectStreamClass. + * The values for these constants are specified by the Java library + * specification. + */ public interface ObjectStreamConstants { + // FIXME: Javadoc comment these values. public final static int PROTOCOL_VERSION_1 = 1; public final static int PROTOCOL_VERSION_2 = 2; @@ -85,3 +86,4 @@ public interface ObjectStreamConstants final static SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION = new SerializablePermission("enableSubclassImplementation"); } + diff --git a/libjava/java/io/ObjectStreamException.java b/libjava/java/io/ObjectStreamException.java index ee4a341..da1ca46 100644 --- a/libjava/java/io/ObjectStreamException.java +++ b/libjava/java/io/ObjectStreamException.java @@ -1,5 +1,5 @@ /* ObjectStreamException.java -- Superclass of all serialization exceptions - Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,7 +40,7 @@ package java.io; /** * This exception is thrown when a problem occurs during serialization. - * There are more specific subclasses than give more fine grained + * There are more specific subclasses that give more fine grained * indications of the precise failure. * * @author Aaron M. Renn (arenn@urbanophile.com) -- cgit v1.1