From af3e932541464f38ada3b0163ddad4154291582f Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Sat, 4 Jan 2020 18:48:10 -0800 Subject: [PATCH 1/5] Fix type instability in hot loop --- src/ReadStat.jl | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ReadStat.jl b/src/ReadStat.jl index b05cca1..dad62d2 100644 --- a/src/ReadStat.jl +++ b/src/ReadStat.jl @@ -68,10 +68,11 @@ mutable struct ReadStatDataFrame filelabel::String timestamp::DateTime format::Clong + types_as_int::Vector{Cint} ReadStatDataFrame() = new(Any[], Symbol[], DataType[], String[], String[], Csize_t[], Cint[], Cint[], - String[], Dict{String, Dict{Any,String}}(), 0, 0, "", Dates.unix2datetime(0), 0) + String[], Dict{String, Dict{Any,String}}(), 0, 0, "", Dates.unix2datetime(0), 0, Cint[]) end include("C_interface.jl") @@ -147,6 +148,7 @@ function handle_variable!(var_index::Cint, variable::Ptr{Nothing}, push!(ds.formats, get_format(variable)) jtype = get_type(variable) push!(ds.types, jtype) + push!(ds.types_as_int, readstat_variable_get_type(variable)) push!(ds.data, DataValueVector{jtype}(ds.rows)) push!(ds.storagewidths, get_storagewidth(variable)) push!(ds.measures, get_measure(variable)) @@ -173,10 +175,24 @@ as_native(val::Value) = convert(get_type(val), val) function handle_value!(obs_index::Cint, variable::Ptr{Nothing}, value::ReadStatValue, ds_ptr::Ptr{ReadStatDataFrame}) - ds = unsafe_pointer_to_objref(ds_ptr) + ds = unsafe_pointer_to_objref(ds_ptr)::ReadStatDataFrame var_index = readstat_variable_get_index(variable) if !readstat_value_is_missing(value, variable) - readfield!(ds.data[var_index + 1], obs_index + 1, value) + if ds.types_as_int[var_index+1]==READSTAT_TYPE_DOUBLE + readfield!(ds.data[var_index + 1]::DataValueVector{Float64}, obs_index + 1, value) + elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_INT32 + readfield!(ds.data[var_index + 1]::DataValueVector{Int32}, obs_index + 1, value) + elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_STRING + readfield!(ds.data[var_index + 1]::DataValueVector{String}, obs_index + 1, value) + elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_CHAR + readfield!(ds.data[var_index + 1]::DataValueVector{Int8}, obs_index + 1, value) + elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_INT16 + readfield!(ds.data[var_index + 1]::DataValueVector{Int16}, obs_index + 1, value) + elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_FLOAT + readfield!(ds.data[var_index + 1]::DataValueVector{Float32}, obs_index + 1, value) + else + readfield!(ds.data[var_index + 1], obs_index + 1, value) + end end return Cint(0) From 01d9ae47208f286def18c58b9847a66067a609d0 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Sat, 4 Jan 2020 21:08:58 -0800 Subject: [PATCH 2/5] More performance work --- src/C_interface.jl | 6 +++- src/ReadStat.jl | 77 ++++++++++++++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/C_interface.jl b/src/C_interface.jl index e345342..4509f98 100644 --- a/src/C_interface.jl +++ b/src/C_interface.jl @@ -69,4 +69,8 @@ end function readstat_parse(filename::String, type::Val{:sas7bdat}, parser::Ptr{Nothing}, ds::ReadStatDataFrame) return ccall((:readstat_parse_sas7bdat, libreadstat), Int, (Ptr{Nothing}, Cstring, Any), parser, string(filename), ds) -end \ No newline at end of file +end + +function readstat_variable_get_missing_ranges_count(variable::Ptr{Nothing}) + return ccall((:readstat_variable_get_missing_ranges_count, libreadstat), Cint, (Ptr{Nothing},), variable) +end diff --git a/src/ReadStat.jl b/src/ReadStat.jl index dad62d2..6b29c32 100644 --- a/src/ReadStat.jl +++ b/src/ReadStat.jl @@ -69,10 +69,11 @@ mutable struct ReadStatDataFrame timestamp::DateTime format::Clong types_as_int::Vector{Cint} + hasmissings::Vector{Bool} ReadStatDataFrame() = new(Any[], Symbol[], DataType[], String[], String[], Csize_t[], Cint[], Cint[], - String[], Dict{String, Dict{Any,String}}(), 0, 0, "", Dates.unix2datetime(0), 0, Cint[]) + String[], Dict{String, Dict{Any,String}}(), 0, 0, "", Dates.unix2datetime(0), 0, Cint[], Bool[]) end include("C_interface.jl") @@ -140,7 +141,9 @@ get_alignment(variable::Ptr{Nothing}) = readstat_variable_get_measure(variable) function handle_variable!(var_index::Cint, variable::Ptr{Nothing}, val_label::Cstring, ds_ptr::Ptr{ReadStatDataFrame}) col = var_index + 1 - ds = unsafe_pointer_to_objref(ds_ptr) + ds = unsafe_pointer_to_objref(ds_ptr)::ReadStatDataFrame + + missing_count = readstat_variable_get_missing_ranges_count(variable) push!(ds.val_label_keys, (val_label == C_NULL ? "" : unsafe_string(val_label))) push!(ds.headers, get_name(variable)) @@ -149,7 +152,8 @@ function handle_variable!(var_index::Cint, variable::Ptr{Nothing}, jtype = get_type(variable) push!(ds.types, jtype) push!(ds.types_as_int, readstat_variable_get_type(variable)) - push!(ds.data, DataValueVector{jtype}(ds.rows)) + push!(ds.hasmissings, missing_count > 0) + push!(ds.data, missing_count==0 ? Vector{jtype}(undef, ds.rows) : DataValueVector{jtype}(ds.rows)) push!(ds.storagewidths, get_storagewidth(variable)) push!(ds.measures, get_measure(variable)) push!(ds.alignments, get_alignment(variable)) @@ -174,54 +178,73 @@ end as_native(val::Value) = convert(get_type(val), val) function handle_value!(obs_index::Cint, variable::Ptr{Nothing}, - value::ReadStatValue, ds_ptr::Ptr{ReadStatDataFrame}) + value::Ptr{ReadStatValue}, ds_ptr::Ptr{ReadStatDataFrame}) ds = unsafe_pointer_to_objref(ds_ptr)::ReadStatDataFrame - var_index = readstat_variable_get_index(variable) - if !readstat_value_is_missing(value, variable) - if ds.types_as_int[var_index+1]==READSTAT_TYPE_DOUBLE - readfield!(ds.data[var_index + 1]::DataValueVector{Float64}, obs_index + 1, value) - elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_INT32 - readfield!(ds.data[var_index + 1]::DataValueVector{Int32}, obs_index + 1, value) - elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_STRING - readfield!(ds.data[var_index + 1]::DataValueVector{String}, obs_index + 1, value) - elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_CHAR - readfield!(ds.data[var_index + 1]::DataValueVector{Int8}, obs_index + 1, value) - elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_INT16 - readfield!(ds.data[var_index + 1]::DataValueVector{Int16}, obs_index + 1, value) - elseif ds.types_as_int[var_index+1]==READSTAT_TYPE_FLOAT - readfield!(ds.data[var_index + 1]::DataValueVector{Float32}, obs_index + 1, value) + var_index = readstat_variable_get_index(variable) + 1 + data = ds.data + @inbounds type_as_int = ds.types_as_int[var_index] + @inbounds if ds.hasmissings[var_index] + if readstat_value_is_missing(value, variable) + elseif type_as_int==READSTAT_TYPE_DOUBLE + readfield!(data[var_index]::DataValueVector{Float64}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_INT32 + readfield!(data[var_index]::DataValueVector{Int32}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_STRING + readfield!(data[var_index]::DataValueVector{String}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_CHAR + readfield!(data[var_index]::DataValueVector{Int8}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_INT16 + readfield!(data[var_index]::DataValueVector{Int16}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_FLOAT + readfield!(data[var_index]::DataValueVector{Float32}, obs_index + 1, value) + else + readfield!(data[var_index], obs_index + 1, value) + end + else + if type_as_int==READSTAT_TYPE_DOUBLE + readfield!(data[var_index]::Vector{Float64}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_INT32 + readfield!(data[var_index]::Vector{Int32}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_STRING + readfield!(data[var_index]::Vector{String}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_CHAR + readfield!(data[var_index]::Vector{Int8}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_INT16 + readfield!(data[var_index]::Vector{Int16}, obs_index + 1, value) + elseif type_as_int==READSTAT_TYPE_FLOAT + readfield!(data[var_index]::Vector{Float32}, obs_index + 1, value) else - readfield!(ds.data[var_index + 1], obs_index + 1, value) + readfield!(data[var_index], obs_index + 1, value) end end return Cint(0) end -function readfield!(dest::DataValueVector{String}, row, val::Value) +function readfield!(dest::Union{DataValueVector{String}, Vector{String}}, row, val::Value) ptr = ccall((:readstat_string_value, libreadstat), Cstring, (Value,), val) if ptr ≠ C_NULL @inbounds dest[row] = unsafe_string(ptr) end end -function readfield!(dest::DataValueVector{Int8}, row, val::Value) +function readfield!(dest::Union{DataValueVector{Int8}, Vector{Int8}}, row, val::Value) @inbounds dest[row] = ccall((:readstat_int8_value, libreadstat), Int8, (Value,), val) end -function readfield!(dest::DataValueVector{Int16}, row, val::Value) +function readfield!(dest::Union{DataValueVector{Int16}, Vector{Int16}}, row, val::Value) @inbounds dest[row] = ccall((:readstat_int16_value, libreadstat), Int16, (Value,), val) end -function readfield!(dest::DataValueVector{Int32}, row, val::Value) +function readfield!(dest::Union{DataValueVector{Int32}, Vector{Int32}}, row, val::Value) @inbounds dest[row] = ccall((:readstat_int32_value, libreadstat), Int32, (Value,), val) end -function readfield!(dest::DataValueVector{Float64}, row, val::Value) - @inbounds dest[row] = ccall((:readstat_double_value, libreadstat), Float64, (Value,), val) +function readfield!(dest::Union{DataValueVector{Float64}, Vector{Float64}}, row, val::Ptr{Value}) + @inbounds dest[row] = ccall((:readstat_double_value, libreadstat), Float64, (Ptr{Value},), val) end -function readfield!(dest::DataValueVector{Float32}, row, val::Value) +function readfield!(dest::Union{DataValueVector{Float32}, Vector{Float32}}, row, val::Value) @inbounds dest[row] = ccall((:readstat_float_value, libreadstat), Float32, (Value,), val) end @@ -250,7 +273,7 @@ function Parser() info_fxn = @cfunction(handle_info!, Cint, (Cint, Cint, Ptr{ReadStatDataFrame})) meta_fxn = @cfunction(handle_metadata!, Cint, (Ptr{Nothing}, Ptr{ReadStatDataFrame})) var_fxn = @cfunction(handle_variable!, Cint, (Cint, Ptr{Nothing}, Cstring, Ptr{ReadStatDataFrame})) - val_fxn = @cfunction(handle_value!, Cint, (Cint, Ptr{Nothing}, ReadStatValue, Ptr{ReadStatDataFrame})) + val_fxn = @cfunction(handle_value!, Cint, (Cint, Ptr{Nothing}, Ptr{ReadStatValue}, Ptr{ReadStatDataFrame})) label_fxn = @cfunction(handle_value_label!, Cint, (Cstring, Value, Cstring, Ptr{ReadStatDataFrame})) ccall((:readstat_set_metadata_handler, libreadstat), Int, (Ptr{Nothing}, Ptr{Nothing}), parser, meta_fxn) ccall((:readstat_set_variable_handler, libreadstat), Int, (Ptr{Nothing}, Ptr{Nothing}), parser, var_fxn) From a2a91ee92de7c16d2946f0831d82c6a7bfa15898 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Sun, 5 Jan 2020 14:25:05 -0800 Subject: [PATCH 3/5] Rework missing handling --- src/C_interface.jl | 4 +- src/ReadStat.jl | 121 ++++++++++++++++++++++++++++----------------- 2 files changed, 78 insertions(+), 47 deletions(-) diff --git a/src/C_interface.jl b/src/C_interface.jl index 4509f98..d1975bb 100644 --- a/src/C_interface.jl +++ b/src/C_interface.jl @@ -19,8 +19,8 @@ function readstat_get_var_count(metadata::Ptr{Nothing}) return ccall((:readstat_get_var_count, libreadstat), UInt, (Ptr{Nothing},), metadata) end -function readstat_value_is_missing(value::ReadStatValue, variable::Ptr{Nothing}) - return ccall((:readstat_value_is_missing, libreadstat), Bool, (ReadStatValue,Ptr{Nothing}), value, variable) +function readstat_value_is_missing(value::Ptr{ReadStatValue}, variable::Ptr{Nothing}) + return ccall((:readstat_value_is_missing, libreadstat), Bool, (Ptr{ReadStatValue},Ptr{Nothing}), value, variable) end function readstat_variable_get_index(variable::Ptr{Nothing}) diff --git a/src/ReadStat.jl b/src/ReadStat.jl index 6b29c32..1749efe 100644 --- a/src/ReadStat.jl +++ b/src/ReadStat.jl @@ -9,6 +9,7 @@ using ReadStat_jll ############################################################################## using DataValues: DataValueVector +import DataValues using Dates export ReadStatDataFrame, read_dta, read_sav, read_por, read_sas7bdat @@ -153,7 +154,7 @@ function handle_variable!(var_index::Cint, variable::Ptr{Nothing}, push!(ds.types, jtype) push!(ds.types_as_int, readstat_variable_get_type(variable)) push!(ds.hasmissings, missing_count > 0) - push!(ds.data, missing_count==0 ? Vector{jtype}(undef, ds.rows) : DataValueVector{jtype}(ds.rows)) + push!(ds.data, DataValueVector{jtype}(Vector{jtype}(undef, ds.rows), fill(false, ds.rows))) push!(ds.storagewidths, get_storagewidth(variable)) push!(ds.measures, get_measure(variable)) push!(ds.alignments, get_alignment(variable)) @@ -183,69 +184,99 @@ function handle_value!(obs_index::Cint, variable::Ptr{Nothing}, var_index = readstat_variable_get_index(variable) + 1 data = ds.data @inbounds type_as_int = ds.types_as_int[var_index] - @inbounds if ds.hasmissings[var_index] - if readstat_value_is_missing(value, variable) - elseif type_as_int==READSTAT_TYPE_DOUBLE - readfield!(data[var_index]::DataValueVector{Float64}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_INT32 - readfield!(data[var_index]::DataValueVector{Int32}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_STRING - readfield!(data[var_index]::DataValueVector{String}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_CHAR - readfield!(data[var_index]::DataValueVector{Int8}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_INT16 - readfield!(data[var_index]::DataValueVector{Int16}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_FLOAT - readfield!(data[var_index]::DataValueVector{Float32}, obs_index + 1, value) - else - readfield!(data[var_index], obs_index + 1, value) - end + + ismissing = if @inbounds(ds.hasmissings[var_index]) + readstat_value_is_missing(value, variable) else - if type_as_int==READSTAT_TYPE_DOUBLE - readfield!(data[var_index]::Vector{Float64}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_INT32 - readfield!(data[var_index]::Vector{Int32}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_STRING - readfield!(data[var_index]::Vector{String}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_CHAR - readfield!(data[var_index]::Vector{Int8}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_INT16 - readfield!(data[var_index]::Vector{Int16}, obs_index + 1, value) - elseif type_as_int==READSTAT_TYPE_FLOAT - readfield!(data[var_index]::Vector{Float32}, obs_index + 1, value) - else - readfield!(data[var_index], obs_index + 1, value) + readstat_value_is_missing(value, C_NULL) + end + + if type_as_int==READSTAT_TYPE_DOUBLE + col_float64 = data[var_index]::DataValueVector{Float64} + + if ismissing + DataValues.unsafe_setindex_isna!(col_float64, true, obs_index + 1) + else + readfield!(col_float64, obs_index + 1, value) + end + elseif type_as_int==READSTAT_TYPE_INT32 + col_int32 = data[var_index]::DataValueVector{Int32} + + if ismissing + DataValues.unsafe_setindex_isna!(col_int32, true, obs_index + 1) + else + readfield!(col_int32, obs_index + 1, value) + end + elseif type_as_int==READSTAT_TYPE_STRING + col_string = data[var_index]::DataValueVector{String} + + if ismissing + DataValues.unsafe_setindex_isna!(col_string, true, obs_index + 1) + else + readfield!(col_string, obs_index + 1, value) + end + elseif type_as_int==READSTAT_TYPE_CHAR + col_int8 = data[var_index]::DataValueVector{Int8} + + if ismissing + DataValues.unsafe_setindex_isna!(col_int8, true, obs_index + 1) + else + readfield!(col_int8, obs_index + 1, value) + end + elseif type_as_int==READSTAT_TYPE_INT16 + col_int16 = data[var_index]::DataValueVector{Int16} + + if ismissing + DataValues.unsafe_setindex_isna!(col_int16, true, obs_index + 1) + else + readfield!(col_int16, obs_index + 1, value) + end + elseif type_as_int==READSTAT_TYPE_FLOAT + col_float32 = data[var_index]::DataValueVector{Float32} + + if ismissing + DataValues.unsafe_setindex_isna!(col_float32, true, obs_index + 1) + else + readfield!(col_float32, obs_index + 1, value) + end + else + col_untyped = data[var_index] + + if ismissing + DataValues.unsafe_setindex_isna!(col_untyped, true, obs_index + 1) + else + readfield!(col_untyped, obs_index + 1, value) end end return Cint(0) end -function readfield!(dest::Union{DataValueVector{String}, Vector{String}}, row, val::Value) - ptr = ccall((:readstat_string_value, libreadstat), Cstring, (Value,), val) +function readfield!(dest::DataValueVector{String}, row, val::Ptr{Value}) + ptr = ccall((:readstat_string_value, libreadstat), Cstring, (Ptr{Value},), val) if ptr ≠ C_NULL - @inbounds dest[row] = unsafe_string(ptr) + @inbounds DataValues.unsafe_setindex_value!(dest, unsafe_string(ptr), row) end end -function readfield!(dest::Union{DataValueVector{Int8}, Vector{Int8}}, row, val::Value) - @inbounds dest[row] = ccall((:readstat_int8_value, libreadstat), Int8, (Value,), val) +function readfield!(dest::DataValueVector{Int8}, row, val::Ptr{Value}) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int8_value, libreadstat), Int8, (Ptr{Value},), val), row) end -function readfield!(dest::Union{DataValueVector{Int16}, Vector{Int16}}, row, val::Value) - @inbounds dest[row] = ccall((:readstat_int16_value, libreadstat), Int16, (Value,), val) +function readfield!(dest::DataValueVector{Int16}, row, val::Ptr{Value}) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int16_value, libreadstat), Int16, (Ptr{Value},), val), row) end -function readfield!(dest::Union{DataValueVector{Int32}, Vector{Int32}}, row, val::Value) - @inbounds dest[row] = ccall((:readstat_int32_value, libreadstat), Int32, (Value,), val) +function readfield!(dest::DataValueVector{Int32}, row, val::Ptr{Value}) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int32_value, libreadstat), Int32, (Ptr{Value},), val), row) end -function readfield!(dest::Union{DataValueVector{Float64}, Vector{Float64}}, row, val::Ptr{Value}) - @inbounds dest[row] = ccall((:readstat_double_value, libreadstat), Float64, (Ptr{Value},), val) +function readfield!(dest::DataValueVector{Float64}, row, val::Ptr{Value}) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_double_value, libreadstat), Float64, (Ptr{Value},), val), row) end -function readfield!(dest::Union{DataValueVector{Float32}, Vector{Float32}}, row, val::Value) - @inbounds dest[row] = ccall((:readstat_float_value, libreadstat), Float32, (Value,), val) +function readfield!(dest::DataValueVector{Float32}, row, val::Ptr{Value}) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_float_value, libreadstat), Float32, (Ptr{Value},), val), row) end function handle_value_label!(val_labels::Cstring, value::Value, label::Cstring, ds_ptr::Ptr{ReadStatDataFrame}) From 66e9fb9fb5144dceb2b61f3136a47b718c3fa0f5 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Sun, 5 Jan 2020 14:42:55 -0800 Subject: [PATCH 4/5] Bump min version for DataValues --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 29430ff..be80f57 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,7 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] julia = "1.3" -DataValues = "0.4.4" +DataValues = "0.4.13" ReadStat_jll = "1.1.1" [targets] From 00118dcb73feea598c4c23621e85d31c28ac2d98 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Mon, 6 Jan 2020 10:00:49 -0800 Subject: [PATCH 5/5] Fix some bugs --- src/C_interface.jl | 4 ++-- src/ReadStat.jl | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/C_interface.jl b/src/C_interface.jl index d1975bb..4509f98 100644 --- a/src/C_interface.jl +++ b/src/C_interface.jl @@ -19,8 +19,8 @@ function readstat_get_var_count(metadata::Ptr{Nothing}) return ccall((:readstat_get_var_count, libreadstat), UInt, (Ptr{Nothing},), metadata) end -function readstat_value_is_missing(value::Ptr{ReadStatValue}, variable::Ptr{Nothing}) - return ccall((:readstat_value_is_missing, libreadstat), Bool, (Ptr{ReadStatValue},Ptr{Nothing}), value, variable) +function readstat_value_is_missing(value::ReadStatValue, variable::Ptr{Nothing}) + return ccall((:readstat_value_is_missing, libreadstat), Bool, (ReadStatValue,Ptr{Nothing}), value, variable) end function readstat_variable_get_index(variable::Ptr{Nothing}) diff --git a/src/ReadStat.jl b/src/ReadStat.jl index 1749efe..eb4565f 100644 --- a/src/ReadStat.jl +++ b/src/ReadStat.jl @@ -179,7 +179,7 @@ end as_native(val::Value) = convert(get_type(val), val) function handle_value!(obs_index::Cint, variable::Ptr{Nothing}, - value::Ptr{ReadStatValue}, ds_ptr::Ptr{ReadStatDataFrame}) + value::ReadStatValue, ds_ptr::Ptr{ReadStatDataFrame}) ds = unsafe_pointer_to_objref(ds_ptr)::ReadStatDataFrame var_index = readstat_variable_get_index(variable) + 1 data = ds.data @@ -252,31 +252,31 @@ function handle_value!(obs_index::Cint, variable::Ptr{Nothing}, return Cint(0) end -function readfield!(dest::DataValueVector{String}, row, val::Ptr{Value}) - ptr = ccall((:readstat_string_value, libreadstat), Cstring, (Ptr{Value},), val) +function readfield!(dest::DataValueVector{String}, row, val::ReadStatValue) + ptr = ccall((:readstat_string_value, libreadstat), Cstring, (ReadStatValue,), val) if ptr ≠ C_NULL @inbounds DataValues.unsafe_setindex_value!(dest, unsafe_string(ptr), row) end end -function readfield!(dest::DataValueVector{Int8}, row, val::Ptr{Value}) - @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int8_value, libreadstat), Int8, (Ptr{Value},), val), row) +function readfield!(dest::DataValueVector{Int8}, row, val::ReadStatValue) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int8_value, libreadstat), Int8, (ReadStatValue,), val), row) end -function readfield!(dest::DataValueVector{Int16}, row, val::Ptr{Value}) - @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int16_value, libreadstat), Int16, (Ptr{Value},), val), row) +function readfield!(dest::DataValueVector{Int16}, row, val::ReadStatValue) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int16_value, libreadstat), Int16, (ReadStatValue,), val), row) end -function readfield!(dest::DataValueVector{Int32}, row, val::Ptr{Value}) - @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int32_value, libreadstat), Int32, (Ptr{Value},), val), row) +function readfield!(dest::DataValueVector{Int32}, row, val::ReadStatValue) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_int32_value, libreadstat), Int32, (ReadStatValue,), val), row) end -function readfield!(dest::DataValueVector{Float64}, row, val::Ptr{Value}) - @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_double_value, libreadstat), Float64, (Ptr{Value},), val), row) +function readfield!(dest::DataValueVector{Float64}, row, val::ReadStatValue) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_double_value, libreadstat), Float64, (ReadStatValue,), val), row) end -function readfield!(dest::DataValueVector{Float32}, row, val::Ptr{Value}) - @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_float_value, libreadstat), Float32, (Ptr{Value},), val), row) +function readfield!(dest::DataValueVector{Float32}, row, val::ReadStatValue) + @inbounds DataValues.unsafe_setindex_value!(dest, ccall((:readstat_float_value, libreadstat), Float32, (ReadStatValue,), val), row) end function handle_value_label!(val_labels::Cstring, value::Value, label::Cstring, ds_ptr::Ptr{ReadStatDataFrame}) @@ -304,7 +304,7 @@ function Parser() info_fxn = @cfunction(handle_info!, Cint, (Cint, Cint, Ptr{ReadStatDataFrame})) meta_fxn = @cfunction(handle_metadata!, Cint, (Ptr{Nothing}, Ptr{ReadStatDataFrame})) var_fxn = @cfunction(handle_variable!, Cint, (Cint, Ptr{Nothing}, Cstring, Ptr{ReadStatDataFrame})) - val_fxn = @cfunction(handle_value!, Cint, (Cint, Ptr{Nothing}, Ptr{ReadStatValue}, Ptr{ReadStatDataFrame})) + val_fxn = @cfunction(handle_value!, Cint, (Cint, Ptr{Nothing}, ReadStatValue, Ptr{ReadStatDataFrame})) label_fxn = @cfunction(handle_value_label!, Cint, (Cstring, Value, Cstring, Ptr{ReadStatDataFrame})) ccall((:readstat_set_metadata_handler, libreadstat), Int, (Ptr{Nothing}, Ptr{Nothing}), parser, meta_fxn) ccall((:readstat_set_variable_handler, libreadstat), Int, (Ptr{Nothing}, Ptr{Nothing}), parser, var_fxn)