Skip to content

Commit

Permalink
array: PrefixedArray
Browse files Browse the repository at this point in the history
PrefixedArray = Prefixed + SizedArray
  • Loading branch information
miRoox committed Nov 2, 2022
1 parent 68618be commit 0abd321
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Sequence

```@docs
SizedArray
PrefixedArray
GreedyVector
```

Expand Down
35 changes: 35 additions & 0 deletions src/Array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,41 @@ function serialize(array::SizedArray{T, N, TA, TSubCon}, s::IO, obj::TA; context
end
estimatesize(array::SizedArray; contextkw...) = prod(array.size) * estimatesize(array.subcon; contextkw...)

"""
PrefixedArray([TA], S|size, T|element) -> Construct{TA}
Defines an array with its size in the header.
# Arguments
- `TA<:AbstractArray{T, N}`: the target array type, the default is `Array{T, N}`.
- `S<:Union{Integer, NTuple{N, Integer}}`: the type of the size in the header.
- `T`: the type of elements.
- `size::Construct{S}`: the construct of size.
- `element::Construct{T}`: the construct of elements.
"""
PrefixedArray(size::Union{Type, Construct}, el::Union{Type, Construct}) = PrefixedArray(Construct(size), Construct(el))
PrefixedArray(::Type{TA}, size::Union{Type, Construct}, el::Union{Type, Construct}) where {TA} = PrefixedArray(TA, Construct(size), Construct(el))

PrefixedArray(sizecon::Construct{S}, subcon::Construct{T}) where {S<:Integer, T} = PrefixedArray(Vector{T}, sizecon, subcon)
PrefixedArray(sizecon::Construct{S}, subcon::Construct{T}) where {N, S<:NTuple{N, Integer}, T} = PrefixedArray(Array{T, N}, sizecon, subcon)

function PrefixedArray(::Type{TA}, sizecon::Construct{S}, subcon::Construct{T}) where {S<:Integer, T, TA<:AbstractVector{T}}
Prefixed{S, TA, typeof(sizecon), SizedArray{T, 1, TA, typeof(subcon)}}(
sizecon,
length,
(n::S) -> SizedArray(TA, subcon, n)
)
end

function PrefixedArray(::Type{TA}, sizecon::Construct{S}, subcon::Construct{T}) where {N, S<:NTuple{N, Integer}, T, TA<:AbstractArray{T, N}}
Prefixed{S, TA, typeof(sizecon), SizedArray{T, N, TA, typeof(subcon)}}(
sizecon,
size,
(n::S) -> SizedArray(TA, subcon, n)
)
end

struct GreedyVector{T, TSubCon<:Construct{T}} <: Wrapper{T, Vector{T}}
subcon::TSubCon
end
Expand Down
1 change: 1 addition & 0 deletions src/Constructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export
Try,
Sequence,
SizedArray,
PrefixedArray,
GreedyVector

include("context.jl")
Expand Down
17 changes: 17 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,23 @@ end
@test deserialize(SizedArray(Int8, 2, 3), Vector{UInt8}(1:6)) == Int8[1 3 5; 2 4 6]
@test serialize(SizedArray(Int8, 2, 3), Int8[1 2 3; 4 5 6]) == b"\x01\x04\x02\x05\x03\x06"
end
@testset "PrefixedArray" begin
@testset "deduce type" begin
@test Constructs.deducetype(() -> PrefixedArray(UInt32, UInt8)) <: Construct{Vector{UInt8}}
@test Constructs.deducetype(() -> PrefixedArray(Sequence(UInt16, UInt16), UInt8)) <: Construct{Matrix{UInt8}}
@test Constructs.deducetype(() -> PrefixedArray(BitVector, UInt32, Bool)) <: Construct{BitVector}
@test Constructs.deducetype(() -> PrefixedArray(BitArray{2}, Sequence(UInt16, UInt16), Bool)) <: Construct{BitArray{2}}
end
@test estimatesize(PrefixedArray(UInt32, UInt8)) == UnboundedSize(sizeof(UInt32))
@test estimatesize(PrefixedArray(Sequence(UInt32, UInt16), UInt8)) == UnboundedSize(sizeof(UInt32) + sizeof(UInt16))
@test estimatesize(PrefixedArray(BitVector, UInt32, Bool)) == UnboundedSize(sizeof(UInt32))
@test estimatesize(PrefixedArray(BitArray{2}, Sequence(UInt16, UInt16), Bool)) == UnboundedSize(2 * sizeof(UInt16))
@test deserialize(PrefixedArray(UInt16le, Int8), b"\x02\x00\x12\xfe") == Int8[18, -2]
@test serialize(PrefixedArray(UInt16le, Int8), Int8[-3, 1, 7]) == b"\x03\x00\xfd\x01\x07"
@test deserialize(PrefixedArray(Sequence(UInt8, UInt16le), Int8), b"\x03\x02\x00\xff\xfe\xfd\x01\x02\x03") == Int8[-1 1; -2 2; -3 3]
@test serialize(PrefixedArray(Sequence(UInt16le, UInt8), Int8), Int8[-3 -2 -1; 1 2 3]) == b"\x02\x00\x03\xfd\x01\xfe\x02\xff\x03"
@test_throws InexactError serialize(PrefixedArray(Int8, UInt8), collect(0x01:0xff))
end
@testset "GreedyVector" begin
@test estimatesize(GreedyVector(Int8)) == UnboundedSize(0)
@test deserialize(GreedyVector(Int8), b"\x01\xff\x00") == Int8[1, -1, 0]
Expand Down

0 comments on commit 0abd321

Please sign in to comment.