On Mon, Oct 12, 2015 at 6:46 PM, Matt <[email protected]> wrote:
> 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)))
> ?

Don't use `pointer_from_objref`

> The issue with reinterpret is that it fails when the new type fits in less
> than a 64-bit field

Cast to a smaller integer first should work. (Although you might need
to worry a little about the endianess).

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