All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.openhft.chronicle.wire.WireIn Maven / Gradle / Ivy

/*
 * Copyright 2016-2020 chronicle.software
 *
 *       https://chronicle.software
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.openhft.chronicle.wire;

import net.openhft.chronicle.core.annotation.DontChain;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.core.io.InvalidMarshallableException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.EOFException;
import java.io.ObjectInput;
import java.io.StreamCorruptedException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;

/**
 * Defines the standard interface for reading sequentially from a Bytes stream.
 */
@DontChain
public interface WireIn extends WireCommon, MarshallableIn {

    /**
     * Reads all available entries and populates the provided map with these entries.
     * Each entry in the wire source is read as a key-value pair where the key is of type {@code K} and the value is of type {@code V}.
     *
     * @param      The type of keys in the map.
     * @param      The type of values in the map.
     * @param kClass  The class type of the key.
     * @param vClass  The class type of the value.
     * @param map     The map to populate with read entries.
     * @return The populated map.
     * @throws InvalidMarshallableException If there's an error in the marshalling process.
     */
    @NotNull
    default  Map readAllAsMap(Class kClass, @NotNull Class vClass, @NotNull Map map) throws InvalidMarshallableException {
        while (isNotEmptyAfterPadding()) {
            long len = bytes().readRemaining();
            final K k = readEvent(kClass);
            @Nullable final V v = getValueIn()
                    .object(vClass);
            if (len == bytes().readRemaining())
                break;
            map.put(k, v);
        }
        return map;
    }

    /**
     * Copies the content from the current WireIn source to the provided WireOut destination.
     *
     * @param wire The WireOut instance where the content will be copied to.
     * @throws InvalidMarshallableException If there's an error in the marshalling process.
     */
    void copyTo(@NotNull WireOut wire) throws InvalidMarshallableException;

    /**
     * Reads the next field if present, or returns an empty string if not present.
     *
     * @return The value of the next field, encapsulated in a {@link ValueIn} instance.
     */
    @NotNull
    ValueIn read();

    /**
     * Reads the next field if present. The field should match the provided {@link WireKey}.
     *
     * @param key The WireKey that should match the next field.
     * @return The value of the matched field, encapsulated in a {@link ValueIn} instance.
     */
    @NotNull
    ValueIn read(@NotNull WireKey key);

    /**
     * Reads the next field based on the provided field name.
     *
     * @param fieldName The name of the field to read.
     * @return The value of the specified field, encapsulated in a {@link ValueIn} instance.
     */
    @NotNull
    default ValueIn read(String fieldName) {
        return read(() -> fieldName);
    }

    /**
     * Reads the next event number. If no number is present, returns Long.MIN_VALUE.
     *
     * @return The next event number or Long.MIN_VALUE if no number is present.
     */
    long readEventNumber();

    /**
     * Reads a field or string, ensuring the value is always read.
     * This method is specifically designed to ensure reading even for formats that might
     * potentially omit the field, such as RAW.
     *
     * @param name The StringBuilder that holds the name of the field or string.
     * @return The value of the field or string, encapsulated in a {@link ValueIn} instance.
     * @throws IORuntimeException If the bytes fail to be parsed.
     */
    @NotNull
    default ValueIn readEventName(@NotNull StringBuilder name) {
        try {
            return read(name);
        } catch (Exception e) {
            String s;
            try {
                s = bytes().toDebugString(128);
            } catch (Throwable ex) {
                s = ex.toString();
            }
            throw new IORuntimeException("failed to parse bytes=" + s, e);
        }
    }

    /**
     * Reads a specific field based on the provided field name.
     * If the field is not present, it returns an empty string.
     *
     * @param name The name of the field to read.
     * @return The value of the specified field, encapsulated in a {@link ValueIn} instance.
     */
    @NotNull
    ValueIn read(@NotNull StringBuilder name);

    /**
     * Reads a field which may contain an object of any specified type.
     *
     * @param            The type of object expected.
     * @param expectedClass The class type hint of the expected object. If no hint is available, use Object.class.
     * @return An instance of the specified expectedClass.
     * @throws InvalidMarshallableException If there's an error in the marshalling process.
     */
    @Nullable  K readEvent(Class expectedClass) throws InvalidMarshallableException;

    /**
     * Obtains the value associated with a field or event for more advanced use cases.
     * Typically used after a call to {@link #readEvent(Class)}.
     *
     * @return The value of the field or event, encapsulated in a {@link ValueIn} instance.
     */
    @NotNull
    ValueIn getValueIn();

    /**
     * Returns the ObjectInput associated with this WireIn for serialization operations.
     *
     * @return the ObjectInput instance.
     */
    ObjectInput objectInput();

    /**
     * Reads a comment from the Wire data and appends it to the provided StringBuilder.
     *
     * @param sb StringBuilder to which the comment will be appended.
     * @return the WireIn instance for method chaining.
     */
    @NotNull
    WireIn readComment(@NotNull StringBuilder sb);

    /**
     * Clears the WireIn, effectively resetting its state.
     */
    @Override
    void clear();

    /**
     * This consumes any padding before checking if readRemaining() > 0 

NOTE: This method * only works inside a document. Call it just before a document and it won't know not to read * the read in case there is padding. * * @return if there is more data to be read in this document. */ default boolean hasMore() { return isNotEmptyAfterPadding(); } /** * This consumes any padding before checking if readRemaining() > 0

NOTE: This method * only works inside a document. Call it just before a document and it won't know not to read * the read in case there is padding. * * @return if there is more data to be read in this document. */ default boolean isNotEmptyAfterPadding() { consumePadding(); return !isEmpty(); } /** * Checks if the WireIn is empty. * * @return true if empty, otherwise false. */ default boolean isEmpty() { return bytes().isEmpty(); } /** * Adjusts the read position of the WireIn to align with the specified boundary. * Typically used for cases where data is structured in blocks of fixed sizes, ensuring proper alignment. * * @param alignment The byte boundary to which the read position should align. * @return the WireIn instance for method chaining. */ @NotNull default WireIn readAlignTo(int alignment) { return this; } // TODO add a try-with-resource support for readDocument. /** * Reads a document, consuming both its metadata and data sections. * * @param metaDataConsumer Consumer that processes the metadata section of the document. * @param dataConsumer Consumer that processes the main data section of the document. * @return true if the document was successfully read, otherwise false. * @throws InvalidMarshallableException if there's an error during marshalling. */ default boolean readDocument(@Nullable ReadMarshallable metaDataConsumer, @Nullable ReadMarshallable dataConsumer) throws InvalidMarshallableException { return WireInternal.readData(this, metaDataConsumer, dataConsumer); } /** * Reads a document from a specific position, consuming both its metadata and data sections. * * @param position The position from which to start reading the document. * @param metaDataConsumer Consumer that processes the metadata section of the document. * @param dataConsumer Consumer that processes the main data section of the document. * @return true if the document was successfully read from the given position, otherwise false. * @throws InvalidMarshallableException if there's an error during marshalling. */ default boolean readDocument(long position, @Nullable ReadMarshallable metaDataConsumer, @Nullable ReadMarshallable dataConsumer) throws InvalidMarshallableException { return WireInternal.readData(position, this, metaDataConsumer, dataConsumer); } /** * Performs a raw data read operation. * * @param marshallable Data to be read in its raw form. * @throws InvalidMarshallableException if there's an error during marshalling. */ default void rawReadData(@NotNull ReadMarshallable marshallable) throws InvalidMarshallableException { WireInternal.rawReadData(this, marshallable); } /** * equivalent to {@link WireIn#readDocument(net.openhft.chronicle.wire.ReadMarshallable, * net.openhft.chronicle.wire.ReadMarshallable)} but with out the use of a lambda expression * * @return the document context */ @Override @NotNull DocumentContext readingDocument(); /** * Provides a context for reading a document starting at a specific position. * * @param readLocation The position from which to start reading the document. * @return the document context associated with the specific read location. */ DocumentContext readingDocument(long readLocation); /** * Consumes and discards any padding that may exist between the current read position and the next piece of meaningful data. */ void consumePadding(); /** * Sets a listener that gets notified whenever a comment is encountered during reading. * * @param commentListener The consumer that handles and processes the comments. */ void commentListener(Consumer commentListener); /** * Consume a header if one is available. * * @return true, if a message can be read between readPosition and readLimit, else false if no * header is ready. * @throws EOFException if the end of wire marker is reached. */ default boolean readDataHeader() throws EOFException { return readDataHeader(false) == HeaderType.DATA; } /** * Attempts to read a header for data or metadata, based on the provided parameter. * * @param includeMetaData If true, metadata headers are included in the read attempt. * @return The type of header that was read. * @throws EOFException if an end-of-file marker is encountered. */ @NotNull HeaderType readDataHeader(boolean includeMetaData) throws EOFException; /** * Reads and sets the length of the data or metadata at the specified position. * * @param position The position from which to start reading the length. */ void readAndSetLength(long position); /** * Reads the first header in the stream with a timeout. * * @param timeout Maximum time to wait for a header to be available. * @param timeUnit The unit of time for the timeout. * @throws TimeoutException If no header is read within the given timeout. * @throws StreamCorruptedException If there is an error in reading the header due to stream corruption. */ void readFirstHeader(long timeout, TimeUnit timeUnit) throws TimeoutException, StreamCorruptedException; /** * Reads the first header in the stream. * * @throws StreamCorruptedException If there is an error in reading the header due to stream corruption. */ void readFirstHeader() throws StreamCorruptedException; /** * Reads the metadata header from the current position in the stream. */ void readMetaDataHeader(); /** * Peeks at the content in the current WireIn instance and returns it as a YAML string. * * @return A String containing a YAML representation of the peeked content. */ String readingPeekYaml(); /** * Marks the start of an event or method flow. */ default void startEvent() { } /** * Checks if the current position in the stream represents the end of an event or method flow. * * @return true if the current position is the end of an event, otherwise false. */ default boolean isEndEvent() { return false; } /** * Marks the end of an event or method flow. */ default void endEvent() { } /** * Provides a hint about the order in which the input should be read. * * @return true if the input should be read in a specific order, otherwise false. */ default boolean hintReadInputOrder() { return false; } /** * Checks if the current position in the stream has a metadata prefix. * * @return true if there's a metadata prefix at the current position, otherwise false. */ default boolean hasMetaDataPrefix() { return false; } /** * Enumeration representing possible header types that can be read from a WireIn instance. */ enum HeaderType { NONE, // No header was found or read. DATA, // Data header was found or read. META_DATA, // Metadata header was found or read. EOF // End-of-file marker was found or read. } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy