Skip to content

Commit 7777933

Browse files
authored
Merge pull request #38 from dmbates/value_labels
Value labels
2 parents 8aafcac + 582121d commit 7777933

1 file changed

Lines changed: 28 additions & 4 deletions

File tree

src/ReadStat.jl

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ mutable struct ReadStatDataFrame
6262
storagewidths::Vector{Csize_t}
6363
measures::Vector{Cint}
6464
alignments::Vector{Cint}
65-
value_labels::Vector{Dict{Any,String}}
65+
val_label_keys::Vector{String}
66+
val_label_dict::Dict{String, Dict{Any,String}}
6667
rows::Int
6768
columns::Int
6869
filelabel::String
@@ -71,7 +72,7 @@ mutable struct ReadStatDataFrame
7172

7273
ReadStatDataFrame() =
7374
new(Any[], Symbol[], DataType[], String[], String[], Csize_t[], Cint[], Cint[],
74-
Dict{Any,String}[], 0, 0, "", Dates.unix2datetime(0), 0)
75+
String[], Dict{String, Dict{Any,String}}(), 0, 0, "", Dates.unix2datetime(0), 0)
7576
end
7677

7778
##############################################################################
@@ -135,10 +136,11 @@ get_measure(var::Ptr{Void}) = ccall((:readstat_variable_get_measure, libreadstat
135136
get_alignment(var::Ptr{Void}) = ccall((:readstat_variable_get_alignment, libreadstat), Cint, (Ptr{Void},), var)
136137

137138
function handle_variable!(var_index::Cint, variable::Ptr{Void},
138-
variable_label::Cstring, ds_ptr::Ptr{ReadStatDataFrame})
139+
val_label::Cstring, ds_ptr::Ptr{ReadStatDataFrame})
139140
col = var_index + 1
140-
ds = unsafe_pointer_to_objref(ds_ptr)::ReadStatDataFrame
141+
ds = unsafe_pointer_to_objref(ds_ptr)
141142

143+
push!(ds.val_label_keys, (val_label == C_NULL ? "" : unsafe_string(val_label)))
142144
push!(ds.headers, get_name(variable))
143145
push!(ds.labels, get_label(variable))
144146
push!(ds.formats, get_format(variable))
@@ -154,6 +156,23 @@ end
154156

155157
const Value = ReadStatValue
156158

159+
function get_type(val::Value)
160+
data_type = ccall((:readstat_value_type, libreadstat), Cint, (Value,), val)
161+
162+
return [String, UInt8, Int16, Int32, Float32, Float64, String][data_type + 1]
163+
end
164+
165+
Base.convert(::Type{UInt8}, val::Value) = ccall((:readstat_int8_value, libreadstat), UInt8, (Value,), val)
166+
Base.convert(::Type{Int16}, val::Value) = ccall((:readstat_int16_value, libreadstat), Int16, (Value,), val)
167+
Base.convert(::Type{Int32}, val::Value) = ccall((:readstat_int32_value, libreadstat), Int32, (Value,), val)
168+
Base.convert(::Type{Float32}, val::Value) = ccall((:readstat_float_value, libreadstat), Float32, (Value,), val)
169+
Base.convert(::Type{Float64}, val::Value) = ccall((:readstat_double_value, libreadstat), Float64, (Value,), val)
170+
function Base.convert(::Type{String}, val::Value)
171+
ptr = ccall((:readstat_string_value, libreadstat), Cstring, (Value,), val)
172+
ptr C_NULL ? unsafe_string(ptr) : ""
173+
end
174+
as_native(val::Value) = convert(get_type(val), val)
175+
157176
val_ismissing(val::Value) = ccall((:readstat_value_is_missing, libreadstat), Bool, (Value,), val)
158177
function handle_value!(obs_index::Cint, var_index::Cint,
159178
value::Value, ds_ptr::Ptr{ReadStatDataFrame})
@@ -193,6 +212,11 @@ function readfield!(dest::DataValueVector{Float32}, row, val::Value)
193212
end
194213

195214
function handle_value_label!(val_labels::Cstring, value::Value, label::Cstring, ds_ptr::Ptr{ReadStatDataFrame})
215+
val_labels C_NULL || return Cint(0)
216+
ds = unsafe_pointer_to_objref(ds_ptr)
217+
dict = get!(ds.val_label_dict, unsafe_string(val_labels), Dict{Any,String}())
218+
dict[as_native(value)] = unsafe_string(label)
219+
196220
return Cint(0)
197221
end
198222

0 commit comments

Comments
 (0)