Ah, sorry.  There's a mistake in the highlighting.  At the bottom of 
read_object, it should actually be highlighted like this:

  elseif rType == defaultRType.RAWSXP
    rawLength = readInt32(rr.reader)
    result = RObject(readbytes(rr.reader, rawLength), is_raw = true)

  elseif rType == defaultRType.LANGSXP
    result = RObject(None)
    att_list = read_attribute_list(rr) # att_list returns nothing DataType
    setAttributes(result, att_list)

  elseif rType == defaultRType.SYMSXP
    symbol = read_symbol_or_string(rr)
    push!(rr.symbols, symbol)
    return RObject([symbol])

  else
    error("Unexpected type")
  end

  if getAttributeFlag(typeTag)
    att_list = read_attribute_list(rr)
    setAttributes(result, att_list)
  end

  return result
end

On Tuesday, August 11, 2015 at 5:03:23 PM UTC-4, Sayeed Tasnim wrote:
>
> I'm working on some Julia code to read XDR data/files (something that 
> might be generated from R using save).
>
> I have a function read_attribute_list to read the attributes associated 
> with an R Object which returns a Dict.  I also have a function read_object 
> to read an R Object which calls read_attribute_list.
>
> function read_attribute_list(rr::RReader)
>   result = Dict{String,RObject}()
>   typeTag = get_type_tag(rr)
>
>   defaultRType = RType()
>   while getRType(typeTag) == defaultRType.LISTSXP
>     tagFlag = getTagFlag(typeTag)
>     tag = None
>
>     if tagFlag
>       tag = read_symbol_or_string(rr)
>     end
>
>     car = read_object(rr)
>     if car != None
>       result[tag] = car
>     end
>
>     typeTag = get_type_tag(rr)
>
>   end
>
>   if getRType(typeTag) != defaultRType.EMPTYTAIL &&
>       getRType(typeTag) != defaultRType.STRSXP
>     error("Not Implemented")
>   end
>
>   return result  # result remains a Dict here and can be printed right 
> before
> end
>
>
> function read_object(rr::RReader)
>   typeTag = get_type_tag(rr)
>   lengthVar = 0
>   result = None
>   rType = getRType(typeTag)
>
>   defaultRType = RType()
>   if rType == defaultRType.LGLSXP
>     lengthVar = readInt32(rr.reader)
>     boolValues = @data(bitunpack(falses(lengthVar)))
>     for i in 1:lengthVar
>       flag = read_integer(rr)
>       if flag == 0 || flag == 1
>         boolValues[i] = !(flag == 0)
>       elseif flag == None
>         boolValues[i] = NA
>       else
>         error("Invalid boolean flag from XDR: $(flag)")
>       end
>     end
>
>     result = RObject(boolValues)
>
>   elseif rType == defaultRType.INTSXP
>     lengthVar = readInt32(rr.reader)
>     values = @data(zeros(Int32, lengthVar))
>
>     for i in 1:lengthVar
>       value = read_integer(rr)
>       if value == None
>         values[i] = NA
>       else
>         values[i] = value
>       end
>     end
>
>     result = RObject(values)
>
>   elseif rType == defaultRType.REALSXP
>     lengthVar = readInt32(rr.reader)
>     values = @data(zeros(Float64, lengthVar))
>
>     for i in 1:lengthVar
>       value = readFloat64(rr.reader)
>       if isnan(value)
>         values[i] = NA
>       else
>         values[i] = value
>       end
>     end
>
>     result = RObject(values)
>
>   elseif rType == defaultRType.CPLXSXP
>     lengthVar = readInt32(rr.reader)
>     complexValues = @data(zeros(Complex128,lengthVar))
>
>     for i in 1:lengthVar
>       realVal = readFloat64(rr.reader)
>       imaginaryVal = readFloat64(rr.reader)
>       if !isnan(realVal) && !isnan(imaginaryVal)
>         complexValues[i] = complex128(realVal, imaginaryVal)
>       else
>         complexValues[i] = NA
>       end
>     end
>
>     result = RObject(complexValues)
>
>   elseif rType == defaultRType.STRSXP
>     lengthVar = readInt32(rr.reader)
>     stringVector = @data(fill("", lengthVar))
>
>     for i in 1:lengthVar
>       val = read_symbol_or_string(rr)
>       stringVector[i] = val != None ? val : NA
>     end
>
>     result = RObject(stringVector)
>
>   elseif rType == defaultRType.VECSXP
>     lengthVar = readInt32(rr.reader)
>     vectorObject = @data(fill!(Array(Any,lengthVar),None))
>     for i in 1:lengthVar
>       vectorObject[i] = read_object(rr)
>     end
>
>     result = RObject(vectorObject)
>
>   elseif rType == defaultRType.EXTPTRSXP
>     readInt64(rr.reader)
>     result = None
>
>   elseif rType == defaultRType.RAWSXP
>     rawLength = readInt32(rr.reader)
>     result = RObject(readbytes(rr.reader, rawLength), is_raw = true)
>
>   elseif rType == defaultRType.LANGSXP
>     result = RObject(None)
>     att_list = read_attribute_list(rr) # att_list returns nothing DataType
>     setAttributes(result, att_list)
>
>   elseif rType == defaultRType.SYMSXP
>     symbol = read_symbol_or_string(rr)
>     push!(rr.symbols, symbol)
>     return RObject([symbol])
>
>   else
>     error("Unexpected type")
>   end
>
>   if getAttributeFlag(typeTag)
>     att_list = read_attribute_list(rr)
>     setAttributes(result, att_list)
>   end
>
>   return result
> end
>
>
> As read_attribute_list is called, the attributes are read correctly and 
> the Dict can be viewed by printing it right before the return statement.  
> However, in the highlighted code for read_object, the att_list returned is 
> a nothing DataType and the Dict that was visible before is lost.
>
> I can't figure out what would be causing this bug.  Some things that I 
> have tried that might be helpful:
> 1) Turn off gc().  I disable garbage collection and run the code.  The 
> behavior remains the same and nothing is returned.
> 2) Return a list of tuples instead.  Instead of returning a Dict, I return 
> Array{(String,RObject)} to serialize the Dict.  The behavior remains the 
> same and nothing is returned.
> 3) Reproduce the bug outside of the module.  I extract the part of the XDR 
> file with only the attributes.  read_attribute_list reads properly and 
> returns the Dict.
>
> Feel free to ask questions about other pieces of the code or 
> implementation details.  Any help with this would be appreciated!
>

Reply via email to