Package io.sisu.nng

Class Message

  • All Implemented Interfaces:
    java.lang.AutoCloseable

    public class Message
    extends java.lang.Object
    implements java.lang.AutoCloseable

    Wraps the native NNG message structure and provides convenience methods for ferrying data to and from the JVM.

    Note: Per NNG's design, Message's may change "ownership" when being sent, which is a paradigm not native to Java. The valid flag is designed to indicate if it's safe to continue mutating the Message in the JVM (valid: true) or if it's expected that the Message is owned by the native NNG layer (and expected to have its backing memory freed automatically).

    • Field Summary

      Fields 
      Modifier and Type Field Description
      static java.util.concurrent.atomic.AtomicInteger created  
      static java.util.concurrent.atomic.AtomicInteger freed  
      static java.util.concurrent.atomic.AtomicInteger invalidated  
      protected java.util.concurrent.atomic.AtomicBoolean valid  
    • Constructor Summary

      Constructors 
      Constructor Description
      Message()
      Allocate a new Message with a 0-byte Body
      Message​(int size)
      Allocate a new NNG Message of the given size.
      Message​(com.sun.jna.Pointer pointer)  
      Message​(MessagePointer pointer)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void append​(byte[] data)
      Append the given byte array to the body of the Message
      void append​(com.sun.jna.Pointer p, int size)  
      void append​(java.lang.String s)
      Convenience method for appending a Java String to the Message body, assuming UTF-8 encoding.
      void append​(java.lang.String s, java.nio.charset.Charset charset)
      Convenience method for appending a Java String to the Message body using the given Charset.
      void append​(java.nio.ByteBuffer data)
      Append data from the given ByteBuffer to the body of the Message, reallocating if necessary.
      void appendToHeader​(java.nio.ByteBuffer data)
      Append data from a ByteBuffer to the header of the Message, increasing the allocation for the header if required.
      void appendU16​(int i)
      Append an unsigned, 16-bit number in network byte order to the Message's body
      void appendU32​(int i)
      Append an unsigned, 32-bit number in network byte order to the Message's body
      void appendU64​(long i)
      Append an unsigned, 64-bit number in network byte order to the Message's body
      void close()  
      protected void finalize()
      Cleanup the Message, attempting to free it if required.
      void free()
      Attempt to deallocate the underlying nng_msg, releasing unmanaged memory.
      java.nio.ByteBuffer getBody()
      Returns a native ByteBuffer backed by the message's body data.
      java.nio.ByteBuffer getBodyCopy()
      Convenience method to extract data from native memory onto the JVM by allocating a non-native ByteBuffer and copying the data into it.
      int getBodyLen()
      Get the current length of the Message's body in bytes.
      java.nio.ByteBuffer getHeader()
      Get a reference to the Message's header as a direct ByteBuffer, allowing for read/write access.
      int getHeaderLen()
      Get the current length of the Message's header in bytes.
      MessagePointer getMessagePointer()  
      void insertToHeader​(java.nio.ByteBuffer data)
      Insert data from a ByteBuffer to the front of the header of the Message.
      void insertU16​(int i)
      Prepends an unsigned, 16-bit number in network byte order to the Message's body
      void insertU32​(int i)
      Prepends an unsigned, 32-bit number in network byte order to the Message's body
      void insertU64​(long i)
      Prepends an unsigned, 64-bit number in network byte order to the Message's body
      boolean isValid()
      Check if the Message is still valid or not.
      void setInvalid()
      Set the message invalid, preventing the JVM from attempting to free the underlying native memory during garbage collection.
      void setValid()
      Set the Message state back to valid and owned by the JVM.
      void trim​(int len)
      Removes bytes from the start of the Message body.
      int trim32Bits()
      Removes 32 bits from the start of the Message body, returning then in network byte order.
      • Methods inherited from class java.lang.Object

        clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • created

        public static java.util.concurrent.atomic.AtomicInteger created
      • freed

        public static java.util.concurrent.atomic.AtomicInteger freed
      • invalidated

        public static java.util.concurrent.atomic.AtomicInteger invalidated
      • valid

        protected java.util.concurrent.atomic.AtomicBoolean valid
    • Constructor Detail

      • Message

        public Message()
                throws NngException
        Allocate a new Message with a 0-byte Body
        Throws:
        NngException - if failed to allocate a new Message
      • Message

        public Message​(int size)
                throws NngException
        Allocate a new NNG Message of the given size. Equivalent to a call to
        nng_msg_alloc
        Parameters:
        size - number of bytes to allocate for the message
        Throws:
        NngException - if nng_msg_alloc fails
    • Method Detail

      • appendToHeader

        public void appendToHeader​(java.nio.ByteBuffer data)
                            throws NngException
        Append data from a ByteBuffer to the header of the Message, increasing the allocation for the header if required.
        Parameters:
        data - the ByteBuffer with the data
        Throws:
        NngException - on failure to append
      • insertToHeader

        public void insertToHeader​(java.nio.ByteBuffer data)
                            throws NngException
        Insert data from a ByteBuffer to the front of the header of the Message.

        Note: the insertion does not occur "at a position" and will prepend the data. If looking to flip specific bits in the existing header, use getHeader() and manipulate it.

        Parameters:
        data - the ByteBuffer with the data
        Throws:
        NngException - on failure to append
      • append

        public void append​(java.nio.ByteBuffer data)
                    throws NngException
        Append data from the given ByteBuffer to the body of the Message, reallocating if necessary.
        Parameters:
        data - the ByteBuffer with the data for appending
        Throws:
        NngException - on failure to append
      • append

        public void append​(byte[] data)
                    throws NngException
        Append the given byte array to the body of the Message
        Parameters:
        data - an array of bytes to append
        Throws:
        NngException - on error
      • append

        public void append​(java.lang.String s,
                           java.nio.charset.Charset charset)
                    throws NngException
        Convenience method for appending a Java String to the Message body using the given Charset.

        Similar to using String.getBytes(Charset) and append(byte[])

        Parameters:
        s - the String to append
        charset - the charset used for interpreting the String
        Throws:
        NngException - if the call to nng_msg_append fails
      • append

        public void append​(java.lang.String s)
                    throws NngException
        Convenience method for appending a Java String to the Message body, assuming UTF-8 encoding.
        Parameters:
        s - the String to append
        Throws:
        NngException - on error appending
      • appendU16

        public void appendU16​(int i)
                       throws NngException
        Append an unsigned, 16-bit number in network byte order to the Message's body
        Parameters:
        i - the number to append
        Throws:
        NngException - on error
      • appendU32

        public void appendU32​(int i)
                       throws NngException
        Append an unsigned, 32-bit number in network byte order to the Message's body
        Parameters:
        i - the number to append
        Throws:
        NngException - on error
      • appendU64

        public void appendU64​(long i)
                       throws NngException
        Append an unsigned, 64-bit number in network byte order to the Message's body
        Parameters:
        i - the number to append
        Throws:
        NngException - on error
      • insertU16

        public void insertU16​(int i)
                       throws NngException
        Prepends an unsigned, 16-bit number in network byte order to the Message's body
        Parameters:
        i - the number to append
        Throws:
        NngException - on error
      • insertU32

        public void insertU32​(int i)
                       throws NngException
        Prepends an unsigned, 32-bit number in network byte order to the Message's body
        Parameters:
        i - the number to append
        Throws:
        NngException - on error
      • insertU64

        public void insertU64​(long i)
                       throws NngException
        Prepends an unsigned, 64-bit number in network byte order to the Message's body
        Parameters:
        i - the number to append
        Throws:
        NngException - on error
      • getBodyLen

        public int getBodyLen()
        Get the current length of the Message's body in bytes.

        Gives a measurement from native memory performed by the nng_body_len api call.

        Returns:
        size of the body in number of bytes
      • getHeaderLen

        public int getHeaderLen()
        Get the current length of the Message's header in bytes.

        Gives a measurement from native memory performed by the nng_header_len api call.

        Returns:
        size of the header in number of bytes
      • getHeader

        public java.nio.ByteBuffer getHeader()
        Get a reference to the Message's header as a direct ByteBuffer, allowing for read/write access.

        Caution!: this method exists for now until a safer API can be implemented. You will have direct access to native memory for the header. No safety net is provided. You must prevent this ByteBuffer from being garbage collected before the Message is invalidated or freed.

        Returns:
        a direct ByteBuffer accessing the header on success, or a zero-byte ByteBuffer on error
      • getBody

        public java.nio.ByteBuffer getBody()
        Returns a native ByteBuffer backed by the message's body data.

        Caution!: this method exists for now until a safer API can be implemented. You will have direct access to native memory for the body. No safety net is provided. You must prevent this ByteBuffer from being garbage collected before the Message is invalidated or freed.

        Returns:
        new native ByteBuffer or an empty ByteBuffer if body length is zero
      • getBodyCopy

        public java.nio.ByteBuffer getBodyCopy()
        Convenience method to extract data from native memory onto the JVM by allocating a non-native ByteBuffer and copying the data into it.
        Returns:
        non-native ByteBuffer containing a copy of the message body data
      • trim

        public void trim​(int len)
                  throws NngException
        Removes bytes from the start of the Message body.
        Parameters:
        len - number of bytes to remove
        Throws:
        NngException - on error
      • trim32Bits

        public int trim32Bits()
                       throws NngException
        Removes 32 bits from the start of the Message body, returning then in network byte order.

        Note: it's assumed the value is in network byte order

        Returns:
        an int value from the leading 32 bits of the message
        Throws:
        NngException - on error trimming the message
      • free

        public void free()
        Attempt to deallocate the underlying nng_msg, releasing unmanaged memory. This action only occurs if the Message is currently valid and owned by the JVM. If freed, the Message is no longer valid. Note: it's recommended that the programmer liberally make use for free() when they know their Message instance is no longer required and not to rely solely on the garbage collector. Native heap fragmentation can occur if large quantities of messages are freed, as will happen if waiting for a gc event to clean up. The end result typically is excessive memory use and in the worst cases result in out of memory conditions for the JVM process.
      • setValid

        public void setValid()
        Set the Message state back to valid and owned by the JVM. N.b. This should be used typically only when a Send of the Message fails and the nng library didn't take ownership.
      • setInvalid

        public void setInvalid()
        Set the message invalid, preventing the JVM from attempting to free the underlying native memory during garbage collection.
      • isValid

        public boolean isValid()
        Check if the Message is still valid or not.
        Returns:
        boolean whether or not the Message is valid
      • finalize

        protected void finalize()
                         throws java.lang.Throwable
        Cleanup the Message, attempting to free it if required.

        TODO: replace with the Java Cleaner api

        Overrides:
        finalize in class java.lang.Object
        Throws:
        java.lang.Throwable - only if the super's finalize throws an error
      • close

        public void close()
        Specified by:
        close in interface java.lang.AutoCloseable