github.com/astrogo/cfitsio@v0.1.0/card.go (about)

     1  package cfitsio
     2  
     3  // #include "go-cfitsio.h"
     4  // #include "go-cfitsio-utils.h"
     5  import "C"
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  	"strings"
    10  	"unsafe"
    11  )
    12  
    13  // Card is a record block (meta data) in a Header.
    14  type Card struct {
    15  	Name    string
    16  	Value   interface{}
    17  	Comment string
    18  }
    19  
    20  // newCard returns the i-th Card from the current HDU of file f.
    21  func newCard(f *File, i int) (Card, error) {
    22  	var card Card
    23  	var err error
    24  
    25  	c_status := C.int(0)
    26  	c_key := C.CStringN(C.FLEN_KEYWORD)
    27  	defer C.free(unsafe.Pointer(c_key))
    28  	c_value := C.CStringN(C.FLEN_VALUE)
    29  	defer C.free(unsafe.Pointer(c_value))
    30  	c_com := C.CStringN(C.FLEN_COMMENT)
    31  	defer C.free(unsafe.Pointer(c_com))
    32  
    33  	c_keyn := C.int(i)
    34  
    35  	C.fits_read_keyn(f.c, c_keyn, c_key, c_value, c_com, &c_status)
    36  	if c_status > 0 {
    37  		return card, to_err(c_status)
    38  	}
    39  
    40  	name := C.GoString(c_key)
    41  	value := C.GoString(c_value)
    42  	if strIsContinued(value) {
    43  		restoreQuote := value[0] == '\''
    44  		if restoreQuote {
    45  			const q = string('\'')
    46  			v, err := getLongValueString(f, name)
    47  			if err != nil {
    48  				return card, err
    49  			}
    50  			value = q + v + q
    51  		}
    52  	}
    53  	comment := C.GoString(c_com)
    54  
    55  	keyclass := C.fits_get_keyclass(c_key)
    56  	switch keyclass {
    57  	case C.TYP_COMM_KEY, C.TYP_CONT_KEY:
    58  		return card, fmt.Errorf("comm key | continue key")
    59  	}
    60  
    61  	err = parseRecord(name, value, comment, &card)
    62  	return card, err
    63  }
    64  
    65  func parseRecord(name, value, comment string, card *Card) error {
    66  	var err error
    67  
    68  	card.Name = name
    69  	card.Comment = comment
    70  
    71  	c_status := C.int(0)
    72  	c_value := C.CString(value)
    73  	defer C.free(unsafe.Pointer(c_value))
    74  	var c_type C.char
    75  	C.fits_get_keytype(c_value, &c_type, &c_status)
    76  	if c_status > 0 {
    77  		return to_err(c_status)
    78  	}
    79  
    80  	if value[0] == '\'' {
    81  		value = value[1 : len(value)-1]
    82  	}
    83  
    84  	dtype := rune(c_type)
    85  	switch dtype {
    86  	case 'L':
    87  		card.Value = value == "T"
    88  
    89  	case 'F':
    90  		var vv float64
    91  		vv, err = strconv.ParseFloat(value, 64)
    92  		if err != nil {
    93  			return err
    94  		}
    95  		card.Value = vv
    96  
    97  	case 'I', 'T':
    98  		var vv int64
    99  		vv, err = strconv.ParseInt(value, 10, 64)
   100  		if err != nil {
   101  			return err
   102  		}
   103  		card.Value = vv
   104  
   105  	case 'X':
   106  		toks := strings.Split(value[1:len(value)-1], ",")
   107  		var vv0 float64
   108  		vv0, err = strconv.ParseFloat(strings.Trim(toks[0], " \t\n"), 64)
   109  		if err != nil {
   110  			return err
   111  		}
   112  		var vv1 float64
   113  		vv1, err = strconv.ParseFloat(strings.Trim(toks[1], " \t\n"), 64)
   114  		if err != nil {
   115  			return err
   116  		}
   117  
   118  		card.Value = complex(vv0, vv1)
   119  
   120  	case 'C':
   121  		card.Value = strings.TrimRight(value, " ")
   122  
   123  	default:
   124  		return fmt.Errorf("invalid keyword-type value (%v)", string(dtype))
   125  	}
   126  	return err
   127  }
   128  
   129  // EOF