Index: trunk/psLib/src/fits/psFitsTable.c
===================================================================
--- trunk/psLib/src/fits/psFitsTable.c	(revision 15640)
+++ trunk/psLib/src/fits/psFitsTable.c	(revision 15662)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-10-09 02:56:23 $
+ *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-11-20 19:14:22 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -42,9 +42,36 @@
     if (fits_get_num_rows(fits->fd, &numRows, &status)) {
         psFitsError(status, true, "Unable to determine number of rows in table.");
-        return 0;
+        return -1;
     }
 
     return numRows;
 }
+
+// Check the FITS file in preparation for reading a table
+static bool readTableCheck(const psFits *fits // FITS file
+                           )
+{
+    PS_ASSERT_FITS_NON_NULL(fits, NULL);
+
+    if (psFitsGetExtNum(fits) == 0 && !psFitsMoveExtNum(fits, 1, false)) {
+        psError(PS_ERR_IO, false, "Unable to move to first extension to read table.");
+        return false;
+    }
+
+
+    // check that we are positioned on a table HDU
+    int status = 0;                     // CFITSIO status
+    int hdutype;                        // Type of HDU
+    fits_get_hdu_type(fits->fd, &hdutype, &status);
+    if (psFitsError(status, true, "Could not determine the HDU type.")) {
+        return false;
+    }
+    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
+        psError(PS_ERR_IO, true, _("Current FITS HDU is not a table."));
+        return false;
+    }
+    return true;
+}
+
 
 psMetadata* psFitsReadTableRow(const psFits* fits,
@@ -54,34 +81,16 @@
     PS_ASSERT_INT_NONNEGATIVE(row, NULL);
 
+    if (!readTableCheck(fits)) {
+        return NULL;
+    }
+
+    // get the size of the FITS table
     long numRows;
     int numCols;
     int status = 0;
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    fits_get_hdu_type(fits->fd,&hdutype, &status);
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the HDU type. CFITSIO Error: %s"),
-                fitsErr);
-        return NULL;
-    }
-    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                _("Current FITS HDU type must be a table."));
-        return NULL;
-    }
-
-    // get the size of the FITS table
     fits_get_num_rows(fits->fd, &numRows, &status);
     fits_get_num_cols(fits->fd, &numCols, &status);
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Failed to determine the size of the current HDU table. CFITSIO Error: %s"),
-                fitsErr);
+    if (status != 0) {
+        psFitsError(status, true, "Failed to determine the size of the current HDU table.");
         return NULL;
     }
@@ -97,4 +106,10 @@
 
     psMetadata* data = psMetadataAlloc();
+
+    int hdutype;                        // Type of HDU: need to distinguish ASCII and binary tables
+    fits_get_hdu_type(fits->fd, &hdutype, &status);
+    if (psFitsError(status, true, "Could not determine the HDU type.")) {
+        return false;
+    }
 
     int typecode;
@@ -113,8 +128,10 @@
         // get the column type
         fits_get_coltype(fits->fd, col, &typecode, &repeat, &width, &status);
-
-        if (status == 0) {
-
-            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE, VECTYPE) \
+        if (psFitsError(status, true, "Unable to get column type for column %d", col)) {
+            psFree(data);
+            return NULL;
+        }
+
+#define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE, VECTYPE) \
         case FITSTYPE: { \
                 if (repeat == 1) { \
@@ -144,47 +161,34 @@
             }
 
-            switch (typecode) {
-            case TBYTE:
-            case TSHORT:
-            case TLONGLONG:
-                READ_TABLE_ROW_CASE(TLONG, long, S32,S32)
-                READ_TABLE_ROW_CASE(TFLOAT, float, F32,F32)
-                READ_TABLE_ROW_CASE(TDOUBLE, double, F64,F64)
-                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL,S8);
-            case TSTRING: {
-                    char* value = psAlloc(repeat+1);
-                    int anynul = 0;
-                    fits_read_col(fits->fd, TSTRING, col,row+1,
-                                  1, 1, NULL, &value, &anynul, &status);
-                    psTrace("psLib.fits",5,"Column #%i, '%s', is type %i, repeat %li, value = %s\n",
-                            col, name, typecode, repeat, value);
-                    if (anynul == 0) {
-                        psMetadataAdd(data,PS_LIST_TAIL, name,
-                                      PS_DATA_STRING,
-                                      "", value);
-                    }
-                    psFree(value);
-                    break;
-                }
-            default:
-                psWarning("Data type (%d) not supportted for column %d",
-                          typecode, col);
-
-                psTrace("psLib.fits", 2,
-                        "Column %d or row %d was of a non primitive type, %d",
-                        col, row, typecode);
-            }
-        }
-
-        if ( status != 0) {
-            char fitsErr[MAX_STRING_LENGTH];
-            (void)fits_get_errstatus(status, fitsErr);
-            psError(PS_ERR_IO, true,
-                    _("Failed to retrieve table element (%d,%d). CFITSIO Error: %s"),
-                    col,row,fitsErr);
+        switch (typecode) {
+          case TBYTE:
+          case TSHORT:
+          case TLONGLONG:
+            READ_TABLE_ROW_CASE(TLONG, long, S32, S32);
+            READ_TABLE_ROW_CASE(TFLOAT, float, F32, F32);
+            READ_TABLE_ROW_CASE(TDOUBLE, double, F64, F64);
+            READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL, S8);
+          case TSTRING: {
+              psString value = psStringAlloc(repeat);
+              int anynul = 0;
+              fits_read_col(fits->fd, TSTRING, col,row+1, 1, 1, NULL, &value, &anynul, &status);
+              psTrace("psLib.fits", 5, "Column #%i, '%s', is type %i, repeat %li, value = %s\n",
+                      col, name, typecode, repeat, value);
+              if (anynul == 0) {
+                  psMetadataAdd(data,PS_LIST_TAIL, name, PS_DATA_STRING, NULL, value);
+              }
+              psFree(value);
+              break;
+          }
+          default:
+            psWarning("Data type (%d) not supportted for column %d", typecode, col);
+            psTrace("psLib.fits", 2, "Column %d or row %d was of a non primitive type, %d",
+                    col, row, typecode);
+        }
+
+        if (psFitsError(status, true, "Failed to retrieve table element (%d,%d)", col, row)) {
             psFree(data);
             return NULL;
         }
-
     }
 
@@ -198,45 +202,27 @@
     PS_ASSERT_STRING_NON_EMPTY(colname, NULL);
 
+    if (!readTableCheck(fits)) {
+        return NULL;
+    }
+
     int colnum = 0;
     int status = 0;
 
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the HDU type. CFITSIO Error: %s"),
-                fitsErr);
-        return NULL;
-    }
-    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                _("Current FITS HDU type must be a table."));
-        return NULL;
-    }
-
     // find the column by name
-    if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Specified column, %s, was not found. CFITSIO Error: %s"),
-                colname, fitsErr);
+    if (fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        psFitsError(status, true, "Specified column, %s, was not found.", colname);
         return NULL;
     }
 
     // get the number of rows
-    long numRows = 0;
-    fits_get_num_rows(fits->fd, &numRows, &status);
+    long numRows = psFitsTableSize(fits);
+    if (numRows == -1) {
+        return NULL;
+    }
 
     // get the column length.
     int width;
-    if ( fits_get_col_display_width(fits->fd, colnum, &width, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the datatype of the table column. CFITSIO Error: %s"),
-                fitsErr);
+    if (fits_get_col_display_width(fits->fd, colnum, &width, &status) != 0) {
+        psFitsError(status, true, "Could not determine the datatype of the table column.");
         return NULL;
     }
@@ -245,23 +231,10 @@
     psArray* result = psArrayAlloc(numRows);
     for (int row = 0; row < numRows; row++) {
-        result->data[row] = psAlloc((width+1)*sizeof(char));
-    }
-
-    fits_read_col_str(fits->fd,
-                      colnum,
-                      1, // firstrow
-                      1, // firestelem
-                      numRows,
-                      "", // nulstr
-                      (char**)result->data,
-                      NULL,
-                      &status);
-
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Failed to read table column. CFITSIO Error: %s"),
-                fitsErr);
+        result->data[row] = psStringAlloc(width);
+    }
+
+    fits_read_col_str(fits->fd, colnum, 1, 1, numRows, "", (char**)result->data, NULL, &status);
+    if (psFitsError(status, true, "Failed to read table column.")) {
+        psFree(result);
         return NULL;
     }
@@ -276,38 +249,22 @@
     PS_ASSERT_STRING_NON_EMPTY(colname, NULL);
 
+    if (!readTableCheck(fits)) {
+        return NULL;
+    }
+
     int status = 0;
     int colnum = 0;
 
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the HDU type. CFITSIO Error: %s"),
-                fitsErr);
-        return NULL;
-    }
-    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                _("Current FITS HDU type must be a table."));
-        return NULL;
-    }
-
     // find the column by name
-    if ( fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Specified column, %s, was not found. CFITSIO Error: %s"),
-                colname, fitsErr);
+    if (fits_get_colnum(fits->fd, CASESEN, (char*)colname, &colnum, &status) != 0) {
+        psFitsError(status, true, "Specified column, %s, was not found.", colname);
         return NULL;
     }
 
     // get the number of rows
-    long numRows = 0;
-    fits_get_num_rows(fits->fd,
-                      &numRows,
-                      &status);
+    long numRows = psFitsTableSize(fits);
+    if (numRows == -1) {
+        return NULL;
+    }
 
     // get the column datatype.
@@ -315,10 +272,6 @@
     long repeat;
     long width;
-    if ( fits_get_eqcoltype(fits->fd, colnum, &typecode, &repeat, &width, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the datatype of the table column. CFITSIO Error: %s"),
-                fitsErr);
+    if (fits_get_eqcoltype(fits->fd, colnum, &typecode, &repeat, &width, &status) != 0) {
+        psFitsError(status, true, "Could not determine the datatype of the table column.");
         return NULL;
     }
@@ -326,21 +279,7 @@
     psVector* result = psVectorAlloc(numRows, p_psFitsTypeFromCfitsio(typecode));
 
-    fits_read_col(fits->fd,
-                  typecode,
-                  colnum,
-                  1 /* firstrow */,
-                  1 /* firstelem */,
-                  numRows,
-                  NULL,
-                  (psPtr)(result->data.U8),
-                  NULL,
-                  &status);
-
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Failed to read table column. CFITSIO Error: %s"),
-                fitsErr);
+    fits_read_col(fits->fd, typecode, colnum, 1, 1, numRows, NULL, (psPtr)(result->data.U8), NULL, &status);
+    if (psFitsError(status, true, "Failed to read table column.")) {
+        psFree(result);
         return NULL;
     }
@@ -354,39 +293,18 @@
     PS_ASSERT_FITS_NON_NULL(fits, NULL);
 
-    int status = 0;
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the HDU type. CFITSIO Error: %s"),
-                fitsErr);
-        return NULL;
-    }
-    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                _("Current FITS HDU type must be a table."));
-        return NULL;
-    }
-
-    // get the size of the FITS table
-    long numRows = 0;
-    fits_get_num_rows(fits->fd, &numRows, &status);
-    if ( status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Failed to determine the size of the current HDU table. CFITSIO Error: %s"),
-                fitsErr);
-        return NULL;
-    }
-
+    if (!readTableCheck(fits)) {
+        return NULL;
+    }
+
+    // get the number of rows
+    long numRows = psFitsTableSize(fits);
+    if (numRows == -1) {
+        return NULL;
+    }
 
     psArray* table = psArrayAlloc(numRows);
 
     for (int row = 0; row < numRows; row++) {
-        psTrace("psLib.fits",5,"Reading row %i of %li\n",row, numRows);
+        psTrace("psLib.fits",5,"Reading row %i of %li\n", row, numRows);
         table->data[row] = psFitsReadTableRow(fits,row);
     }
@@ -536,11 +454,11 @@
                 }
                 if (colItem->type != spec->type) {
-                    psLogMsg(__func__, PS_LOG_WARN, "Differing type found for column %s: %x vs %x --- "
-                             "using the first found.\n", colSpecItem->name, colItem->type, spec->type);
+                    psWarning("Differing type found for column %s: %x vs %x --- using the first found.\n",
+                              colSpecItem->name, colItem->type, spec->type);
                 }
                 if (colItem->type == PS_DATA_VECTOR) {
                     psVector *vector = colItem->data.V; // The vector
                     if (vector->type.type != spec->vectorType) {
-                        psLogMsg(__func__, PS_LOG_WARN, "Differing vector type found for column %s: %x vs %x"
+                        psWarning("Differing vector type found for column %s: %x vs %x "
                                  "--- using the first found.\n", colSpecItem->name, vector->type.type,
                                  spec->vectorType);
@@ -616,9 +534,6 @@
 
     if (status != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_LOCATION_INVALID, true,
-                "Unable to create FITS table with %ld columns and %ld rows: %s",
-                numColumns, table->n, fitsErr);
+        psFitsError(status, true, "Unable to create FITS table with %ld columns and %ld rows",
+                    numColumns, table->n);
         psFree(colSpecsIter);
         psFree(colSpecs);
@@ -713,8 +628,5 @@
         // Check error status from writing column
         if (status != 0) {
-            char fitsErr[MAX_STRING_LENGTH];
-            fits_get_errstatus(status, fitsErr);
-            psError(PS_ERR_LOCATION_INVALID, true, "Unable to write column %ld of FITS table: %s",
-                    colNum, fitsErr);
+            psFitsError(status, true, "Unable to write column %ld of FITS table", colNum);
             psFree(colSpecsIter);
             psFree(colSpecs);
@@ -738,26 +650,11 @@
     PS_ASSERT_INT_NONNEGATIVE(row, false);
 
+    if (!readTableCheck(fits)) {
+        return NULL;
+    }
+
     int status = 0;
-
-    // check to see if we even are positioned on a table HDU
-    int hdutype;
-    if ( fits_get_hdu_type(fits->fd,&hdutype, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        (void)fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_IO, true,
-                _("Could not determine the HDU type. CFITSIO Error: %s"),
-                fitsErr);
-        return false;
-    }
-    if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
-        psError(PS_ERR_IO, true,
-                _("Current FITS HDU type must be a table."));
-        return false;
-    }
-
-    psMetadataIterator* iter = psMetadataIteratorAlloc((psPtr)data,PS_LIST_HEAD,NULL);
-
+    psMetadataIterator* iter = psMetadataIteratorAlloc((psPtr)data, PS_LIST_HEAD, NULL);
     psMetadataItem* item;
-
     while ( (item=psMetadataGetAndIncrement(iter)) != NULL) {
         if (PS_DATA_IS_PRIMITIVE(item->type) ||
@@ -767,15 +664,11 @@
             int colnum = 0;
 
-            if ( fits_get_colnum(fits->fd, CASESEN, item->name, &colnum, &status) == 0) {
+            if (fits_get_colnum(fits->fd, CASESEN, item->name, &colnum, &status) == 0) {
                 // cooresponding column found in table
                 int dataType;
                 p_psFitsTypeToCfitsio(item->type, NULL, NULL, &dataType);
 
-                if (fits_write_col(fits->fd, dataType, colnum, row+1, 1, 1, &item->data,&status) != 0) {
-                    char fitsErr[MAX_STRING_LENGTH];
-                    (void)fits_get_errstatus(status, fitsErr);
-                    psError(PS_ERR_IO, true,
-                            _("Could not write data to file. CFITSIO Error: %s"),
-                            fitsErr);
+                if (fits_write_col(fits->fd, dataType, colnum, row+1, 1, 1, &item->data, &status) != 0) {
+                    psFitsError(status, true, "Could not write data to file.");
                     psFree(iter);
                     return false;
@@ -783,6 +676,5 @@
             } else {
                 // the column was not found.
-                psWarning("No column with the name '%s' exists in the table.",
-                          item->name);
+                psWarning("No column with the name '%s' exists in the table.", item->name);
             }
         }
