github.com/sbinet/go-cfitsio@v0.0.0-20140625105338-0307f985659e/column.go (about) 1 package cfitsio 2 3 // #include <complex.h> 4 // #include "go-cfitsio.h" 5 // #include "go-cfitsio-utils.h" 6 import "C" 7 import ( 8 "fmt" 9 "reflect" 10 "unsafe" 11 ) 12 13 // Value is a value in a FITS table 14 type Value interface{} 15 16 // Column represents a column in a FITS table 17 type Column struct { 18 Name string // column name, corresponding to ``TTYPE`` keyword 19 Format string // column format, corresponding to ``TFORM`` keyword 20 Unit string // column unit, corresponding to ``TUNIT`` keyword 21 Null string // null value, corresponding to ``TNULL`` keyword 22 Bscale float64 // bscale value, corresponding to ``TSCAL`` keyword 23 Bzero float64 // bzero value, corresponding to ``TZERO`` keyword 24 Display string // display format, corresponding to ``TDISP`` keyword 25 Dim []int64 // column dimension corresponding to ``TDIM`` keyword 26 Start int64 // column starting position, corresponding to ``TBCOL`` keyword 27 IsVLA bool // whether this is a variable length array 28 Value Value // value at current row 29 } 30 31 // inferFormat infers the FITS format associated with a Column, according to its HDUType and Go type. 32 func (col *Column) inferFormat(htype HDUType) error { 33 var err error 34 if col.Format != "" { 35 return nil 36 } 37 38 str := gotype2FITS(col.Value, htype) 39 if str == "" { 40 return fmt.Errorf("cfitsio: %v can not handle [%T]", htype, col.Value) 41 } 42 col.Format = str 43 return err 44 } 45 46 // read reads the value at column number icol and row irow, into ptr. 47 // icol and irow are 0-based indices. 48 func (col *Column) read(f *File, icol int, irow int64, ptr interface{}) error { 49 var err error 50 51 c_type := C.int(0) 52 c_icol := C.int(icol + 1) // 0-based to 1-based index 53 c_irow := C.LONGLONG(irow + 1) // 0-based to 1-based index 54 c_anynul := C.int(0) 55 c_status := C.int(0) 56 57 var value interface{} 58 rv := reflect.ValueOf(ptr).Elem() 59 rt := reflect.TypeOf(rv.Interface()) 60 61 switch rt.Kind() { 62 case reflect.Bool: 63 c_type = C.TLOGICAL 64 c_value := C.char(0) // 'F' 65 c_ptr := unsafe.Pointer(&c_value) 66 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 67 value = c_value == 1 68 69 case reflect.Uint8: 70 c_type = C.TBYTE 71 var c_value C.char 72 c_ptr := unsafe.Pointer(&c_value) 73 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 74 value = byte(c_value) 75 76 case reflect.Uint16: 77 c_type = C.TUSHORT 78 var c_value C.ushort 79 c_ptr := unsafe.Pointer(&c_value) 80 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 81 value = uint16(c_value) 82 83 case reflect.Uint32: 84 c_type = C.TUINT 85 var c_value C.uint 86 c_ptr := unsafe.Pointer(&c_value) 87 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 88 value = uint32(c_value) 89 90 case reflect.Uint64: 91 c_type = C.TULONG 92 var c_value C.ulong 93 c_ptr := unsafe.Pointer(&c_value) 94 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 95 value = uint64(c_value) 96 97 case reflect.Uint: 98 c_type = C.TULONG 99 var c_value C.ulong 100 c_ptr := unsafe.Pointer(&c_value) 101 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 102 value = uint(c_value) 103 104 case reflect.Int8: 105 c_type = C.TSBYTE 106 var c_value C.char 107 c_ptr := unsafe.Pointer(&c_value) 108 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 109 value = int8(c_value) 110 111 case reflect.Int16: 112 c_type = C.TSHORT 113 var c_value C.short 114 c_ptr := unsafe.Pointer(&c_value) 115 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 116 value = int16(c_value) 117 118 case reflect.Int32: 119 c_type = C.TINT 120 var c_value C.int 121 c_ptr := unsafe.Pointer(&c_value) 122 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 123 value = int32(c_value) 124 125 case reflect.Int64: 126 c_type = C.TLONG 127 var c_value C.long 128 c_ptr := unsafe.Pointer(&c_value) 129 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 130 value = int64(c_value) 131 132 case reflect.Int: 133 c_type = C.TLONG 134 var c_value C.long 135 c_ptr := unsafe.Pointer(&c_value) 136 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 137 value = int(c_value) 138 139 case reflect.Float32: 140 c_type = C.TFLOAT 141 var c_value C.float 142 c_ptr := unsafe.Pointer(&c_value) 143 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 144 value = float32(c_value) 145 146 case reflect.Float64: 147 c_type = C.TDOUBLE 148 var c_value C.double 149 c_ptr := unsafe.Pointer(&c_value) 150 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 151 value = float64(c_value) 152 153 case reflect.Complex64: 154 c_type = C.TCOMPLEX 155 var c_value C.complexfloat 156 c_ptr := unsafe.Pointer(&c_value) 157 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 158 value = complex( 159 float32(C.crealf(c_value)), 160 float32(C.cimagf(c_value)), 161 ) 162 163 case reflect.Complex128: 164 c_type = C.TDBLCOMPLEX 165 var c_value C.complexdouble 166 c_ptr := unsafe.Pointer(&c_value) 167 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 168 value = complex( 169 float64(C.creal(c_value)), 170 float64(C.cimag(c_value)), 171 ) 172 173 case reflect.String: 174 c_type = C.TSTRING 175 // FIXME: get correct maximum size from card 176 c_value := C.CStringN(C.FLEN_FILENAME) 177 defer C.free(unsafe.Pointer(c_value)) 178 c_ptr := unsafe.Pointer(&c_value) 179 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, c_ptr, &c_anynul, &c_status) 180 value = C.GoString(c_value) 181 182 case reflect.Array: 183 c_len := C.LONGLONG(rt.Len()) 184 switch rt.Elem().Kind() { 185 case reflect.Bool: 186 c_type = C.TLOGICAL 187 v := make([]bool, int(c_len), int(c_len)) 188 value = v 189 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 190 c_ptr := unsafe.Pointer(slice.Data) 191 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 192 193 case reflect.Uint8: 194 c_type = C.TBYTE 195 v := make([]uint8, int(c_len), int(c_len)) 196 value = v 197 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 198 c_ptr := unsafe.Pointer(slice.Data) 199 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 200 201 case reflect.Uint16: 202 c_type = C.TUSHORT 203 v := make([]uint16, int(c_len), int(c_len)) 204 value = v 205 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 206 c_ptr := unsafe.Pointer(slice.Data) 207 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 208 209 case reflect.Uint32: 210 c_type = C.TUINT 211 v := make([]uint32, int(c_len), int(c_len)) 212 value = v 213 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 214 c_ptr := unsafe.Pointer(slice.Data) 215 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 216 217 case reflect.Uint64: 218 c_type = C.TULONG 219 v := make([]uint64, int(c_len), int(c_len)) 220 value = v 221 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 222 c_ptr := unsafe.Pointer(slice.Data) 223 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 224 225 case reflect.Uint: 226 c_type = C.TULONG 227 v := make([]uint, int(c_len), int(c_len)) 228 value = v 229 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 230 c_ptr := unsafe.Pointer(slice.Data) 231 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 232 233 case reflect.Int8: 234 c_type = C.TSBYTE 235 v := make([]int8, int(c_len), int(c_len)) 236 value = v 237 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 238 c_ptr := unsafe.Pointer(slice.Data) 239 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 240 241 case reflect.Int16: 242 c_type = C.TSHORT 243 v := make([]int16, int(c_len), int(c_len)) 244 value = v 245 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 246 c_ptr := unsafe.Pointer(slice.Data) 247 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 248 249 case reflect.Int32: 250 c_type = C.TINT 251 v := make([]int32, int(c_len), int(c_len)) 252 value = v 253 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 254 c_ptr := unsafe.Pointer(slice.Data) 255 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 256 257 case reflect.Int64: 258 c_type = C.TLONG 259 v := make([]int64, int(c_len), int(c_len)) 260 value = v 261 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 262 c_ptr := unsafe.Pointer(slice.Data) 263 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 264 265 case reflect.Int: 266 c_type = C.TLONG 267 v := make([]int, int(c_len), int(c_len)) 268 value = v 269 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 270 c_ptr := unsafe.Pointer(slice.Data) 271 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 272 273 case reflect.Float32: 274 c_type = C.TFLOAT 275 v := make([]float32, int(c_len), int(c_len)) 276 value = v 277 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 278 c_ptr := unsafe.Pointer(slice.Data) 279 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 280 281 case reflect.Float64: 282 c_type = C.TDOUBLE 283 v := make([]float64, int(c_len), int(c_len)) 284 value = v 285 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 286 c_ptr := unsafe.Pointer(slice.Data) 287 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 288 289 case reflect.Complex64: 290 c_type = C.TCOMPLEX 291 v := make([]complex64, int(c_len), int(c_len)) // FIXME: assume same binary layout 292 value = v 293 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 294 c_ptr := unsafe.Pointer(slice.Data) 295 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 296 297 case reflect.Complex128: 298 c_type = C.TDBLCOMPLEX 299 v := make([]complex128, int(c_len), int(c_len)) // FIXME: assume same binary layout 300 value = v 301 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 302 c_ptr := unsafe.Pointer(slice.Data) 303 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 304 default: 305 panic(fmt.Errorf("invalid type [%T]", value)) 306 } 307 308 case reflect.Slice: 309 switch rt.Elem().Kind() { 310 case reflect.Bool: 311 c_type = C.TLOGICAL 312 c_len := C.long(0) 313 c_off := C.long(0) 314 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 315 if c_status > 0 { 316 err = to_err(c_status) 317 return err 318 } 319 v := make([]bool, int(c_len), int(c_len)) 320 value = v 321 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 322 c_ptr := unsafe.Pointer(slice.Data) 323 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 324 325 case reflect.Uint8: 326 c_type = C.TBYTE 327 c_len := C.long(0) 328 c_off := C.long(0) 329 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 330 if c_status > 0 { 331 err = to_err(c_status) 332 return err 333 } 334 v := make([]uint8, int(c_len), int(c_len)) 335 value = v 336 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 337 c_ptr := unsafe.Pointer(slice.Data) 338 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 339 340 case reflect.Uint16: 341 c_type = C.TUSHORT 342 c_len := C.long(0) 343 c_off := C.long(0) 344 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 345 if c_status > 0 { 346 err = to_err(c_status) 347 return err 348 } 349 v := make([]uint16, int(c_len), int(c_len)) 350 value = v 351 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 352 c_ptr := unsafe.Pointer(slice.Data) 353 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 354 355 case reflect.Uint32: 356 c_type = C.TUINT 357 c_len := C.long(0) 358 c_off := C.long(0) 359 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 360 if c_status > 0 { 361 err = to_err(c_status) 362 return err 363 } 364 v := make([]uint32, int(c_len), int(c_len)) 365 value = v 366 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 367 c_ptr := unsafe.Pointer(slice.Data) 368 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 369 370 case reflect.Uint64: 371 c_type = C.TULONG 372 c_len := C.long(0) 373 c_off := C.long(0) 374 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 375 if c_status > 0 { 376 err = to_err(c_status) 377 return err 378 } 379 v := make([]uint64, int(c_len), int(c_len)) 380 value = v 381 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 382 c_ptr := unsafe.Pointer(slice.Data) 383 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 384 385 case reflect.Uint: 386 c_type = C.TULONG 387 c_len := C.long(0) 388 c_off := C.long(0) 389 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 390 if c_status > 0 { 391 err = to_err(c_status) 392 return err 393 } 394 v := make([]uint, int(c_len), int(c_len)) 395 value = v 396 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 397 c_ptr := unsafe.Pointer(slice.Data) 398 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 399 400 case reflect.Int8: 401 c_type = C.TSBYTE 402 c_len := C.long(0) 403 c_off := C.long(0) 404 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 405 if c_status > 0 { 406 err = to_err(c_status) 407 return err 408 } 409 v := make([]int8, int(c_len), int(c_len)) 410 value = v 411 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 412 c_ptr := unsafe.Pointer(slice.Data) 413 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 414 415 case reflect.Int16: 416 c_type = C.TSHORT 417 c_len := C.long(0) 418 c_off := C.long(0) 419 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 420 if c_status > 0 { 421 err = to_err(c_status) 422 return err 423 } 424 v := make([]int16, int(c_len), int(c_len)) 425 value = v 426 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 427 c_ptr := unsafe.Pointer(slice.Data) 428 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 429 430 case reflect.Int32: 431 c_type = C.TINT 432 c_len := C.long(0) 433 c_off := C.long(0) 434 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 435 if c_status > 0 { 436 err = to_err(c_status) 437 return err 438 } 439 v := make([]int32, int(c_len), int(c_len)) 440 value = v 441 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 442 c_ptr := unsafe.Pointer(slice.Data) 443 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 444 445 case reflect.Int64: 446 c_type = C.TLONG 447 c_len := C.long(0) 448 c_off := C.long(0) 449 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 450 if c_status > 0 { 451 err = to_err(c_status) 452 return err 453 } 454 v := make([]int64, int(c_len), int(c_len)) 455 value = v 456 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 457 c_ptr := unsafe.Pointer(slice.Data) 458 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 459 460 case reflect.Int: 461 c_type = C.TLONG 462 c_len := C.long(0) 463 c_off := C.long(0) 464 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 465 if c_status > 0 { 466 err = to_err(c_status) 467 return err 468 } 469 v := make([]int, int(c_len), int(c_len)) 470 value = v 471 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 472 c_ptr := unsafe.Pointer(slice.Data) 473 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 474 475 case reflect.Float32: 476 c_type = C.TFLOAT 477 c_len := C.long(0) 478 c_off := C.long(0) 479 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 480 if c_status > 0 { 481 err = to_err(c_status) 482 return err 483 } 484 v := make([]float32, int(c_len), int(c_len)) 485 value = v 486 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 487 c_ptr := unsafe.Pointer(slice.Data) 488 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 489 490 case reflect.Float64: 491 c_type = C.TDOUBLE 492 c_len := C.long(0) 493 c_off := C.long(0) 494 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 495 if c_status > 0 { 496 err = to_err(c_status) 497 return err 498 } 499 v := make([]float64, int(c_len), int(c_len)) 500 value = v 501 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 502 c_ptr := unsafe.Pointer(slice.Data) 503 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 504 505 case reflect.Complex64: 506 c_type = C.TCOMPLEX 507 c_len := C.long(0) 508 c_off := C.long(0) 509 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 510 if c_status > 0 { 511 err = to_err(c_status) 512 return err 513 } 514 v := make([]complex64, int(c_len), int(c_len)) // FIXME: assume same binary layout 515 value = v 516 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 517 c_ptr := unsafe.Pointer(slice.Data) 518 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 519 520 case reflect.Complex128: 521 c_type = C.TDBLCOMPLEX 522 c_len := C.long(0) 523 c_off := C.long(0) 524 C.fits_read_descript(f.c, c_icol, c_irow, &c_len, &c_off, &c_status) 525 if c_status > 0 { 526 err = to_err(c_status) 527 return err 528 } 529 v := make([]complex128, int(c_len), int(c_len)) // FIXME: assume same binary layout 530 value = v 531 slice := (*reflect.SliceHeader)((unsafe.Pointer(&v))) 532 c_ptr := unsafe.Pointer(slice.Data) 533 C.fits_read_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(c_len), nil, c_ptr, &c_anynul, &c_status) 534 default: 535 panic(fmt.Errorf("invalid type [%T]", value)) 536 } 537 538 default: 539 panic(fmt.Errorf("invalid type [%T]", value)) 540 } 541 542 if c_status > 0 { 543 err = to_err(c_status) 544 } 545 546 rv.Set(reflect.ValueOf(value)) 547 col.Value = value 548 return err 549 } 550 551 // write writes the current value of this Column into file f at column icol and row irow. 552 // icol and irow are 0-based indices. 553 func (col *Column) write(f *File, icol int, irow int64, value interface{}) error { 554 var err error 555 556 c_type := C.int(0) 557 c_icol := C.int(icol + 1) // 0-based to 1-based index 558 c_irow := C.LONGLONG(irow + 1) // 0-based to 1-based index 559 c_status := C.int(0) 560 561 rv := reflect.ValueOf(value) 562 rt := reflect.TypeOf(value) 563 564 switch rt.Kind() { 565 case reflect.Bool: 566 c_type = C.TLOGICAL 567 c_value := C.char(0) // 'F' 568 if value.(bool) { 569 c_value = 1 570 } 571 c_ptr := unsafe.Pointer(&c_value) 572 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 573 574 case reflect.Uint8: 575 c_type = C.TBYTE 576 c_value := C.char(value.(byte)) 577 c_ptr := unsafe.Pointer(&c_value) 578 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 579 580 case reflect.Uint16: 581 c_type = C.TUSHORT 582 c_value := C.ushort(value.(uint16)) 583 c_ptr := unsafe.Pointer(&c_value) 584 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 585 586 case reflect.Uint32: 587 c_type = C.TUINT 588 c_value := C.uint(value.(uint32)) 589 c_ptr := unsafe.Pointer(&c_value) 590 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 591 592 case reflect.Uint64: 593 c_type = C.TULONG 594 c_value := C.ulong(value.(uint64)) 595 c_ptr := unsafe.Pointer(&c_value) 596 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 597 598 case reflect.Uint: 599 c_type = C.TULONG 600 c_value := C.ulong(value.(uint)) 601 c_ptr := unsafe.Pointer(&c_value) 602 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 603 604 case reflect.Int8: 605 c_type = C.TSBYTE 606 c_value := C.char(value.(int8)) 607 c_ptr := unsafe.Pointer(&c_value) 608 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 609 610 case reflect.Int16: 611 c_type = C.TSHORT 612 c_value := C.short(value.(int16)) 613 c_ptr := unsafe.Pointer(&c_value) 614 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 615 616 case reflect.Int32: 617 c_type = C.TINT 618 c_value := C.int(value.(int32)) 619 c_ptr := unsafe.Pointer(&c_value) 620 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 621 622 case reflect.Int64: 623 c_type = C.TLONG 624 c_value := C.long(value.(int64)) 625 c_ptr := unsafe.Pointer(&c_value) 626 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 627 628 case reflect.Int: 629 c_type = C.TLONG 630 c_value := C.long(value.(int)) 631 c_ptr := unsafe.Pointer(&c_value) 632 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 633 634 case reflect.Float32: 635 c_type = C.TFLOAT 636 c_value := C.float(value.(float32)) 637 c_ptr := unsafe.Pointer(&c_value) 638 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 639 640 case reflect.Float64: 641 c_type = C.TDOUBLE 642 c_value := C.double(value.(float64)) 643 c_ptr := unsafe.Pointer(&c_value) 644 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 645 646 case reflect.Complex64: 647 c_type = C.TCOMPLEX 648 value := value.(complex64) 649 c_ptr := unsafe.Pointer(&value) // FIXME: assumes same memory layout 650 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 651 652 case reflect.Complex128: 653 c_type = C.TDBLCOMPLEX 654 value := value.(complex128) 655 c_ptr := unsafe.Pointer(&value) // FIXME: assumes same memory layout 656 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 657 658 case reflect.String: 659 c_type = C.TSTRING 660 c_value := C.CString(value.(string)) 661 defer C.free(unsafe.Pointer(c_value)) 662 c_ptr := unsafe.Pointer(&c_value) 663 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, 1, c_ptr, &c_status) 664 665 case reflect.Slice: 666 switch rt.Elem().Kind() { 667 case reflect.Bool: 668 c_type = C.TLOGICAL 669 value := value.([]bool) 670 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 671 c_ptr := unsafe.Pointer(slice.Data) 672 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 673 674 case reflect.Uint8: 675 c_type = C.TBYTE 676 value := value.([]uint8) 677 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 678 c_ptr := unsafe.Pointer(slice.Data) 679 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 680 681 case reflect.Uint16: 682 c_type = C.TUSHORT 683 value := value.([]uint16) 684 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 685 c_ptr := unsafe.Pointer(slice.Data) 686 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 687 688 case reflect.Uint32: 689 c_type = C.TUINT 690 value := value.([]uint32) 691 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 692 c_ptr := unsafe.Pointer(slice.Data) 693 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 694 695 case reflect.Uint64: 696 c_type = C.TULONG 697 value := value.([]uint64) 698 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 699 c_ptr := unsafe.Pointer(slice.Data) 700 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 701 702 case reflect.Uint: 703 c_type = C.TULONG 704 value := value.([]uint) 705 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 706 c_ptr := unsafe.Pointer(slice.Data) 707 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 708 709 case reflect.Int8: 710 c_type = C.TSBYTE 711 value := value.([]int8) 712 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 713 c_ptr := unsafe.Pointer(slice.Data) 714 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 715 716 case reflect.Int16: 717 c_type = C.TSHORT 718 value := value.([]int16) 719 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 720 c_ptr := unsafe.Pointer(slice.Data) 721 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 722 723 case reflect.Int32: 724 c_type = C.TINT 725 value := value.([]int32) 726 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 727 c_ptr := unsafe.Pointer(slice.Data) 728 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 729 730 case reflect.Int64: 731 c_type = C.TLONG 732 value := value.([]int64) 733 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 734 c_ptr := unsafe.Pointer(slice.Data) 735 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 736 737 case reflect.Int: 738 c_type = C.TLONG 739 value := value.([]int) 740 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 741 c_ptr := unsafe.Pointer(slice.Data) 742 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 743 744 case reflect.Float32: 745 c_type = C.TFLOAT 746 value := value.([]float32) 747 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 748 c_ptr := unsafe.Pointer(slice.Data) 749 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 750 751 case reflect.Float64: 752 c_type = C.TDOUBLE 753 value := value.([]float64) 754 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) 755 c_ptr := unsafe.Pointer(slice.Data) 756 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 757 758 case reflect.Complex64: 759 c_type = C.TCOMPLEX 760 value := value.([]complex64) 761 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) // FIXME: assume same bin-layout 762 c_ptr := unsafe.Pointer(slice.Data) 763 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 764 765 case reflect.Complex128: 766 c_type = C.TDBLCOMPLEX 767 value := value.([]complex128) 768 slice := (*reflect.SliceHeader)((unsafe.Pointer(&value))) // FIXME: assume same bin-layout 769 c_ptr := unsafe.Pointer(slice.Data) 770 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, C.LONGLONG(slice.Len), c_ptr, &c_status) 771 default: 772 panic(fmt.Errorf("unhandled type '%T'", value)) 773 } 774 775 case reflect.Array: 776 //rp := reflect.PtrTo(rv.Type()) 777 c_ptr := unsafe.Pointer(rv.Pointer()) 778 c_len := C.LONGLONG(rt.Len()) 779 780 switch rt.Elem().Kind() { 781 case reflect.Bool: 782 c_type = C.TLOGICAL 783 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 784 785 case reflect.Uint8: 786 c_type = C.TBYTE 787 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 788 789 case reflect.Uint16: 790 c_type = C.TUSHORT 791 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 792 793 case reflect.Uint32: 794 c_type = C.TUINT 795 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 796 797 case reflect.Uint64: 798 c_type = C.TULONG 799 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 800 801 case reflect.Uint: 802 c_type = C.TULONG 803 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 804 805 case reflect.Int8: 806 c_type = C.TSBYTE 807 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 808 809 case reflect.Int16: 810 c_type = C.TSHORT 811 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 812 813 case reflect.Int32: 814 c_type = C.TINT 815 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 816 817 case reflect.Int64: 818 c_type = C.TLONG 819 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 820 821 case reflect.Int: 822 c_type = C.TLONG 823 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 824 825 case reflect.Float32: 826 c_type = C.TFLOAT 827 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 828 829 case reflect.Float64: 830 c_type = C.TDOUBLE 831 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 832 833 case reflect.Complex64: 834 c_type = C.TCOMPLEX 835 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 836 837 case reflect.Complex128: 838 c_type = C.TDBLCOMPLEX 839 C.fits_write_col(f.c, c_type, c_icol, c_irow, 1, c_len, c_ptr, &c_status) 840 default: 841 panic(fmt.Errorf("unhandled type '%T'", value)) 842 } 843 844 default: 845 panic(fmt.Errorf("unhandled type '%T' (%v)", value, rt.Kind())) 846 } 847 848 if c_status > 0 { 849 err = to_err(c_status) 850 } 851 852 return err 853 } 854 855 // EOF