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

     1  package cfitsio
     2  
     3  // #include <string.h>
     4  // #include <stdlib.h>
     5  // #include "go-cfitsio.h"
     6  // #include "go-cfitsio-utils.h"
     7  import "C"
     8  
     9  import (
    10  	"unsafe"
    11  )
    12  
    13  type Mode int
    14  
    15  const (
    16  	ReadOnly  Mode = C.READONLY
    17  	ReadWrite Mode = C.READWRITE
    18  )
    19  
    20  // File is a handle to a FITS file
    21  type File struct {
    22  	c    *C.fitsfile
    23  	hdus []HDU
    24  }
    25  
    26  // HDUs returns the list of all Header-Data Unit blocks in the file
    27  func (f *File) HDUs() []HDU {
    28  	return f.hdus
    29  }
    30  
    31  // Open an existing FITS file
    32  // Open will create HDU values, loading the Header part but leaving the Data part on disk.
    33  func Open(fname string, mode Mode) (File, error) {
    34  	var f File
    35  	var err error
    36  
    37  	c_status := C.int(0)
    38  	c_fname := C.CString(fname)
    39  	defer C.free(unsafe.Pointer(c_fname))
    40  
    41  	C.ffopen(&f.c, c_fname, C.int(mode), &c_status)
    42  	if c_status > 0 {
    43  		return f, to_err(c_status)
    44  	}
    45  
    46  	// ffopen might have moved to specific HDU (via fname specifications)
    47  	// remember it and go back to that one after we've dealt with "our" HDUs
    48  	ihdu := f.HDUNum()
    49  	defer f.SeekHDU(ihdu, 0)
    50  
    51  	nhdus, err := f.NumHDUs()
    52  	if err != nil {
    53  		return f, err
    54  	}
    55  
    56  	f.hdus = make([]HDU, 0, nhdus)
    57  	for i := 0; i < nhdus; i++ {
    58  		hdu, err := f.readHDU(i)
    59  		if err != nil {
    60  			return f, err
    61  		}
    62  		f.hdus = append(f.hdus, hdu)
    63  	}
    64  	if err != nil {
    65  		return f, err
    66  	}
    67  
    68  	return f, err
    69  }
    70  
    71  // Create creates and opens a new empty output FITS file.
    72  func Create(fname string) (File, error) {
    73  	var f File
    74  	var err error
    75  
    76  	c_status := C.int(0)
    77  	c_fname := C.CString(fname)
    78  	defer C.free(unsafe.Pointer(c_fname))
    79  
    80  	C.fits_create_file(&f.c, c_fname, &c_status)
    81  	if c_status > 0 {
    82  		err = to_err(c_status)
    83  		return f, err
    84  	}
    85  
    86  	f.hdus = make([]HDU, 0)
    87  
    88  	return f, err
    89  }
    90  
    91  // Close closes a previously opened FITS file.
    92  func (f *File) Close() error {
    93  	c_status := C.int(0)
    94  	C.fits_close_file(f.c, &c_status)
    95  	err := to_err(c_status)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	for _, hdu := range f.hdus {
   101  		err2 := hdu.Close()
   102  		if err2 != nil {
   103  			err = err2
   104  		}
   105  	}
   106  	return err
   107  }
   108  
   109  // Delete closes a previously opened FITS file and also DELETES the file.
   110  func (f *File) Delete() error {
   111  	err := f.Close()
   112  	if err != nil {
   113  		return err
   114  	}
   115  	c_status := C.int(0)
   116  	C.fits_delete_file(f.c, &c_status)
   117  	return to_err(c_status)
   118  }
   119  
   120  // Name returns the name of a FITS file
   121  func (f *File) Name() (string, error) {
   122  	c_name := C.CStringN(C.FLEN_FILENAME)
   123  	defer C.free(unsafe.Pointer(c_name))
   124  	c_status := C.int(0)
   125  	C.fits_file_name(f.c, c_name, &c_status)
   126  	if c_status > 0 {
   127  		return "", to_err(c_status)
   128  	}
   129  	return C.GoString(c_name), nil
   130  }
   131  
   132  // Mode returns the mode of a FITS file (ReadOnly or ReadWrite)
   133  func (f *File) Mode() (Mode, error) {
   134  	c_mode := C.int(0)
   135  	c_status := C.int(0)
   136  	C.fits_file_mode(f.c, &c_mode, &c_status)
   137  	if c_status > 0 {
   138  		return Mode(0), to_err(c_status)
   139  	}
   140  	return Mode(c_mode), nil
   141  }
   142  
   143  // UrlType returns the type of a FITS file (e.g. ftp:// or file://)
   144  func (f *File) UrlType() (string, error) {
   145  	c_url := C.CStringN(C.FLEN_VALUE)
   146  	defer C.free(unsafe.Pointer(c_url))
   147  	c_status := C.int(0)
   148  	C.fits_url_type(f.c, c_url, &c_status)
   149  	if c_status > 0 {
   150  		return "", to_err(c_status)
   151  	}
   152  	return C.GoString(c_url), nil
   153  }
   154  
   155  // eof