Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot determine specific type of datatype #26

Open
enkoder opened this issue Jun 16, 2016 · 2 comments
Open

Cannot determine specific type of datatype #26

enkoder opened this issue Jun 16, 2016 · 2 comments
Assignees
Labels

Comments

@enkoder
Copy link

enkoder commented Jun 16, 2016

I need to be able to read a dataset into memory, but cannot create a struct for each dataset because of some difficult requirements of my project.

I would like to be able to read a compound dataset with an unknown format into memory by using a slice := []interface{} but in order for me to set the underlying memory for each element I need to get the specific type for each member of the compound dataset. So I need to know whether the datatype is a uint8, float32, int64, string, etc.

Currently, from what I know so far, I can only get the high level types using the Dataset.Class() function. I can check the Dataset.Size() value to know the size of each type, but I dont have any knowledge if the value is unsigned or signed.

Here is what I have cooking up so far, I think I am close:

var i uint
for i = 0; i < numDsets; i++ {
    dsetName, err := f.CommonFG.ObjectNameByIndex(i)
    table, err := f.OpenTable(dsetName)
    numRows, err := table.NumPackets()
    dset, err := f.OpenDataset(dsetName)
    dtype, err := dset.Datatype()
    fmt.Printf("\n%s: %d\n", dsetName, numRows)
    if dtype.Class() == h5.T_COMPOUND {
        comp := h5.CompoundType{
            Datatype: *dtype,
        }
        numMembers := comp.NMembers()
        container := make([]interface{}, numMembers)
        for i := 0; i < numMembers; i++ {
            memberClass := comp.MemberClass(i)
            switch memberClass {
            // Right here I would switch on types to be able to set the interface value to the correct type
            // But I dont know how to determine if its a uint8 for example 
            case h5.T_INTEGER:
                container[i] = new(int)
            default:
                container[i] = new(int)
            }
        }
        err = table.ReadPackets(0, 1, &c)
    }
}

For each high level class I can also switch on the size value and set the interface that way, but it feels clunky. Is there a better way for me to be doing this? Thanks in advance.

@sbinet
Copy link
Owner

sbinet commented Jun 16, 2016

untested, but one way would be to retrieve the matching go type from the Datatype:

dtype, err := dset.Datatype()
gotype := dtype.GoType()
switch gotype.Kind() {
    case reflect.Uint8:
        container[i] = new(uint8)
    case reflect.Int64:
        container[i] = new(int64)
    case reflect.Struct:
    // etc...
}
// or directly:
container[i] = reflect.New(gotype).Interface()

https://godoc.org/github.com/sbinet/go-hdf5#Datatype.GoType

@sbinet sbinet self-assigned this Jun 16, 2016
@enkoder
Copy link
Author

enkoder commented Jun 16, 2016

Thanks for the response sbinet. After I posted the initial issue I tried that exact method of using reflect.New() but I hit the following issue.

panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 1 [running]:
panic(0x70f0a0, 0xc82000a730)
    /usr/lib/go/src/runtime/panic.go:481 +0x3e6
github.com/sbinet/go-hdf5._cgoCheckPointer0(0x6703c0, 0xc8200e6000, 0x0, 0x0, 0x0, 0x197)
    ??:0 +0x4d
github.com/sbinet/go-hdf5.(*Table).ReadPackets(0xc8200d8038, 0x0, 0x1, 0x6598e0, 0xc8200de080, 0x0, 0x0)

I dont think that I will be able to read packets into a slice of interfaces because the underlying implementation of interfaces.I haven't found a way to read variable packets yet. I am unfamiliar with the hdf5 C API, but I am about to dive in to get a better understanding. If you have any thoughts on the matter, I would love to hear them thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants