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

com.tangosol.io.WriteBuffer Maven / Gradle / Ivy

There is a newer version: 24.03
Show newest version
/*
 * Copyright (c) 2000, 2020, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

package com.tangosol.io;


import com.tangosol.util.Binary;

import java.io.DataOutput;
import java.io.EOFException;
import java.io.IOException;


/**
* The WriteBuffer interface represents an in-memory block of binary data
* that is being accumulated (written to). It is analogous to the byte[]
* inside a Java ByteArrayOutputStream.
*
* @author cp  2005.01.18 created
* @author cp  2005.03.21 defining
*/
public interface WriteBuffer
    {
    // ----- buffer write operations ----------------------------------------

    /**
    * Store the specified byte at the specified offset within the buffer.
    * 

* For purposes of side-effects and potential exceptions, this method is * functionally equivalent to the following code: *


    * byte[] abSrc = new byte[1];
    * abSrc[0] = b;
    * write(ofDest, abSrc, 0, abSrc.length);
    * 
* * @param ofDest the offset within this buffer to store the passed data * @param b the byte to store in this buffer */ public void write(int ofDest, byte b); /** * Store the specified bytes at the specified offset within the buffer. *

* For purposes of side-effects and potential exceptions, this method is * functionally equivalent to the following code: *


    * write(ofDest, abSrc, 0, abSrc.length);
    * 
* * @param ofDest the offset within this buffer to store the passed data * @param abSrc the array of bytes to store in this buffer * * @exception NullPointerException if abSrc is * null * @exception IndexOutOfBoundsException if ofDest is negative, * or if ofDest + abSrc.length is * greater than {@link #getMaximumCapacity()} */ public void write(int ofDest, byte[] abSrc); /** * Store the specified number of bytes from the specified location within * the passed byte array at the specified offset within this buffer. *

* As a result of this method, the buffer length as reported by the * {@link #length()} method will become * Math.max({@link #length()}, ofDest + cbSrc). *

* As a result of this method, the buffer capacity as reported by the * {@link #getCapacity()} method will not change if the new value * returned by {@link #length()} would not exceed the old value * returned by {@link #getCapacity()}; otherwise, the capacity * will be increased such that * {@link #getCapacity()} >= {@link #length()}. Regardless, it is * always true that {@link #getCapacity()} >= {@link #length()} * and {@link #getMaximumCapacity()} >= {@link #getCapacity()}. * If the buffer capacity cannot be increased due to resource constraints, * an undesignated Error or RuntimeException will be thrown, such as * OutOfMemoryError. * * @param ofDest the offset within this buffer to store the passed data * @param abSrc the array containing the bytes to store in this buffer * @param ofSrc the offset within the passed byte array to copy from * @param cbSrc the number of bytes to copy from the passed byte array * * @exception NullPointerException if abSrc is * null * @exception IndexOutOfBoundsException if ofDest, * ofSrc or cbSrc is negative, if * ofSrc + cbSrc is greater than * abSrc.length, or if ofDest + cbSrc is * greater than {@link #getMaximumCapacity()} */ public void write(int ofDest, byte[] abSrc, int ofSrc, int cbSrc); /** * Store the contents of the specified ReadBuffer at the specified offset * within this buffer. *

* For purposes of side-effects and potential exceptions, this method is * functionally equivalent to the following code: *


    * byte[] abSrc = bufSrc.toByteArray();
    * write(ofDest, abSrc, 0, abSrc.length);
    * 
* * @param ofDest the offset within this buffer to store the passed data * @param bufSrc the array of bytes to store in this buffer * * @exception NullPointerException if bufSrc is * null * @exception IndexOutOfBoundsException if ofDest is negative, * or if ofDest + bufSrc.length() is * greater than {@link #getMaximumCapacity()} */ public void write(int ofDest, ReadBuffer bufSrc); /** * Store the specified portion of the contents of the specified ReadBuffer * at the specified offset within this buffer. *

* For purposes of side-effects and potential exceptions, this method is * functionally equivalent to the following code: *


    * byte[] abSrc = bufSrc.toByteArray(ofSrc, cbSrc);
    * write(ofDest, abSrc, 0, abSrc.length);
    * 
* * @param ofDest the offset within this buffer to store the passed data * @param bufSrc the array of bytes to store in this buffer * @param ofSrc the offset within the passed ReadBuffer to copy from * @param cbSrc the number of bytes to copy from the passed ReadBuffer * * @exception NullPointerException if bufSrc is * null * @exception IndexOutOfBoundsException if ofDest, * ofSrc or cbSrc is negative, if * ofSrc + cbSrc is greater than * bufSrc.length(), or if ofDest + cbSrc is * greater than {@link #getMaximumCapacity()} */ public void write(int ofDest, ReadBuffer bufSrc, int ofSrc, int cbSrc); /** * Store the remaining contents of the specified InputStreaming object at * the specified offset within this buffer. *

* For purposes of side-effects and potential exceptions, this method is * functionally similar to the following code: *


    * ByteArrayOutputStream streamOut = new ByteArrayOutputStream();
    * int b;
    * while ((b = stream.read()) >= 0)
    *     {
    *     streamOut.write(b);
    *     }
    * byte[] abSrc = streamOut.toByteArray();
    * write(ofDest, abSrc, 0, abSrc.length);
    * 
* * @param ofDest the offset within this buffer to store the passed data * @param stream the stream of bytes to read and store in this buffer * * @exception IOException if an IOException occurs reading from the * passed stream */ public void write(int ofDest, InputStreaming stream) throws IOException; /** * Store the specified number of bytes from the specified InputStreaming * object at the specified offset within this buffer. *

* For purposes of side-effects and potential exceptions, this method is * functionally similar to the following code: *


    * DataInputStream streamData = new DataInputStream(
    *         new WrapperInputStream(stream));
    * byte[] abSrc = new byte[cbSrc];
    * streamData.readFully(abSrc);
    * write(ofDest, abSrc, 0, abSrc.length);
    * 
* * @param ofDest the offset within this buffer to store the passed data * @param stream the stream of bytes to read and store in this buffer * @param cbSrc the exact number of bytes to read from the stream and * put in this buffer * * @exception IOException if an IOException occurs reading from the * passed stream */ public void write(int ofDest, InputStreaming stream, int cbSrc) throws IOException; // ----- buffer maintenance ---------------------------------------------- /** * Determine the length of the data that is in the buffer. This is the * actual number of bytes of data that have been written to the buffer, * not the capacity of the buffer. * * @return the number of bytes of data represented by this WriteBuffer */ public int length(); /** * Starting with the byte at offset of, retain the remainder * of this WriteBuffer, such that the byte at offset of is * shifted to offset 0, the byte at offset of + 1 is shifted to * offset 1, and so on up to the byte at offset * {@link #length()} - 1, which is shifted to offset * {@link #length()} - of - 1. After this method, the length of * of the buffer as indicated by the {@link #length()} method will be * equal to {@link #length()} - of. *

* This method is functionally equivalent to the following code: *


    * retain(of, length() - of);
    * 
* * @param of the offset of the first byte within the WriteBuffer that * will be retained * * @exception IndexOutOfBoundsException if of is negative or if * of is greater than {@link #length()} */ public void retain(int of); /** * Starting with the byte at offset of, retain cb bytes * in this WriteBuffer, such that the byte at offset of is * shifted to offset 0, the byte at offset of + 1 is shifted to * offset 1, and so on up to the byte at offset of + cb - 1, * which is shifted to offset cb - 1. After this method, the * length of the buffer as indicated by the {@link #length()} method will * be equal to cb. *

* Legal values for the offset of the first byte to retain of are * (of >= 0 && of <= {@link #length()}). Legal values for the * number of bytes to retain cb are * (cb >= 0 && cb <= {@link #length()}), such that * (of + cb <= {@link #length()}). *

* If cb is zero, then this method will have the same effect as * clear. If of is zero, then this method will have the effect * of truncating the data in the buffer, but no bytes will be shifted * within the buffer. *

* The effect on the capacity of the buffer is implementation-specific; * some implementations are expected to retain the same capacity while * others are expected to shrink accordingly. * * @param of the offset of the first byte within the WriteBuffer that * will be retained * @param cb the number of bytes to retain * * @exception IndexOutOfBoundsException if of or cb is * negative of if of + cb is greater than * {@link #length()} */ public void retain(int of, int cb); /** * Set the length of the buffer as indicated by the {@link #length()} * method to zero. *

* The effect on the capacity of the buffer is implementation-specific; * some implementations are expected to retain the same capacity while * others are expected to shrink accordingly. */ public void clear(); /** * Determine the number of bytes that the buffer can hold without resizing * itself. In other words, a WriteBuffer has getCapacity() - * {@link #length()} bytes that can be written to it without * overflowing the current underlying buffer allocation. Since the buffer * is an abstract concept, the actual mechanism for the underlying buffer * is not known, but it could be a Java NIO buffer, or a byte array, etc. *

* Note that if the maximum size returned by {@link #getMaximumCapacity()} * is greater than the current size returned by this method, then the * WriteBuffer will automatically resize itself to allocate more space * when the amount of data written to it passes the current size. * * @return the number of bytes of data that this WriteBuffer can hold * without resizing its underlying buffer */ public int getCapacity(); /** * Determine the maximum number of bytes that the buffer can hold. If the * maximum size is greater than the current size, then the buffer is * expected to resize itself as necessary up to the maximum size in order * to contain the data given to it. * * @return the maximum number of bytes of data that the WriteBuffer can * hold */ public int getMaximumCapacity(); // ----- obtaining different "write views" to the buffer ---------------- /** * Obtain a WriteBuffer starting at a particular offset within this * WriteBuffer. *

* This is functionally equivalent to: *

{@code
    * return getWriteBuffer(of, getMaximumCapacity() - of);
    * }
* * @param of the beginning index, inclusive * * @return a WriteBuffer that represents a portion of this WriteBuffer * * @exception IndexOutOfBoundsException if of is * negative, or of is larger than the * {@link #getMaximumCapacity()} of this * WriteBuffer object */ public WriteBuffer getWriteBuffer(int of); /** * Obtain a WriteBuffer for a portion of this WriteBuffer. *

* Use of the resulting buffer will correspond to using this buffer * directly but with the offset being passed to the buffer methods * automatically having of added. As a result, the length of this * buffer can be modified by writing to the new buffer; however, changes * made directly to this buffer will not affect the length of the new * buffer. *

* Note that the resulting WriteBuffer is limited in the number of bytes * that can be written to it; in other words, its * {@link #getMaximumCapacity()} must return the same value as * was passed in cb. * * @param of the offset of the first byte within this WriteBuffer * to map to offset 0 of the new WriteBuffer * @param cb the number of bytes to cover in the resulting WriteBuffer * * @return a WriteBuffer that represents a portion of this WriteBuffer * * @exception IndexOutOfBoundsException if of or cb * is negative, or of + cb is larger than * the {@link #getMaximumCapacity()} of this * WriteBuffer object */ public WriteBuffer getWriteBuffer(int of, int cb); /** * Get a BufferOutput object to write data to this buffer, starting at * the beginning of the WriteBuffer. *

* This is functionally equivalent to: *

{@code
    * return getBufferOutput(0);
    * }
* * @return a BufferOutput that is writing to this buffer starting at * offset zero */ public BufferOutput getBufferOutput(); /** * Get a BufferOutput object to write data to this buffer starting at a * particular offset. *

* Note that each call to this method will return a new BufferOutput * object, with the possible exception being that a zero-length * non-resizing WriteBuffer could always return the same instance (since * it is not writable). *

* This is functionally equivalent to: *


    * BufferOutput bufout = getBufferOutput();
    * bufout.setOffset(of);
    * return bufout;
    * 
* * @param of the offset of the first byte of this buffer that the * BufferOutput will write to * * @return a BufferOutput that will write to this buffer */ public BufferOutput getBufferOutput(int of); /** * Get a BufferOutput object to write data to this buffer. The * BufferOutput object returned by this method is set to append to the * WriteBuffer, meaning that its offset is pre-set to the * {@link #length()} of this buffer. *

* This is functionally equivalent to: *


    * return getBufferOutput(length());
    * 
* * @return a BufferOutput configured to append to this buffer */ public BufferOutput getAppendingBufferOutput(); // ----- accessing the buffered data ------------------------------------ /** * Get a ReadBuffer object that is a snapshot of this WriteBuffer's data. *

* This method is functionally equivalent to the following code: *


    * ReadBuffer buf = getUnsafeReadBuffer();
    * byte[] ab = buf.toByteArray();
    * return new ByteArrayReadBuffer(ab);
    * 
* * @return a ReadBuffer that reflects the point-in-time contents of this * WriteBuffer */ public ReadBuffer getReadBuffer(); /** * Get a ReadBuffer object to read data from this buffer. This method is * not guaranteed to return a snapshot of this buffer's data, nor is it * guaranteed to return a live view of this buffer, which means that * subsequent changes to this WriteBuffer may or may not affect the * contents and / or the length of the returned ReadBuffer. *

* To get a snapshot, use the {@link #getReadBuffer()} method. * * @return a ReadBuffer that reflects the contents of this WriteBuffer * but whose behavior is undefined if the WriteBuffer is modified */ public ReadBuffer getUnsafeReadBuffer(); /** * Returns a new byte array that holds the complete contents of this * WriteBuffer. *

* This method is functionally equivalent to the following code: *


    * return getUnsafeReadBuffer().toByteArray();
    * 
* * @return the contents of this WriteBuffer as a byte[] */ public byte[] toByteArray(); /** * Returns a new Binary object that holds the complete contents of this * WriteBuffer. *

* This method is functionally equivalent to the following code: *


    * return getUnsafeReadBuffer().toBinary();
    * 
* * @return the contents of this WriteBuffer as a Binary object */ public Binary toBinary(); // ----- Object methods ------------------------------------------------- /** * Create a clone of this WriteBuffer object. Changes to the clone will * not affect the original, and vice-versa. * * @return a WriteBuffer object with the same contents as this * WriteBuffer object */ public Object clone(); // ----- inner interface: BufferOutput ---------------------------------- /** * The BufferOutput interface represents a DataOutputStream on top of a * WriteBuffer. * * @author cp 2005.01.18 */ public interface BufferOutput extends OutputStreaming, DataOutput { // ----- OutputStreaming methods -------------------------------- /** * Close the OutputStream and release any system resources associated * with it. *

* BufferOutput implementations do not pass this call down onto an * underlying stream, if any. * * @exception IOException if an I/O error occurs */ public void close() throws IOException; // ----- DataOutput methods ------------------------------------- /** * Writes the boolean value f. * * @param f the boolean to be written * * @exception IOException if an I/O error occurs */ public void writeBoolean(boolean f) throws IOException; /** * Writes the eight low-order bits of the argument b. The 24 * high-order bits of b are ignored. * * @param b the byte to write (passed as an integer) * * @exception IOException if an I/O error occurs */ public void writeByte(int b) throws IOException; /** * Writes a short value, comprised of the 16 low-order bits of the * argument n; the 16 high-order bits of n are * ignored. * * @param n the short to write (passed as an integer) * * @exception IOException if an I/O error occurs */ public void writeShort(int n) throws IOException; /** * Writes a char value, comprised of the 16 low-order bits of the * argument ch; the 16 high-order bits of ch are * ignored. * * @param ch the char to write (passed as an integer) * * @exception IOException if an I/O error occurs */ public void writeChar(int ch) throws IOException; /** * Writes an int value. * * @param n the int to write * * @exception IOException if an I/O error occurs */ public void writeInt(int n) throws IOException; /** * Writes a long value. * * @param l the long to write * * @exception IOException if an I/O error occurs */ public void writeLong(long l) throws IOException; /** * Writes a float value. * * @param fl the float to write * * @exception IOException if an I/O error occurs */ public void writeFloat(float fl) throws IOException; /** * Writes a double value. * * @param dfl the double to write * * @exception IOException if an I/O error occurs */ public void writeDouble(double dfl) throws IOException; /** * Writes the String s, but only the low-order byte from each * character of the String is written. * * @param s the String to write * * @exception IOException if an I/O error occurs * @exception NullPointerException if s is null */ public void writeBytes(String s) throws IOException; /** * Writes the String s as a sequence of characters. * * @param s the String to write * * @exception IOException if an I/O error occurs * @exception NullPointerException if s is null */ public void writeChars(String s) throws IOException; /** * Writes the String s as a sequence of characters, but using * UTF-8 encoding for the characters, and including the String length * data so that the corresponding {@link java.io.DataInput#readUTF} * method can reconstitute a String from the written data. * * @param s the String to write * * @exception IOException if an I/O error occurs * @exception NullPointerException if s is null */ public void writeUTF(String s) throws IOException; // ----- BufferOutput methods ----------------------------------- /** * Get the WriteBuffer object that this BufferOutput is writing to. * * @return the underlying WriteBuffer object */ public WriteBuffer getBuffer(); /** * Write a variable-length encoded UTF packed String. The major * differences between this implementation and DataOutput is that this * implementation supports null values and is not limited to 64KB * UTF-encoded values. *

* The binary format for a Safe UTF value is a "packed int" for the * binary length followed by the UTF-encoded byte stream. The length * is either -1 (indicating a null String) or in the range * 0 .. Integer.MAX_VALUE (inclusive). The UTF-encoded * portion uses a format identical to DataOutput. * * @param s a String value to write; may be null * * @exception IOException if an I/O error occurs */ public void writeSafeUTF(String s) throws IOException; /** * Write an int value using a variable-length storage-format. *

* The format differs from DataOutput in that DataOutput always uses * a fixed-length 4-byte Big Endian binary format for int values. * The "packed" format includes a sign bit (0x40) and a continuation * bit (0x80) in the first byte, followed by the least 6 significant * bits of the int value. Subsequent bytes (each appearing only if * the previous byte had its continuation bit set) include a * continuation bit (0x80) and the next least 7 significant bits of * the int value. In this way, a 32-bit value is encoded into 1-5 * bytes, depending on the magnitude of the int value being encoded. * * @param n an int value to write * * @exception IOException if an I/O error occurs */ public void writePackedInt(int n) throws IOException; /** * Write a long value using a variable-length storage-format. *

* The format differs from DataOutput in that DataOutput always uses * a fixed-length 8-byte Big Endian binary format for long values. * The "packed" format includes a sign bit (0x40) and a continuation * bit (0x80) in the first byte, followed by the least 6 significant * bits of the long value. Subsequent bytes (each appearing only if * the previous byte had its continuation bit set) include a * continuation bit (0x80) and the next least 7 significant bits of * the long value. In this way, a 64-bit value is encoded into 1-10 * bytes, depending on the magnitude of the long value being encoded. * * @param l a long value to write * * @exception IOException if an I/O error occurs */ public void writePackedLong(long l) throws IOException; /** * Write all the bytes from the passed ReadBuffer object. *

* This is functionally equivalent to the following code: *

{@code
        * getBuffer().write(getOffset(), buf);
        * }
* * @param buf a ReadBuffer object * * @exception IOException if an I/O error occurs */ public void writeBuffer(ReadBuffer buf) throws IOException; /** * Write cb bytes from the passed ReadBuffer object * starting at offset of within the passed ReadBuffer. *

* This is functionally equivalent to the following code: *

{@code
        * getBuffer().write(getOffset(), buf, of, cb);
        * }
* * @param buf a ReadBuffer object * @param of the offset within the ReadBuffer of the first byte to * write to this BufferOutput * @param cb the number of bytes to write * * @exception IOException if an I/O error occurs */ public void writeBuffer(ReadBuffer buf, int of, int cb) throws IOException; /** * Write the remaining contents of the specified InputStreaming * object. *

* This is functionally equivalent to the following code: *

{@code
        * getBuffer().write(getOffset(), stream);
        * }
* * @param stream the stream of bytes to write to this BufferOutput * * @exception IOException if an I/O error occurs, specifically if an * IOException occurs reading from the passed stream */ public void writeStream(InputStreaming stream) throws IOException; /** * Write the specified number of bytes of the specified InputStreaming * object. *

* This is functionally equivalent to the following code: *

{@code
        * getBuffer().write(getOffset(), stream, cb);
        * }
* * @param stream the stream of bytes to write to this BufferOutput * @param cb the exact number of bytes to read from the stream * and write to this BufferOutput * * @exception EOFException if the stream is exhausted before * the number of bytes indicated could be read * @exception IOException if an I/O error occurs, specifically if an * IOException occurs reading from the passed stream */ public void writeStream(InputStreaming stream, int cb) throws IOException; /** * Determine the current offset of this BufferOutput within the * underlying WriteBuffer. * * @return the offset of the next byte to write to the WriteBuffer */ public int getOffset(); /** * Specify the offset of the next byte to write to the underlying * WriteBuffer. * * @param of the offset of the next byte to write to the * WriteBuffer * * @exception IndexOutOfBoundsException if of < 0 or * of > getBuffer().getMaximumCapacity() */ public void setOffset(int of); // ----- constants ---------------------------------------------- /** * Maximum encoding length for a packed int value. */ public static final int MAX_PACKED_INT_SIZE = 5; /** * Maximum encoding length for a packed long value. */ public static final int MAX_PACKED_LONG_SIZE = 10; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy