Skip to content

Commit 45e05d3

Browse files
committed
refactor: vendor StaticString implementation and remove StaticStrings.jl dependency (too many invalidations caused by StaticStrings.jl)
1 parent ed4814f commit 45e05d3

File tree

7 files changed

+74
-10
lines changed

7 files changed

+74
-10
lines changed

Project.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ LibDeflate = "9255714d-24a7-4b30-8ea3-d46a97f7e13b"
1212
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
1313
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
1414
ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184"
15-
StaticStrings = "4db0a0c5-418a-4e1d-8806-cb305fe13294"
1615

1716
[weakdeps]
1817
CommonDataModel = "1fbeeb36-5f17-413c-809b-666fb144f157"
@@ -30,5 +29,4 @@ LibDeflate = "0.4.3"
3029
Mmap = "1"
3130
PrecompileTools = "1"
3231
ResumableFunctions = "1"
33-
StaticStrings = "0.2.6"
3432
julia = "1.10"

src/CommonDataFormat.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ using Mmap
55
using Dictionaries: Dictionary
66
using ResumableFunctions
77
using DiskArrays
8-
using StaticStrings: StaticString
98
using Base.Threads
109
using CodecZlib: GzipDecompressor, transcode
1110
using LibDeflate
@@ -22,6 +21,7 @@ export is_record_varying
2221
include("epochs.jl")
2322
include("enums.jl")
2423
include("types.jl")
24+
include("staticstring.jl")
2525
include("parsing.jl")
2626
include("decompress.jl")
2727
include("records/records.jl")

src/enums.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,5 @@ const type_map = Dict(
6767

6868
function julia_type(cdf_type, num_elems)
6969
cdf_type = DataType(cdf_type)
70-
return cdf_type in (CDF_CHAR, CDF_UCHAR) ? StaticString{Int(num_elems)} : type_map[cdf_type]
70+
return cdf_type in (CDF_CHAR, CDF_UCHAR) ? StaticString{Int(num_elems), UInt8} : type_map[cdf_type]
7171
end

src/epochs.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ function Base.show(io::IO, epoch::Epoch16)
149149
end
150150

151151
Base.promote_rule(::Type{<:CDFDateTime}, ::Type{Dates.DateTime}) = Dates.DateTime
152+
Base.promote_rule(::Type{T}, ::Type{Dates.Date}) where {T <: CDFDateTime} = T
153+
# Comment out because of invalidation
152154
Base.convert(::Type{Dates.DateTime}, x::CDFDateTime) = Dates.DateTime(x)
153155
Base.bswap(x::Epoch) = Epoch(Base.bswap(x.instant))
154156
Base.bswap(x::Epoch16) = Epoch16(Base.bswap(x.seconds), Base.bswap(x.picoseconds))

src/parsing.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ function validate_cdf_magic(magic_bytes)
164164
end
165165

166166
_btye_swap!(data) = map!(ntoh, data, data)
167-
_btye_swap!(data::AbstractArray{StaticString{N}}) where {N} = data
167+
_btye_swap!(data::AbstractArray{<:StaticString{N}}) where {N} = data
168168
# function _btye_swap!(data::AbstractArray{TT2000})
169169
# rd = reinterpret(Int64, data)
170170
# return map!(ntoh, rd, rd)

src/staticstring.jl

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# https://github.com/mkitti/StaticStrings.jl
2+
# https://github.com/JuliaPy/PythonCall.jl/blob/main/src/Utils/Utils.jl
3+
4+
struct StaticString{N, T} <: AbstractString
5+
codeunits::NTuple{N, T}
6+
StaticString{N, T}(codeunits::NTuple{N, T}) where {N, T} = new{N, T}(codeunits)
7+
end
8+
9+
function Base.iterate(x::StaticString{N, UInt8}, i::Int = 1) where {N}
10+
i > N && return
11+
cs = x.codeunits
12+
c = @inbounds cs[i]
13+
if all(iszero, (cs[j] for j in i:N))
14+
return
15+
elseif (c & 0x80) == 0x00
16+
return (reinterpret(Char, UInt32(c) << 24), i + 1)
17+
elseif (c & 0x40) == 0x00
18+
nothing
19+
elseif (c & 0x20) == 0x00
20+
if @inbounds (i N - 1) && ((cs[i + 1] & 0xC0) == 0x80)
21+
return (
22+
reinterpret(Char, (UInt32(cs[i]) << 24) | (UInt32(cs[i + 1]) << 16)),
23+
i + 2,
24+
)
25+
end
26+
elseif (c & 0x10) == 0x00
27+
if @inbounds (i N - 2) && ((cs[i + 1] & 0xC0) == 0x80) && ((cs[i + 2] & 0xC0) == 0x80)
28+
return (
29+
reinterpret(
30+
Char,
31+
(UInt32(cs[i]) << 24) |
32+
(UInt32(cs[i + 1]) << 16) |
33+
(UInt32(cs[i + 2]) << 8),
34+
),
35+
i + 3,
36+
)
37+
end
38+
elseif (c & 0x08) == 0x00
39+
if @inbounds (i N - 3) &&
40+
((cs[i + 1] & 0xC0) == 0x80) &&
41+
((cs[i + 2] & 0xC0) == 0x80) &&
42+
((cs[i + 3] & 0xC0) == 0x80)
43+
return (
44+
reinterpret(
45+
Char,
46+
(UInt32(cs[i]) << 24) |
47+
(UInt32(cs[i + 1]) << 16) |
48+
(UInt32(cs[i + 2]) << 8) |
49+
UInt32(cs[i + 3]),
50+
),
51+
i + 4,
52+
)
53+
end
54+
end
55+
throw(StringIndexError(x, i))
56+
end
57+
58+
function Base.String(x::StaticString{N, T}) where {N, T}
59+
b = Base.StringVector(N)
60+
return String(b .= x.codeunits)
61+
end

test/comprehensive_test.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1+
# Comprehensive test based on the Python CDFpp test.py
2+
# Tests all variables in a_cdf.cdf for expected shapes, types, values, and attributes
13
using Test
24
using CommonDataFormat
35
import CommonDataFormat as CDF
46
using Dates
57

68
include("utils.jl")
79

8-
"""
9-
Comprehensive test based on the Python CDFpp test.py
10-
Tests all variables in a_cdf.cdf for expected shapes, types, values, and attributes
11-
"""
12-
1310
# Expected variable definitions (translated from Python test.py)
1411
const EXPECTED_VARIABLES = Dict(
1512
"epoch" => (
@@ -129,6 +126,12 @@ ds = CDFDataset(file)
129126
@test Set(keys(ds)) == Set(keys(EXPECTED_VARIABLES))
130127
end
131128

129+
@testset "StaticString" begin
130+
using CommonDataFormat: StaticString
131+
@test typeof(ds["var_string"][1]) == StaticString{16, UInt8}
132+
@test String(ds["var_string"][1]) == "This is a string"
133+
end
134+
132135
@testset "DateTime Conversions" begin
133136
for var in ("epoch", "epoch16", "tt2000")
134137
@testset "Variable: $var" begin

0 commit comments

Comments
 (0)