diff --git a/README.md b/README.md index dfb772c..b7ae018 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Julia 0.4 Status](http://pkg.julialang.org/badges/LegacyStrings_0.4.svg)](http://pkg.julialang.org/?pkg=LegacyStrings&ver=0.4) [![Julia 0.5 Status](http://pkg.julialang.org/badges/LegacyStrings_0.5.svg)](http://pkg.julialang.org/?pkg=LegacyStrings&ver=0.5) -The LegacyStrings package provides compatibility string types from Julia 0.4 (and earlier), which were removed in Julia 0.5, including: +The LegacyStrings package provides compatibility string types from Julia 0.5 (and earlier), which were removed in subsequent versions, including: - `ASCIIString`: a single-byte-per character string type that can only hold ASCII string data. - `UTF8String`: a string type with single byte code units (`UInt8`), encoding strings as UTF-8. @@ -14,6 +14,7 @@ The LegacyStrings package provides compatibility string types from Julia 0.4 (an - `UTF32String`: a string type with four-byte native-endian code units (`UInt32`), encoding strings as UTF-32. - `ByteString`: a type alias for `Union{ASCIIString,UTF8String}`, i.e. strings that can be passed to C directly. - `WString`: an alias for `UTF16String` if `Cwchart_t` is two bytes (i.e. Windows) or `UTF32String` otherwise. +- `RepString`: a string type for efficient handling of repeated strings. LegacyStrings also defines and exports converter functions for these types, i.e.: diff --git a/src/LegacyStrings.jl b/src/LegacyStrings.jl index eeef23c..106a25a 100644 --- a/src/LegacyStrings.jl +++ b/src/LegacyStrings.jl @@ -7,6 +7,7 @@ module LegacyStrings export ByteString, ASCIIString, + RepString, UTF8String, UTF16String, UTF32String, @@ -81,4 +82,10 @@ import Base: else using Base: UTF_ERR_SHORT, checkstring end + + if isdefined(Base, :RepString) + using Base: RepString + else + include("rep.jl") + end end # module diff --git a/src/rep.jl b/src/rep.jl new file mode 100644 index 0000000..98fd52e --- /dev/null +++ b/src/rep.jl @@ -0,0 +1,33 @@ +# This file includes code that was formerly a part of Julia. License is MIT: http://julialang.org/license + +immutable RepString <: AbstractString + string::AbstractString + repeat::Integer +end + +function endof(s::RepString) + e = endof(s.string) + (next(s.string,e)[2]-1) * (s.repeat-1) + e +end +length(s::RepString) = length(s.string)*s.repeat +sizeof(s::RepString) = sizeof(s.string)*s.repeat + +function next(s::RepString, i::Int) + if i < 1 + throw(BoundsError(s, i)) + end + e = endof(s.string) + sz = next(s.string,e)[2]-1 + + r, j = divrem(i-1, sz) + j += 1 + + if r >= s.repeat || j > e + throw(BoundsError(s, i)) + end + + c, k = next(s.string, j) + c, k-j+i +end + +convert(::Type{RepString}, s::AbstractString) = RepString(s,1) diff --git a/test/runtests.jl b/test/runtests.jl index 86ce055..3e59d8b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -518,3 +518,31 @@ let str = ascii("this ") end @test isvalid(Char['f','o','o','b','a','r']) + + +## Repeat strings ## + +# Base Julia issue #7764 +let + rs = RepString("foo", 2) + @test length(rs) == 6 + @test sizeof(rs) == 6 + @test isascii(rs) + @test convert(RepString, "foobar") == "foobar" + @test typeof(convert(RepString, "foobar")) == RepString + + srep = RepString("Σβ",2) + s="Σβ" + ss=SubString(s,1,endof(s)) + + @test ss^2 == "ΣβΣβ" + @test RepString(ss,2) == "ΣβΣβ" + + @test endof(srep) == 7 + + @test next(srep, 3) == ('β',5) + @test next(srep, 7) == ('β',9) + + @test srep[7] == 'β' + @test_throws BoundsError srep[8] +end