All pastes #987713 Raw Edit

Someone

public text v1 · immutable
#987713 ·published 2008-04-16 20:28 UTC
rendered paste body

/**
 * The BxmlStreamReader interface defines forward, read-only API to parse XML data structures
 * encoded as per the OGC Binary XML specification, in a "pull" fashion.
 * <p>
 * BxmlStreamReader is designed to iterate over BXML using <code>next()</code> and
 * <code>hasNext()</code>. This interface defines a cursor like API to iterate over XML
 * structured documents encoded as per the OGC Binary XML implementation specification. The API is
 * inspired by the <i>StAX</i> XML pull API and provides for querying element and attribute
 * contents stored as primitive or arrays of primitive data types.
 * </p>
 * <p>
 * <h2>Query methods</h2>
 * Some document metadata derived from the BXML header token and the XML declaration token, as well
 * as some state control may be safely queried at any time. For instance, the following methods
 * return such information:
 * <ul>
 * <li>{@link #getCharset()} which character set the string content is encoded with
 * <li>{@link #getXmlVersion()} the xml version declared in the document's xml declaration token
 * <li>{@link #isStandalone()} whether the document is standalone as per the xml specification
 * <li>{@link #isLittleEndian()} whether the binary contents are little endian
 * <li>{@link #isNamespaceAware()} whether the reader handles namespaces
 * <li>{@link #getEventType()} which is the current parsing event
 * <li>{@link #isOpen()} whether this reader is open and this able to operate
 * </ul>
 * </p>
 * <p>
 * <h2>Data access</h2>
 * The data being parsed can be accessed using methods such as <code>next()</code>,
 * <code>nextTag()</code>, <code>getElementName()</code>, <code>getValueCount()</code> and
 * the various <code>getValue()</code> methods.
 * </p>
 * <p>
 * The {@link #next()} method causes the reader to read the next parse event.
 * </p>
 * <p>
 * The next() method returns an integer which identifies the type of event just read. The event type
 * can be determined using getEventType()
 * </p>
 * <p>
 * <b>How to get the content of an element</b>: The process of getting at the value of elements is
 * two-fold. First, the last call to {@code next()} and thus the current
 * {@link #getEventType() event type} shall returned one of {@link EventType#VALUE_BOOL VALUE_BOOL},
 * {@link EventType#VALUE_BYTE VALUE_BYTE}, {@link EventType#VALUE_INT VALUE_INT},
 * {@link EventType#VALUE_LONG VALUE_LONG}, {@link EventType#VALUE_FLOAT VALUE_FLOAT},
 * {@link EventType#VALUE_DOUBLE VALUE_DOUBLE}, {@link EventType#VALUE_STRING VALUE_STRING}. Or,
 * what is the same, {@code getEventType().isValue == true}.
 * </p>
 * <p>
 * Then, the count of elements of that kind needs to be requested through {@link #getValueCount()}.
 * With that information at hand, the client code may use the appropriate
 * {@code getValue(type[], int, int)}, or <b>a String representation</b> of the value may be asked
 * directly through {@link #getStringValue()}. By using the {@code getValue()} methods client code
 * can be under control of memory resources. It is allowed to make multiple calls to a
 * {@code getValue()} method as long as the total requested length between the multiple calls does
 * not exceed the value count returned by {@code getValueCount()}. Also, it is allowed to call
 * {@code next()} before having consumed all the values in a value array. The reader shall just skip
 * to the next token. The same applies to the {@link #nextTag()} method, which can be called at any
 * time as long as the end of document has not been reached, to advance to the next start element or
 * end element event, whatever is found first.
 * </p>
 * <p>
 * Note the BXML specification only supports arrays of primitive types.
 * </p>
 * 
 * @author Gabriel Roldan (TOPP)
 * @version $Id: BxmlStreamReader.java 465 2008-04-01 19:54:45Z groldan $
 * @since 1.0
 */
public interface BxmlStreamReader {

    /**
     * Derived property from the BXML file header, indicates whether the BXML document is marked as
     * standalone, as per the XML standalone definition.
     * 
     * @return {@code true} if the document is standalone, {@code false} otherwise
     */
    public boolean isStandalone();

    /**
     * Derived property from the BXML file header, indicates whether the BXML document standalone
     * mark is set at all.
     * 
     * @return {@code true} if the document standalone mark is explicitly set, {@code false}
     *         otherwise
     */
    public boolean standAloneIsSet();

    /**
     * Returns whether the multi-byte primitive values (doubles, longs, etc) in the document are
     * encoded in little endian or big endian byte order.
     * 
     * @return {@code true} if the document is little endian, {@code false} if its big endian.
     */
    public boolean isLittleEndian();

    /**
     * Returns whether this reader is namespace aware or not.
     * 
     * @return {@code true} if this reader handles namespaces, {@code false otherwise}
     */
    public boolean isNamespaceAware();

    /**
     * Returns a flag set in the bxml document header that indicates if the document structure and
     * contents is already validated, with the aim of easying the task of parsers.
     * 
     * @return {@code true} is the document is marked to be validated, {@code false} otherwise
     */
    public boolean isValidated();

    /**
     * Get the xml version declared on the xml declaration token, or {@code null} if none was
     * declared.
     * 
     * @return the xml version or {@code null} if not declared.
     */
    public String getXmlVersion();

    /**
     * Derived property from the BXML file header, identifies the character-set encoding that is
     * used for all of the Strings in the file.
     * 
     * @post {$return != null}
     * @return the charset used by the document
     */
    public Charset getCharset();

    /**
     * Frees any resource associated with this reader, including closing the underlying input stream
     * this reader fetches data from.
     * <p>
     * The first call to this method closes and releases resources. Subsequent calls shall take no
     * effect and return quitely. After the first call to this method any non query method (defined
     * as metadata retrieval methods in the class' javadoc) shall fail with an io exception.
     * </p>
     * 
     * @throws IOException if an I/O error occurs closing this reader or the underlying input stream
     */
    public void close() throws IOException;

    /**
     * Returns whether this stream reader and its underlying input source are open and able to
     * receive more parsing calls.
     * <p>
     * A {@code BxmlStreamReader} should be open since its creation until {@link #close()} was
     * explicitly called by client code, regardless of whether there are or not more parsing events
     * to process.
     * </p>
     * 
     * @return {@code true} if this stream is still open, {@code false} otherwise
     */
    public boolean isOpen();

    /**
     * Returns whether there are more parsing events to be processed.
     * 
     * @pre {isOpen() == true}
     * @post {$return == (getEventType() == END_DOCUMENT? false : true)}
     * @return {@code true} if there are more parsing events and {@code false} if there are no more
     *         events (i.e. the trailer token has been reached, which is the same than the current
     *         event being END_DOCUMENT).
     * @throws IOException if an I/O error occurs checking whether there are more parsing events to
     *             process
     */
    public boolean hasNext() throws IOException;

    /**
     * Advances the cursor to the next BXML token that has an {@link EventType} mapping and returns
     * the corresponding event type.
     * <p>
     * The first call to {@code next()} shall always return {@link EventType#START_DOCUMENT}.
     * </p>
     * 
     * @pre {hasNext() == true}
     * @post {$return != null}
     * @post {$return == getEventType()}
     * @return the event corresponding to the parsing event the cursor advanced to
     * @throws IOException if an I/O error occurs checking whether there are more parsing events to
     *             process
     * @see #getEventType()
     */
    public EventType next() throws IOException;

    /**
     * Advances the cursor skipping any content until the first start or end element token is found.
     * 
     * @pre {hasNext() == true}
     * @post {$return != null}
     * @post {$return == getEventType()}
     * @post {getEventType().isTag() == true}
     * @return the event type corresponding to the first START_ELEMENT or END_ELEMENT parse event
     *         found
     * @throws IOException if an I/O exception is found while reading through the contents looking
     *             for a tag token
     */
    public EventType nextTag() throws IOException;

    /**
     * Returns the event type for the current position of the BXML reader cursor.
     * <p>
     * When a {@code BxmlStreamReader} is first created, the current event type is
     * {@link EventType#NONE NONE}. It is after the first call to {@code next()} when
     * {@code getEventType()} will return {@link EventType#START_DOCUMENT START_DOCUMENT}.
     * </p>
     * 
     * @return the {@link EventType} returned by the last {@link #next()} call, or
     *         {@link EventType#NONE} if the document did not started being parssed yet.
     */
    public EventType getEventType();

    /**
     * Returns the qualified name of the current element, being at a START_ELEMENT or END_ELEMENT
     * event
     * <p>
     * If this bxml reader is {@link #isNamespaceAware() namespace aware}, the returned name
     * contains both the attribute namespace uri, as well as the local name. The prefix shall be
     * included only if its present in the element name as it is in the file being parsed, to better
     * reflect the actual file format.
     * </p>
     * <p>
     * If this bxml reader is <b>not</b> namespace aware, the namespace and prefix in the returned
     * name are the {@link XMLConstants#NULL_NS_URI null namespace URI} and
     * {@link XMLConstants#DEFAULT_NS_PREFIX default namespace prefix}, as defined in the XML 1.0
     * spec, and the {@code localName} field contains the element name as it is in the file being
     * parsed.
     * </p>
     * 
     * @pre {getEventType().isTag() == true}
     * @post {$return != null}
     * @return the name of the current element
     */
    public QName getElementName();

    /**
     * Returns the count of attributes on this {@code START_ELEMENT}
     * <p>
     * This count excludes namespace definitions <b>if</b> this parser is
     * {@link #isNamespaceAware() namespace aware}. If the parser does not handle namespaces,
     * namespace definitions are returned as normal attributes.
     * </p>
     * <p>
     * Attribute indices are zero-based.
     * </p>
     * 
     * @pre {getEventType() == START_ELEMENT}
     * @post {$return >= 0}
     * @return the number of attributes for the current start element tag or zero if there are no
     *         declared attributes.
     */
    public int getAttributeCount();

    /**
     * Returns the qualified name of the attribute at the provided {@code index}, for the current
     * {@code START_ELEMENT} event
     * <p>
     * If this bxml reader is {@link #isNamespaceAware() namespace aware}, the returned name
     * contains both the attribute namespace uri, as well as the local name. The prefix shall be
     * included only if its present in the attribute name as it is in the file being parsed, to
     * better reflect the actual file format.
     * </p>
     * <p>
     * If this bxml reader is <b>not</b> namespace aware, the namespace and prefix in the returned
     * name are the {@link XMLConstants#NULL_NS_URI null namespace URI} and
     * {@link XMLConstants#DEFAULT_NS_PREFIX default namespace prefix}, as defined in the XML 1.0
     * spec, and the {@code localName} field contains the element name as it is in the file being
     * parsed.
     * </p>
     * <p>
     * The attribute order reported by the {@code BxmlStreamReader} implementation shall be self
     * consistent between {@code getAttributeName} and {@code getAttributeValue}, though it might
     * not match the order in the bxml file being parsed.
     * </p>
     * 
     * @pre {getEventType() == START_ELEMENT}
     * @pre {index >= 0}
     * @pre {index < getAttributeCount()}
     * @post {$return != null}
     * @param index zero based index for which to return the qualified name
     * @return the name of the attribute at index {@code index}
     * @see #getAttributeCount()
     */
    public QName getAttributeName(int index);

    /**
     * Returns the coalesced value for the attribute at index {@code index}
     * <p>
     * NOTE in the binary xml file being parsed, the {@code AttributeStart} token from which an
     * attribute is parsed, may be followed by one or more value tokens. In case it is not followed
     * by any value token, the returned value for the attribute will be the empty string, not
     * {@code null}. In case it is followed by more than one value token, the returned attribute
     * value will be the concatenated string value from all the value tokens composing the attribute
     * value. The rules to transform a non string value to String are the same than for the
     * {@link #getStringValue()} method.
     * </p>
     * 
     * @pre {getEventType() == START_ELEMENT}
     * @pre {index >= 0}
     * @pre {index < getAttributeCount()}
     * @post {$return != null}
     * @param index
     * @return the coalesced String representation of the attribute value, or the empty string if
     *         the attribute has no value.
     */
    public String getAttributeValue(int index);

    /**
     * Returns the normalized attribute value of the attribute with the namespace and localName If
     * the namespaceURI is null the namespace is not checked for equality
     * 
     * @pre {getEventType() == START_ELEMENT}
     * @pre {localName != null}
     * @param namespaceURI the namespace of the attribute
     * @param localName the local name of the attribute, cannot be null
     * @return returns the value of the attribute , or {@code null} if not found
     */
    public String getAttributeValue(String namespaceURI, String localName);

    /**
     * Returns the number of elements of the given value type that are directly available when a
     * value token was found.
     * <p>
     * If the current value type refers to a StringValue, {@code getValueCount} will return always
     * {@code 1}, since the spec does not defines the array of strings as a value element.
     * Otherwise, if the current value type is of a single primitive element, returns {@code 1},
     * and if it is of an array of some primitive value type, returns the array length, which might
     * be any integer including zero.
     * </p>
     * 
     * @pre {getEventType().isValue() == true}
     * @post {$return >= 0}
     * @return {@code 1} in case {@code getEventType() == VALUE_STRING}, as there are no arrays of
     *         Strings, otherwise the number of elements of the primitive data type corresponding to
     *         the current {@code VALUE_*} event type that are stored in the document for that value
     *         token.
     * @see #getValueReadCount()
     */
    public int getValueCount();

    /**
     * Returns the number of elements of the current value event type that was already read.
     * <p>
     * This is useful to control the required value read count does not exceed the actual value
     * element count.
     * </p>
     * 
     * @pre {getEventType().isValue() == true}
     * @post {$return <= getValueCount()}
     * @return the number of elements already read for the current value event
     * @see #getValueCount()
     */
    public int getValueReadCount();

    /**
     * Returns the String representation of the current value or comment token.
     * <p>
     * When the current value token represents an array of some primitive value, the content is
     * translated to String using the standard xml list type encoding. For example, the
     * <code>double[]{1.0, 1.1, 2.2}</code> array will be converted to the {@code "1.0 1.1 2.2"}
     * String before returning it.
     * </p>
     * <p>
     * NOTE calling this method implies parsing all the remaining elements for the current value
     * event, so it is not allowed to call other {@code getValue} or {@code getXXXValue} method
     * after this method returns, since the whole value event was consumed.
     * </p>
     * 
     * @pre {getEventType().isValue() == true || getEventType() == {@link EventType#COMMENT}}
     * @post {$return != null}
     * @return the current value object, whether it is a single element or an array of some
     *         primitive types, as a String.
     * @throws IOException if an I/O error occurs while reading the data
     */
    public String getStringValue() throws IOException;

    /**
     * Being at a {@link EventType#VALUE_BOOL boolean value} event, reads {@code length} booleans
     * out of the underlying input stream and stores them in {@code dst}, starting at array index
     * {@code offset}.
     * <p>
     * This operation is semantically equivalent to calling {@link #getBooleanValue()}
     * {@code length} times, though its recommended for bulk reads as the implementation may perform
     * better.
     * </p>
     * 
     * @pre {getEventType() == VALUE_BOOL}
     * @pre {dst != null}
     * @pre {offset >= 0}
     * @pre {length <= (dst.length - offset)}
     * @pre {getValueCount() - getValueReadCount() >= length}
     * @param dst the client supplied buffer where to store the read content
     * @param offset the zero based index at which to start storing the read content in {@code dst}
     * @param length the amount of elements to store in {@code dst}
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     */
    public void getValue(boolean[] dst, int offset, int length) throws IOException;

    /**
     * Reads a single boolean value out of the underlying input stream.
     * <p>
     * Calls to this method may be interleaved with calls to {@link #getValue(boolean[], int, int)}
     * for the same VALUE_BOOL event, as long as the accumulated number of elements read does not
     * exceed the current {@link #getValueCount() value count}.
     * </p>
     * 
     * @pre {getEventType() == VALUE_BOOL}
     * @pre {getValueReadCount() < getValueCount()}
     * @return the value read
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getValue(boolean[], int, int)
     */
    public boolean getBooleanValue() throws IOException;

    /**
     * Being at a {@link EventType#VALUE_BYTE byte value} event, reads {@code length} bytes out of
     * the underlying input stream and stores them in {@code dst}, starting at array index
     * {@code offset}.
     * <p>
     * This operation is semantically equivalent to calling {@link #getByteValue()} {@code length}
     * times, though its recommended for bulk reads as the implementation may perform better.
     * </p>
     * 
     * @pre {getEventType() == VALUE_BYTE}
     * @pre {dst != null}
     * @pre {offset >= 0}
     * @pre {length <= (dst.length - offset)}
     * @pre {getValueCount() - getValueReadCount() >= length}
     * @param dst the client supplied buffer where to store the read content
     * @param offset the zero based index at which to start storing the read content in {@code dst}
     * @param length the amount of elements to store in {@code dst}
     * @throws IOException if an I/O error occurs while reading the data
     * @throws IllegalArgumentException if the accumulated read length for the current value event
     *             exceeds the actual value length
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getBooleanValue()
     */
    public void getValue(byte[] dst, int offset, int length) throws IOException;

    /**
     * Reads a single byte value out of the underlying input stream.
     * <p>
     * Calls to this method may be interleaved with calls to {@link #getValue(byte[], int, int)} for
     * the same VALUE_BYTE event, as long as the accumulated number of elements read does not exceed
     * the current {@link #getValueCount() value count}.
     * </p>
     * 
     * @pre {getEventType() == VALUE_BYTE}
     * @pre {getValueReadCount() < getValueCount()}
     * @return the value read
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getValue(byte[], int, int)
     */
    public int getByteValue() throws IOException;

    /**
     * Being at a {@link EventType#VALUE_INT int value} event, reads {@code length} integers out of
     * the underlying input stream and stores them in {@code dst}, starting at array index
     * {@code offset}.
     * <p>
     * This operation is semantically equivalent to calling {@link #getIntValue()} {@code length}
     * times, though its recommended for bulk reads as the implementation may perform better.
     * </p>
     * 
     * @pre {getEventType() == VALUE_INT}
     * @pre {dst != null}
     * @pre {offset >= 0}
     * @pre {length <= (dst.length - offset)}
     * @pre {getValueCount() - getValueReadCount() >= length}
     * @param dst the client supplied buffer where to store the read content
     * @param offset the zero based index at which to start storing the read content in {@code dst}
     * @param length the amount of elements to store in {@code dst}
     * @throws IOException if an I/O error occurs while reading the data
     * @throws IllegalArgumentException if the accumulated read length for the current value event
     *             exceeds the actual value length
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getIntValue()
     */
    public void getValue(int[] dst, int offset, int length) throws IOException;

    /**
     * Reads a single integer value out of the underlying input stream.
     * <p>
     * Calls to this method may be interleaved with calls to {@link #getValue(int[], int, int)} for
     * the same VALUE_INT event, as long as the accumulated number of elements read does not exceed
     * the current {@link #getValueCount() value count}.
     * </p>
     * 
     * @pre {getEventType() == VALUE_INT}
     * @pre {getValueReadCount() < getValueCount()}
     * @return the value read
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getValue(int[], int, int)
     */
    public int getIntValue() throws IOException;

    /**
     * Being at a {@link EventType#VALUE_LONG long value} event, reads {@code length} longs out of
     * the underlying input stream and stores them in {@code dst}, starting at array index
     * {@code offset}.
     * <p>
     * This operation is semantically equivalent to calling {@link #getLongValue()} {@code length}
     * times, though its recommended for bulk reads as the implementation may perform better.
     * </p>
     * 
     * @pre {getEventType() == VALUE_LONG}
     * @pre {dst != null}
     * @pre {offset >= 0}
     * @pre {length <= (dst.length - offset)}
     * @pre {getValueCount() - getValueReadCount() >= length}
     * @param dst the client supplied buffer where to store the read content
     * @param offset the zero based index at which to start storing the read content in {@code dst}
     * @param length the amount of elements to store in {@code dst}
     * @throws IOException if an I/O error occurs while reading the data
     * @throws IllegalArgumentException if the accumulated read length for the current value event
     *             exceeds the actual value length
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getLongValue()
     */
    public void getValue(long[] dst, int offset, int length) throws IOException;

    /**
     * Reads a single long value out of the underlying input stream.
     * <p>
     * Calls to this method may be interleaved with calls to {@link #getValue(long[], int, int)} for
     * the same VALUE_LONG event, as long as the accumulated number of elements read does not exceed
     * the current {@link #getValueCount() value count}.
     * </p>
     * 
     * @pre {getEventType() == VALUE_LONG}
     * @pre {getValueReadCount() < getValueCount()}
     * @return the value read
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getValue(long[], int, int)
     */
    public long getLongValue() throws IOException;

    /**
     * Being at a {@link EventType#VALUE_FLOAT float value} event, reads {@code length} floats out
     * of the underlying input stream and stores them in {@code dst}, starting at array index
     * {@code offset}.
     * <p>
     * This operation is semantically equivalent to calling {@link #getFloatValue()} {@code length}
     * times, though its recommended for bulk reads as the implementation may perform better.
     * </p>
     * 
     * @pre {getEventType() == VALUE_FLOAT}
     * @pre {dst != null}
     * @pre {offset >= 0}
     * @pre {length <= (dst.length - offset)}
     * @pre {getValueCount() - getValueReadCount() >= length}
     * @param dst the client supplied buffer where to store the read content
     * @param offset the zero based index at which to start storing the read content in {@code dst}
     * @param length the amount of elements to store in {@code dst}
     * @throws IOException if an I/O error occurs while reading the data
     * @throws IllegalArgumentException if the accumulated read length for the current value event
     *             exceeds the actual value length
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getFloatValue()
     */
    public void getValue(float[] dst, int offset, int length) throws IOException;

    /**
     * Reads a single float value out of the underlying input stream.
     * <p>
     * Calls to this method may be interleaved with calls to {@link #getValue(float[], int, int)}
     * for the same VALUE_FLOAT event, as long as the accumulated number of elements read does not
     * exceed the current {@link #getValueCount() value count}.
     * </p>
     * 
     * @pre {getEventType() == VALUE_FLOAT}
     * @pre {getValueReadCount() < getValueCount()}
     * @return the value read
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getValue(float[], int, int)
     */
    public float getFloatValue() throws IOException;

    /**
     * Being at a {@link EventType#VALUE_DOUBLE double value} event, reads {@code length} doubles
     * out of the underlying input stream and stores them in {@code dst}, starting at array index
     * {@code offset}.
     * <p>
     * This operation is semantically equivalent to calling {@link #getDoubleValue()} {@code length}
     * times, though its recommended for bulk reads as the implementation may perform better.
     * </p>
     * 
     * @pre {getEventType() == VALUE_DOUBLE}
     * @pre {dst != null}
     * @pre {offset >= 0}
     * @pre {length <= (dst.length - offset)}
     * @pre {getValueCount() - getValueReadCount() >= length}
     * @param dst the client supplied buffer where to store the read content
     * @param offset the zero based index at which to start storing the read content in {@code dst}
     * @param length the amount of elements to store in {@code dst}
     * @throws IOException if an I/O error occurs while reading the data
     * @throws IllegalArgumentException if the accumulated read length for the current value event
     *             exceeds the actual value length
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getDoubleValue()
     */
    public void getValue(double[] dst, int offset, int length) throws IOException;

    /**
     * Reads a single double value out of the underlying input stream.
     * <p>
     * Calls to this method may be interleaved with calls to {@link #getValue(double[], int, int)}
     * for the same VALUE_DOUBLE event, as long as the accumulated number of elements read does not
     * exceed the current {@link #getValueCount() value count}.
     * </p>
     * 
     * @pre {getEventType() == VALUE_DOUBLE}
     * @pre {getValueReadCount() < getValueCount()}
     * @return the value read
     * @throws IOException if an I/O error occurs while reading the data
     * @see #getValueCount()
     * @see #getValueReadCount()
     * @see #getValue(double[], int, int)
     */
    public double getDoubleValue() throws IOException;
}