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
>
>

Reply via email to