⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mutablememory.java

📁 这是一个分布式通信程序框架源程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package dim;

/**
 * An object of this class holds a reference to a block of native memory that is
 * allocated and managed by the native code on behalve of a user object.
 * Objects of this class can be instantiated by user objects and are used
 * to communicate outgoing data to the native code (see the
 * {@link DataEncoder#encodeData <code>encodeData()</code>} method of the {@link DataEncoder} interface).
 * The referenced native memory can be altered by the user using the
 * <code>set<i>Primitive</i>()</code> and <code>copyFrom<i>Primitive</i>Array()</code> methods of this class.
 * @author M.Jonker Cern; Adjustments for 64bit platforms Joern Adamczewski, gsi, 27-Oct-2007
 * @version v1.2
 * @todo add mechanism to extend the data container size when needed.
 */
public class MutableMemory extends Memory
{
    /**
     * This exception is thrown by the methods of MutableMemory when a user attempts to write outside the boundaries
     * of the allocated memory area. This error refects a condition that is normally not expected to happen.
     * For this reason the Exception inherits from {@link IncorrectUsageException} (which inherits from
     * java.lang.RuntimeException RuntimeException} and hence does not have to be caught by the user.
     */
    static class NoRoomException extends IncorrectUsageException
    {
        public String toString()
        {
            return "There is no more room to accomodate the requested store.";
        }
    }


    /**
     * This exception is thrown when a user attempts to set the write offset outside the boundaries
     * of the allocated memory area. This error refects a condition that is normally not expected to happen.
     * For this reason the Exception inherits from {@link IncorrectUsageException} (which inherits from
     * java.lang.RuntimeException RuntimeException} and hence does not have to be caught by the user.
     */
    class IllegalOffsetException extends IncorrectUsageException
    {
        public String toString()
        {
            return "The specified offset exceeds the allocated size of " +allocatedSize;
        }
    }

    public MutableMemory()
    {
        dataAddress = 0;
        allocatedSize = 0;
    }

	/**
     * Creates a new MutableMemory object with preallocated initial size.
     * @param size The allocated size of the object.
     */
    public MutableMemory(int size)
    {
        dataAddress = allocateNativeDataBlock(size);
        if(dataAddress!=0) allocatedSize = size;
        else               throw new OutOfMemoryError("Native malloc failure");
    }

    /**
     * Creates a new MutableMemory object intialized with a copy of a Memory object.
     * @param source The object that will be used as a source to initialize the created object.
     */
    public MutableMemory(Memory source)
    {
        dataAddress = allocateNativeDataBlock(source.highWaterMark);
        if(dataAddress==0) throw new OutOfMemoryError("Native malloc failure");

        allocatedSize = source.highWaterMark;
        copyFromMemory(source);
    }

    protected void finalize()
    {
        if(allocatedSize!=0) releaseNativeDataBlock(dataAddress);
    }

    public void setSize(int size) throws IllegalOffsetException
    {
    	int copyIt = 0;
		if(size > allocatedSize)
		{
			MutableMemory tmpData = new MutableMemory(size);
//			System.out.println("********** Memory New, allocating "+size);
			if(allocatedSize!=0)
			{
		        copyNativeDataBlock(tmpData.dataAddress, dataAddress, highWaterMark);
				releaseNativeDataBlock(dataAddress);
				copyIt = 1;
			}
			dataAddress = allocateNativeDataBlock(size);
			if(dataAddress!=0) allocatedSize = size;
			else               throw new OutOfMemoryError("Native malloc failure");
			if(copyIt == 1)
		    	copyNativeDataBlock(dataAddress, tmpData.dataAddress, highWaterMark);
		}
		dataStoreOffset = 0;
		dataFetchOffset = 0;
		return;
    }

	/**
     * Changes the dataStoreOffset. The dataStoreOffset normally points to the end of the last data data store
     * operation. Every data store operation will store the data at the offset given by the value of dataStoreOffset.
     * After a data store operation, the dataStoreOffset is incremented with the size of the data store operation.
     * This method alows the user to change the value of the data store and to set to an lower, or higher location.
     * In case the dataStoreOffset is pushed beyon the high water mark (the highest location ever written), the
     * unwritten area will be initialized with zero.
     * @param newOffset The value to which the offset should be changed.
     * @throws IllegalOffsetException This exception is thrown if an attempt is made to set the dataStoreOffset outside
     * the allocated area.
     */
    public MutableMemory setDataStoreOffset(int newOffset) throws IllegalOffsetException
    {
        if(newOffset< 0 || newOffset > allocatedSize)  throw new IllegalOffsetException();
        if(newOffset > highWaterMark)
        {
            // memset(dataAddress+ highWaterMark, 0, newOffset - highWaterMark);
            highWaterMark = newOffset;
        }
        dataStoreOffset = newOffset;
        return this;
    }

    /**
     * Changes the dataStoreOffset with a relative amount.
     * @param delta The amount by which the offset has to be increased with (or decreased with
     * in case of a negative value).
     * @see #setDataStoreOffset
     */
    public MutableMemory moveDataStoreOffset(int delta) throws IllegalOffsetException
    {
        return setDataStoreOffset(dataStoreOffset+delta);
    }

    /**
     * Restores the dataStoreOffset to highest location ever written.
     * @see #setDataStoreOffset
     */
    public MutableMemory restoreDataStoreOffset(int delta)
    {
        dataStoreOffset = highWaterMark;
        return this;
    }


    /**
     * Changes the dataSize. The dataSize points to the end of the highest offset written and is used to
     * determines the amount of data that is transmitted by dim.
     * Normally the dataSize pointer never decreases, even when the dataStoreOffset is decreased.
     * This methods alows the dataSize to be changed, for example to reset the dataSize to zero such that a
     * MutableMemory object can be reused. The method will also set the dataStoreOffset to the same value.
     * <p><b>Remark: </b><br>
     * This method will have as a side effect to reset the dataStoreOffset to the same location as the dataSize.
     * <br>
     * In case the dataSize is lowered, any previous data in the memory block is discarded.
     * <br>
     * In a future release, when the case the dataSize is increased, the increased data area will be initialized with zero.
     * <p>
     * <b>Example:</b>
     * <blockindent><pre>
     * // Define a MutableMemory object and initialize it with a fixed header.
     * MutableMemory myMessage = new MutableMemory(1024).setString("This is a message from me\n");
     * int dataOffset = myMessage.getDataStoreOffset()-1; // -1 to remove the terminator
     *
     * public void tell(String them, String it)
     * {
     *     Client.Send(them, myMessage.setDataSize(dataOffset).setString(it));
     * }
     * </pre></blockindent>
     * @param newSize The value to new datasize.
     * @throws IllegalOffsetException This exception is thrown if an attempt is made to set the dataSize outside
     * the allocated area.
     */
    public MutableMemory setDataSize(int newSize) throws IllegalOffsetException
    {
        if(newSize< 0 || newSize > allocatedSize)  throw new IllegalOffsetException();
        if(newSize > highWaterMark)
        {
            // memset(dataAddress+ highWaterMark, 0, newOffset - highWaterMark);
        }
        highWaterMark   = newSize;
        dataStoreOffset = newSize;
        return this;
    }

    private static native long  allocateNativeDataBlock(int size);
    private static native void releaseNativeDataBlock(long nativeDataAddress);
    private static native void copyNativeDataBlock(long destinationDataAddress, long sourceDataAddress, int dataSize);


    // private native packing methods ==================================================================================

    /**
     * Copies a boolean data item into an internal data store.
     * @param nativeDataAddress The address of the NativeDataBlock where the data should be copied into.
     * @param dataOffset The data offset (in bytes) into the NativeDataBlock to where the data should be copied.
     * @param data The data item to be copied.
     */
    private static native void setBoolean(long nativeDataAddress, boolean data);

    /**
     * Copies a char data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setChar   (long nativeDataAddress,    char data);

    /**
     * Copies a byte data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setByte   (long nativeDataAddress,    byte data);

    /**
     * Copies a short data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setShort  (long nativeDataAddress,   short data);

    /**
     * Copies a int data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setInt    (long nativeDataAddress,     int data);

    /**
     * Copies a long data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setLong   (long nativeDataAddress,    long data);

    /**
     * Copies a float data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setFloat  (long nativeDataAddress,   float data);

    /**
     * Copies a double data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setDouble (long nativeDataAddress,  double data);

    /**
     * Copies a String data item into an internal data store.
     * @see #setBoolean(int, boolean)
     */
    private static native void setString (long nativeDataAddress,  String data);


    /**
     * Copies a boolean data array into an internal data store.
     * @param nativeDataAddress The address of the internal data store where the data should be copied into.
     * @param dataOffset The data offset (in bytes) into the internal data store to where the data should be copied.
     * @param array The data array to be copied.
     * @param arrayOffset The offset (in elements) in the data array from where the copy should start.
     * @param length The number of elements from the data array to be copied.
     */
    private static native void copyFromBooleanArray(long nativeDataAddress, boolean[] array, int arrayOffset, int length);

    /**
     * Copies a char data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromCharArray   (long nativeDataAddress,    char[] array, int arrayOffset, int length);

    /**
     * Copies a byte data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromByteArray   (long nativeDataAddress,    byte[] array, int arrayOffset, int length);

    /**
     * Copies a short data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromShortArray  (long nativeDataAddress,   short[] array, int arrayOffset, int length);

    /**
     * Copies a int data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromIntArray    (long nativeDataAddress,     int[] array, int arrayOffset, int length);

    /**
     * Copies a long data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromLongArray   (long nativeDataAddress,    long[] array, int arrayOffset, int length);

    /**
     * Copies a float data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromFloatArray  (long nativeDataAddress,   float[] array, int arrayOffset, int length);

    /**
     * Copies a double data array into an internal data store.
     * @see #copyFromBooleanArray(int, boolean[], int, int)
     */
    private static native void copyFromDoubleArray (long nativeDataAddress,  double[] array, int arrayOffset, int length);


    // public packing methods ==========================================================================================

    /**
     * Copies the contence of a source Memory object.
     * The data is copied starting at the current value of the dataStoreOffset.
     * The dataStoreOffset is updated after the operation.
     * @param source The Memory object to be copied.
     * @throws NoRoomException This exception is thrown if an attempt is made to write outside
     * the allocated area.
     */
    public MutableMemory copyFromMemory(Memory source) throws NoRoomException
    {
        if(dataStoreOffset+source.highWaterMark > allocatedSize) throw new NoRoomException();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -