JavaScript is disabled on your browser.
javolution.io

Class Struct

  • Direct Known Subclasses:
    Union


    @Realtime
    public class Struct
    extends Object 

    Equivalent to a C/C++ struct; this class confers interoperability between Java classes and C/C++ struct.

    Unlike C/C++, the storage layout of Java objects is not determined by the compiler. The layout of objects in memory is deferred to run time and determined by the interpreter (or just-in-time compiler). This approach allows for dynamic loading and binding; but also makes interfacing with C/C++ code difficult. Hence, this class for which the memory layout is defined by the initialization order of the Struct's members and follows the same wordSize rules as C/C++ structs.

    This class (as well as the Union sub-class) facilitates:

    • Memory sharing between Java applications and native libraries.
    • Direct encoding/decoding of streams for which the structure is defined by legacy C/C++ code.
    • Serialization/deserialization of Java objects (complete control, e.g. no class header)
    • Mapping of Java objects to physical addresses (with JNI).

    Because of its one-to-one mapping, it is relatively easy to convert C header files (e.g. OpenGL bindings) to Java Struct/Union using simple text macros. Here is an example of C struct:

     enum Gender{MALE, FEMALE};
     struct Date {
     unsigned short year;
     unsigned byte month;
     unsigned byte day;
     };
     struct Student {
     enum Gender gender;
     char name[64];
     struct Date birth;
     float grades[10];
     Student* next;
     };
    and here is the Java equivalent using this class:
     public enum Gender { MALE, FEMALE };
     public static class Date extends Struct {
     public final Unsigned16 year = new Unsigned16();
     public final Unsigned8 month = new Unsigned8();
     public final Unsigned8 day = new Unsigned8();
     }
     public static class Student extends Struct {
     public final Enum32<Gender> gender = new Enum32<Gender>(Gender.values());
     public final UTF8String name = new UTF8String(64);
     public final Date birth = inner(new Date());
     public final Float32[] grades = array(new Float32[10]);
     public final Reference32<Student> next = new Reference32<Student>();
     }
    Struct's members are directly accessible:
     Student student = new Student();
     student.gender.set(Gender.MALE);
     student.name.set("John Doe"); // Null terminated (C compatible)
     int age = 2003 - student.birth.year.get();
     student.grades[2].set(12.5f);
     student = student.next.get();

    Applications can work with the raw bytes directly. The following illustrate how Struct can be used to decode/encode UDP messages directly:

     class UDPMessage extends Struct {
     Unsigned16 xxx = new Unsigned16();
     ...
     }
     public void run() {
     byte[] bytes = new byte[1024];
     DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
     UDPMessage message = new UDPMessage();
     message.setByteBuffer(ByteBuffer.wrap(bytes), 0);
     // packet and message are now two different views of the same data.
     while (isListening) {
     multicastSocket.receive(packet);
     int xxx = message.xxx.get();
     ... // Process message fields directly.
     }
     }

    It is relatively easy to map instances of this class to any physical address using JNI. Here is an example:

     import java.nio.ByteBuffer;
     class Clock extends Struct { // Hardware clock mapped to memory.
     Unsigned16 seconds = new Unsigned16(5); // unsigned short seconds:5
     Unsigned16 minutes = new Unsigned16(5); // unsigned short minutes:5
     Unsigned16 hours = new Unsigned16(4); // unsigned short hours:4
     Clock() {
     setByteBuffer(Clock.nativeBuffer(), 0);
     }
     private static native ByteBuffer nativeBuffer();
     }
    Below is the nativeBuffer() implementation (Clock.c):
     #include <jni.h>
     #include "Clock.h" // Generated using javah
     JNIEXPORT jobject JNICALL Java_Clock_nativeBuffer (JNIEnv *env, jclass) {
     return (*env)->NewDirectByteBuffer(env, clock_address, buffer_size)
     }

    Bit-fields are supported (see Clock example above). Bit-fields allocation order is defined by the Struct byteOrder() return value. Leftmost bit to rightmost bit if BIG_ENDIAN and rightmost bit to leftmost bit if LITTLE_ENDIAN (same layout as Microsoft Visual C++). C/C++ Bit-fields cannot straddle the storage-unit boundary as defined by their base type (padding is inserted at the end of the first bit-field and the second bit-field is put into the next storage unit). It is possible to avoid bit padding by using the Struct.BitField member (or a sub-class). In which case the allocation order is always from the leftmost to the rightmost bit (same as BIG_ENDIAN).

    Finally, it is possible to change the ByteBuffer and/or the Struct position in its ByteBuffer to allow for a single Struct object to encode/decode multiple memory mapped instances.

    Note: Because Struct/Union are basically wrappers around java.nio.ByteBuffer, tutorials/usages for the Java NIO package are directly applicable to Struct/Union.

    Version:
    5.5.1, April 1, 2010
    Author:
    Jean-Marie Dautelle
    • Nested Class Summary

      Nested Classes
      Modifier and Type Class and Description
      class Struct.BitField
      This class represents an arbitrary size (unsigned) bit field with no word size constraint (they can straddle words boundaries).
      class Struct.Bool
      This class represents a 8 bits boolean with true represented by 1 and false represented by 0.
      class Struct.Enum16<T extends Enum<T>>
      This class represents a 16 bits Enum.
      class Struct.Enum32<T extends Enum<T>>
      This class represents a 32 bits Enum.
      class Struct.Enum64<T extends Enum<T>>
      This class represents a 64 bits Enum.
      class Struct.Enum8<T extends Enum<T>>
      This class represents a 8 bits Enum.
      class Struct.Float32
      This class represents a 32 bits float (C/C++/Java float).
      class Struct.Float64
      This class represents a 64 bits float (C/C++/Java double).
      protected class Struct.Member
      This inner class represents the base class for all Struct members.
      class Struct.Reference32<S extends Struct>
      This class represents a 32 bits reference (C/C++ pointer) to a Struct object (other types may require a Struct wrapper).
      class Struct.Reference64<S extends Struct>
      This class represents a 64 bits reference (C/C++ pointer) to a Struct object (other types may require a Struct wrapper).
      class Struct.Signed16
      This class represents a 16 bits signed integer.
      class Struct.Signed32
      This class represents a 32 bits signed integer.
      class Struct.Signed64
      This class represents a 64 bits signed integer.
      class Struct.Signed8
      This class represents a 8 bits signed integer.
      class Struct.Unsigned16
      This class represents a 16 bits unsigned integer.
      class Struct.Unsigned32
      This class represents a 32 bits unsigned integer.
      class Struct.Unsigned8
      This class represents a 8 bits unsigned integer.
      class Struct.UTF8String
      This class represents a UTF-8 character string, null terminated (for C/C++ compatibility)
    • Constructor Summary

      Constructors
      Constructor and Description
      Struct ()
      Default constructor.
    • Method Summary

      Methods
      Modifier and Type Method and Description
      long address ()
      Returns this struct address.
      protected <M extends Struct.Member>
      M[]
      array (M[] arrayMember)
      Defines the specified array member.
      protected <M extends Struct.Member>
      M[][]
      array (M[][] arrayMember)
      Defines the specified two-dimensional array member.
      protected <M extends Struct.Member>
      M[][][]
      array (M[][][] arrayMember)
      Defines the specified three-dimensional array member.
      protected <S extends Struct>
      S[]
      array (S[] structs)
      Defines the specified array of structs as inner structs.
      protected <S extends Struct>
      S[][]
      array (S[][] structs)
      Defines the specified two-dimensional array of structs as inner structs.
      protected <S extends Struct>
      S[][][]
      array (S[][][] structs)
      Defines the specified three dimensional array of structs as inner structs.
      protected Struct.UTF8String[] array (Struct.UTF8String[] array, int stringLength)
      Defines the specified array of UTF-8 strings, all strings having the specified length (convenience method).
      ByteOrder byteOrder ()
      Returns the byte order for this struct (configurable).
      ByteBuffer getByteBuffer ()
      Returns the byte buffer for this struct.
      int getByteBufferPosition ()
      Returns the absolute byte position of this struct within its associated byte buffer.
      protected <S extends Struct>
      S
      inner (S struct)
      Defines the specified struct as inner of this struct.
      boolean isPacked ()
      Indicates if this struct is packed (configurable).
      boolean isUnion ()
      Indicates if this struct's members are mapped to the same location in memory (default false).
      Struct outer ()
      Returns the outer of this struct or null if this struct is not an inner struct.
      int read (InputStream in)
      Reads this struct from the specified input stream (convenience method when using Stream I/O).
      long readBits (int bitOffset, int bitSize)
      Reads the specified bits from this Struct as an long (signed) integer value.
      Struct setByteBuffer (ByteBuffer byteBuffer, int position)
      Sets the current byte buffer for this struct.
      Struct setByteBufferPosition (int position)
      Sets the byte position of this struct within its byte buffer.
      int size ()
      Returns the size in bytes of this struct.
      String toString ()
      Returns the String representation of this struct in the form of its constituing bytes (hexadecimal).
      void write (OutputStream out)
      Writes this struct to the specified output stream (convenience method when using Stream I/O).
      void writeBits (long value, int bitOffset, int bitSize)
      Writes the specified bits into this Struct.
    • Field Detail

      • MAXIMUM_ALIGNMENT

        public static final LocalContext.Parameter<Integer> MAXIMUM_ALIGNMENT
        Configurable holding the maximum wordSize in bytes (default 4). Should be a value greater or equal to 1.
    • Constructor Detail

      • Struct

        public Struct()
        Default constructor.
    • Method Detail

      • size

        public final int size()
        Returns the size in bytes of this struct. The size includes tail padding to satisfy the struct word size requirement (defined by the largest word size of its members).
        Returns:
        the C/C++ sizeof(this).
      • outer

        public Struct outer()
        Returns the outer of this struct or null if this struct is not an inner struct.
        Returns:
        the outer struct or null.
      • getByteBuffer

        public final ByteBuffer getByteBuffer()
        Returns the byte buffer for this struct. This method will allocate a new direct buffer if none has been set.

        Changes to the buffer's content are visible in this struct, and vice versa.

        The buffer of an inner struct is the same as its parent struct.

        If no byte buffer has been set, a direct buffer is allocated with a capacity equals to this struct's size.

        Returns:
        the current byte buffer or a new direct buffer if none set.
        See Also:
        setByteBuffer(java.nio.ByteBuffer, int)
      • setByteBuffer

        public final Struct setByteBuffer(ByteBuffer byteBuffer,
         int position)
        Sets the current byte buffer for this struct. The specified byte buffer can be mapped to memory for direct memory access or can wrap a shared byte array for I/O purpose (e.g. DatagramPacket). The capacity of the specified byte buffer should be at least the size of this struct plus the offset position.
        Parameters:
        byteBuffer - the new byte buffer.
        position - the position of this struct in the specified byte buffer.
        Returns:
        this
        Throws:
        IllegalArgumentException - if the specified byteBuffer has a different byte order than this struct.
        UnsupportedOperationException - if this struct is an inner struct.
        See Also:
        byteOrder()
      • setByteBufferPosition

        public final Struct setByteBufferPosition(int position)
        Sets the byte position of this struct within its byte buffer.
        Parameters:
        position - the position of this struct in its byte buffer.
        Returns:
        this
        Throws:
        UnsupportedOperationException - if this struct is an inner struct.
      • getByteBufferPosition

        public final int getByteBufferPosition()
        Returns the absolute byte position of this struct within its associated byte buffer.
        Returns:
        the absolute position of this struct (can be an inner struct) in the byte buffer.
      • read

        public int read(InputStream in)
         throws IOException 
        Reads this struct from the specified input stream (convenience method when using Stream I/O). For better performance, use of Block I/O (e.g. java.nio.channels.*) is recommended. This method behaves appropriately when not all of the data is available from the input stream. Incomplete data is extremely common when the input stream is associated with something like a TCP connection. The typical usage pattern in those scenarios is to repeatedly call read() until the entire message is received.
        Parameters:
        in - the input stream being read from.
        Returns:
        the number of bytes read (typically the size of this struct.
        Throws:
        IOException - if an I/O error occurs.
      • write

        public void write(OutputStream out)
         throws IOException 
        Writes this struct to the specified output stream (convenience method when using Stream I/O). For better performance, use of Block I/O (e.g. java.nio.channels.*) is recommended.
        Parameters:
        out - the output stream to write to.
        Throws:
        IOException - if an I/O error occurs.
      • toString

        public String toString()
        Returns the String representation of this struct in the form of its constituing bytes (hexadecimal). For example:
         public static class Student extends Struct {
         Utf8String name = new Utf8String(16);
         Unsigned16 year = new Unsigned16();
         Float32 grade = new Float32();
         }
         Student student = new Student();
         student.name.set("John Doe");
         student.year.set(2003);
         student.grade.set(12.5f);
         System.out.println(student);
         4A 6F 68 6E 20 44 6F 65 00 00 00 00 00 00 00 00
         07 D3 00 00 41 48 00 00
        Overrides:
        toString in class Object
        Returns:
        a hexadecimal representation of the bytes content for this struct.
      • isUnion

        public boolean isUnion()
        Indicates if this struct's members are mapped to the same location in memory (default false). This method is useful for applications extending Struct with new member types in order to create unions from these new structs. For example:
         public abstract class FortranStruct extends Struct {
         public class FortranString extends Member {...}
         protected FortranString[] array(FortranString[] array, int stringLength) { ... }
         }
         public abstract class FortranUnion extends FortranStruct {
         // Inherits new members and methods.
         public final isUnion() {
         return true;
         }
         }
        Returns:
        true if this struct's members are mapped to to the same location in memory; false otherwise.
        See Also:
        Union
      • byteOrder

        public ByteOrder byteOrder()
        Returns the byte order for this struct (configurable). The byte order is inherited by inner structs. Sub-classes may change the byte order by overriding this method. For example:
         public class TopStruct extends Struct {
         ... // Members initialization.
         public ByteOrder byteOrder() {
         // TopStruct and its inner structs use hardware byte order.
         return ByteOrder.nativeOrder();
         }
         }}

        Returns:
        the byte order when reading/writing multibyte values (default: network byte order, BIG_ENDIAN).
      • isPacked

        public boolean isPacked()
        Indicates if this struct is packed (configurable). By default, members of a struct are aligned on the boundary corresponding to the member base type; padding is performed if necessary. This directive is not inherited by inner structs. Sub-classes may change the packing directive by overriding this method. For example:
         public class MyStruct extends Struct {
         ... // Members initialization.
         public boolean isPacked() {
         return true; // MyStruct is packed.
         }
         }}
        Returns:
        true if word size requirements are ignored. false otherwise (default).
      • inner

        protected <S extends Struct> S inner(S struct)
        Defines the specified struct as inner of this struct.
        Parameters:
        struct - the inner struct.
        Returns:
        the specified struct.
        Throws:
        IllegalArgumentException - if the specified struct is already an inner struct.
      • array

        protected <S extends Struct> S[] array(S[] structs)
        Defines the specified array of structs as inner structs. The array is populated if necessary using the struct component default constructor (which must be public).
        Parameters:
        structs - the struct array.
        Returns:
        the specified struct array.
        Throws:
        IllegalArgumentException - if the specified array contains inner structs.
      • array

        protected <S extends Struct> S[][] array(S[][] structs)
        Defines the specified two-dimensional array of structs as inner structs. The array is populated if necessary using the struct component default constructor (which must be public).
        Parameters:
        structs - the two dimensional struct array.
        Returns:
        the specified struct array.
        Throws:
        IllegalArgumentException - if the specified array contains inner structs.
      • array

        protected <S extends Struct> S[][][] array(S[][][] structs)
        Defines the specified three dimensional array of structs as inner structs. The array is populated if necessary using the struct component default constructor (which must be public).
        Parameters:
        structs - the three dimensional struct array.
        Returns:
        the specified struct array.
        Throws:
        IllegalArgumentException - if the specified array contains inner structs.
      • array

        protected <M extends Struct.Member> M[] array(M[] arrayMember)
        Defines the specified array member. For predefined members, the array is populated when empty; custom members should use literal (populated) arrays.
        Parameters:
        arrayMember - the array member.
        Returns:
        the specified array member.
        Throws:
        UnsupportedOperationException - if the specified array is empty and the member type is unknown.
      • array

        protected <M extends Struct.Member> M[][] array(M[][] arrayMember)
        Defines the specified two-dimensional array member. For predefined members, the array is populated when empty; custom members should use literal (populated) arrays.
        Parameters:
        arrayMember - the two-dimensional array member.
        Returns:
        the specified array member.
        Throws:
        UnsupportedOperationException - if the specified array is empty and the member type is unknown.
      • array

        protected <M extends Struct.Member> M[][][] array(M[][][] arrayMember)
        Defines the specified three-dimensional array member. For predefined members, the array is populated when empty; custom members should use literal (populated) arrays.
        Parameters:
        arrayMember - the three-dimensional array member.
        Returns:
        the specified array member.
        Throws:
        UnsupportedOperationException - if the specified array is empty and the member type is unknown.
      • array

        protected Struct.UTF8String[] array(Struct.UTF8String[] array,
         int stringLength)
        Defines the specified array of UTF-8 strings, all strings having the specified length (convenience method).
        Parameters:
        array - the string array.
        stringLength - the length of the string elements.
        Returns:
        the specified string array.
      • readBits

        public long readBits(int bitOffset,
         int bitSize)
        Reads the specified bits from this Struct as an long (signed) integer value.
        Parameters:
        bitOffset - the bit start position in the Struct.
        bitSize - the number of bits.
        Returns:
        the specified bits read as a signed long.
        Throws:
        IllegalArgumentException - if (bitOffset + bitSize - 1) / 8>= this.size()
      • writeBits

        public void writeBits(long value,
         int bitOffset,
         int bitSize)
        Writes the specified bits into this Struct.
        Parameters:
        value - the bits value as a signed long.
        bitOffset - the bit start position in the Struct.
        bitSize - the number of bits.
        Throws:
        IllegalArgumentException - if (bitOffset + bitSize - 1) / 8>= this.size()

Copyright © 2005-2013 Javolution. All Rights Reserved.

AltStyle によって変換されたページ (->オリジナル) /