Skip to content

Commit f7d4f41

Browse files
authored
Merge pull request #23 from oxinabox/ox/construct
Constructing one ShortString from another
2 parents 28a1e24 + 430f7f6 commit f7d4f41

2 files changed

Lines changed: 34 additions & 4 deletions

File tree

src/base.jl

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ struct ShortString{T} <: AbstractString where T
66
size_content::T
77
end
88

9+
# check if a string of size `sz` can be stored in ShortString{T}`
10+
function check_size(T, sz)
11+
max_len = sizeof(T) - size_nibbles(T) # the last few nibbles are is used to store the length
12+
if sz > max_len
13+
throw(ErrorException("sizeof(::ShortString) must be shorter than or equal to $(max_len) in length; you have supplied a string of size $sz"))
14+
end
15+
end
916

1017
function ShortString{T}(s::Union{String, SubString{String}}) where T
1118
sz = sizeof(s)
12-
max_len = sizeof(T) - size_nibbles(T)
13-
if sz > max_len # the last byte is used to store the length
14-
throw(ErrorException("sizeof(::ShortString) must be shorter than or equal to $(max_len) in length; you have supplied a string of size $sz"))
15-
end
19+
check_size(T, sz)
1620
bits_to_wipe = 8(sizeof(T) - sz)
1721
# TODO some times this can throw errors for longish strings
1822
# Exception: EXCEPTION_ACCESS_VIOLATION at 0x1e0b7afd -- bswap at C:\Users\RTX2080\.julia\packages\BitIntegers\xU40U\src\BitIntegers.jl:332 [inlined]
@@ -21,6 +25,19 @@ function ShortString{T}(s::Union{String, SubString{String}}) where T
2125
ShortString{T}(content | T(sz))
2226
end
2327

28+
ShortString{T}(s::ShortString{T}) where T = s
29+
function ShortString{T}(s::ShortString{S}) where {T, S}
30+
sz = sizeof(s)
31+
check_size(T, sz)
32+
# Flip it so empty bytes are at start, grow/shrink it, flip it back
33+
# S(size_mask(S)) will return a mask for getting the size for Shorting Strings in (content size)
34+
# format, so something like 00001111 in binary.
35+
# ~S(size_mask(S))) will yield 11110000 which can be used as maks to extract the content
36+
content = ntoh(T(ntoh(s.size_content & ~S(size_mask(S)))))
37+
ShortString{T}(content | T(sz))
38+
end
39+
40+
2441
String(s::ShortString) = String(reinterpret(UInt8, [s.size_content|>ntoh])[1:sizeof(s)])
2542

2643
Base.codeunit(s::ShortString) = codeunit(String(s))

test/runtests.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,16 @@ basic_test(ShortString{MyUInt2048}, 254)
7070
@test cmp(ShortString3("α"), "a") == 1
7171
@test cmp(ShortString3("b"), "β") == -1
7272
end
73+
74+
@testset "Construction from other ShortStrings" begin
75+
@test ShortString7(ShortString3("ab")) == "ab"
76+
@test ShortString7(ShortString3("ab")) isa ShortString7
77+
78+
@test ShortString3(ShortString7("ab")) == "ab"
79+
@test ShortString3(ShortString7("ab")) isa ShortString3
80+
81+
@test ShortString7(ShortString7("ab")) == "ab"
82+
@test ShortString7(ShortString7("ab")) isa ShortString7
83+
84+
@test_throws ErrorException ShortString3(ShortString7("123456"))
85+
end

0 commit comments

Comments
 (0)