Repository navigation
Expand file tree
/
Copy pathNumpyDtypeParser.cs
More file actions
71 lines (63 loc) · 2.82 KB
/
Copy pathNumpyDtypeParser.cs
File metadata and controls
71 lines (63 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
namespace ZarrNET;
/// <summary>
/// Parses numpy-style dtype strings used in Zarr v2.
/// Format: [byteorder][typecode][size]
/// byteorder: '<' (little), '>' (big), '|' (not applicable)
/// typecode: 'u' (uint), 'i' (int), 'f' (float), 'c' (complex), 'b' (bool)
/// size: number of bytes (1, 2, 4, 8, 16)
/// Examples: "<u2" → uint16, ">f4" → big-endian float32, "<c8" → complex64, "<c16" → complex128
/// </summary>
public static class NumpyDtypeParser
{
public static (ZarrDataType DataType, ByteOrder ByteOrder) Parse(string dtype)
{
if (string.IsNullOrEmpty(dtype) || dtype.Length < 2)
throw new ArgumentException($"Invalid numpy dtype string: '{dtype}'");
var byteOrderChar = dtype[0];
var typeCode = dtype[1];
var sizeStr = dtype[2..];
if (!int.TryParse(sizeStr, out var size))
throw new ArgumentException($"Cannot parse size from dtype '{dtype}'");
var byteOrder = ParseByteOrder(byteOrderChar);
var dataType = ParseDataType(typeCode, size);
return (dataType, byteOrder);
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
private static ByteOrder ParseByteOrder(char byteOrderChar)
{
return byteOrderChar switch
{
'<' => ByteOrder.LittleEndian,
'>' => ByteOrder.BigEndian,
'|' => ByteOrder.LittleEndian, // byte-order not applicable (e.g. uint8)
'=' => BitConverter.IsLittleEndian
? ByteOrder.LittleEndian
: ByteOrder.BigEndian, // native byte order
_ => throw new NotSupportedException(
$"Unsupported byte order character: '{byteOrderChar}'")
};
}
private static ZarrDataType ParseDataType(char typeCode, int size)
{
return (typeCode, size) switch
{
('b', 1) => ZarrDataType.Parse("bool"),
('u', 1) => ZarrDataType.Parse("uint8"),
('i', 1) => ZarrDataType.Parse("int8"),
('u', 2) => ZarrDataType.Parse("uint16"),
('i', 2) => ZarrDataType.Parse("int16"),
('u', 4) => ZarrDataType.Parse("uint32"),
('i', 4) => ZarrDataType.Parse("int32"),
('u', 8) => ZarrDataType.Parse("uint64"),
('i', 8) => ZarrDataType.Parse("int64"),
('f', 4) => ZarrDataType.Parse("float32"),
('f', 8) => ZarrDataType.Parse("float64"),
('c', 8) => ZarrDataType.Parse("complex64"),
('c', 16) => ZarrDataType.Parse("complex128"),
_ => throw new NotSupportedException(
$"Unsupported numpy dtype: type='{typeCode}', size={size} bytes")
};
}
}