Skip to content

Commit 5f0a23c

Browse files
author
Vincent Wilms
committed
Prepare release
1 parent 3f2a023 commit 5f0a23c

10 files changed

Lines changed: 22 additions & 21 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
## v2.1.4 - 2026-07-29
22

3+
- [fix(writing): emit the group info message](https://github.com/Apollo3zehn/PureHDF/pull/178)
4+
- [fix(writing): zero the padding of a fixed-length string](https://github.com/Apollo3zehn/PureHDF/pull/177)
5+
- [fix(writing): key the datatype cache by everything the message depends on](https://github.com/Apollo3zehn/PureHDF/pull/173)
6+
- [fix(writing): encode datatype names as UTF-8](https://github.com/Apollo3zehn/PureHDF/pull/171)
7+
8+
- [fix(reading): partial stream reads, cache thread safety, and group header re-decode](https://github.com/Apollo3zehn/PureHDF/pull/175)
9+
- [fix(reading): never decode strings as ASCII](https://github.com/Apollo3zehn/PureHDF/pull/170)
10+
11+
Thanks @Blackclaws for your contributions!
12+
13+
## v2.2.0 - 2026-08-16
14+
15+
## v2.1.4 - 2026-07-29
16+
317
- [Make tests runnable on Windows and with newer h5dump, with related fixes](https://github.com/Apollo3zehn/PureHDF/pull/160)
418
- Add SharedHdf5StateCollection to serialize tests using HDF5/global state, preventing failures from sharing problems.
519
- Update xUnit dependencies and add Xunit.SkippableFact for conditional test skipping.

src/PureHDF/VFD/H5StreamDriver.Reading.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ private T Read<T>() where T : unmanaged
9494
var size = Unsafe.SizeOf<T>();
9595
Span<byte> buffer = stackalloc byte[size];
9696

97-
// ReadExactly, not Read: Read's return value was discarded, so a stream that delivered fewer
98-
// bytes than asked left the rest of the value as whatever the stack slot held. Every length,
99-
// address and checksum in the file goes through here.
10097
_stream.ReadExactly(buffer);
10198

10299
return MemoryMarshal.Cast<byte, T>(buffer)[0];

src/PureHDF/VOL/Native/API.Reading/NativeGroup.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,6 @@ private bool InternalLinkExists(string path, H5LinkAccess linkAccess)
140140
var segments = isRooted ? path.Split('/').Skip(1).ToArray() : path.Split('/');
141141
var current = isRooted ? Context.File.Reference : Reference;
142142

143-
// The first hop of a RELATIVE path is this group, whose object header is already decoded and
144-
// held. Dereferencing our own reference to get it - which is what this did - builds a second
145-
// NativeGroup and decodes that header again, from the file, on every lookup.
146-
//
147-
// The cost is proportional to the number of LINKS, not to the depth of the path, because a
148-
// group that stores its links compactly keeps one header message per link: measured on a
149-
// 1000-link group written by PureHDF's own writer, one LinkExists re-read 30,113 bytes and
150-
// allocated 2.1 MB, and 2000 links doubled both. A lookup that missed cost exactly as much as
151-
// one that hit, since the whole cost was the re-decode rather than the search.
152-
//
153143
// Only the first iteration can reuse a group we already hold; every later segment names an
154144
// object not yet resolved, so this is cleared at the end of each pass.
155145
var group = isRooted ? null : this;
@@ -183,7 +173,8 @@ internal NativeNamedReference InternalGet(string path, H5LinkAccess linkAccess)
183173
var segments = isRooted ? path.Split('/').Skip(1).ToArray() : path.Split('/');
184174
var current = isRooted ? Context.File.Reference : Reference;
185175

186-
// See InternalLinkExists for why the first hop of a relative path reuses this group.
176+
// Only the first iteration can reuse a group we already hold; every later segment names an
177+
// object not yet resolved, so this is cleared at the end of each pass.
187178
var group = isRooted ? null : this;
188179

189180
for (int i = 0; i < segments.Length; i++)

src/PureHDF/VOL/Native/Core.Writing/H5NativeWriter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ internal ulong EncodeGroup(
161161
// No flags, which means the reader applies its own defaults for those thresholds (8 compact /
162162
// 6 dense in the C library). Declaring values here would state a policy this writer does not
163163
// implement, since it always stores links compactly.
164+
//
165+
// See https://github.com/HDFGroup/hdf5/issues/6616 for more info.
164166
var groupInfoMessage = new GroupInfoMessage(
165167
Flags: default,
166168
MaximumCompactValue: default,

src/PureHDF/VOL/Native/FileFormat/Level2/ObjectHeaderMessages/Datatype/DatatypeMessage.Writing.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -732,11 +732,8 @@ void encode(object source, IH5WriteStream target)
732732
else
733733
{
734734
using var paddingBufferOwner = MemoryPool<byte>.Shared.Rent(padding);
735+
735736
var paddingBuffer = paddingBufferOwner.Memory.Span[..padding];
736-
737-
// Rent does not zero the buffer, so without this the padding written to the file is
738-
// whatever was last in that pooled memory. The stackalloc branch above clears for the
739-
// same reason.
740737
paddingBuffer.Clear();
741738

742739
target.WriteDataset(paddingBuffer);

src/PureHDF/VOL/Native/FileFormat/Level2/ObjectHeaderMessages/Datatype/DatatypePropertyDescriptions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ public override ushort GetEncodeSize(uint typeSize)
206206

207207
public override void Encode(H5DriverBase driver, uint typeSize)
208208
{
209-
// name
210209
// The specification gives a compound member name no character set field, and the
211210
// reference library copies it as an opaque NUL-terminated byte string
212211
// (H5MM_xstrdup in H5Odtype.c), so whatever bytes the caller supplied are stored.

src/PureHDF/VOL/Native/FileFormat/Level2/ObjectHeaderMessages/GroupInfo/GroupInfoMessage.cs renamed to src/PureHDF/VOL/Native/FileFormat/Level2/ObjectHeaderMessages/GroupInfo/GroupInfoMessage.Reading.cs

File renamed without changes.

src/PureHDF/VOL/Native/FileFormat/Level2/ObjectHeaderMessages/Link/LinkInfoMessage.Reading.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ public static LinkInfoMessage Decode(NativeReadContext context)
7777
{
7878

7979
var (driver, superblock) = context;
80-
var b = driver.Position;
8180

8281
// version
8382
var version = driver.ReadByte();

tests/PureHDF.Tests/Writing/DatatypeTests@NonAsciiNames.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ namespace PureHDF.Tests.Writing;
1212
/// every byte >= 0x80 with <c>'?'</c>, destroying the name before any reader is involved.
1313
/// <para>These assertions go through h5dump rather than PureHDF's own reader, so they check
1414
/// what actually reached the file.</para>
15+
///
16+
/// More info: https://github.com/HDFGroup/hdf5/issues/6610
1517
/// </summary>
1618
[Collection(SharedHdf5StateCollection.Name)]
1719
public class NonAsciiNameWritingTests

version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"version": "2.1.4",
2+
"version": "2.2.0",
33
"suffix": ""
44
}

0 commit comments

Comments
 (0)