Ok. It works know. I was stuck to the last two lines. I defined
is_system_missing::Cint
is_considered_missing::Cint.
instead of an UInt8
A last question: I actually have the structure itself as an argument, not a
pointer to the structure. Is the best way to convert v.union to the right
type
unsafe_load(convert(Ptr{T}, pointer_from_objref(val)))
?
The issue with reinterpret is that it fails when the new type fits in less
than a 64-bit field
On Monday, October 12, 2015 at 3:55:53 PM UTC-4, Steven G. Johnson wrote:
>
>
>
> On Monday, October 12, 2015 at 3:30:18 PM UTC-4, Douglas Bates wrote:
>>
>> On Monday, October 12, 2015 at 11:24:06 AM UTC-5, Matt wrote:
>>>
>>> ReadStat is an excellent C library by Evan Millers that allows to read
>>> files from Stata, SPSS and SAS.
>>> Evan wrote a wrapper for ReadStat in the Dataread.jl package
>>> https://github.com/WizardMac/DataRead.jl
>>> However, the package was not updated with the most recent API of
>>> ReadStat.
>>> I've been trying to solve this without success (see the WIP pull request
>>> in the repository)
>>> The hard part is to write a Julia function (handle_value) that accepts a
>>> C structure with a union field.
>>>
>>> typedef struct readstat_value_s {
>>> union {
>>> char char_value;
>>> float float_value;
>>> double double_value;
>>> int16_t i16_value;
>>> int32_t i32_value;
>>> char *string_value;
>>> } v;
>>> readstat_types_t type;
>>> char tag;
>>> int is_system_missing:1;
>>> int is_considered_missing:1;
>>> } readstat_value_t;
>>>
>>
>
> Something like the following should work, because the union types all fit
> into a 64-bit field and will be aligned as such:
>
> immutable readstat_value_t
> union::Int64
> typ::Cint # enum
> tag::Cchar
> bits::UInt8 # bitfield (first two bits are is_system_missing and
> is_considered_missing)
> end
>
> function handle_value(p::Ptr{readstat_value_t})
> v = unsafe_load(p)
> if v.tag == READSTAT_TYPE_DOUBLE
> value = unsafe_load(convert(Ptr{Cdouble}, p))
> ...do stuff...
> else if v.tag == READSTAT_TYPE_STRING
> value = bytestring(unsafe_load(convert(Ptr{Cchar}, p)))
> ... do stuff...
> else ...
> ....
> end
> end
>
>