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

RasterBand IO() fails to deduce buffer data type, aborts #43

Open
calenlas opened this issue Aug 11, 2019 · 3 comments
Open

RasterBand IO() fails to deduce buffer data type, aborts #43

calenlas opened this issue Aug 11, 2019 · 3 comments

Comments

@calenlas
Copy link

The type swtich at the top of RasterBand IO() (gdal.go:1130) used to guess the appropriate GDAL data type for the buffer fails if passed a sized array, aborting the IO() function and returning an error string.

This can be verified by using the examples/test_tiff code to try to write a dataset using this function. No data will be written.

The following code demonstrates the failure of a type switch in this situation. You can see that the reflect package gets it right, while the type switch fails to identify the type of the sized array buffer. However, if declared as an array of unknown size then assigned a slice the type switch will work as intended.

package main

import (
	"fmt"
	"reflect"
)

func readType(buffer interface{}) {
	fmt.Println("reflect got ", reflect.TypeOf(buffer))
	
	switch buffer.(type) {
	case []uint8:
		fmt.Println("switch got []uint8")
	case []float32:
		fmt.Println("switch got []float32")
	default:
		fmt.Println("switch got unknown?")
	}
}

func main() {
	const bufsize = 256

	// Declaring the buffer as a sized array (as done in test_tiff.go)
	// will result in the type switch failing.
	var buffer [bufsize]uint8
	readType(buffer)

	// Declaring the buffer as an array of unknown size then assigning
	// it a sized slice will allow the type switch to work as intended.
	var buffer2 []uint8
	buffer2 = make([]uint8, bufsize)
	readType(buffer2)
}
@calenlas
Copy link
Author

This same type switch is used in Dataset IO() as well, so it will misbehave as well under the same conditions.

@mtfelian
Copy link
Contributor

mtfelian commented Jun 3, 2020

This behaves as intended.

Take notice at error message there:

err = fmt.Errorf("Error: buffer is not a valid data type (must be a valid numeric slice)")

Golang makes a difference between a slice and an array.

[2]float64 // array
[]float64 // slice

Slice is not an array, please consider reading https://golang.org/doc/effective_go.html#slices

Even when you pass it, array is being copied, slice is passed by reference.

It is possible to implement this also for arrays in Go via reflection, but this is not Go-way coding and the code itself will look ugly.

@mtfelian
Copy link
Contributor

mtfelian commented Jun 3, 2020

Minor refactoring of this here - #51 to avoid code duplication.

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

No branches or pull requests

2 participants