@@ -89,48 +89,79 @@ public AttributeMessage(int version, HdfString name, DatatypeMessage datatypeMes
8989 /**
9090 * Parses an AttributeMessage from the provided data and file context.
9191 *
92- * @param flags message flags
93- * @param data the byte array containing the message data
94- * @param hdfDataFile the HDF5 file context for global heap and other resources
92+ * @param messageFlags message flags
93+ * @param data the byte array containing the message data
94+ * @param hdfDataFile the HDF5 file context for global heap and other resources
9595 * @return a new AttributeMessage instance parsed from the data
9696 */
97- public static HdfMessage parseHeaderMessage (int flags , byte [] data , HdfDataFile hdfDataFile ) throws InvocationTargetException , InstantiationException , IllegalAccessException , IOException {
97+ public static HdfMessage parseHeaderMessage (int messageFlags , byte [] data , HdfDataFile hdfDataFile ) throws InvocationTargetException , InstantiationException , IllegalAccessException , IOException {
9898 ByteBuffer buffer = ByteBuffer .wrap (data ).order (ByteOrder .LITTLE_ENDIAN );
9999 // Read the version (1 byte)
100100 int version = Byte .toUnsignedInt (buffer .get ());
101101
102- // Skip the reserved byte (1 byte, should be zero)
103- buffer .get ();
104-
105- // Read the sizes of name, datatype, and dataspace (2 bytes each)
106- int nameSize = Short .toUnsignedInt (buffer .getShort ());
107- int datatypeSize = Short .toUnsignedInt (buffer .getShort ());
108- int dataspaceSize = Short .toUnsignedInt (buffer .getShort ());
109-
110- // Read the name (variable size)
111- byte [] nameBytes = new byte [nameSize ];
112- buffer .get (nameBytes );
113- BitSet bitSet = StringDatatype .createClassBitField (StringDatatype .PaddingType .NULL_TERMINATE , StringDatatype .CharacterSet .ASCII );
114- HdfString name = new HdfString (nameBytes , new StringDatatype (StringDatatype .createClassAndVersion (), bitSet , nameSize , hdfDataFile ));
115- // get padding bytes
116- int padding = (8 - (nameSize % 8 )) % 8 ;
117- byte [] paddingBytes = new byte [padding ];
118- buffer .get (paddingBytes );
119-
120- byte [] dtBytes = new byte [datatypeSize ];
121- buffer .get (dtBytes );
122- // get padding bytes
123- padding = (8 - (datatypeSize % 8 )) % 8 ;
124- paddingBytes = new byte [padding ];
125- buffer .get (paddingBytes );
126-
127- byte [] dsBytes = new byte [dataspaceSize ];
128- buffer .get (dsBytes );
129- // get padding bytes
130- padding = (8 - (dataspaceSize % 8 )) % 8 ;
131- paddingBytes = new byte [padding ];
132- buffer .get (paddingBytes );
102+ int nameSize ;
103+ int datatypeSize ;
104+ int dataspaceSize ;
105+ HdfString name ;
106+
107+ byte [] dtBytes ;
108+ byte [] dsBytes ;
109+
110+ if (version == 1 ) {
111+ // Version 1 requires 8-byte padding between fields.
112+ buffer .get (); // Skip reserved byte
113+ nameSize = Short .toUnsignedInt (buffer .getShort ());
114+ datatypeSize = Short .toUnsignedInt (buffer .getShort ());
115+ dataspaceSize = Short .toUnsignedInt (buffer .getShort ());
116+
117+ byte [] nameBytes = new byte [nameSize ];
118+ buffer .get (nameBytes );
119+ BitSet bitSet = StringDatatype .createClassBitField (StringDatatype .PaddingType .NULL_TERMINATE , StringDatatype .CharacterSet .ASCII );
120+ name = new HdfString (nameBytes , new StringDatatype (StringDatatype .createClassAndVersion (), bitSet , nameSize , hdfDataFile ));
121+
122+ // Apply 8-byte alignment padding after the name
123+ buffer .position ((buffer .position () + 7 ) & ~7 );
124+
125+ dtBytes = new byte [datatypeSize ];
126+ buffer .get (dtBytes );
127+ // Apply 8-byte alignment padding after the datatype
128+ buffer .position ((buffer .position () + 7 ) & ~7 );
129+
130+ dsBytes = new byte [dataspaceSize ];
131+ buffer .get (dsBytes );
132+ // Apply 8-byte alignment padding after the dataspace
133+ buffer .position ((buffer .position () + 7 ) & ~7 );
134+
135+ } else if (version == 2 || version == 3 ) {
136+ // Versions 2 & 3 have NO PADDING between fields.
137+ buffer .get (); // Read flags (for v3) or reserved byte (for v2)
138+ nameSize = Short .toUnsignedInt (buffer .getShort ());
139+ datatypeSize = Short .toUnsignedInt (buffer .getShort ());
140+ dataspaceSize = Short .toUnsignedInt (buffer .getShort ());
141+
142+ StringDatatype .CharacterSet characterSet = StringDatatype .CharacterSet .ASCII ;
143+ if (version == 3 ) {
144+ byte charSetByte = buffer .get ();
145+ characterSet = (charSetByte == 0 ) ? StringDatatype .CharacterSet .ASCII : StringDatatype .CharacterSet .UTF8 ;
146+ }
147+
148+ byte [] nameBytes = new byte [nameSize ];
149+ buffer .get (nameBytes );
150+ BitSet bitSet = StringDatatype .createClassBitField (StringDatatype .PaddingType .NULL_TERMINATE , characterSet );
151+ name = new HdfString (nameBytes , new StringDatatype (StringDatatype .createClassAndVersion (), bitSet , nameSize , hdfDataFile ));
152+
153+ // Read fields sequentially with no padding
154+ dtBytes = new byte [datatypeSize ];
155+ buffer .get (dtBytes );
156+
157+ dsBytes = new byte [dataspaceSize ];
158+ buffer .get (dsBytes );
133159
160+ } else {
161+ throw new IOException ("Unsupported AttributeMessage version: " + version );
162+ }
163+
164+ // --- (This section is restored to your original code) ---
134165 HdfMessage hdfDataObjectHeaderDt = parseHeaderMessage (MessageType .DATATYPE_MESSAGE , (byte ) 0 , dtBytes , hdfDataFile );
135166 DatatypeMessage dt = (DatatypeMessage ) hdfDataObjectHeaderDt ;
136167 HdfMessage hdfDataObjectHeaderDs = parseHeaderMessage (MessageType .DATASPACE_MESSAGE , (byte ) 0 , dsBytes , hdfDataFile );
@@ -146,7 +177,7 @@ public static HdfMessage parseHeaderMessage(int flags, byte[] data, HdfDataFile
146177 byte [] dataBytes = new byte [dtDataSize ];
147178 buffer .get (dataBytes );
148179 HdfData scalarValue = dt .getHdfDatatype ().getInstance (HdfData .class , dataBytes );
149- return new AttributeMessage (version , name , dt , ds , HdfDataHolder .ofScalar (scalarValue ), flags , data .length );
180+ return new AttributeMessage (version , name , dt , ds , HdfDataHolder .ofScalar (scalarValue ), messageFlags , data .length );
150181 }
151182
152183 // Case 2: Array data (dimensionality is 1 or more)
@@ -160,15 +191,12 @@ public static HdfMessage parseHeaderMessage(int flags, byte[] data, HdfDataFile
160191 dimensions = Arrays .copyOfRange (dimensions , 0 , count );
161192
162193 // Step 1: Create the n-dimensional array dynamically.
163- // Array.newInstance() is the key. It can create an array of any type with any dimensions.
164- // Example: Array.newInstance(HdfData.class, 2, 3) creates a HdfData[2][3]
165194 Object multiDimArray = Array .newInstance (HdfData .class , dimensions );
166195
167196 // Step 2: Populate the array recursively from the flat buffer.
168197 populateArray (multiDimArray , dimensions , 0 , buffer , dt .getHdfDatatype (), dtDataSize );
169198
170- return new AttributeMessage (version , name , dt , ds , HdfDataHolder .ofArray (multiDimArray , dimensions ), flags , data .length );
171-
199+ return new AttributeMessage (version , name , dt , ds , HdfDataHolder .ofArray (multiDimArray , dimensions ), messageFlags , data .length );
172200 }
173201
174202 /**
0 commit comments