github.com/lenartj/cfitsio@v0.0.0-20210325092924-ef692a403eb8/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