summaryrefslogtreecommitdiffstats
path: root/ast/table.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 16:24:30 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 16:24:30 (GMT)
commit97d207f0a76b98e4a4d4a74b7417fc9aa7828654 (patch)
tree0155897549ec7a272d0453351e9da374ae34c8a9 /ast/table.c
parente9ad1f4c4c12164247d284f2d1824b75e35de23f (diff)
downloadblt-97d207f0a76b98e4a4d4a74b7417fc9aa7828654.zip
blt-97d207f0a76b98e4a4d4a74b7417fc9aa7828654.tar.gz
blt-97d207f0a76b98e4a4d4a74b7417fc9aa7828654.tar.bz2
upgrade ast 8.7.1
Diffstat (limited to 'ast/table.c')
-rw-r--r--ast/table.c5246
1 files changed, 5246 insertions, 0 deletions
diff --git a/ast/table.c b/ast/table.c
new file mode 100644
index 0000000..0d283bc
--- /dev/null
+++ b/ast/table.c
@@ -0,0 +1,5246 @@
+/*
+*class++
+* Name:
+* Table
+
+* Purpose:
+* A 2-dimensional table of values.
+
+* Constructor Function:
+c astTable
+f AST_TABLE
+
+* Description:
+* The Table class is a type of KeyMap that represents a two-dimensional
+* table of values. The
+c astMapGet... and astMapPut...
+f AST_MAPGET... and AST_MAPPUT...
+* methods provided by the KeyMap class should be used for storing and
+* retrieving values from individual cells within a Table. Each entry
+* in the KeyMap represents a single cell of the table and has an
+* associated key of the form "<COL>(i)" where "<COL>" is the
+* upper-case name of a table column and "i" is the row index (the
+* first row is row 1). Keys of this form should always be used when
+* using KeyMap methods to access entries within a Table.
+*
+* Columns must be declared using the
+c astAddColumn
+f AST_ADDCOLUMN
+* method before values can be stored within them. This also fixes the
+* type and shape of the values that may be stored in any cell of the
+* column. Cells may contain scalar or vector values of any data type
+* supported by the KeyMap class. Multi-dimensional arrays may also be
+* stored, but these must be vectorised when storing and retrieving
+* them within a table cell. All cells within a single column must
+* have the same type and shape, as specified when the column is added
+* to the Table.
+*
+* Tables may have parameters that describe global properties of the
+* entire table. These are stored as entries in the parent KeyMap and
+* can be access using the get and set method of the KeyMap class.
+* However, parameters must be declared using the
+c astAddParameter
+f AST_ADDPARAMETER
+* method before being accessed.
+*
+* Note - since accessing entries within a KeyMap is a relatively slow
+* process, it is not recommended to use the Table class to store
+* very large tables.
+
+* Inheritance:
+* The Table class inherits from the KeyMap class.
+
+* Attributes:
+* In addition to those attributes common to all KeyMaps, every
+* Table also has the following attributes:
+*
+* - ColumnLenC(column): The largest string length of any value in a column
+* - ColumnLength(column): The number of elements in each value in a column
+* - ColumnNdim(column): The number of axes spanned by each value in a column
+* - ColumnType(column): The data type of each value in a column
+* - ColumnUnit(column): The unit string describing each value in a column
+* - Ncolumn: The number of columns currently in the Table
+* - Nrow: The number of rows currently in the Table
+* - Nparameter: The number of global parameters currently in the Table
+
+* Functions:
+c In addition to those functions applicable to all KeyMaps, the
+c following functions may also be applied to all Tables:
+f In addition to those routines applicable to all KeyMaps, the
+f following routines may also be applied to all Tables:
+*
+c - astAddColumn: Add a new column definition to a Table
+c - astAddParameter: Add a new global parameter definition to a Table
+c - astColumnName: Return the name of the column with a given index
+c - astColumnShape: Return the shape of the values in a named column
+c - astHasColumn: Checks if a column exists in a Table
+c - astHasParameter: Checks if a global parameter exists in a Table
+c - astParameterName: Return the name of the parameter with a given index
+c - astPurgeRows: Remove all empty rows from a Table
+c - astRemoveColumn: Remove a column from a Table
+c - astRemoveParameter: Remove a global parameter from a Table
+c - astRemoveRow: Remove a row from a Table
+f - AST_ADDCOLUMN: Add a new column definition to a Table
+f - AST_ADDPARAMETER: Add a new global parameter definition to a Table
+f - AST_COLUMNNAME: Return the name of the column with a given index
+f - AST_COLUMNSHAPE: Return the shape of the values in a named column
+f - AST_HASCOLUMN: Checks if a column exists in a Table
+f - AST_HASPARAMETER: Checks if a global parameter exists in a Table
+f - AST_PARAMETERNAME: Return the name of the parameter with a given index
+f - AST_PURGEROWS: Remove all empty rows from a Table
+f - AST_REMOVECOLUMN: Remove a column from a Table
+f - AST_REMOVEPARAMETER: Remove a global parameter from a Table
+f - AST_REMOVEROW: Remove a row from a Table
+
+* Copyright:
+* Copyright (C) 2010-2011 Science & Technology Facilities Council.
+* All Rights Reserved.
+
+* Licence:
+* This program is free software: you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation, either
+* version 3 of the License, or (at your option) any later
+* version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General
+* License along with this program. If not, see
+* <http://www.gnu.org/licenses/>.
+
+* Authors:
+* DSB: David S. Berry (Starlink)
+
+* History:
+* 22-NOV-2010 (DSB):
+* Original version.
+* 13-MAY-2011 (DSB):
+* Added support for table parameters.
+* 16-NOV-2013 (DSB):
+* Fix bug in forming keys in GetColumnLenC.
+*class--
+*/
+
+/* Module Macros. */
+/* ============== */
+/* Set the name of the class we are implementing. This indicates to
+ the header files that define class interfaces that they should make
+ "protected" symbols available. */
+#define astCLASS Table
+
+/* Fixed KeyMap entry names */
+#define LENGTH "Length"
+#define NAME "Name"
+#define NROW "Nrow"
+#define SHAPE "Shape"
+#define SIZE "Size"
+#define TYPE "Type"
+#define UNIT "Unit"
+
+/* A function macro that puts quotes around a value */
+#define STRING(w) #w
+
+/* Include files. */
+/* ============== */
+/* Interface definitions. */
+/* ---------------------- */
+
+#include "globals.h" /* Thread-safe global data access */
+#include "error.h" /* Error reporting facilities */
+#include "memory.h" /* Memory allocation facilities */
+#include "object.h" /* Base Object class */
+#include "keymap.h" /* Coordinate keymaps (parent class) */
+#include "channel.h" /* I/O channels */
+#include "table.h" /* Interface definition for this class */
+
+
+/* Error code definitions. */
+/* ----------------------- */
+#include "ast_err.h" /* AST error codes */
+
+/* C header files. */
+/* --------------- */
+#include <ctype.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* Module Variables. */
+/* ================= */
+
+/* Address of this static variable is used as a unique identifier for
+ member of this class. */
+static int class_check;
+
+/* Pointers to parent class methods which are extended by this class. */
+static const char *(* parent_getattrib)( AstObject *, const char *, int * );
+static void (* parent_setkeycase)( AstKeyMap *, int, int * );
+static void (* parent_clearkeycase)( AstKeyMap *, int * );
+static int (* parent_equal)( AstObject *, AstObject *, int * );
+static int (* parent_getobjsize)( AstObject *, int * );
+static int (* parent_mapget0a)( AstKeyMap *, const char *, AstObject * *, int *);
+static int (* parent_mapget0c)( AstKeyMap *, const char *, const char **, int *);
+static int (* parent_mapget0d)( AstKeyMap *, const char *, double *, int *);
+static int (* parent_mapget0f)( AstKeyMap *, const char *, float *, int *);
+static int (* parent_mapget0i)( AstKeyMap *, const char *, int *, int *);
+static int (* parent_mapget0p)( AstKeyMap *, const char *, void **, int *);
+static int (* parent_mapget0b)( AstKeyMap *, const char *, unsigned char *, int *);
+static int (* parent_mapget0s)( AstKeyMap *, const char *, short int *, int *);
+static int (* parent_mapget1a)( AstKeyMap *, const char *, int, int *, AstObject **, int * );
+static int (* parent_mapget1c)( AstKeyMap *, const char *, int, int, int *, char *, int * );
+static int (* parent_mapget1d)( AstKeyMap *, const char *, int, int *, double *, int * );
+static int (* parent_mapget1f)( AstKeyMap *, const char *, int, int *, float *, int * );
+static int (* parent_mapget1i)( AstKeyMap *, const char *, int, int *, int *, int * );
+static int (* parent_mapget1p)( AstKeyMap *, const char *, int, int *, void **, int * );
+static int (* parent_mapget1s)( AstKeyMap *, const char *, int, int *, short int *, int * );
+static int (* parent_mapget1b)( AstKeyMap *, const char *, int, int *, unsigned char *, int * );
+static int (* parent_mapgetelema)( AstKeyMap *, const char *, int, AstObject **, int * );
+static int (* parent_mapgetelemc)( AstKeyMap *, const char *, int, int, char *, int * );
+static int (* parent_mapgetelemd)( AstKeyMap *, const char *, int, double *, int * );
+static int (* parent_mapgetelemf)( AstKeyMap *, const char *, int, float *, int * );
+static int (* parent_mapgetelemi)( AstKeyMap *, const char *, int, int *, int * );
+static int (* parent_mapgetelemp)( AstKeyMap *, const char *, int, void **, int * );
+static int (* parent_mapgetelems)( AstKeyMap *, const char *, int, short int *, int * );
+static int (* parent_mapgetelemb)( AstKeyMap *, const char *, int, unsigned char *, int * );
+static int (* parent_testattrib)( AstObject *, const char *, int * );
+static void (* parent_clearattrib)( AstObject *, const char *, int * );
+static void (* parent_mapput0a)( AstKeyMap *, const char *, AstObject *, const char *, int *);
+static void (* parent_mapput0c)( AstKeyMap *, const char *, const char *, const char *, int *);
+static void (* parent_mapput0d)( AstKeyMap *, const char *, double, const char *, int *);
+static void (* parent_mapput0f)( AstKeyMap *, const char *, float, const char *, int *);
+static void (* parent_mapput0i)( AstKeyMap *, const char *, int, const char *, int *);
+static void (* parent_mapput0p)( AstKeyMap *, const char *, void *, const char *, int *);
+static void (* parent_mapput0b)( AstKeyMap *, const char *, unsigned char, const char *, int *);
+static void (* parent_mapput0s)( AstKeyMap *, const char *, short int, const char *, int *);
+static void (* parent_mapput1a)( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * );
+static void (* parent_mapput1c)( AstKeyMap *, const char *, int, const char *const [], const char *, int * );
+static void (* parent_mapput1d)( AstKeyMap *, const char *, int, const double *, const char *, int * );
+static void (* parent_mapput1f)( AstKeyMap *, const char *, int, const float *, const char *, int * );
+static void (* parent_mapput1i)( AstKeyMap *, const char *, int, const int *, const char *, int * );
+static void (* parent_mapput1p)( AstKeyMap *, const char *, int, void *const [], const char *, int * );
+static void (* parent_mapput1b)( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * );
+static void (* parent_mapput1s)( AstKeyMap *, const char *, int, const short int *, const char *, int * );
+static void (* parent_mapputelema)( AstKeyMap *, const char *, int, AstObject *, int * );
+static void (* parent_mapputelemc)( AstKeyMap *, const char *, int, const char *, int * );
+static void (* parent_mapputelemd)( AstKeyMap *, const char *, int, double, int * );
+static void (* parent_mapputelemf)( AstKeyMap *, const char *, int, float, int * );
+static void (* parent_mapputelemi)( AstKeyMap *, const char *, int, int, int * );
+static void (* parent_mapputelemp)( AstKeyMap *, const char *, int, void *, int * );
+static void (* parent_mapputelemb)( AstKeyMap *, const char *, int, unsigned char, int * );
+static void (* parent_mapputelems)( AstKeyMap *, const char *, int, short int, int * );
+static void (* parent_mapremove)( AstKeyMap *, const char *, int * );
+static void (* parent_setattrib)( AstObject *, const char *, int * );
+static void (* parent_mapputu)( AstKeyMap *, const char *, const char *, int * );
+
+#if defined(THREAD_SAFE)
+static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * );
+#endif
+
+
+/* Define macros for accessing each item of thread specific global data. */
+#ifdef THREAD_SAFE
+
+/* Define how to initialise thread-specific globals. */
+#define GLOBAL_inits \
+ globals->Class_Init = 0; \
+ globals->GetAttrib_Buff[ 0 ] = 0;
+
+/* Create the function that initialises global data for this module. */
+astMAKE_INITGLOBALS(Table)
+
+/* Define macros for accessing each item of thread specific global data. */
+#define class_init astGLOBAL(Table,Class_Init)
+#define class_vtab astGLOBAL(Table,Class_Vtab)
+#define getattrib_buff astGLOBAL(Table,GetAttrib_Buff)
+
+
+
+/* If thread safety is not needed, declare and initialise globals at static
+ variables. */
+#else
+
+static char getattrib_buff[ 101 ];
+
+/* Define the class virtual function table and its initialisation flag
+ as static variables. */
+static AstTableVtab class_vtab; /* Virtual function table */
+static int class_init = 0; /* Virtual function table initialised? */
+
+#endif
+
+/* External Interface Function Prototypes. */
+/* ======================================= */
+/* The following functions have public prototypes only (i.e. no
+ protected prototypes), so we must provide local prototypes for use
+ within this module. */
+AstTable *astTableId_( const char *, ... );
+
+/* Prototypes for Private Member Functions. */
+/* ======================================== */
+static AstKeyMap *ColumnProps( AstTable *, int * );
+static AstKeyMap *ParameterProps( AstTable *, int * );
+static const char *ColumnName( AstTable *, int index, int * );
+static const char *ParameterName( AstTable *, int index, int * );
+static const char *GetColumnUnit( AstTable *, const char *, int * );
+static const char *TypeString( int );
+static int Equal( AstObject *, AstObject *, int * );
+static int GetColumnLenC( AstTable *, const char *, int * );
+static int GetColumnLength( AstTable *, const char *, int * );
+static int GetColumnNdim( AstTable *, const char *, int * );
+static int GetColumnType( AstTable *, const char *, int * );
+static int GetNcolumn( AstTable *, int * );
+static int GetNparameter( AstTable *, int * );
+static int GetObjSize( AstObject *, int * );
+static int HasColumn( AstTable *, const char *, int *);
+static int HasParameter( AstTable *, const char *, int *);
+static int MapGet0A( AstKeyMap *, const char *, AstObject **, int * );
+static int MapGet0B( AstKeyMap *, const char *, unsigned char *, int * );
+static int MapGet0C( AstKeyMap *, const char *, const char **, int * );
+static int MapGet0D( AstKeyMap *, const char *, double *, int * );
+static int MapGet0F( AstKeyMap *, const char *, float *, int * );
+static int MapGet0I( AstKeyMap *, const char *, int *, int * );
+static int MapGet0P( AstKeyMap *, const char *, void **, int * );
+static int MapGet0S( AstKeyMap *, const char *, short int *, int * );
+static int MapGet1A( AstKeyMap *, const char *, int, int *, AstObject **, int * );
+static int MapGet1B( AstKeyMap *, const char *, int, int *, unsigned char *, int * );
+static int MapGet1C( AstKeyMap *, const char *, int, int, int *, char *, int * );
+static int MapGet1D( AstKeyMap *, const char *, int, int *, double *, int * );
+static int MapGet1F( AstKeyMap *, const char *, int, int *, float *, int * );
+static int MapGet1I( AstKeyMap *, const char *, int, int *, int *, int * );
+static int MapGet1P( AstKeyMap *, const char *, int, int *, void **, int * );
+static int MapGet1S( AstKeyMap *, const char *, int, int *, short int *, int * );
+static int MapGetElemA( AstKeyMap *, const char *, int, AstObject **, int * );
+static int MapGetElemB( AstKeyMap *, const char *, int, unsigned char *, int * );
+static int MapGetElemC( AstKeyMap *, const char *, int, int, char *, int * );
+static int MapGetElemD( AstKeyMap *, const char *, int, double *, int * );
+static int MapGetElemF( AstKeyMap *, const char *, int, float *, int * );
+static int MapGetElemI( AstKeyMap *, const char *, int, int *, int * );
+static int MapGetElemP( AstKeyMap *, const char *, int, void **, int * );
+static int MapGetElemS( AstKeyMap *, const char *, int, short int *, int * );
+static int ParseKey( AstTable *, const char *, int, char *, int *, AstKeyMap **, const char *, int * );
+static void AddColumn( AstTable *, const char *, int, int, int *, const char *, int * );
+static void AddParameter( AstTable *, const char *, int * );
+static void ColumnShape( AstTable *, const char *, int, int *, int *, int *);
+static void Copy( const AstObject *, AstObject *, int * );
+static void Delete( AstObject *, int * );
+static void Dump( AstObject *, AstChannel *, int * );
+static void MapPut0A( AstKeyMap *, const char *, AstObject *, const char *, int * );
+static void MapPut0B( AstKeyMap *, const char *, unsigned char, const char *, int * );
+static void MapPut0C( AstKeyMap *, const char *, const char *, const char *, int * );
+static void MapPut0D( AstKeyMap *, const char *, double, const char *, int * );
+static void MapPut0F( AstKeyMap *, const char *, float, const char *, int * );
+static void MapPut0I( AstKeyMap *, const char *, int, const char *, int * );
+static void MapPut0P( AstKeyMap *, const char *, void *, const char *, int * );
+static void MapPut0S( AstKeyMap *, const char *, short int, const char *, int * );
+static void MapPut1A( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * );
+static void MapPut1B( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * );
+static void MapPut1C( AstKeyMap *, const char *, int, const char *const [], const char *, int * );
+static void MapPut1D( AstKeyMap *, const char *, int, const double *, const char *, int * );
+static void MapPut1F( AstKeyMap *, const char *, int, const float *, const char *, int * );
+static void MapPut1I( AstKeyMap *, const char *, int, const int *, const char *, int * );
+static void MapPut1P( AstKeyMap *, const char *, int, void *const [], const char *, int * );
+static void MapPut1S( AstKeyMap *, const char *, int, const short int *, const char *, int * );
+static void MapPutElemA( AstKeyMap *, const char *, int, AstObject *, int * );
+static void MapPutElemB( AstKeyMap *, const char *, int, unsigned char, int * );
+static void MapPutElemC( AstKeyMap *, const char *, int, const char *, int * );
+static void MapPutElemD( AstKeyMap *, const char *, int, double, int * );
+static void MapPutElemF( AstKeyMap *, const char *, int, float, int * );
+static void MapPutElemI( AstKeyMap *, const char *, int, int, int * );
+static void MapPutElemP( AstKeyMap *, const char *, int, void *, int * );
+static void MapPutElemS( AstKeyMap *, const char *, int, short int, int * );
+static void MapPutU( AstKeyMap *, const char *, const char *, int * );
+static void PurgeRows( AstTable *, int * );
+static void RemoveColumn( AstTable *, const char *, int * );
+static void RemoveParameter( AstTable *, const char *, int * );
+static void RemoveRow( AstTable *, int, int * );
+static void SetKeyCase( AstKeyMap *, int, int * );
+static void ClearKeyCase( AstKeyMap *, int * );
+
+#if defined(THREAD_SAFE)
+static int ManageLock( AstObject *, int, int, AstObject **, int * );
+#endif
+
+static const char *GetAttrib( AstObject *, const char *, int * );
+static int TestAttrib( AstObject *, const char *, int * );
+static void ClearAttrib( AstObject *, const char *, int * );
+static void SetAttrib( AstObject *, const char *, int * );
+
+static int GetNrow( AstTable *, int * );
+static void SetNrow( AstTable *, int, int * );
+
+static int GetNcolumn( AstTable *, int * );
+static int GetNparameter( AstTable *, int * );
+
+
+/* Member functions. */
+/* ================= */
+static void AddColumn( AstTable *this, const char *name, int type,
+ int ndim, int *dims, const char *unit, int *status ) {
+/*
+*++
+* Name:
+c astAddColumn
+f AST_ADDCOLUMN
+
+* Purpose:
+* Add a new column definition to a table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astAddColumn( AstTable *this, const char *name, int type, int ndim,
+c int *dims, const char *unit )
+f CALL AST_ADDCOLUMN( THIS, NAME, TYPE, NDIM, DIMS, UNIT, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* Adds the definition of a new column to the supplied table. Initially,
+* the column is empty. Values may be added subsequently using the
+* methods of the KeyMap class.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c name
+f NAME = CHARACTER * ( * ) (Given)
+* The column name. Trailing spaces are ignored (all other spaces
+* are significant). The supplied string is converted to upper case.
+c type
+f TYPE = INTEGER (Given)
+* The data type associated with the column. See "Applicability:"
+* below.
+c ndim
+f NDIM = INTEGER (Given)
+* The number of dimensions spanned by the values stored in a single
+* cell of the column. Zero if the column holds scalar values.
+c dims
+f DIMS( NDIM ) = INTEGER (Given)
+* An array holding the the lengths of each of the axes spanned by
+* the values stored in a single cell of the column. Ignored if the
+* column holds scalara values.
+c unit
+f UNIT = CHARACTER * ( * ) (Given)
+* A string specifying the units of the column. Supply a blank
+* string if the column is unitless.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Applicability:
+* Table
+* Tables can hold columns with any of the following data types -
+* AST__INTTYPE (for integer), AST__SINTTYPE (for
+c short int),
+f INTEGER*2),
+* AST__BYTETYPE (for
+c unsigned bytes - i.e. unsigned chars),
+f bytes),
+* AST__DOUBLETYPE (for double
+* precision floating point), AST__FLOATTYPE (for single
+* precision floating point), AST__STRINGTYPE (for character string),
+* AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for
+* arbitrary C pointer) or AST__UNDEFTYPE (for undefined values
+* created by
+c astMapPutU).
+f AST_MAPPUTU).
+* FitsTable
+* FitsTables can hold columns with any of the following data types -
+* AST__INTTYPE (for integer), AST__SINTTYPE (for
+c short int),
+f INTEGER*2),
+* AST__BYTETYPE (for
+c unsigned bytes - i.e. unsigned chars),
+f bytes),
+* AST__DOUBLETYPE (for double
+* precision floating point), AST__FLOATTYPE (for single
+* precision floating point), AST__STRINGTYPE (for character string).
+
+* Notes:
+* - This
+c function
+f routine
+* returns without action if a column already exists in the Table
+* with the supplied name and properties. However an error is
+* reported if any of the properties differ.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding all column details */
+ AstKeyMap *col_km; /* KeyMap holding new column details */
+ const char *oldunit; /* Pointer to the old coumn unit string */
+ int *olddims; /* Shape of pre-existing column */
+ int idim; /* Axis index */
+ int namlen; /* Used length of "name" */
+ int nval; /* Number of values returned */
+ int oldtype; /* Data type of pre-existing column */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Verify supplied values. */
+ namlen = astChrLen( name );
+ if( namlen == 0 ) {
+ astError( AST__BADKEY, "astAddColumn(%s): Illegal blank column name "
+ "supplied.", status, astGetClass( this ) );
+
+ } else if( namlen > AST__MXCOLNAMLEN ) {
+ astError( AST__BADKEY, "astAddColumn(%s): Column name '%s' is too "
+ "long (must be no more than %d characters).", status,
+ astGetClass( this ), name, AST__MXCOLNAMLEN );
+
+ } else if( ndim < 0 ) {
+ astError( AST__NAXIN, "astAddColumn(%s): No of axes (%d) for values in "
+ "new column %s is invalid.", status, astGetClass( this ),
+ ndim, name );
+
+ } else if( TypeString( type ) == NULL ) {
+ astError( AST__NAXIN, "astAddColumn(%s): Bad data type supplied (%d) "
+ "for new column %s.", status, astGetClass( this ), type,
+ name );
+
+ } else {
+ for( idim = 0; idim < ndim; idim++ ) {
+ if( dims[ idim ] < 1 ) {
+ astError( AST__DIMIN, "astAddColumn(%s): Length of axis %d (%d) "
+ "for new column %s is invalid.", status,
+ astGetClass( this ), idim + 1, dims[ idim ], name );
+ break;
+ }
+ }
+ }
+
+/* If there is already a column with the given name, check its properties
+ match the supplied properties. */
+ if( astOK ) {
+ cols = astColumnProps( this );
+ if( astMapGet0A( cols, name, &col_km ) ) {
+
+ astMapGet0I( col_km, TYPE, &oldtype );
+ if( oldtype != type && astOK ) {
+ astError( AST__OLDCOL, "astAddColumn(%s): A column called "
+ "%s already exists in the table with a different "
+ "data type (%s).", status, astGetClass( this ),
+ name, TypeString( oldtype ) );
+ }
+
+ if( !astMapGet0C( col_km, UNIT, &oldunit ) ) oldunit = "";
+ if( strcmp( oldunit, unit ) && astOK ) {
+ astError( AST__OLDCOL, "astAddColumn(%s): A column called "
+ "%s already exists in the table with a different "
+ "unit string ('%s').", status, astGetClass( this ),
+ name, oldunit );
+ }
+
+ if( ndim != astMapLength( col_km, SHAPE ) && astOK ) {
+ astError( AST__OLDCOL, "astAddColumn(%s): A column called "
+ "%s already exists in the table with a different "
+ "number of axes (%d).", status, astGetClass( this ),
+ name, astMapLength( col_km, SHAPE ) );
+ }
+
+ if( ndim > 0 && astOK ) {
+ olddims = astMalloc( sizeof( int )*ndim );
+ (void) astMapGet1I( col_km, SHAPE, ndim, &nval, olddims );
+ for( idim = 0; idim < ndim && astOK; idim++ ) {
+ if( dims[ idim ] != olddims[ idim ] ) {
+ astError( AST__OLDCOL, "astAddColumn(%s): A column called "
+ "%s already exists in the table with a different "
+ "shape.", status, astGetClass( this ), name );
+ }
+ }
+ olddims = astFree( olddims );
+ }
+
+/* Otherwise, add a new column to the table. */
+ } else {
+
+/* Add a suitable entry describing the column to the Columns KeyMap. */
+ col_km = astKeyMap( " ", status );
+ astMapPut0C( col_km, NAME, name, NULL );
+ astMapPut0I( col_km, TYPE, type, NULL );
+ if( ndim ) astMapPut1I( col_km, SHAPE, ndim, dims, NULL );
+ astMapPut0C( col_km, UNIT, unit, NULL );
+
+/* Put the column KeyMap into the KeyMap holding details of all columns.
+ Use the column name as the key. */
+ astMapPut0A( cols, name, col_km, NULL );
+ }
+
+/* Annul the local KeyMap pointers. */
+ col_km = astAnnul( col_km );
+ cols = astAnnul( cols );
+ }
+}
+
+static void AddParameter( AstTable *this, const char *name, int *status ) {
+/*
+*++
+* Name:
+c astAddParameter
+f AST_ADDPARAMETER
+
+* Purpose:
+* Add a new global parameter definition to a table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astAddParameter( AstTable *this, const char *name )
+f CALL AST_ADDPARAMETER( THIS, NAME, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* Adds the definition of a new global parameter to the supplied
+* table. Note, this does not store a value for the parameter. To get
+* or set the parameter value, the methods of the paremt KeyMap class
+* should be used, using the name of the parameter as the key.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c name
+f NAME = CHARACTER * ( * ) (Given)
+* The parameter name. Trailing spaces are ignored (all other spaces
+* are significant). The supplied string is converted to upper case.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Notes:
+* - Unlike columns, the definition of a parameter does not specify its type,
+* size or dimensionality.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *pars; /* KeyMap holding all parameter details */
+ int namlen; /* Used length of "name" */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Verify supplied values. */
+ namlen = astChrLen( name );
+ if( namlen == 0 ) {
+ astError( AST__BADKEY, "astAddParameter(%s): Illegal blank parameter name "
+ "supplied.", status, astGetClass( this ) );
+
+ } else if( namlen > AST__MXCOLNAMLEN ) {
+ astError( AST__BADKEY, "astAddParameter(%s): Parameter name '%s' is too "
+ "long (must be no more than %d characters).", status,
+ astGetClass( this ), name, AST__MXCOLNAMLEN );
+ }
+
+/* Do nothing if there is already a parameter with the given name. */
+ if( astOK ) {
+ pars = astParameterProps( this );
+ if( !astMapHasKey( pars, name ) ) {
+
+/* Add a suitable entry to the Parameters KeyMap. The value is arbitrary
+ and currently unused. */
+ astMapPut0I( pars, name, 1, NULL );
+ }
+
+/* Annul the local KeyMap pointer. */
+ pars = astAnnul( pars );
+ }
+}
+
+static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
+/*
+* Name:
+* ClearAttrib
+
+* Purpose:
+* Clear an attribute value for a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* void ClearAttrib( AstObject *this, const char *attrib )
+
+* Class Membership:
+* Table member function (over-rides the astClearAttrib protected
+* method inherited from the KeyMap class).
+
+* Description:
+* This function clears the value of a specified attribute for a
+* Table, so that the default value will subsequently be used.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* attrib
+* Pointer to a null terminated string specifying the attribute
+* name. This should be in lower case with no surrounding white
+* space.
+*/
+
+/* Local Variables: */
+ AstTable *this;
+ int nc;
+ int len;
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the Table structure. */
+ this = (AstTable *) this_object;
+
+/* Get the length of the attribute string. */
+ len = strlen( attrib );
+
+/* Check the attribute name and clear the appropriate attribute. */
+ /* None yet */
+
+/* Define a macro to see if the attribute string matches any of the
+ read-only column attributes of this class. */
+#define MATCH(attr) \
+ ( nc = 0, ( 0 == astSscanf( attrib, attr "(%*s)%n", &nc ) ) && \
+ ( nc >= len ) )
+
+/* If the name was not recognised, test if it matches any of the
+ read-only attributes of this class. If it does, then report an
+ error. */
+ if ( !strcmp( attrib, "nrow" ) ||
+ !strcmp( attrib, "ncolumn" ) ||
+ !strcmp( attrib, "nparameter" ) ||
+ MATCH( "columnlenc" ) ||
+ MATCH( "columnlength" ) ||
+ MATCH( "columnndim" ) ||
+ MATCH( "columntype" ) ||
+ MATCH( "columnunit" ) ) {
+ astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" "
+ "value for a %s.", status, attrib, astGetClass( this ) );
+ astError( AST__NOWRT, "This is a read-only attribute." , status);
+
+/* If the attribute is still not recognised, pass it on to the parent
+ method for further interpretation. */
+ } else {
+ (*parent_clearattrib)( this_object, attrib, status );
+ }
+
+#undef MATCH
+
+}
+
+static void ClearKeyCase( AstKeyMap *this, int *status ) {
+/*
+* Name:
+* ClearKeyCase
+
+* Purpose:
+* Clear the KeyCase attribute value for a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "keymape.h"
+* void ClearKeyCase( AstKeyMap *this, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astClearKeyCase protected
+* method inherited from the KeyMap class).
+
+* Description:
+* This function clears the value of the KeyCase attribute for a
+* Table. For a Table, the KeyCase attribute cannot be changed so this
+* function exits without action.
+
+* Parameters:
+* this
+* Pointer to the Table.
+*/
+
+}
+
+static const char *ColumnName( AstTable *this, int index, int *status ) {
+/*
+*++
+* Name:
+c astColumnName
+f AST_COLUMNNAME
+
+* Purpose:
+* Get the name of the column at a given index within the Table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c const char *astColumnName( AstTable *this, int index )
+f RESULT = AST_COLUMNNAME( THIS, INDEX, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns a string holding the name of the column with
+* the given index within the Table.
+*
+* This function is intended primarily as a means of iterating round all
+* the columns in a Table. For this purpose, the number of columns in
+* the Table is given by the Ncolumn attribute of the Table. This function
+* could then be called in a loop, with the index value going from
+c zero to one less than Ncolumn.
+f one to Ncolumn.
+*
+* Note, the index associated with a column decreases monotonically with
+* the age of the column: the oldest Column in the Table will have index
+* one, and the Column added most recently to the Table will have the
+* largest index.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c index
+f INDEX = INTEGER (Given)
+* The index into the list of columns. The first column has index
+* one, and the last has index "Ncolumn".
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Returned Value:
+c astColumnName()
+c A pointer to a null-terminated string containing the
+f AST_COLUMNNAME = CHARACTER * ( AST__SZCHR )
+f The
+* upper case column name.
+
+* Notes:
+c - The returned pointer is guaranteed to remain valid and the
+c string to which it points will not be over-written for a total
+c of 50 successive invocations of this function. After this, the
+c memory containing the string may be re-used, so a copy of the
+c string should be made if it is needed for longer than this.
+c - A NULL pointer will be returned if this function is invoked
+c with the AST error status set, or if it should fail for any
+c reason.
+f - A blank string will be returned if this function is invoked
+f with STATUS set to an error value, or if it should fail for any
+f reason.
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding column definitions */
+ const char *result;
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Get apointer to the KeyMap holding all column definitions. */
+ cols = astColumnProps( this );
+
+/* Issue a more useful error message than that issued by astMapKey if the
+ index is invalid. */
+ if( index < 1 || index > astMapSize( cols ) ) {
+ astError( AST__MPIND, "astColumnName(%s): Cannot find column "
+ "%d (zero-based) of the %s - invalid index.", status,
+ astGetClass( this ), index, astGetClass( this ) );
+ }
+
+/* Get the column name. */
+ result = astMapKey( cols, index - 1 );
+
+/* Free resources. */
+ cols = astAnnul( cols );
+
+/* Return a pointer to the required column name. */
+ return result;
+}
+
+static AstKeyMap *ColumnProps( AstTable *this, int *status ) {
+/*
+*+
+* Name:
+* astColumnProps
+
+* Purpose:
+* Returns a pointer to the KeyMap holding column properties.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* AstKeyMap *astColumnProps( AstTable *this )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns a pointer to the KeyMap that holds
+* definitions of all the coumns added to the Table.
+
+* Parameters:
+* this
+* Pointer to the Table.
+
+* Returned Value:
+* A pointer to the KeyMap. It shpould be annulled using astAnnul
+* when no longer needed.
+
+*-
+*/
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Return a cloned pointer to the required KeyMap. */
+ return astClone( this->columns );
+}
+
+static void ColumnShape( AstTable *this, const char *column, int mxdim,
+ int *ndim, int *dims, int *status ){
+/*
+*++
+* Name:
+c astColumnShape
+f AST_COLUMNSHAPE
+
+* Purpose:
+* Returns the shape of the values in a named column.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astColumnShape( AstTable *this, const char *column, int mxdim,
+c int *ndim, int *dims )
+f CALL AST_COLUMNSHAPE( THIS, COLUMN, MXDIM, NDIM, DIMS, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+c This function
+f This routine
+* returns the number of dimensions spaned by each value in a named
+* column of a Table, together with the length of each dimension.
+* These are the values supplied when the column was created using
+c astAddColumn.
+f AST_ADDCOLUMN.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c column
+f COLUMN = CHARACTER * ( * ) (Given)
+* The character string holding the upper case name of the column. Trailing
+* spaces are ignored.
+c mxdim
+f MXDIM = INTEGER (Given)
+* The length of the
+c "dims" array.
+f DIMS array.
+c ndim
+f NDIM = INTEGER (Returned)
+c Pointer to an int in which to return the
+f The
+* number of dimensions spanned by values in the named column.
+* This will be zero if the column contains scalar values.
+c dims
+f DIMS( MXDIM ) = INTEGER (Returned)
+c Pointer to an
+f An
+* array in which to return the length of each dimension. Any
+* excess trailing elements will be filled with the value 1.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Notes:
+* - No error is reported if the requested column cannot be found in the
+* given Table. A value of zero is returned for
+c "ndim" and the supplied values in "dims"
+f NDIM and the supplied values in DIMS
+* are left unchanged.
+* - A value of zero is returned for
+c "ndim"
+f NDIM
+* if an error occurs.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* Pointer to KeyMap holding all column info */
+ AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */
+ int idim; /* Axis index */
+
+/* Initialise */
+ *ndim = 0;
+
+/* Check the inherited status. */
+ if( !astOK ) return;
+
+
+/* Get the KeyMap holding information about the requested column. */
+ cols = astColumnProps( this );
+ if( astMapGet0A( cols, column, &col_km ) ) {
+
+/* Get the shape of the column values. */
+ (void) astMapGet1I( col_km, SHAPE, mxdim, ndim, dims );
+
+/* Fill excess array elements with 1. */
+ for( idim = *ndim; idim < mxdim; idim++ ) dims[ idim ] = 1;
+
+/* Free resources. */
+ col_km = astAnnul( col_km );
+ }
+ cols = astAnnul( cols );
+
+/* If an error has occurred, set ndim to zero. */
+ if( !astOK ) *ndim = 0;
+
+}
+
+static int Equal( AstObject *this_object, AstObject *that_object, int *status ) {
+/*
+* Name:
+* Equal
+
+* Purpose:
+* Test if two Tables are equivalent.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int Equal( AstObject *this, AstObject *that, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astEqual protected
+* method inherited from the astKeyMap class).
+
+* Description:
+* This function returns a boolean result (0 or 1) to indicate whether
+* two Tables are equivalent.
+
+* Parameters:
+* this
+* Pointer to the first Object (a Table).
+* that
+* Pointer to the second Object.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* One if the Tables are equivalent, zero otherwise.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked
+* with the global status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstKeyMap *this_km;
+ AstKeyMap *that_km;
+ AstTable *that;
+ AstTable *this;
+ int result;
+
+/* Initialise. */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain pointers to the two Table structures. */
+ this = (AstTable *) this_object;
+ that = (AstTable *) that_object;
+
+/* Check the second object is a Table. We know the first is a
+ Table since we have arrived at this implementation of the virtual
+ function. */
+ if( astIsATable( that ) ) {
+
+/* Check the Tables are equal when compared as KeyMaps. */
+ if( (*parent_equal)( this_object, that_object, status ) ) {
+
+/* Check the Columns KeyMaps are equal. */
+ this_km = astColumnProps( this );
+ that_km = astColumnProps( that );
+ result = astEqual( this_km, that_km );
+ this_km = astAnnul( this_km );
+ that_km = astAnnul( that_km );
+
+/* Check the Parameter KeyMaps are equal. */
+ this_km = astParameterProps( this );
+ that_km = astParameterProps( that );
+ result = astEqual( this_km, that_km );
+ this_km = astAnnul( this_km );
+ that_km = astAnnul( that_km );
+ }
+ }
+
+/* If an error occurred, clear the result value. */
+ if ( !astOK ) result = 0;
+
+/* Return the result, */
+ return result;
+}
+
+static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
+/*
+* Name:
+* GetAttrib
+
+* Purpose:
+* Get the value of a specified attribute for a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* const char *GetAttrib( AstObject *this, const char *attrib, int *status )
+
+* Class Membership:
+* Table member function (over-rides the protected astGetAttrib
+* method inherited from the KeyMap class).
+
+* Description:
+* This function returns a pointer to the value of a specified
+* attribute for a Table, formatted as a character string.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* attrib
+* Pointer to a null terminated string containing the name of
+* the attribute whose value is required. This name should be in
+* lower case, with all white space removed.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* - Pointer to a null terminated string containing the attribute
+* value.
+
+* Notes:
+* - The returned string pointer may point at memory allocated
+* within the Table, or at static memory. The contents of the
+* string may be over-written or the pointer may become invalid
+* following a further invocation of the same function or any
+* modification of the Table. A copy of the string should
+* therefore be made if necessary.
+* - A NULL pointer will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ char cname[ AST__MXCOLNAMLEN + 1 ]; /* Column name */
+ AstTable *this; /* Pointer to the Table structure */
+ const char *result; /* Pointer value to return */
+ int ival; /* Int attribute value */
+ int len; /* Length of attrib string */
+ int nc; /* No. characters read by astSscanf */
+
+/* Initialise. */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(this_object);
+
+/* Obtain a pointer to the Table structure. */
+ this = (AstTable *) this_object;
+
+/* Obtain the length of the attrib string. */
+ len = strlen( attrib );
+
+/* Compare "attrib" with each recognised attribute name in turn,
+ obtaining the value of the required attribute. If necessary, write
+ the value into "getattrib_buff" as a null terminated string in an
+ appropriate format. Set "result" to point at the result string. */
+
+/* Table properties */
+/* ================ */
+
+/* Ncolumn */
+/* ------- */
+ if( !strcmp( attrib, "ncolumn" ) ) {
+ ival = astGetNcolumn( this );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+/* Nrow */
+/* ---- */
+ } else if( !strcmp( attrib, "nrow" ) ) {
+ ival = astGetNrow( this );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+/* Nparameter */
+/* ---------- */
+ } else if( !strcmp( attrib, "nparameter" ) ) {
+ ival = astGetNparameter( this );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+
+
+/* Column properties */
+/* ================= */
+
+/* A macro that gives the scannf pattern to test for a given column
+ property. Needed since the buffer length is defined by a macro
+ (AST__MXCOLNAMLEN). */
+#define PATTERN(cnam,blen) #cnam "(%" STRING(blen) "[^()])%n"
+
+/* ColumnNdim */
+ } else if ( nc = 0,
+ ( 1 == astSscanf( attrib, PATTERN(columnndim,AST__MXCOLNAMLEN),
+ cname, &nc ) ) && ( nc >= len ) ) {
+ ival = astGetColumnNdim( this, cname );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+/* ColumnLenC */
+ } else if ( nc = 0,
+ ( 1 == astSscanf( attrib, PATTERN(columnlenc,AST__MXCOLNAMLEN),
+ cname, &nc ) ) && ( nc >= len ) ) {
+ ival = astGetColumnLenC( this, cname );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+/* ColumnType */
+ } else if ( nc = 0,
+ ( 1 == astSscanf( attrib, PATTERN(columntype,AST__MXCOLNAMLEN),
+ cname, &nc ) ) && ( nc >= len ) ) {
+ ival = astGetColumnType( this, cname );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+/* ColumnLength */
+ } else if ( nc = 0,
+ ( 1 == astSscanf( attrib, PATTERN(columnlength,AST__MXCOLNAMLEN),
+ cname, &nc ) ) && ( nc >= len ) ) {
+ ival = astGetColumnLength( this, cname );
+ if ( astOK ) {
+ (void) sprintf( getattrib_buff, "%d", ival );
+ result = getattrib_buff;
+ }
+
+/* ColumnUnit */
+ } else if ( nc = 0,
+ ( 1 == astSscanf( attrib, PATTERN(columnunit,AST__MXCOLNAMLEN),
+ cname, &nc ) ) && ( nc >= len ) ) {
+ result = astGetColumnUnit( this, cname );
+
+#undef PATTERN
+
+
+/* Unknown attributes */
+/* ================== */
+
+/* If the attribute name was not recognised, pass it on to the parent
+ method for further interpretation. */
+ } else {
+ result = (*parent_getattrib)( this_object, attrib, status );
+ }
+
+/* Return the result. */
+ return result;
+}
+
+static int GetColumnLenC( AstTable *this, const char *column, int *status ) {
+/*
+*+
+* Name:
+* astGetColumnLenC
+
+* Purpose:
+* Get the maximum formatted length of any value in a column.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* int astGetColumnLenC( AstTable *this, const char *column )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns the minimum length which a character variable
+* must have in order to be able to store the longest value currently
+* present (at any row) in a specified column of the supplied Table. If
+* the named column holds vector values, then the returned value is
+* the length of the longest element of the vector value.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* column
+* The character string holding the upper-case name of the column.
+* Trailing spaces are ignored. An error is reported if the supplied
+* column is not found in the Table.
+
+* Returned Value:
+* The length (i.e. number of characters) of the longest formatted
+* value associated with the named column. This does not include the
+* trailing null character.
+
+* Notes:
+* - Automatic data type conversion occurs if the named column holds
+* numerical values.
+* - An error will be reported if named column does not exist or cannot
+* be formatted as a character
+* string.
+* - A function value of zero will be returned if an error has already
+* occurred, or if this function should fail for any reason.
+
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding column definitions */
+ char key[ AST__MXCOLKEYLEN ]; /* Current cell key string */
+ int irow; /* Current row index */
+ int len; /* Length needed to format current cell */
+ int nrow; /* Number of rows in table */
+ int result; /* Returned value */
+
+/* Initialise */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get the KeyMap holding information about all columns. */
+ cols = astColumnProps( this );
+
+/* Check the table contains the requested column. */
+ if( astMapHasKey( cols, column ) ) {
+
+/* Loop round all rows in the table. */
+ nrow = astGetNrow( this );
+ for( irow = 1; irow <= nrow; irow++ ) {
+
+/* Format the cell name. */
+ sprintf( key, "%.*s(%d)", (int) astChrLen(column), column, irow );
+
+/* Get the maximum length needed to format a string in the current
+ row/column. */
+ len = astMapLenC( this, key );
+
+/* Return the largest value found for any row. */
+ if( len > result ) result = len;
+ }
+
+/* Report an error if the column does not exist. */
+ } else if( astOK ) {
+ astError( AST__BADCOL, "astGetColumnLenC(%s): No column named '%s' "
+ "exists in the table.", status, astGetClass( this ), column );
+ }
+
+/* Free resources */
+ cols = astAnnul( cols );
+
+/* Return AST__BADTYPE if an error occurred. */
+ if( !astOK ) result = 0;
+
+/* Return the result. */
+ return result;
+}
+
+static int GetColumnLength( AstTable *this, const char *column, int *status ) {
+/*
+*+
+* Name:
+* astGetColumnLength
+
+* Purpose:
+* Get the number of elements in each value in a column.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* int astGetColumnLength( AstTable *this, const char *column )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns the number of elements in each value stored
+* in a named column. Each value can be a scalar (in which case the
+* ColumnLength attribute has a value of 1), or a multi-dimensional
+* array ( in which case the ColumnLength value is equal to the
+* product of the array dimensions).
+
+* Parameters:
+* this
+* Pointer to the Table.
+* column
+* The character string holding the upper-case name of the column.
+* Trailing spaces are ignored. An error is reported if the supplied
+* column is not found in the Table.
+
+* Returned Value:
+* The number of elements in each column value.
+
+* Notes:
+* - An error will be reported if named column does not exist or cannot
+* be formatted as a character
+* string.
+* - A function value of zero will be returned if an error has already
+* occurred, or if this function should fail for any reason.
+
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *col_km; /* KeyMap holding requested column definition */
+ AstKeyMap *cols; /* KeyMap holding all column definitions */
+ int *dims; /* Pointer to array holding dimensions */
+ int idim; /* Index of dimension */
+ int ndim; /* Number of dimensions */
+ int result; /* Returned value */
+
+/* Initialise */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get the KeyMap holding information about all columns. */
+ cols = astColumnProps( this );
+
+/* Get the KeyMap holding information about the requested column. */
+ if( astMapGet0A( cols, column, &col_km ) ) {
+
+/* If the Column properties includes the length, return it. Otherwise,
+ calculate the length and store it in the KeyMap as a column property. */
+ if( ! astMapGet0I( col_km, LENGTH, &result ) ) {
+
+/* Get the number of axes spanned by each column value, and allocate an
+ array big enough to hold the dimensions of these axes. */
+ ndim = astMapLength( col_km, SHAPE );
+ dims = astMalloc( sizeof( int )*ndim );
+ if( astOK ) {
+
+/* Get the dimensions. */
+ astMapGet1I( col_km, SHAPE, ndim, &ndim, dims );
+
+/* Find the number of elements. */
+ result = 1;
+ for( idim = 0; idim < ndim; idim++ ) {
+ result *= dims[ idim ];
+ }
+
+/* Store the result in the column KeyMap. */
+ astMapPut0I( col_km, LENGTH, result, NULL );
+ }
+ dims = astFree( dims );
+ }
+
+/* Free resources */
+ col_km = astAnnul( col_km );
+
+/* Report an error if the column does not exist. */
+ } else if( astOK ) {
+ astError( AST__BADCOL, "astGetColumnLength(%s): No column named '%s' "
+ "exists in the table.", status, astGetClass( this ), column );
+ }
+
+/* Free resources */
+ cols = astAnnul( cols );
+
+/* Return AST__BADTYPE if an error occurred. */
+ if( !astOK ) result = 0;
+
+/* Return the result. */
+ return result;
+}
+
+static int GetColumnNdim( AstTable *this, const char *column, int *status ) {
+/*
+*+
+* Name:
+* astGetColumnNdim
+
+* Purpose:
+* Get the number of dimensions for a column in a Table.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* int astGetColumnNdim( AstTable *this, const char *column )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function attribute holds the number of axes spanned by each value
+* in a column. If each cell in the column is a scalar, ColumnNdim will
+* be zero. If each cell in the column is a 1D spectrum, ColumnNdim will
+* be one. If each cell in the column is a 2D image, ColumnNdim will be
+* two, etc.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* column
+* The character string holding the upper-case name of the column.
+* Trailing spaces are ignored. An error is reported if the supplied
+* column is not found in the Table.
+
+* Returned Value:
+* The number of dimensions - zero for a scalar.
+
+* Notes:
+* - A function value of zero will be returned if an error has
+* already occurred, or if this function should fail for any reason.
+
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding column definitions */
+ AstKeyMap *col_km; /* Pointer to KeyMap holding column info */
+ int result; /* Returned value */
+
+/* Initialise */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get the KeyMap holding information about all columns. */
+ cols = astColumnProps( this );
+
+/* Get the KeyMap holding information about the requested column. */
+ if( astMapGet0A( cols, column, &col_km ) ) {
+
+/* Get the number of dimensions. */
+ result = astMapLength( col_km, SHAPE );
+
+/* Free resources */
+ col_km = astAnnul( col_km );
+
+/* Report an error if the column does not exist. */
+ } else if( astOK ) {
+ astError( AST__BADCOL, "astGetColumnNdim(%s): No column named '%s' "
+ "exists in the table.", status, astGetClass( this ), column );
+ }
+ cols = astAnnul( cols );
+
+/* Return AST__BADTYPE if an error occurred. */
+ if( !astOK ) result = 0;
+
+/* Return the result. */
+ return result;
+}
+
+static int GetColumnType( AstTable *this, const char *column, int *status ) {
+/*
+*+
+* Name:
+* astGetColumnType
+
+* Purpose:
+* Get the data type of a column in a Table.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* int astGetColumnType( AstTable *this, const char *column )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns a value indicating the data type of a
+* named column in a Table. This is the data type which was used
+* when the column was added to the Table using astAddColumn.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* column
+* The character string holding the upper-case name of the column.
+* Trailing spaces are ignored. An error is reported if the supplied
+* column is not found in the Table.
+
+* Returned Value:
+* One of AST__INTTYPE (for integer), AST__SINTTYPE (for short int),
+* AST__BYTETYPE (for unsigned bytes - i.e. unsigned chars),
+* AST__DOUBLETYPE (for double precision floating point),
+* AST__FLOATTYPE (for single precision floating point), AST__STRINGTYPE
+* (for character string), AST__OBJECTTYPE (for AST Object pointer),
+* AST__POINTERTYPE (for arbitrary C pointer) or AST__UNDEFTYPE (for
+* undefined values created by astMapPutU).
+
+* Notes:
+* - A function value of AST__BADTYPE will be returned if an error has
+* already occurred, or if this function should fail for any reason.
+
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* Pointer to KeyMap holding all column info */
+ AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */
+ int result; /* Returned value */
+
+/* Initialise */
+ result = AST__BADTYPE;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get the KeyMap holding information about the requested column. */
+ cols = astColumnProps( this );
+ if( astMapGet0A( cols, column, &col_km ) ) {
+
+/* Get the column data type. */
+ (void) astMapGet0I( col_km, TYPE, &result );
+
+/* Annul the KeyMap pointer. */
+ col_km = astAnnul( col_km );
+
+/* Report an error if the column does not exist. */
+ } else if( astOK ) {
+ astError( AST__BADCOL, "astGetColumnType(%s): No column named '%s' "
+ "exists in the table.", status, astGetClass( this ), column );
+ }
+ cols = astAnnul( cols );
+
+/* Return AST__BADTYPE if an error occurred. */
+ if( !astOK ) result = AST__BADTYPE;
+
+/* Return the result. */
+ return result;
+}
+
+static const char *GetColumnUnit( AstTable *this, const char *column, int *status ) {
+/*
+*+
+* Name:
+* astGetColumnUnit
+
+* Purpose:
+* Get the unit string for a column in a Table.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* const char *astGetColumnUnit( AstTable *this, const char *column )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns the unit string for a named column in a Table.
+* This is the unit string that was provided when the column was added to
+* the Table using astAddColumn.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* column
+* The character string holding the upper-case name of the column.
+* Trailing spaces are ignored. An error is reported if the supplied
+* column is not found in the Table.
+
+* Returned Value:
+* A pointer to a null-terminated string containing the column units.
+
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */
+ AstKeyMap *cols; /* Pointer to KeyMap holding all column info */
+ const char *result; /* Returned value */
+
+/* Initialise */
+ result = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get the KeyMap holding information about the requested column. */
+ cols = astColumnProps( this );
+ if( astMapGet0A( cols, column, &col_km ) ) {
+
+/* Get the column unit string. */
+ (void) astMapGet0C( col_km, UNIT, &result );
+
+/* Annul the KeyMap pointer. */
+ col_km = astAnnul( col_km );
+
+/* Report an error if the column does not exist. */
+ } else if( astOK ) {
+ astError( AST__BADCOL, "astGetColumnUnit(%s): No column named '%s' "
+ "exists in the table.", status, astGetClass( this ), column );
+ }
+ cols = astAnnul( cols );
+
+/* Return NULL if an error occurred. */
+ if( !astOK ) result = NULL;
+
+/* Return the result. */
+ return result;
+}
+
+static int GetNcolumn( AstTable *this, int *status ) {
+/*
+*+
+* Name:
+* astGetNcolumn
+
+* Purpose:
+* Get the number of columns in a Table.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* int astGetNcolumn( AstTable *this )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns the number of columns currently in the Table.
+
+* Parameters:
+* this
+* Pointer to the Table.
+
+* Returned Value:
+* Number of columns.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols;
+ int result;
+
+/* Check the global error status. */
+ if ( !astOK ) return 0;
+
+/* Get a pointer to the KeyMap holding the column definitions. */
+ cols = astColumnProps( this );
+
+/* Get the number of column definitions in the KeyMap. */
+ result = astMapSize( cols );
+
+/* Annul the KeyMap pointer. */
+ cols = astAnnul( cols );
+
+/* Return the result. */
+ return result;
+}
+
+static int GetNparameter( AstTable *this, int *status ) {
+/*
+*+
+* Name:
+* astGetNparameter
+
+* Purpose:
+* Get the number of global parameters in a Table.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* int astGetNparameter( AstTable *this )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns the number of global parameters currently in the Table.
+
+* Parameters:
+* this
+* Pointer to the Table.
+
+* Returned Value:
+* Number of parameters.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*-
+*/
+
+/* Local Variables: */
+ AstKeyMap *pars;
+ int result;
+
+/* Check the global error status. */
+ if ( !astOK ) return 0;
+
+/* Get a pointer to the KeyMap holding the parameter definitions. */
+ pars = astParameterProps( this );
+
+/* Get the number of parameter definitions in the KeyMap. */
+ result = astMapSize( pars );
+
+/* Annul the KeyMap pointer. */
+ pars = astAnnul( pars );
+
+/* Return the result. */
+ return result;
+}
+
+static int GetObjSize( AstObject *this_object, int *status ) {
+/*
+* Name:
+* GetObjSize
+
+* Purpose:
+* Return the in-memory size of an Object.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int GetObjSize( AstObject *this, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astGetObjSize protected
+* method inherited from the parent class).
+
+* Description:
+* This function returns the in-memory size of the supplied Tables,
+* in bytes.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* The Table size, in bytes.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked
+* with the global status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ AstKeyMap *km; /* KeyMap holding column/parameter definitions */
+ AstTable *this; /* Pointer to Table structure */
+ int result; /* Result value to return */
+
+/* Initialise. */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Obtain a pointers to the Table structure. */
+ this = (AstTable *) this_object;
+
+/* Invoke the GetObjSize method inherited from the parent KeyMap class, and
+ then add on any components of the class structure defined by this class
+ which are stored in dynamically allocated memory. */
+ result = (*parent_getobjsize)( this_object, status );
+
+ km = astColumnProps( this );
+ result += astGetObjSize( km );
+ km = astAnnul( km );
+
+ km = astParameterProps( this );
+ result += astGetObjSize( km );
+ km = astAnnul( km );
+
+/* If an error occurred, clear the result value. */
+ if ( !astOK ) result = 0;
+
+/* Return the result, */
+ return result;
+}
+
+static int HasColumn( AstTable *this, const char *column, int *status ){
+/*
+*++
+* Name:
+c astHasColumn
+f AST_HASCOLUMN
+
+* Purpose:
+* Returns a flag indicating if a column is present in a Table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c int astHasColumn( AstTable *this, const char *column )
+f RESULT = AST_HASCOLUMN( THIS, COLUMN, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+c This function
+f This routine
+* returns a flag indicating if a named column exists in a Table, for
+* instance, by having been added to to the Table using
+c astAddColumn.
+f AST_ADDCOLUMN.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c column
+f COLUMN = CHARACTER * ( * ) (Given)
+* The character string holding the upper case name of the column. Trailing
+* spaces are ignored.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Notes:
+* - A value of
+c zero
+f .FALSE.
+* is returned for if an error occurs.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols;
+ int result;
+
+/* Initialise */
+ result = 0;
+
+/* Check the inherited status. */
+ if( !astOK ) return result;
+
+/* Get the KeyMap holding information about all columns. */
+ cols = astColumnProps( this );
+
+/* Seeif it contains an entry for the named column. */
+ result = astMapHasKey( cols, column );
+
+/* Free resources. */
+ cols = astAnnul( cols );
+
+/* If an error has occurred, return zero. */
+ if( !astOK ) result = 0;
+ return result;
+}
+
+static int HasParameter( AstTable *this, const char *parameter, int *status ){
+/*
+*++
+* Name:
+c astHasParameter
+f AST_HASPARAMETER
+
+* Purpose:
+* Returns a flag indicating if a named global parameter is present in a Table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c int astHasParameter( AstTable *this, const char *parameter )
+f RESULT = AST_HASPARAMETER( THIS, PARAMETER, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+c This function
+f This routine
+* returns a flag indicating if a named parameter exists in a Table, for
+* instance, by having been added to to the Table using
+c astAddParameter.
+f AST_ADDPARAMETER.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c parameter
+f PARAMETER = CHARACTER * ( * ) (Given)
+* The character string holding the upper case name of the parameter. Trailing
+* spaces are ignored.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Notes:
+* - A value of
+c zero
+f .FALSE.
+* is returned for if an error occurs.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *pars;
+ int result;
+
+/* Initialise */
+ result = 0;
+
+/* Check the inherited status. */
+ if( !astOK ) return result;
+
+/* Get the KeyMap holding information about all parameters. */
+ pars = astParameterProps( this );
+
+/* See if it contains an entry for the named parameter. */
+ result = astMapHasKey( pars, parameter );
+
+/* Free resources. */
+ pars = astAnnul( pars );
+
+/* If an error has occurred, return zero. */
+ if( !astOK ) result = 0;
+ return result;
+}
+
+void astInitTableVtab_( AstTableVtab *vtab, const char *name, int *status ) {
+/*
+*+
+* Name:
+* astInitTableVtab
+
+* Purpose:
+* Initialise a virtual function table for a Table.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "table.h"
+* void astInitTableVtab( AstTableVtab *vtab, const char *name )
+
+* Class Membership:
+* Table vtab initialiser.
+
+* Description:
+* This function initialises the component of a virtual function
+* table which is used by the Table class.
+
+* Parameters:
+* vtab
+* Pointer to the virtual function table. The components used by
+* all ancestral classes will be initialised if they have not already
+* been initialised.
+* name
+* Pointer to a constant null-terminated character string which contains
+* the name of the class to which the virtual function table belongs (it
+* is this pointer value that will subsequently be returned by the Object
+* astClass function).
+*-
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstObjectVtab *object; /* Pointer to Object component of Vtab */
+ AstKeyMapVtab *keymap; /* Pointer to KeyMap component of Vtab */
+
+/* Check the local error status. */
+ if ( !astOK ) return;
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(NULL);
+
+/* Initialize the component of the virtual function table used by the
+ parent class. */
+ astInitKeyMapVtab( (AstKeyMapVtab *) vtab, name );
+
+/* Store a unique "magic" value in the virtual function table. This
+ will be used (by astIsATable) to determine if an object belongs
+ to this class. We can conveniently use the address of the (static)
+ class_check variable to generate this unique value. */
+ vtab->id.check = &class_check;
+ vtab->id.parent = &(((AstKeyMapVtab *) vtab)->id);
+
+/* Initialise member function pointers. */
+/* ------------------------------------ */
+/* Store pointers to the member functions (implemented here) that provide
+ virtual methods for this class. */
+ vtab->AddColumn = AddColumn;
+ vtab->AddParameter = AddParameter;
+ vtab->ColumnName = ColumnName;
+ vtab->ParameterName = ParameterName;
+ vtab->ColumnProps = ColumnProps;
+ vtab->ColumnShape = ColumnShape;
+ vtab->GetColumnLenC = GetColumnLenC;
+ vtab->GetColumnLength = GetColumnLength;
+ vtab->GetColumnNdim = GetColumnNdim;
+ vtab->GetColumnType = GetColumnType;
+ vtab->GetColumnUnit = GetColumnUnit;
+ vtab->GetNcolumn = GetNcolumn;
+ vtab->GetNparameter = GetNparameter;
+ vtab->GetNrow = GetNrow;
+ vtab->HasColumn = HasColumn;
+ vtab->HasParameter = HasParameter;
+ vtab->ParameterProps = ParameterProps;
+ vtab->PurgeRows = PurgeRows;
+ vtab->RemoveColumn = RemoveColumn;
+ vtab->RemoveParameter = RemoveParameter;
+ vtab->RemoveRow = RemoveRow;
+ vtab->SetNrow = SetNrow;
+
+/* Save the inherited pointers to methods that will be extended, and
+ replace them with pointers to the new member functions. */
+ object = (AstObjectVtab *) vtab;
+ keymap = (AstKeyMapVtab *) vtab;
+
+ parent_equal = object->Equal;
+ object->Equal = Equal;
+
+ parent_getobjsize = object->GetObjSize;
+ object->GetObjSize = GetObjSize;
+
+ parent_clearattrib = object->ClearAttrib;
+ object->ClearAttrib = ClearAttrib;
+
+ parent_getattrib = object->GetAttrib;
+ object->GetAttrib = GetAttrib;
+
+ parent_setattrib = object->SetAttrib;
+ object->SetAttrib = SetAttrib;
+
+ parent_testattrib = object->TestAttrib;
+ object->TestAttrib = TestAttrib;
+
+#if defined(THREAD_SAFE)
+ parent_managelock = object->ManageLock;
+ object->ManageLock = ManageLock;
+#endif
+
+ parent_mapremove = keymap->MapRemove;
+
+/* Define convenience macros for overriding methods inherited from the
+ parent KeyMap class using all data type supported by KeyMap. */
+#define OVERRIDE(method,code,methodlc,codelc) \
+ parent_##methodlc##codelc = keymap->method##code; \
+ keymap->method##code = method##code; \
+
+#define OVERRIDE_METHOD(method,methodlc) \
+ OVERRIDE(method,A,methodlc,a) \
+ OVERRIDE(method,P,methodlc,p) \
+ OVERRIDE(method,C,methodlc,c) \
+ OVERRIDE(method,D,methodlc,d) \
+ OVERRIDE(method,F,methodlc,f) \
+ OVERRIDE(method,I,methodlc,i) \
+ OVERRIDE(method,S,methodlc,s) \
+ OVERRIDE(method,B,methodlc,b)
+
+/* Use these macros to override the required methods. */
+ OVERRIDE_METHOD(MapPut0,mapput0)
+ OVERRIDE_METHOD(MapGet0,mapget0)
+ OVERRIDE_METHOD(MapPut1,mapput1)
+ OVERRIDE_METHOD(MapGet1,mapget1)
+ OVERRIDE_METHOD(MapPutElem,mapputelem)
+ OVERRIDE_METHOD(MapGetElem,mapgetelem)
+ OVERRIDE(MapPut,U,mapput,u)
+ OVERRIDE(SetKeyCase,,setkeycase,)
+ OVERRIDE(ClearKeyCase,,clearkeycase,)
+
+/* Remove the macros. */
+#undef OVERRIDE_METHOD
+#undef OVERRIDE
+
+/* Store replacement pointers for methods which will be over-ridden by
+ new member functions implemented here. */
+
+/* Declare the copy constructor, destructor and class dump function. */
+ astSetCopy( vtab, Copy );
+ astSetDelete( vtab, Delete );
+ astSetDump( vtab, Dump, "Table", "Two-dimensional table of data values" );
+
+/* If we have just initialised the vtab for the current class, indicate
+ that the vtab is now initialised, and store a pointer to the class
+ identifier in the base "object" level of the vtab. */
+ if( vtab == &class_vtab ) {
+ class_init = 1;
+ astSetVtabClassIdentifier( vtab, &(vtab->id) );
+ }
+}
+
+#if defined(THREAD_SAFE)
+static int ManageLock( AstObject *this_object, int mode, int extra,
+ AstObject **fail, int *status ) {
+/*
+* Name:
+* ManageLock
+
+* Purpose:
+* Manage the thread lock on an Object.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "object.h"
+* AstObject *ManageLock( AstObject *this, int mode, int extra,
+* AstObject **fail, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astManageLock protected
+* method inherited from the parent class).
+
+* Description:
+* This function manages the thread lock on the supplied Object. The
+* lock can be locked, unlocked or checked by this function as
+* deteremined by parameter "mode". See astLock for details of the way
+* these locks are used.
+
+* Parameters:
+* this
+* Pointer to the Object.
+* mode
+* An integer flag indicating what the function should do:
+*
+* AST__LOCK: Lock the Object for exclusive use by the calling
+* thread. The "extra" value indicates what should be done if the
+* Object is already locked (wait or report an error - see astLock).
+*
+* AST__UNLOCK: Unlock the Object for use by other threads.
+*
+* AST__CHECKLOCK: Check that the object is locked for use by the
+* calling thread (report an error if not).
+* extra
+* Extra mode-specific information.
+* fail
+* If a non-zero function value is returned, a pointer to the
+* Object that caused the failure is returned at "*fail". This may
+* be "this" or it may be an Object contained within "this". Note,
+* the Object's reference count is not incremented, and so the
+* returned pointer should not be annulled. A NULL pointer is
+* returned if this function returns a value of zero.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* A local status value:
+* 0 - Success
+* 1 - Could not lock or unlock the object because it was already
+* locked by another thread.
+* 2 - Failed to lock a POSIX mutex
+* 3 - Failed to unlock a POSIX mutex
+* 4 - Bad "mode" value supplied.
+
+* Notes:
+* - This function attempts to execute even if an error has already
+* occurred.
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to Table structure */
+ int result; /* Returned status value */
+
+/* Initialise */
+ result = 0;
+
+/* Check the supplied pointer is not NULL. */
+ if( !this_object ) return result;
+
+/* Obtain a pointers to the Table structure. */
+ this = (AstTable *) this_object;
+
+/* Invoke the ManageLock method inherited from the parent class. */
+ if( !result ) result = (*parent_managelock)( this_object, mode, extra,
+ fail, status );
+
+/* Invoke the astManageLock method on any Objects contained within
+ the supplied Object. */
+ if( !result && this->columns ) result = astManageLock( this->columns, mode, extra,
+ fail );
+
+ if( !result && this->parameters ) result = astManageLock( this->parameters, mode, extra,
+ fail );
+
+/* Return the result. */
+ return result;
+}
+#endif
+
+/*
+* Name:
+* MapGet0<X>
+
+* Purpose:
+* Get a scalar value from a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int MapGet0<X>( AstKeyMap *this, const char *key, <X>type *value );
+
+* Class Membership:
+* Table member function (over-rides the astMapGet0<X> method inherited
+* from the KeyMap class).
+
+* Description:
+* This is a set of functions for retrieving a scalar value from a
+* cell of a Table. You should replace <X> in the generic function name
+* MapGet0<X> by an appropriate 1-character type code (see the "Data
+* Type Codes" section in the astMapGet0<X> docs). The stored value is
+* converted to the data type indiced by <X> before being returned (an
+* error is reported if it is not possible to convert the stored value
+* to the requested data type).
+
+* Parameters:
+* this
+* Pointer to the Table.
+* key
+* A character string identifying the cell from which the value is
+* to be retrieved. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* value
+* A pointer to a buffer in which to return the requested value.
+* If the requested cell is not found, or if it is found but has an
+* undefined value (see astMapPutU), then the contents of the buffer
+* on entry to this function will be unchanged on exit. For pointer
+* types ("A" and "C"), the buffer should be a suitable pointer, and
+* the address of this pointer should be supplied as the "value"
+* parameter.
+* status
+* Pointer to inherited status value.
+
+* Returned Value:
+* A non-zero value is returned if the requested key name was found, and
+* does not have an undefined value (see astMapPutU). Zero is returned
+* otherwise.
+
+* Notes:
+* - No error is reported if the requested cell cannot be found in the
+* given KeyMap, but a zero value will be returned as the function value.
+* The supplied buffer will be returned unchanged.
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - If the stored value is a vector value, then the first value in
+* the vector will be returned.
+* - A string pointer returned by astMapGet0C is guaranteed to remain
+* valid and the string to which it points will not be over-written for
+* a total of 50 successive invocations of this function. After this,
+* the memory containing the string may be re-used, so a copy of
+* the string should be made if it is needed for longer than this.
+* - If the returned value is an AST Object pointer, the Object's reference
+* count is incremented by this call. Any subsequent changes made to
+* the Object using the returned pointer will be reflected in any
+* any other active pointers for the Object. The returned pointer
+* should be annulled using astAnnul when it is no longer needed.
+*/
+
+/* Define a macro to implement the function for a specific data type. */
+#define MAKE_MAPGET0(X,Xlc,Xtype,Itype) \
+static int MapGet0##X( AstKeyMap *this_keymap, const char *key, Xtype *value, \
+ int *status ) { \
+\
+/* Local Variables: */ \
+ AstTable *this; /* Pointer to Table structure */ \
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
+ int irow; /* Row index within key string */ \
+ int result; /* Returned flag */ \
+\
+/* Initialise */ \
+ result = 0; \
+\
+/* Check the global error status. */ \
+ if ( !astOK ) return result; \
+\
+/* Get a pointer to the Table structure. */ \
+ this = (AstTable *) this_keymap; \
+\
+/* If the key is the name of a global table parameter, use the parent \
+ method to get the value of hte parameter. */ \
+ if( astHasParameter( this, key ) ) { \
+ result = (*parent_mapget0##Xlc)( this_keymap, key, value, status ); \
+\
+/* Check the supplied key looks like a table cell key, and get the \
+ the column name and the row number. Also checks that the table \
+ contains a column with the specified name. */ \
+ } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \
+ NULL, "astMapGet0" #X, status ) ) { \
+\
+/* If the row index is larger than the current number of rows in the \
+ table, do nothing more. */ \
+ if( irow <= astGetNrow( this ) ){ \
+\
+/* Use the astMapGet0<X> method in the parent keyMap class to get the \
+ cell contents. */ \
+ result = (*parent_mapget0##Xlc)( this_keymap, key, value, status ); \
+ } \
+ } \
+\
+/* If an error occurred, return zero. */ \
+ if( !astOK ) result = 0; \
+\
+/* Return the result.*/ \
+ return result; \
+}
+
+/* Expand the above macro to generate a function for each required
+ data type. */
+MAKE_MAPGET0(I,i,int,AST__INTTYPE)
+MAKE_MAPGET0(D,d,double,AST__DOUBLETYPE)
+MAKE_MAPGET0(F,f,float,AST__FLOATTYPE)
+MAKE_MAPGET0(C,c,const char *,AST__STRINGTYPE)
+MAKE_MAPGET0(A,a,AstObject *,AST__OBJECTTYPE)
+MAKE_MAPGET0(P,p,void *,AST__POINTERTYPE)
+MAKE_MAPGET0(S,s,short int,AST__SINTTYPE)
+MAKE_MAPGET0(B,b,unsigned char,AST__BYTETYPE)
+
+/* Undefine the macro. */
+#undef MAKE_MAPGET0
+
+/*
+* Name:
+* MapGet1<X>
+
+* Purpose:
+* Get a vector value from a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int MapGet1<X>( AstKeyMap *this, const char *key, int mxval,
+* int *nval, <X>type *value )
+* int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval,
+* int *nval, const char *value )
+
+* Class Membership:
+* Table member function (over-rides the astMapGet1<X> method inherited
+* from the KeyMap class).
+
+* Description:
+* This is a set of functions for retrieving a vector value from a
+* cell of a Table. You should replace <X> in the generic function name
+* MapGet1<X> by an appropriate 1-character type code (see the "Data
+* Type Codes" section in the astMapGet1<X> docs). The stored value is
+* converted to the data type indiced by <X> before being returned (an
+* error is reported if it is not possible to convert the stored value
+* to the requested data type).
+*
+* Note, the MapGet1C function has an extra parameter "l" which
+* specifies the maximum length of each string to be stored in the
+* "value" buffer (see the "astMapGet1C" docs).
+
+* Parameters:
+* this
+* Pointer to the Table.
+* key
+* A character string identifying the cell from which the value is
+* to be retrieved. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* mxval
+* The number of elements in the "value" array.
+* nval
+* The address of an integer in which to put the number of elements
+* stored in the "value" array. Any unused elements of the array are
+* left unchanged.
+* value
+* A pointer to an array in which to return the requested values.
+* If the requested cell is not found, or if it is found but has an
+* undefined value (see astMapPutU), then the contents of the buffer
+* on entry to this function will be unchanged on exit.
+* status
+* Pointer to inherited status value.
+
+* Returned Value:
+* A non-zero value is returned if the requested key name was found, and
+* does not have an undefined value (see astMapPutU). Zero is returned
+* otherwise.
+
+* MapGet1C:
+* The "value" buffer supplied to the MapGet1C function should be a
+* pointer to a character array with "mxval*l" elements, where "l" is
+* the maximum length of a string to be returned. The value of "l"
+* should be supplied as an extra parameter following "key" when
+* invoking MapGet1C, and should include space for a terminating
+* null character.
+
+* Notes:
+* - No error is reported if the requested cell cannot be found in the
+* given KeyMap, but a zero value will be returned as the function value.
+* The supplied buffer will be returned unchanged.
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - If the stored value is a scalar value, then the value will be
+* returned in the first element of the supplied array, and "nval"
+* will be returned set to 1.
+*/
+
+/* Define a macro to implement the function for a specific data type
+ (excluding "C" since that needs an extra parameter). */
+#define MAKE_MAPGET1(X,Xlc,Xtype,Itype) \
+static int MapGet1##X( AstKeyMap *this_keymap, const char *key, int mxval, int *nval, \
+ Xtype *value, int *status ) { \
+\
+/* Local Variables: */ \
+ AstTable *this; /* Pointer to Table structure */ \
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
+ int irow; /* Row index within key string */ \
+ int result; /* Returned flag */ \
+\
+/* Initialise */ \
+ result = 0; \
+\
+/* Check the global error status. */ \
+ if ( !astOK ) return result; \
+\
+/* Get a pointer to the Table structure. */ \
+ this = (AstTable *) this_keymap; \
+\
+/* If the key is the name of a global table parameter, use the parent \
+ method to get the value of hte parameter. */ \
+ if( astHasParameter( this, key ) ) { \
+ result = (*parent_mapget1##Xlc)( this_keymap, key, mxval, nval, \
+ value, status ); \
+\
+/* Check the supplied key looks like a table cell key, and get the \
+ the column name and the row number. Also checks that the table \
+ contains a column with the specified name. */ \
+ } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \
+ NULL, "astMapGet1" #X, status ) ) { \
+\
+/* If the row index is larger than the current number of rows in the \
+ table, do nothing more. */ \
+ if( irow <= astGetNrow( this ) ){ \
+\
+/* Use the astMapGet1<X> method in the parent keyMap class to get the \
+ cell contents. */ \
+ result = (*parent_mapget1##Xlc)( this_keymap, key, mxval, nval, \
+ value, status ); \
+ } \
+ } \
+\
+/* If an error occurred, return zero. */ \
+ if( !astOK ) result = 0; \
+\
+/* Return the result.*/ \
+ return result; \
+}
+
+/* Expand the above macro to generate a function for each required
+ data type. */
+MAKE_MAPGET1(I,i,int,AST__INTTYPE)
+MAKE_MAPGET1(D,d,double,AST__DOUBLETYPE)
+MAKE_MAPGET1(F,f,float,AST__FLOATTYPE)
+MAKE_MAPGET1(A,a,AstObject *,AST__OBJECTTYPE)
+MAKE_MAPGET1(P,p,void *,AST__POINTERTYPE)
+MAKE_MAPGET1(S,s,short int,AST__SINTTYPE)
+MAKE_MAPGET1(B,b,unsigned char,AST__BYTETYPE)
+
+/* Undefine the macro. */
+#undef MAKE_MAPGET1
+
+
+static int MapGet1C( AstKeyMap *this_keymap, const char *key, int l, int mxval,
+ int *nval, char *value, int *status ) {
+/*
+* Name:
+* MapGet1C
+
+* Purpose:
+* Get a vector value from a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval,
+* int *nval, const char *value )
+
+* Class Membership:
+* Table member function (over-rides the astMapGet1C method inherited
+* from the KeyMap class).
+
+* Description:
+* This is the implementation of MapGet1<X> for <X> = "C". We
+* cannot use the MAKE_MAPGET1 macro for this because the string
+* version of this function has an extra parameter giving the maximum
+* length of each string which can be stored in the supplied buffer.
+
+* Parameters:
+* (see MapGet1<X>)
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to Table structure */
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */
+ int irow; /* Row index within key string */
+ int result; /* Returned flag */
+
+/* Initialise */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get a pointer to the Table structure. */
+ this = (AstTable *) this_keymap;
+
+/* If the key is the name of a global table parameter, use the parent
+ method to get the value of hte parameter. */
+ if( astHasParameter( this, key ) ) {
+ result = (*parent_mapget1c)( this_keymap, key, l, mxval, nval,
+ value, status );
+
+/* Check the supplied key looks like a table cell key, and get the
+ the column name and the row number. Also checks that the table
+ contains a column with the specified name. */
+ } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow,
+ NULL, "astMapGet1C", status ) ) {
+
+/* If the row index is larger than the current number of rows in the
+ table, do nothing more. */
+ if( irow <= astGetNrow( this ) ){
+
+/* Use the astMapGet1<X> method in the parent keyMap class to get the
+ cell contents. */
+ result = (*parent_mapget1c)( this_keymap, key, l, mxval, nval,
+ value, status );
+ }
+ }
+
+/* If an error occurred, return zero. */
+ if( !astOK ) result = 0;
+
+/* Return the result.*/
+ return result;
+}
+
+/*
+* Name:
+* MapGetElem<X>
+
+* Purpose:
+* Get a single element of a vector value from a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int MapGetElem<X>( AstKeyMap *this, const char *key, int elem,
+* <X>type *value, int *status )
+* int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem,
+* char *value, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astMapGetElem<X> method inherited
+* from the KeyMap class).
+
+* Description:
+* This is a set of functions for retrieving a single element of a vector
+* value from a cell of a Table. You should replace <X> in the generic
+* function name MapGetElem<X> by an appropriate 1-character type code
+* (see the "Data Type Codes" section in the astMapGetElem<X> docs). The
+* stored value is converted to the data type indiced by <X> before being
+* returned (an error is reported if it is not possible to convert the
+* stored value to the requested data type).
+*
+* Note, the MapGetElemC function has an extra parameter "l" which
+* specifies the maximum length of each string to be stored in the
+* "value" buffer (see the "MapGetElemC" docs).
+
+* Parameters:
+* this
+* Pointer to the Table.
+* key
+* A character string identifying the cell from which the value is
+* to be retrieved. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* elem
+* The index of the vector element to modify, starting at zero.
+* If the index is outside the range of the vector, an error will
+* be reported.
+* value
+* A pointer to a buffer in which to return the requested values.
+* If the requested cell is not found, or if it is found but has an
+* undefined value (see astMapPutU), then the contents of the buffer
+* on entry to this function will be unchanged on exit.
+* status
+* Pointer to inherited status value.
+
+* Returned Value:
+* A non-zero value is returned if the requested key name was found, and
+* does not have an undefined value (see astMapPutU). Zero is returned
+* otherwise.
+
+* MapGetElemC:
+* The "value" buffer supplied to the MapGetElemC function should be a
+* pointer to a character array with "l" elements, where "l" is
+* the maximum length of a string to be returned. The value of "l"
+* should be supplied as an extra parameter following "key" when
+* invoking MapGetElemC, and should include space for a terminating
+* null character.
+
+* Notes:
+* - No error is reported if the requested cell cannot be found in the
+* given KeyMap, but a zero value will be returned as the function value.
+* The supplied buffer will be returned unchanged.
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - If the stored value is a scalar value, then the value will be
+* returned in the first element of the supplied array, and "nval"
+* will be returned set to 1.
+*/
+
+/* Define a macro to implement the function for a specific data type
+(excluding "C" since that needs an extra parameter). */
+#define MAKE_MAPGETELEM(X,Xlc,Xtype,Itype) \
+static int MapGetElem##X( AstKeyMap *this_keymap, const char *key, int elem, \
+ Xtype *value, int *status ) { \
+\
+/* Local Variables: */ \
+ AstTable *this; /* Pointer to Table structure */ \
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
+ int irow; /* Row index within key string */ \
+ int result; /* Returned flag */ \
+\
+/* Initialise */ \
+ result = 0; \
+\
+/* Check the global error status. */ \
+ if ( !astOK ) return result; \
+\
+/* Get a pointer to the Table structure. */ \
+ this = (AstTable *) this_keymap; \
+\
+/* If the key is the name of a global table parameter, use the parent \
+ method to get the value of hte parameter. */ \
+ if( astHasParameter( this, key ) ) { \
+ result = (*parent_mapgetelem##Xlc)( this_keymap, key, elem, \
+ value, status ); \
+\
+/* Check the supplied key looks like a table cell key, and get the \
+ the column name and the row number. Also checks that the table \
+ contains a column with the specified name. */ \
+ } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \
+ NULL, "astMapGetElem" #X, status ) ) { \
+\
+/* If the row index is larger than the current number of rows in the \
+ table, do nothing more. */ \
+ if( irow <= astGetNrow( this ) ){ \
+\
+/* Use the astMapGetElem<X> method in the parent keyMap class to get the \
+ cell contents. */ \
+ result = (*parent_mapgetelem##Xlc)( this_keymap, key, elem, \
+ value, status ); \
+ } \
+ } \
+\
+/* If an error occurred, return zero. */ \
+ if( !astOK ) result = 0; \
+\
+/* Return the result.*/ \
+ return result; \
+}
+
+/* Expand the above macro to generate a function for each required
+ data type. */
+MAKE_MAPGETELEM(I,i,int,AST__INTTYPE)
+MAKE_MAPGETELEM(D,d,double,AST__DOUBLETYPE)
+MAKE_MAPGETELEM(F,f,float,AST__FLOATTYPE)
+MAKE_MAPGETELEM(A,a,AstObject *,AST__OBJECTTYPE)
+MAKE_MAPGETELEM(P,p,void *,AST__POINTERTYPE)
+MAKE_MAPGETELEM(S,s,short int,AST__SINTTYPE)
+MAKE_MAPGETELEM(B,b,unsigned char,AST__BYTETYPE)
+
+/* Undefine the macro. */
+#undef MAKE_MAPGETELEM
+
+static int MapGetElemC( AstKeyMap *this_keymap, const char *key, int l,
+ int elem, char *value, int *status ) {
+/*
+* Name:
+* MapGetElemC
+
+* Purpose:
+* Get a single element of a vector value from a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem,
+* char *value, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astMapGetElemC method inherited
+* from the KeyMap class).
+
+* Description:
+* This is the implementation of MapGetElem<X> for <X> = "C". We
+* cannot use the MAKE_MAPGETELEM macro for this because the string
+* version of this function has an extra parameter giving the maximum
+* length of each string which can be stored in the supplied buffer.
+
+* Parameters:
+* (see MapGetElem<X>)
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to Table structure */
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */
+ int irow; /* Row index within key string */
+ int result; /* Returned flag */
+
+/* Initialise */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get a pointer to the Table structure. */
+ this = (AstTable *) this_keymap;
+
+/* If the key is the name of a global table parameter, use the parent
+ method to get the value of hte parameter. */
+ if( astHasParameter( this, key ) ) {
+ result = (*parent_mapgetelemc)( this_keymap, key, l, elem,
+ value, status );
+
+/* Check the supplied key looks like a table cell key, and get the
+ the column name and the row number. Also checks that the table
+ contains a column with the specified name. */
+ } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow,
+ NULL, "astMapGetElemC", status ) ) {
+
+/* If the row index is larger than the current number of rows in the
+ table, do nothing more. */
+ if( irow <= astGetNrow( this ) ){
+
+/* Use the astMapGetElem<X> method in the parent keyMap class to get the
+ cell contents. */
+ result = (*parent_mapgetelemc)( this_keymap, key, l, elem,
+ value, status );
+ }
+ }
+
+/* If an error occurred, return zero. */
+ if( !astOK ) result = 0;
+
+/* Return the result.*/
+ return result;
+}
+
+/*
+* Name:
+* MapPut0<X>
+
+* Purpose:
+* Stores a scalar value in a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* void MapPut0<X>( AstKeyMap *this, const char *key, <X>type value,
+* const char *comment, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astMapPut0<X> method inherited
+* from the KeyMap class).
+
+* Description:
+* This is a set of functions for storing a scalar value in a cell of
+* a Table. You should use a function which matches the data type of the
+* data you wish to add to the Table by replacing <X> in the generic
+* function name MapPut0<X> by an appropriate 1-character type code (see
+* the "Data Type Codes" section in the astMapPut0<X> docs).
+
+* Parameters:
+* this
+* Pointer to the Table in which to store the supplied value.
+* key
+* A character string identifying the cell in which the value is
+* to be stored. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* value
+* The value to be stored. The data type of this value should match
+* the 1-character type code appended to the function name (e.g. if
+* you are using astMapPut0A, the type of this value should be "pointer
+* to AstObject"). An error will be reported if this data type is
+* different to the data type assigned to the column when it was
+* created via astAddColumn.
+* comment
+* A pointer to a null-terminated comment string to be stored with the
+* value. A NULL pointer may be supplied, in which case no comment is
+* stored.
+* status
+* Pointer to inherited status value.
+
+* Notes:
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - The new value will replace any old value already stored in the
+* Table for the specified cell.
+* - If the stored value is an AST Object pointer, the Object's reference
+* count is incremented by this call. Any subsequent changes made to
+* the Object using the returned pointer will be reflected in any
+* any other active pointers for the Object, including any obtained
+* later using astMapget0A. The reference count for the Object will be
+* decremented when the KeyMap is destroyed, or the entry is removed or
+* over-written with a different pointer.
+
+*/
+/* Define a macro to implement the function for a specific data type. */
+#define MAKE_MAPPUT0(X,Xlc,Xtype,Itype,ValExp) \
+static void MapPut0##X( AstKeyMap *this_keymap, const char *key, Xtype value, \
+ const char *comment, int *status ) { \
+\
+/* Local Variables: */ \
+ AstKeyMap *col_km; /* KeyMap holding details of the requested column */ \
+ AstTable *this; /* Pointer to Table structure */ \
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
+ int irow; /* Row index within key string */ \
+ int type; /* Data type of the requested column */ \
+\
+/* Check the global error status. */ \
+ if ( !astOK ) return; \
+\
+/* Get a pointer to the Table structure. */ \
+ this = (AstTable *) this_keymap; \
+\
+/* If the key is the name of a global table parameter, use the parent \
+ method to put the value of the parameter. */ \
+ if( astHasParameter( this, key ) ) { \
+ (*parent_mapput0##Xlc)( this_keymap, key, value, comment, status ); \
+\
+/* Check the supplied key looks like a table cell key, and get the \
+ the column name and the row number. Also checks that the table \
+ contains a column with the specified name. */ \
+ } else if( ParseKey( this, key, 1, colname, &irow, &col_km, "astMapPut0" #X, \
+ status ) ) { \
+\
+/* Check the column holds scalar values of the type implied by the <X> \
+ code in the function name. */ \
+ (void) astMapGet0I( col_km, TYPE, &type ); \
+ if( type != Itype && astOK ) { \
+ astError( AST__BADTYP, "astMapPut0" #X "(%s): Failed to store a " \
+ #Xtype " value for cell \"%s\": column %s holds %s " \
+ "values.", status, astGetClass( this ), key, colname, \
+ TypeString( type ) ); \
+ } \
+\
+ if( astMapHasKey( col_km, SHAPE ) && astOK ) { \
+ astError( AST__BADTYP, "astMapPut0" #X "(%s): Failed to store a " \
+ "scalar value for cell \"%s\": column %s holds vector " \
+ " values.", status, astGetClass( this ), key, colname ); \
+ } \
+\
+/* If the row index is larger than the current number of rows in the \
+ table, update the number of rows in the table. */ \
+ if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \
+\
+/* Use the astMapPut0<X> method in the parent keyMap class to store the \
+ new cell contents. */ \
+ (*parent_mapput0##Xlc)( this_keymap, key, value, comment, status ); \
+\
+/* Free resources. */ \
+ col_km = astAnnul( col_km ); \
+ } \
+}
+
+/* Expand the above macro to generate a function for each required
+ data type. */
+MAKE_MAPPUT0(I,i,int,AST__INTTYPE,value)
+MAKE_MAPPUT0(D,d,double,AST__DOUBLETYPE,value)
+MAKE_MAPPUT0(F,f,float,AST__FLOATTYPE,value)
+MAKE_MAPPUT0(C,c,const char *,AST__STRINGTYPE,astStore(NULL,value,strlen(value)+1))
+MAKE_MAPPUT0(A,a,AstObject *,AST__OBJECTTYPE,(value?astClone(value):NULL))
+MAKE_MAPPUT0(P,p,void *,AST__POINTERTYPE,value)
+MAKE_MAPPUT0(S,s,short int,AST__SINTTYPE,value)
+MAKE_MAPPUT0(B,b,unsigned char,AST__BYTETYPE,value)
+
+/* Undefine the macro. */
+#undef MAKE_MAPPUT0
+
+/*
+* Name:
+* MapPut1<X>
+
+* Purpose:
+* Stores a vectorised value in a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* void MapPut1<X>( AstKeyMap *this, const char *key, int size,
+* const <X>type value[], const char *comment,
+* int *status );
+
+* Class Membership:
+* Table member function (over-rides the astMapPut1<X> method inherited
+* from the KeyMap class).
+
+* Description:
+* This is a set of functions for storing a vectorised value in a cell of
+* a Table. You should use a function which matches the data type of the
+* data you wish to add to the Table by replacing <X> in the generic
+* function name MapPut1<X> by an appropriate 1-character type code (see
+* the "Data Type Codes" section in the astMapPut1<X> docs).
+
+* Parameters:
+* this
+* Pointer to the Table in which to store the supplied value.
+* key
+* A character string identifying the cell in which the value is
+* to be stored. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* size
+* The number of elements in the supplied array of values.
+* value
+* The value to be stored. The data type of this value should match
+* the 1-character type code appended to the function name (e.g. if
+* you are using astMapPut0A, the type of this value should be "pointer
+* to AstObject"). An error will be reported if this data type is
+* different to the data type assigned to the column when it was
+* created via astAddColumn.
+* comment
+* A pointer to a null-terminated comment string to be stored with the
+* value. A NULL pointer may be supplied, in which case no comment is
+* stored.
+* status
+* Pointer to inherited status value.
+
+* Notes:
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - The new value will replace any old value already stored in the
+* Table for the specified cell.
+
+*/
+
+/* Define a macro to implement the function for a specific data type. */
+#define MAKE_MAPPUT1(X,Xlc,Xtype,Itype,ValExp) \
+static void MapPut1##X( AstKeyMap *this_keymap, const char *key, int size, \
+ Xtype value[], const char *comment, \
+ int *status ) { \
+\
+/* Local Variables: */ \
+ AstTable *this; /* Pointer to Table structure */ \
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
+ int irow; /* Row index within key string */ \
+\
+/* Check the global error status. */ \
+ if ( !astOK ) return; \
+\
+/* Get a pointer to the Table structure. */ \
+ this = (AstTable *) this_keymap; \
+\
+/* If the key is the name of a global table parameter, use the parent \
+ method to put the value of the parameter. */ \
+ if( astHasParameter( this, key ) ) { \
+ (*parent_mapput1##Xlc)( this_keymap, key, size, value, \
+ comment, status ); \
+\
+/* Check the supplied key looks like a table cell key, and get the \
+ the column name and the row number. Also checks that the table \
+ contains a column with the specified name. */ \
+ } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPut1" #X, \
+ status ) ) { \
+\
+/* Check the column holds vector values of the type implied by the <X> \
+ code in the function name. */ \
+ if( astGetColumnType( this, colname ) != Itype && astOK ) { \
+ astError( AST__BADTYP, "astMapPut1" #X "(%s): Failed to store " \
+ #Xtype " values for cell \"%s\": column %s holds %s values.", \
+ status, astGetClass( this ), key, colname, \
+ TypeString( astGetColumnType( this, colname ) ) ); \
+ } \
+\
+/* Check the column holds vectors with length equal to the supplied vector. */ \
+ if( astGetColumnLength( this, colname ) != size && astOK ) { \
+ astError( AST__BADTYP, "astMapPut1" #X "(%s): Failed to " \
+ "store a vector value for cell \"%s\": column " \
+ "%s needs %d values per cell but %d were supplied.", \
+ status, astGetClass( this ), key, colname, \
+ astGetColumnLength( this, colname ), size ); \
+ } \
+\
+/* If all is OK, update the number of rows in the table if required, and \
+ store the vector in the parent KeyMap. */ \
+ if( astOK ) { \
+ if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \
+ (*parent_mapput1##Xlc)( this_keymap, key, size, value, \
+ comment, status ); \
+ } \
+\
+ } \
+}
+
+/* Expand the above macro to generate a function for each required
+ data type. */
+MAKE_MAPPUT1(D,d,const double,AST__DOUBLETYPE,value[i])
+MAKE_MAPPUT1(F,f,const float,AST__FLOATTYPE,value[i])
+MAKE_MAPPUT1(I,i,const int,AST__INTTYPE,value[i])
+MAKE_MAPPUT1(C,c,const char *const,AST__STRINGTYPE,astStore(NULL,value[i],strlen(value[i])+1))
+MAKE_MAPPUT1(A,a,AstObject *const,AST__OBJECTTYPE,(value[i]?astClone(value[i]):NULL))
+MAKE_MAPPUT1(P,p,void *const,AST__POINTERTYPE,value[i])
+MAKE_MAPPUT1(S,s,const short int,AST__SINTTYPE,value[i])
+MAKE_MAPPUT1(B,b,const unsigned char,AST__BYTETYPE,value[i])
+
+/* Undefine the macro. */
+#undef MAKE_MAPPUT1
+
+/*
+* Name:
+* MapPutElem<X>
+
+* Purpose:
+* Put a value into an element of a vector value in a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* void MapPutElem<X>( AstKeyMap *this, const char *key, int elem,
+* <X>type *value, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astMapPutElem<X> method inherited
+* from the KeyMap class).
+
+* Description:
+* This is a set of functions for storing a value in a single element
+* of a vector value stored in a cell of a Table. You should use a
+* function which matches the data type of the data you wish to add to
+* the Table by replacing <X> in the generic function name MapPutElem<X>
+* by an appropriate 1-character type code (see the "Data Type Codes"
+* section in the astMapPutElem<X> docs).
+
+* Parameters:
+* this
+* Pointer to the Table in which to store the supplied value.
+* key
+* A character string identifying the cell in which the value is
+* to be stored. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* elem
+* The index of the vector element to modify, starting at zero.
+* If the index is outside the range of the vector, an error will
+* be reported.
+* value
+* The value to be stored. The data type of this value should match
+* the 1-character type code appended to the function name (e.g. if
+* you are using astMapPut0A, the type of this value should be "pointer
+* to AstObject"). An error will be reported if this data type is
+* different to the data type assigned to the column when it was
+* created via astAddColumn.
+* status
+* Pointer to inherited status value.
+
+* Notes:
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - The new value will replace any old value already stored in the
+* Table for the specified cell.
+* - If the stored value is an AST Object pointer, the Object's reference
+* count is incremented by this call. Any subsequent changes made to
+* the Object using the returned pointer will be reflected in any
+* any other active pointers for the Object, including any obtained
+* later using astMapget0A. The reference count for the Object will be
+* decremented when the KeyMap is destroyed, or the entry is removed or
+* over-written with a different pointer.
+
+*/
+/* Define a macro to implement the function for a specific data type. */
+
+#define MAKE_MAPPUTELEM(X,Xlc,Xtype,Itype) \
+static void MapPutElem##X( AstKeyMap *this_keymap, const char *key, int elem, \
+ Xtype value, int *status ) { \
+\
+/* Local Variables: */ \
+ AstTable *this; /* Pointer to Table structure */ \
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
+ int irow; /* Row index within key string */ \
+ int type; /* Data type of the requested column */ \
+\
+/* Check the global error status. */ \
+ if ( !astOK ) return; \
+\
+/* Get a pointer to the Table structure. */ \
+ this = (AstTable *) this_keymap; \
+\
+/* If the key is the name of a global table parameter, use the parent \
+ method to put the value of the parameter. */ \
+ if( astHasParameter( this, key ) ) { \
+ (*parent_mapputelem##Xlc)( this_keymap, key, elem, value, \
+ status ); \
+\
+/* Check the supplied key looks like a table cell key, and get the \
+ the column name and the row number. Also checks that the table \
+ contains a column with the specified name. */ \
+ } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPutElem" #X, \
+ status ) ) { \
+\
+/* Check the column holds vector values of the type implied by the <X> \
+ code in the function name. */ \
+ type = astGetColumnType( this, colname ); \
+ if( type != Itype && astOK ) { \
+ astError( AST__BADTYP, "astMapPutElem" #X "(%s): Failed to store a " \
+ #Xtype " value in cell \"%s\": column %s holds %s values.", \
+ status, astGetClass( this ), key, colname, \
+ TypeString( type ) ); \
+ } \
+\
+/* Check the column holds vectors with length equal to the supplied vector. */ \
+ if( astGetColumnLength( this, colname ) <= elem && astOK ) { \
+ astError( AST__BADTYP, "astMapPutElem" #X "(%s): Failed to " \
+ "store a value for element %d (zero-based) of " \
+ "cell \"%s\": column %s has only %d values per " \
+ "cell.", status, astGetClass( this ), elem, key, \
+ colname, astGetColumnLength( this, colname ) ); \
+ } \
+\
+/* If all is OK, update the number of rows in the table if required, and \
+ store the value in the parent KeyMap. */ \
+ if( astOK ) { \
+ if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \
+ (*parent_mapputelem##Xlc)( this_keymap, key, elem, value, \
+ status ); \
+ } \
+ } \
+}
+
+/* Expand the above macro to generate a function for each required
+ data type. */
+MAKE_MAPPUTELEM(I,i,int,AST__INTTYPE)
+MAKE_MAPPUTELEM(D,d,double,AST__DOUBLETYPE)
+MAKE_MAPPUTELEM(F,f,float,AST__FLOATTYPE)
+MAKE_MAPPUTELEM(A,a,AstObject *,AST__OBJECTTYPE)
+MAKE_MAPPUTELEM(P,p,void *,AST__POINTERTYPE)
+MAKE_MAPPUTELEM(C,c,const char *,AST__STRINGTYPE)
+MAKE_MAPPUTELEM(S,s,short int,AST__SINTTYPE)
+MAKE_MAPPUTELEM(B,b,unsigned char,AST__BYTETYPE)
+
+/* Undefine the macro. */
+#undef MAKE_MAPPUTELEM
+
+static void MapPutU( AstKeyMap *this_keymap, const char *key, const char *comment,
+ int *status ) {
+/*
+* Name:
+* MapPutU
+
+* Purpose:
+* Stores a undefined value in a cell of a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* void MapPutU( AstKeyMap *this, const char *key, const char *comment,
+* int *status )
+
+* Class Membership:
+* Table member function (over-rides the astMapPutU method inherited
+* from the KeyMap class).
+
+* Description:
+* This function adds a new cell to a Table, but no value is stored with
+* the cell. The cell therefore has a special data type represented by
+* symbolic constant AST__UNDEFTYPE.
+*
+* An example use is to add cells with undefined values to a Table
+* prior to locking them with the MapLocked attribute. Such cells
+* can act as placeholders for values that can be added to the KeyMap
+* later.
+
+* Parameters:
+* this
+* Pointer to the Table in which to store the supplied value.
+* key
+* A character string identifying the cell in which the value is
+* to be stored. It should have the form "COLNAME(irow)", where
+* "COLNAME" is replaced by the name of a column that has been
+* defined previously using the astAddColumn method, and "irow" is
+* an integer row index (the first row is row 1).
+* comment
+* A pointer to a null-terminated comment string to be stored with the
+* value. A NULL pointer may be supplied, in which case no comment is
+* stored.
+* status
+* Pointer to inherited status value.
+
+* Notes:
+* - Key names are case insensitive, and white space is considered
+* significant.
+* - The new undefined value will replace any old value already stored in
+* the Table for the specified cell.
+
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to Table structure */
+ char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */
+ int irow; /* Row index within key string */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Get a pointer to the Table structure. */
+ this = (AstTable *) this_keymap;
+
+/* If the key is the name of a global table parameter, use the parent
+ method to put the value of the parameter. */
+ if( astHasParameter( this, key ) ) {
+ (*parent_mapputu)( this_keymap, key, comment, status );
+
+/* Check the supplied key looks like a table cell key, and get the
+ the column name and the row number. Also checks that the table
+ contains a column with the specified name. */
+ } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPutU",
+ status ) ) {
+
+/* If the row index is larger than the current number of rows in the
+ table, update the number of rows in the table. */
+ if( irow > astGetNrow( this ) ) astSetNrow( this, irow );
+
+/* Use the astMapPutU method in the parent keyMap class to store the
+ new cell contents. */
+ (*parent_mapputu)( this_keymap, key, comment, status );
+ }
+}
+
+static const char *ParameterName( AstTable *this, int index, int *status ) {
+/*
+*++
+* Name:
+c astParameterName
+f AST_PARAMETERNAME
+
+* Purpose:
+* Get the name of the global parameter at a given index within the Table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c const char *astParameterName( AstTable *this, int index )
+f RESULT = AST_PARAMETERNAME( THIS, INDEX, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns a string holding the name of the global parameter with
+* the given index within the Table.
+*
+* This function is intended primarily as a means of iterating round all
+* the parameters in a Table. For this purpose, the number of parameters in
+* the Table is given by the Nparameter attribute of the Table. This function
+* could then be called in a loop, with the index value going from
+c zero to one less than Nparameter.
+f one to Nparameter.
+*
+* Note, the index associated with a parameter decreases monotonically with
+* the age of the parameter: the oldest Parameter in the Table will have index
+* one, and the Parameter added most recently to the Table will have the
+* largest index.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c index
+f INDEX = INTEGER (Given)
+* The index into the list of parameters. The first parameter has index
+* one, and the last has index "Nparameter".
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Returned Value:
+c astParameterName()
+c A pointer to a null-terminated string containing the
+f AST_PARAMETERNAME = CHARACTER * ( AST__SZCHR )
+f The
+* upper case parameter name.
+
+* Notes:
+c - The returned pointer is guaranteed to remain valid and the
+c string to which it points will not be over-written for a total
+c of 50 successive invocations of this function. After this, the
+c memory containing the string may be re-used, so a copy of the
+c string should be made if it is needed for longer than this.
+c - A NULL pointer will be returned if this function is invoked
+c with the AST error status set, or if it should fail for any
+c reason.
+f - A blank string will be returned if this function is invoked
+f with STATUS set to an error value, or if it should fail for any
+f reason.
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *pars; /* KeyMap holding parameter definitions */
+ const char *result;
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Get apointer to the KeyMap holding all parameter definitions. */
+ pars = astParameterProps( this );
+
+/* Issue a more useful error message than that issued by astMapKey if the
+ index is invalid. */
+ if( index < 1 || index > astMapSize( pars ) ) {
+ astError( AST__MPIND, "astParameterName(%s): Cannot find parameter "
+ "%d (zero-based) of the %s - invalid index.", status,
+ astGetClass( this ), index, astGetClass( this ) );
+ }
+
+/* Get the parameter name. */
+ result = astMapKey( pars, index - 1 );
+
+/* Free resources. */
+ pars = astAnnul( pars );
+
+/* Return a pointer to the required parameter name. */
+ return result;
+}
+
+static AstKeyMap *ParameterProps( AstTable *this, int *status ) {
+/*
+*+
+* Name:
+* astParameterProps
+
+* Purpose:
+* Returns a pointer to the KeyMap holding parameter properties.
+
+* Type:
+* Protected virtual function.
+
+* Synopsis:
+* #include "table.h"
+* AstKeyMap *astParameterProps( AstTable *this )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function returns a pointer to the KeyMap that holds
+* definitions of all the parameters added to the Table.
+
+* Parameters:
+* this
+* Pointer to the Table.
+
+* Returned Value:
+* A pointer to the KeyMap. It should be annulled using astAnnul
+* when no longer needed.
+
+*-
+*/
+
+/* Check the global error status. */
+ if ( !astOK ) return NULL;
+
+/* Return a cloned pointer to the required KeyMap. */
+ return astClone( this->parameters );
+}
+
+static int ParseKey( AstTable *this, const char *key, int report,
+ char colname[ AST__MXCOLNAMLEN + 1 ], int *irow,
+ AstKeyMap **col_km, const char *method, int *status ){
+/*
+* Name:
+* ParseKey
+
+* Purpose:
+* Find the column name and row index in a KeyMap key.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int ParseKey( AstTable *this, const char *key, int report,
+* char colname[ AST__MXCOLNAMLEN + 1 ], int *irow,
+* AstKeyMap **col_km, const char *method, int *status )
+
+* Class Membership:
+* Table member function
+
+* Description:
+* This function checks that the supplied KeyMap key conforms to the
+* format expected for Table cells: i.e. "COLNAME(irow)", where
+* "COLNAME" is the name of a column and "irow" is an integer row
+* index (the first row is row 1), An error is reported if this is
+* not the case.
+
+* Parameters:
+* this
+* Pointer to the table.
+* key
+* The key string to test.
+* report
+* If non-zero, an error will be reported if the key does not
+* correspond to a cell of an existing column. Otherwise, no
+* error will be reported.
+* colname
+* A buffer in which to return the column name.
+* irow
+* Address of an int in which to return the row index.
+* col_km
+* Address of a KeyMap pointer in which to return a pointer to the
+* KeyMap holding the information about the column. The returned
+* KeyMap pointer should be annulled using astAnnul when no lngerr
+* needed. If "col_km" is NULL, no KeyMap pointer is returned.
+* method
+* Pointer to a string holding the name of the method to include in
+* any error message.
+* status
+* Address of the inherited status value.
+
+* Returned Value:
+* Zero is returned if the key is not a valid Table cell key, or if an
+* error occurs.
+
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding column definitions */
+ int result; /* Returned flag */
+ int collen; /* Length of column name */
+ int nctot; /* Number of characters read */
+
+/* Initialise */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Check the supplied key looks like a table cell key, and extract the
+ column name and row number. */
+ nctot = 0;
+ if( 1 == astSscanf( key, "%*[^(]%n(%d) %n", &collen, irow, &nctot )
+ && ( nctot >= strlen( key ) ) ) {
+
+/* Check the column name is not too long. */
+ if( collen > AST__MXCOLNAMLEN ) {
+ if( report ) {
+ astError( AST__BADKEY, "%s(%s): Failed to store a value for cell "
+ "\"%s\": column name is too long.", status, method,
+ astGetClass( this ), key );
+ }
+
+/* Check the row index is positive. */
+ } else if( *irow < 1 ) {
+ if( report ) {
+ astError( AST__BADKEY, "%s(%s): Failed to store a value for cell "
+ "\"%s\": row index %d is invalid.", status, method,
+ astGetClass( this ), key, *irow );
+ }
+
+/* If the key looks OK so far... */
+ } else {
+
+/* Convert the column name to upper case and store in the returned buffer. */
+ astChrCase( key, colname, 1, collen + 1 );
+ colname[ collen ] = 0;
+
+/* check that the column exists in the Table, returning a pointer to the
+ column KeyMap is reequired. */
+ cols = astColumnProps( this );
+ if( col_km ) {
+ result = astMapGet0A( cols, colname, col_km );
+ } else {
+ result = astMapHasKey( cols, colname );
+ }
+ cols = astAnnul( cols );
+
+/* Report an error if the table does not contain the specified column. */
+ if( !result && astOK && report) {
+ astError( AST__BADKEY, "%s(%s): Failed to store a value for "
+ "cell \"%s\": the table does not contain a column "
+ "called '%s'.", status, method, astGetClass( this ),
+ key, colname );
+ }
+ }
+
+/* Report an error if the cell key has the wrong format. */
+ } else if( report ) {
+ astError( AST__BADKEY, "%s(%s): Failed to store a value for cell "
+ "\"%s\": the cell name is invalid.", status, method,
+ astGetClass( this ), key );
+ }
+
+/* Return the result.*/
+ return result;
+}
+
+static void PurgeRows( AstTable *this, int *status ) {
+/*
+*++
+* Name:
+c astPurgeRows
+f AST_PURGEROWS
+
+* Purpose:
+* Remove all empty rows from a table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astPurgeRows( AstTable *this )
+f CALL AST_PURGEROWS( THIS, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function removes all empty rows from the Table, renaming
+* the key associated with each table cell accordingly.
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+*--
+*/
+
+/* Local Variables: */
+ char newkey[ AST__MXCOLKEYLEN + 1 ]; /* New cell key string */
+ char oldkey[ AST__MXCOLKEYLEN + 1 ]; /* Old cell key string */
+ const char *col; /* Column name */
+ const char *key; /* Pointer to key string */
+ const char *op; /* Pointer to opening parenthesis */
+ int *w1; /* Work space pointer */
+ int icol; /* Column index */
+ int inew; /* New row index */
+ int iold; /* Old row index */
+ int ncol; /* Number of columns in table */
+ int nrow; /* Number of rows in table */
+ int reset; /* Start a new pass through the KeyMap? */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Get the number of rows in the table. */
+ nrow = astGetNrow( this );
+
+/* Create workspace to hold the number of defined values stored in each
+ row. Initialise every row to have zero defined values. */
+ w1 = astCalloc( nrow, sizeof( int ) );
+ if( astOK ) {
+
+/* Iterate round all keys in the KeyMap. */
+ reset = 1;
+ while( ( key = astMapIterate( this, reset ) ) && astOK ) {
+ reset = 0;
+
+/* Extract the row number from the key. */
+ op = strchr( key, '(' );
+ if( !op || astSscanf( op + 1, "%d", &iold ) != 1 ||
+ iold > nrow ) {
+ astError( AST__INTER, "astPurgeRows(%s): Illegal key '%s' "
+ "found in a %s (internal programming error).",
+ status, astGetClass( this ), key, astGetClass( this ) );
+
+/* Increment the number of values in this row. Note row indices are
+ one-based. */
+ } else {
+ w1[ iold - 1 ]++;
+ }
+ }
+
+/* Loop round all columns in the Table. */
+ ncol = astGetNcolumn( this );
+ inew = nrow;
+ for( icol = 1; icol <= ncol; icol++ ) {
+
+/* Get the column name */
+ col = astColumnName( this, icol );
+
+/* Loop round all the old row numbers. Skip empty rows.*/
+ inew = 0;
+ for( iold = 0; iold < nrow; iold++ ) {
+ if( w1[ iold ] > 0 ) {
+
+/* Increment the row number to use in place of the old row number. If the
+ old and new row numbers are the same, we do not need to rename the cell. */
+ if( iold != inew++ ) {
+
+/* For the old and new cell names */
+ sprintf( oldkey, "%s(%d)", col, iold + 1 );
+ sprintf( newkey, "%s(%d)", col, inew );
+
+/* Rename the KeyMap entry. */
+ astMapRename( this, oldkey, newkey );
+ }
+ }
+ }
+
+/* If all rows were used, we do not need to check any more columns. */
+ if( iold == inew ) break;
+ }
+
+/* Store the new number of rows. */
+ astSetNrow( this, inew );
+ }
+
+/* Free resources. */
+ w1 = astFree( w1 );
+
+}
+
+static void RemoveColumn( AstTable *this, const char *name, int *status ) {
+/*
+*++
+* Name:
+c astRemoveColumn
+f AST_REMOVECOLUMN
+
+* Purpose:
+* Remove a column from a table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astRemoveColumn( AstTable *this, const char *name )
+f CALL AST_REMOVECOLUMN( THIS, NAME, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function removes a specified column from the supplied table.
+* The
+c function
+f routine
+* returns without action if the named column does not exist in the
+* Table (no error is reported).
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c name
+f NAME = CHARACTER * ( * ) (Given)
+* The column name. Trailing spaces are ignored (all other spaces
+* are significant). Case is significant.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding column definitions */
+ char key[ AST__MXCOLKEYLEN + 1 ]; /* Cell key string */
+ int irow; /* Row index */
+ int namlen; /* Used length of "name" */
+ int nrow; /* Number of rows in table */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Verify supplied values. */
+ namlen = astChrLen( name );
+ if( namlen == 0 ) {
+ astError( AST__BADKEY, "astRemoveColumn(%s): Illegal blank column name "
+ "supplied.", status, astGetClass( this ) );
+ }
+
+/* Get the number of rows in the table. */
+ nrow = astGetNrow( this );
+
+/* If there is no column with the given name in the Table, do nothing more. */
+ cols = astColumnProps( this );
+ if( astOK && astMapHasKey( cols, name ) ) {
+
+/* Remove the column description from the columns keymap. */
+ astMapRemove( cols, name );
+
+/* Remove any column cells with defined values from the parent KeyMap. */
+ for( irow = 1; irow <= nrow; irow++ ) {
+ sprintf( key, "%.*s(%d)", namlen, name, irow );
+ (*parent_mapremove)( (AstKeyMap *) this, key, status );
+ }
+ }
+ cols = astAnnul( cols );
+}
+
+static void RemoveParameter( AstTable *this, const char *name, int *status ) {
+/*
+*++
+* Name:
+c astRemoveParameter
+f AST_REMOVEPARAMETER
+
+* Purpose:
+* Remove a global parameter from a table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astRemoveParameter( AstTable *this, const char *name )
+f CALL AST_REMOVEPARAMETER( THIS, NAME, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function removes a specified global parameter from the supplied table.
+* The
+c function
+f routine
+* returns without action if the named parameter does not exist in the
+* Table (no error is reported).
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c name
+f NAME = CHARACTER * ( * ) (Given)
+* The parameter name. Trailing spaces are ignored (all other spaces
+* are significant). Case is significant.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *pars; /* KeyMap holding parameter definitions */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Verify supplied values. */
+ if( astChrLen( name ) == 0 ) {
+ astError( AST__BADKEY, "astRemoveParameter(%s): Illegal blank parameter name "
+ "supplied.", status, astGetClass( this ) );
+ }
+
+/* If there is no parameter with the given name in the Table, do nothing more. */
+ pars = astParameterProps( this );
+ if( astOK && astMapHasKey( pars, name ) ) {
+
+/* Remove the parameter description from the parameters keymap. */
+ astMapRemove( pars, name );
+
+/* Remove any entry holding the parameter value from the parent KeyMap. */
+ (*parent_mapremove)( (AstKeyMap *) this, name, status );
+ }
+ pars = astAnnul( pars );
+}
+
+static void RemoveRow( AstTable *this, int index, int *status ) {
+/*
+*++
+* Name:
+c astRemoveRow
+f AST_REMOVEROW
+
+* Purpose:
+* Remove a row from a table.
+
+* Type:
+* Public virtual function.
+
+* Synopsis:
+c #include "table.h"
+c void astRemoveRow( AstTable *this, int index )
+f CALL AST_REMOVEROW( THIS, INDEX, STATUS )
+
+* Class Membership:
+* Table method.
+
+* Description:
+* This function removes a specified row from the supplied table.
+* The
+c function
+f routine
+* returns without action if the row does not exist in the
+* Table (no error is reported).
+
+* Parameters:
+c this
+f THIS = INTEGER (Given)
+* Pointer to the Table.
+c index
+f INDEX = INTEGER (Given)
+* The index of the row to be removed. The first row has index 1.
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+*--
+*/
+
+/* Local Variables: */
+ AstKeyMap *cols; /* KeyMap holding column definitions */
+ char key[ AST__MXCOLKEYLEN + 1 ]; /* Cell key string */
+ const char *col; /* Column name */
+ int icol; /* Column index */
+ int ncol; /* Number of columns in table */
+ int nrow; /* Number of rows in table */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Get the number of rows in the table. */
+ nrow = astGetNrow( this );
+
+/* Do nothing if the specified row is out of bounds. */
+ if( index > 0 && index <= nrow ) {
+
+/* Loop round all columns in the table. */
+ cols = astColumnProps( this );
+ ncol = astMapSize( cols );
+ for( icol = 0; icol < ncol; icol++ ) {
+ col = astMapKey( cols, icol );
+
+/* Remove the cell of the current column at the requested row. */
+ sprintf( key, "%s(%d)", col, index );
+ (*parent_mapremove)( (AstKeyMap *) this, key, status );
+ }
+ cols = astAnnul( cols );
+
+/* If the removed row was the last row, reduce the number of rows in the
+ Table. */
+ if( index == nrow ) astSetNrow( this, index - 1 );
+ }
+}
+
+static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
+/*
+* Name:
+* SetAttrib
+
+* Purpose:
+* Set an attribute value for a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* void SetAttrib( AstObject *this, const char *setting, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astSetAttrib protected
+* method inherited from the KeyMap class).
+
+* Description:
+* This function assigns an attribute value for a Table, the
+* attribute and its value being specified by means of a string of
+* the form:
+*
+* "attribute= value "
+*
+* Here, "attribute" specifies the attribute name and should be in
+* lower case with no white space present. The value to the right
+* of the "=" should be a suitable textual representation of the
+* value to be assigned and this will be interpreted according to
+* the attribute's data type. White space surrounding the value is
+* only significant for string attributes.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* setting
+* Pointer to a null terminated string specifying the new attribute
+* value.
+* status
+* Pointer to the inherited status variable.
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to the Table structure */
+ int len; /* Length of setting string */
+ int nc; /* Number of characters read by astSscanf */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the Table structure. */
+ this = (AstTable *) this_object;
+
+/* Obtain the length of the setting string. */
+ len = (int) strlen( setting );
+
+/* Test for each recognised attribute in turn, using "astSscanf" to parse
+ the setting string and extract the attribute value (or an offset to
+ it in the case of string values). In each case, use the value set
+ in "nc" to check that the entire string was matched. Once a value
+ has been obtained, use the appropriate method to set it. */
+ /* None as yet */
+
+/* Define a macro to see if the setting string matches any of the
+ read-only attributes of this class. */
+#define MATCH(attrib) \
+ ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \
+ ( nc >= len ) )
+
+#define MATCH2(attrib) \
+ ( nc = 0, ( 0 == astSscanf( setting, attrib "(%*s) =%*[^\n]%n", &nc ) ) && \
+ ( nc >= len ) )
+
+/* If the attribute was not recognised, use this macro to report an error
+ if a read-only attribute has been specified. */
+ if ( MATCH( "ncolumn" ) ||
+ MATCH( "nparameter" ) ||
+ MATCH( "nrow" ) ||
+ MATCH2( "columnlenc" ) ||
+ MATCH2( "columnlength" ) ||
+ MATCH2( "columnndim" ) ||
+ MATCH2( "columntype" ) ||
+ MATCH2( "columnunit" ) ) {
+ astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status,
+ setting, astGetClass( this ) );
+ astError( AST__NOWRT, "This is a read-only attribute." , status);
+
+/* If the attribute is still not recognised, pass it on to the parent
+ method for further interpretation. */
+ } else {
+ (*parent_setattrib)( this_object, setting, status );
+ }
+
+/* Undefine macros local to this function. */
+#undef MATCH
+#undef MATCH2
+}
+
+static void SetKeyCase( AstKeyMap *this, int keycase, int *status ) {
+/*
+* Name:
+* SetKeyCase
+
+* Purpose:
+* Set a value for the KeyCase attribute value for a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "keymape.h"
+* void SetKeyCase( AstKeyMap *this, int keycase, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astSetKeyCase protected
+* method inherited from the KeyMap class).
+
+* Description:
+* This function assigns a new valeu to the KeyCase attribute for a
+* Table. For a Table, the KeyCase attribute cannot be changed so this
+* function exits without action.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* keycase
+* The new value to set.
+*/
+
+}
+
+static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
+/*
+* Name:
+* TestAttrib
+
+* Purpose:
+* Test if a specified attribute value is set for a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* int TestAttrib( AstObject *this, const char *attrib, int *status )
+
+* Class Membership:
+* Table member function (over-rides the astTestAttrib protected
+* method inherited from the KeyMap class).
+
+* Description:
+* This function returns a boolean result (0 or 1) to indicate whether
+* a value has been set for one of a Table's attributes.
+
+* Parameters:
+* this
+* Pointer to the Table.
+* attrib
+* Pointer to a null terminated string specifying the attribute
+* name. This should be in lower case with no surrounding white
+* space.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* One if a value has been set, otherwise zero.
+
+* Notes:
+* - A value of zero will be returned if this function is invoked
+* with the global status set, or if it should fail for any reason.
+*/
+
+/* Local Variables: */
+ int len; /* Length of attribute string */
+ int nc; /* Number of characters read by astSscanf */
+ int result; /* Result value to return */
+
+/* Initialise. */
+ result = 0;
+
+/* Check the global error status. */
+ if ( !astOK ) return result;
+
+/* Get the length of the attribute string. */
+ len = strlen( attrib );
+
+/* Check the attribute name and test the appropriate attribute. */
+ /* None as yet */
+
+/* Define a macro to see if the attribute string matches any of the
+ read-only column attributes of this class. */
+#define MATCH(attr) \
+ ( nc = 0, ( 0 == astSscanf( attrib, attr "(%*s)%n", &nc ) ) && \
+ ( nc >= len ) )
+
+/* If the name is not recognised, test if it matches any of the
+ read-only attributes of this class. If it does, then return
+ zero. */
+ if ( !strcmp( attrib, "ncolumn" ) ||
+ !strcmp( attrib, "nparameter" ) ||
+ !strcmp( attrib, "nrow" ) ||
+ MATCH( "columnlenc" ) ||
+ MATCH( "columnlength" ) ||
+ MATCH( "columnndim" ) ||
+ MATCH( "columntype" ) ||
+ MATCH( "columnunit" ) ) {
+ result = 0;
+
+/* If the attribute is still not recognised, pass it on to the parent
+ method for further interpretation. */
+ } else {
+ result = (*parent_testattrib)( this_object, attrib, status );
+ }
+
+/* Return the result, */
+ return result;
+
+#undef MATCH
+}
+
+static const char *TypeString( int type ) {
+/*
+* Name:
+* TypeString
+
+* Purpose:
+* Return a pointer to a string describing a data type.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* const char *TypeString( int type );
+
+* Description:
+* This function returns a pointer to a string describing a data type.
+
+* Parameters:
+* type
+* The integer data type code.
+
+* Returned Value:
+* Pointer to a a string descirbing the data type (typically the C
+* data type).
+
+*/
+
+/* Local Variables: */
+ const char *result;
+
+/* Compare the supplied type code against each supported value. */
+ if( type == AST__INTTYPE ) {
+ result = "int";
+
+ } else if( type == AST__BYTETYPE ) {
+ result = "byte";
+
+ } else if( type == AST__DOUBLETYPE ) {
+ result = "double";
+
+ } else if( type == AST__STRINGTYPE ) {
+ result = "string";
+
+ } else if( type == AST__OBJECTTYPE ) {
+ result = "Object";
+
+ } else if( type == AST__FLOATTYPE ) {
+ result = "float";
+
+ } else if( type == AST__POINTERTYPE ) {
+ result = "pointer";
+
+ } else if( type == AST__SINTTYPE ) {
+ result = "short int";
+
+ } else if( type == AST__UNDEFTYPE ) {
+ result = "undefined";
+
+ } else {
+ result = NULL;
+ }
+
+/* Return the result. */
+ return result;
+}
+
+
+/* Functions which access class attributes. */
+/* ---------------------------------------- */
+/* Implement member functions to access the attributes associated with
+ this class using the macros defined for this purpose in the
+ "object.h" file. For a description of each attribute, see the class
+ interface (in the associated .h file). */
+
+/*
+*att++
+* Name:
+* ColumnLenC(column)
+
+* Purpose:
+* The largest string length of any value in a column
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds the minimum length which a character variable
+* must have in order to be able to store the longest value currently
+* present (at any row) in a specified column of the supplied Table.
+c This does not include room for a trailing null character.
+* The required column name should be placed inside the parentheses in
+* the attribute name. If the named column holds vector values, then
+* the attribute value is the length of the longest element of the
+* vector value.
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+* Notes:
+* - If the named column holds numerical values, the length returned
+* is the length of the largest string that would be generated if the
+* column values were accessed as strings.
+
+*att--
+*/
+
+/*
+*att++
+* Name:
+* ColumnLength(column)
+
+* Purpose:
+* The number of elements in each value in a column
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds the number of elements in each value stored
+* in a named column. Each value can be a scalar (in which case the
+* ColumnLength attribute has a value of 1), or a multi-dimensional
+* array ( in which case the ColumnLength value is equal to the
+* product of the array dimensions).
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+*att--
+*/
+
+/*
+*att++
+* Name:
+* ColumnNdim(column)
+
+* Purpose:
+* The number of axes spanned by each value in a column
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds the number of axes spanned by each value in a
+* column. If each cell in the column is a scalar, ColumnNdim will be
+* zero. If each cell in the column is a 1D spectrum, ColumnNdim will
+* be one. If each cell in the column is a 2D image, ColumnNdim will be
+* two, etc. The required column name should be placed inside the
+* parentheses in the attribute name.
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+*att--
+*/
+
+/*
+*att++
+* Name:
+* ColumnType(column)
+
+* Purpose:
+* The data type of each value in a column
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds a integer value indicating the data type of
+* a named column in a Table. This is the data type which was used
+* when the column was added to the Table using astAddColumn. The
+* required column name should be placed inside the parentheses in
+* the attribute name.
+*
+* The attribute value will be one of AST__INTTYPE (for integer),
+* AST__SINTTYPE (for
+c short int),
+f INTEGER*2),
+* AST__BYTETYPE (for
+c unsigned bytes - i.e. unsigned chars),
+f bytes),
+* AST__DOUBLETYPE (for double
+* precision floating point), AST__FLOATTYPE (for single
+* precision floating point), AST__STRINGTYPE (for character string),
+* AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for
+* arbitrary C pointer) or AST__UNDEFTYPE (for undefined values
+* created by
+c astMapPutU).
+f AST_MAPPUTU).
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+*att--
+*/
+
+/*
+*att++
+* Name:
+* Ncolumn
+
+* Purpose:
+* The number of columns in the table.
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds the number of columns currently in the table. Columns
+* are added and removed using the
+c astAddColumn and astRemoveColumn
+f AST_ADDCOLUMN and AST_REMOVECOLUMN
+* functions.
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+*att--
+*/
+
+/*
+*att++
+* Name:
+* Nparameter
+
+* Purpose:
+* The number of global parameters in the table.
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds the number of global parameters currently in the table.
+* Parameters are added and removed using the
+c astAddParameter and astRemoveParameter
+f AST_ADDPARAMETER and AST_REMOVEPARAMETER
+* functions.
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+*att--
+*/
+
+/*
+*att++
+* Name:
+* Nrow
+
+* Purpose:
+* The number of rows in the table.
+
+* Type:
+* Public attribute.
+
+* Synopsis:
+* Integer, read-only.
+
+* Description:
+* This attribute holds the index of the last row to which any
+* contents have been added using any of the
+* astMapPut...
+* AST_MAPPUT...
+* functions. The first row has index 1.
+
+* Applicability:
+* Table
+* All Tables have this attribute.
+
+*att--
+*/
+astMAKE_GET(Table,Nrow,int,0,this->nrow)
+astMAKE_SET(Table,Nrow,int,nrow,value)
+
+
+
+/* Copy constructor. */
+/* ----------------- */
+static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
+/*
+* Name:
+* Copy
+
+* Purpose:
+* Copy constructor for Table objects.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* void Copy( const AstObject *objin, AstObject *objout, int *status )
+
+* Description:
+* This function implements the copy constructor for Table objects.
+
+* Parameters:
+* objin
+* Pointer to the object to be copied.
+* objout
+* Pointer to the object being constructed.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* void
+
+* Notes:
+* - This constructor makes a deep copy, including a copy of the component
+* Mappings within the Table.
+*/
+
+/* Local Variables: */
+ AstTable *in; /* Pointer to input Table */
+ AstTable *out; /* Pointer to output Table */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain pointers to the input and output Tables. */
+ in = (AstTable *) objin;
+ out = (AstTable *) objout;
+
+/* Make copies of the component KeyMaps and store pointers to them in the
+ output Table structure. */
+ out->columns = in->columns ? astCopy( in->columns ) : NULL;
+ out->parameters = in->parameters ? astCopy( in->parameters ) : NULL;
+}
+
+
+/* Destructor. */
+/* ----------- */
+static void Delete( AstObject *obj, int *status ) {
+/*
+* Name:
+* Delete
+
+* Purpose:
+* Destructor for Table objects.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* void Delete( AstObject *obj, int *status )
+
+* Description:
+* This function implements the destructor for Table objects.
+
+* Parameters:
+* obj
+* Pointer to the object to be deleted.
+* status
+* Pointer to the inherited status variable.
+
+* Returned Value:
+* void
+
+* Notes:
+* This function attempts to execute even if the global error status is
+* set.
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to Table */
+
+/* Obtain a pointer to the Table structure. */
+ this = (AstTable *) obj;
+
+/* Annul the pointers to the component KeyMaps. */
+ if( this->columns ) this->columns = astAnnul( this->columns );
+ if( this->parameters ) this->parameters = astAnnul( this->parameters );
+
+}
+
+
+/* Dump function. */
+/* -------------- */
+static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
+/*
+* Name:
+* Dump
+
+* Purpose:
+* Dump function for Table objects.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* void Dump( AstObject *this, AstChannel *channel, int *status )
+
+* Description:
+* This function implements the Dump function which writes out data
+* for the Table class to an output Channel.
+
+* Parameters:
+* this
+* Pointer to the Table whose data are being written.
+* channel
+* Pointer to the Channel to which the data are being written.
+* status
+* Pointer to the inherited status variable.
+*/
+
+/* Local Variables: */
+ AstTable *this; /* Pointer to the Table structure */
+
+/* Check the global error status. */
+ if ( !astOK ) return;
+
+/* Obtain a pointer to the Table structure. */
+ this = (AstTable *) this_object;
+
+/* Write out values representing the instance variables for the Table
+ class. Note, the primitive data in the Table will be written out
+ by the parent KeyMap Dump function. This function deals just with the
+ extra information held in the Table structure. */
+
+/* Write out the number of rows in the table. */
+ astWriteInt( channel, "Nrow", 1, 1, astGetNrow( this ),
+ "Number of rows in table" );
+
+/* Write out the KeyMap holding definitions of each column. */
+ if( this->columns ) {
+ astWriteObject( channel, "Columns", 1, 0, this->columns, "KeyMap holding "
+ "column definitions" );
+ }
+
+/* Write out the KeyMap holding definitions of each global parameter. */
+ if( this->parameters ) {
+ astWriteObject( channel, "Params", 1, 0, this->parameters, "KeyMap holding "
+ "parameter definitions" );
+ }
+}
+
+
+
+
+
+
+/* Standard class functions. */
+/* ========================= */
+/* Implement the astIsATable and astCheckTable functions using the macros
+ defined for this purpose in the "object.h" header file. */
+astMAKE_ISA(Table,KeyMap)
+astMAKE_CHECK(Table)
+
+AstTable *astTable_( const char *options, int *status, ...) {
+/*
+*++
+* Name:
+c astTable
+f AST_TABLE
+
+* Purpose:
+* Create a Table.
+
+* Type:
+* Public function.
+
+* Synopsis:
+c #include "table.h"
+c AstTable *astTable( const char *options, ... )
+f RESULT = AST_TABLE( OPTIONS, STATUS )
+
+* Class Membership:
+* Table constructor.
+
+* Description:
+* This function creates a new empty Table and optionally initialises
+* its attributes.
+*
+* The Table class is a type of KeyMap that represents a two-dimensional
+* table of values. The
+c astMapGet... and astMapPut...
+f AST_MAPGET... and AST_MAPPUT...
+* methods provided by the KeyMap class should be used for storing and
+* retrieving values from individual cells within a Table. Each entry
+* in the KeyMap represents a single cell of the table and has an
+* associated key of the form "<COL>(i)" where "<COL>" is the name of a
+* table column and "i" is the row index (the first row is row 1). Keys
+* of this form should always be used when using KeyMap methods to access
+* entries within a Table.
+*
+* Columns must be declared using the
+c astAddColumn
+f AST_ADDCOLUMN
+* method before values can be stored within them. This also fixes the
+* type and shape of the values that may be stored in any cell of the
+* column. Cells may contain scalar or vector values of any data type
+* supported by the KeyMap class. Multi-dimensional arrays may also be
+* stored, but these must be vectorised when storing and retrieving
+* them within a table cell. All cells within a single column must
+* have the same type and shape (specified when the column is declared).
+*
+* Tables may have parameters that describe global properties of the
+* entire table. These are stored as entries in the parent KeyMap and
+* can be access using the get and set method of the KeyMap class.
+* However, parameters must be declared using the
+c astAddParameter
+f AST_ADDPARAMETER
+* method before being accessed.
+*
+* Note - since accessing entries within a KeyMap is a relatively slow
+* process, it is not recommended to use the Table class to store
+* very large tables.
+
+* Parameters:
+c options
+f OPTIONS = CHARACTER * ( * ) (Given)
+c Pointer to a null-terminated string containing an optional
+c comma-separated list of attribute assignments to be used for
+c initialising the new Table. The syntax used is identical to
+c that for the astSet function and may include "printf" format
+c specifiers identified by "%" symbols in the normal way.
+f A character string containing an optional comma-separated
+f list of attribute assignments to be used for initialising the
+f new Table. The syntax used is identical to that for the
+f AST_SET routine.
+c ...
+c If the "options" string contains "%" format specifiers, then
+c an optional list of additional arguments may follow it in
+c order to supply values to be substituted for these
+c specifiers. The rules for supplying these are identical to
+c those for the astSet function (and for the C "printf"
+c function).
+f STATUS = INTEGER (Given and Returned)
+f The global status.
+
+* Returned Value:
+c astTable()
+f AST_TABLE = INTEGER
+* A pointer to the new Table.
+
+* Notes:
+* - A null Object pointer (AST__NULL) will be returned if this
+c function is invoked with the AST error status set, or if it
+f function is invoked with STATUS set to an error value, or if it
+* should fail for any reason.
+
+* Status Handling:
+* The protected interface to this function includes an extra
+* parameter at the end of the parameter list described above. This
+* parameter is a pointer to the integer inherited status
+* variable: "int *status".
+
+*--
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstTable *new; /* Pointer to new Table */
+ va_list args; /* Variable argument list */
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(NULL);
+
+/* Check the global status. */
+ if ( !astOK ) return NULL;
+
+/* Initialise the Table, allocating memory and initialising the
+ virtual function table as well if necessary. */
+ new = astInitTable( NULL, sizeof( AstTable ), !class_init, &class_vtab,
+ "Table" );
+
+/* If successful, note that the virtual function table has been
+ initialised. */
+ if ( astOK ) {
+ class_init = 1;
+
+/* Obtain the variable argument list and pass it along with the options string
+ to the astVSet method to initialise the new Table's attributes. */
+ va_start( args, status );
+ astVSet( new, options, NULL, args );
+ va_end( args );
+
+/* If an error occurred, clean up by deleting the new object. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return a pointer to the new Table. */
+ return new;
+}
+
+AstTable *astTableId_( const char *options, ... ) {
+/*
+* Name:
+* astTableId_
+
+* Purpose:
+* Create a Table.
+
+* Type:
+* Private function.
+
+* Synopsis:
+* #include "table.h"
+* AstTable *astTableId_( const char *options, ... )
+
+* Class Membership:
+* Table constructor.
+
+* Description:
+* This function implements the external (public) interface to the
+* astTable constructor function. It returns an ID value (instead
+* of a true C pointer) to external users, and must be provided
+* because astTable_ has a variable argument list which cannot be
+* encapsulated in a macro (where this conversion would otherwise
+* occur).
+*
+* The variable argument list also prevents this function from
+* invoking astTable_ directly, so it must be a re-implementation
+* of it in all respects, except for the final conversion of the
+* result to an ID value.
+
+* Parameters:
+* As for astTable_.
+
+* Returned Value:
+* The ID value associated with the new Table.
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstTable *new; /* Pointer to new Table */
+ va_list args; /* Variable argument list */
+
+ int *status; /* Pointer to inherited status value */
+
+/* Get a pointer to the inherited status value. */
+ status = astGetStatusPtr;
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(NULL);
+
+/* Check the global status. */
+ if ( !astOK ) return NULL;
+
+/* Initialise the Table, allocating memory and initialising the
+ virtual function table as well if necessary. */
+ new = astInitTable( NULL, sizeof( AstTable ), !class_init, &class_vtab,
+ "Table" );
+
+/* If successful, note that the virtual function table has been
+ initialised. */
+ if ( astOK ) {
+ class_init = 1;
+
+/* Obtain the variable argument list and pass it along with the options string
+ to the astVSet method to initialise the new Table's attributes. */
+ va_start( args, options );
+ astVSet( new, options, NULL, args );
+ va_end( args );
+
+/* If an error occurred, clean up by deleting the new object. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return an ID value for the new Table. */
+ return astMakeId( new );
+}
+
+AstTable *astInitTable_( void *mem, size_t size, int init,
+ AstTableVtab *vtab, const char *name, int *status ) {
+/*
+*+
+* Name:
+* astInitTable
+
+* Purpose:
+* Initialise a Table.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "table.h"
+* AstTable *astInitTable( void *mem, size_t size, int init,
+* AstTableVtab *vtab, const char *name )
+
+* Class Membership:
+* Table initialiser.
+
+* Description:
+* This function is provided for use by class implementations to initialise
+* a new Table object. It allocates memory (if necessary) to accommodate
+* the Table plus any additional data associated with the derived class.
+* It then initialises a Table structure at the start of this memory. If
+* the "init" flag is set, it also initialises the contents of a virtual
+* function table for a Table at the start of the memory passed via the
+* "vtab" parameter.
+
+* Parameters:
+* mem
+* A pointer to the memory in which the Table is to be initialised.
+* This must be of sufficient size to accommodate the Table data
+* (sizeof(Table)) plus any data used by the derived class. If a value
+* of NULL is given, this function will allocate the memory itself using
+* the "size" parameter to determine its size.
+* size
+* The amount of memory used by the Table (plus derived class data).
+* This will be used to allocate memory if a value of NULL is given for
+* the "mem" parameter. This value is also stored in the Table
+* structure, so a valid value must be supplied even if not required for
+* allocating memory.
+* init
+* A logical flag indicating if the Table's virtual function table is
+* to be initialised. If this value is non-zero, the virtual function
+* table will be initialised by this function.
+* vtab
+* Pointer to the start of the virtual function table to be associated
+* with the new Table.
+* name
+* Pointer to a constant null-terminated character string which contains
+* the name of the class to which the new object belongs (it is this
+* pointer value that will subsequently be returned by the astGetClass
+* method).
+
+* Returned Value:
+* A pointer to the new Table.
+
+* Notes:
+* - A null pointer will be returned if this function is invoked with the
+* global error status set, or if it should fail for any reason.
+*-
+*/
+
+/* Local Variables: */
+ AstTable *new; /* Pointer to new Table */
+
+/* Check the global status. */
+ if ( !astOK ) return NULL;
+
+/* If necessary, initialise the virtual function table. */
+ if ( init ) astInitTableVtab( vtab, name );
+
+/* Initialise. */
+ new = NULL;
+
+/* Initialise a KeyMap structure (the parent class) as the first component
+ within the Table structure, allocating memory if necessary. Specify that
+ the KeyMap should be defined in both the forward and inverse directions. */
+ new = (AstTable *) astInitKeyMap( mem, size, 0, (AstKeyMapVtab *) vtab,
+ name );
+ if ( astOK ) {
+
+/* Initialise the Table data. */
+/* ---------------------------- */
+ new->nrow = 0;
+ new->columns = astKeyMap( "KeyCase=0,Sortby=AgeDown", status );
+ new->parameters = astKeyMap( "KeyCase=0,Sortby=AgeDown", status );
+
+/* Tables require the KeyCase attribute to be zero. */
+ (*parent_setkeycase)( (AstKeyMap *) new, 0, status );
+
+/* If an error occurred, clean up by deleting the new Table. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return a pointer to the new Table. */
+ return new;
+}
+
+AstTable *astLoadTable_( void *mem, size_t size, AstTableVtab *vtab,
+ const char *name, AstChannel *channel, int *status ) {
+/*
+*+
+* Name:
+* astLoadTable
+
+* Purpose:
+* Load a Table.
+
+* Type:
+* Protected function.
+
+* Synopsis:
+* #include "table.h"
+* AstTable *astLoadTable( void *mem, size_t size, AstTableVtab *vtab,
+* const char *name, AstChannel *channel )
+
+* Class Membership:
+* Table loader.
+
+* Description:
+* This function is provided to load a new Table using data read
+* from a Channel. It first loads the data used by the parent class
+* (which allocates memory if necessary) and then initialises a
+* Table structure in this memory, using data read from the input
+* Channel.
+*
+* If the "init" flag is set, it also initialises the contents of a
+* virtual function table for a Table at the start of the memory
+* passed via the "vtab" parameter.
+
+
+* Parameters:
+* mem
+* A pointer to the memory into which the Table is to be
+* loaded. This must be of sufficient size to accommodate the
+* Table data (sizeof(Table)) plus any data used by derived
+* classes. If a value of NULL is given, this function will
+* allocate the memory itself using the "size" parameter to
+* determine its size.
+* size
+* The amount of memory used by the Table (plus derived class
+* data). This will be used to allocate memory if a value of
+* NULL is given for the "mem" parameter. This value is also
+* stored in the Table structure, so a valid value must be
+* supplied even if not required for allocating memory.
+*
+* If the "vtab" parameter is NULL, the "size" value is ignored
+* and sizeof(AstTable) is used instead.
+* vtab
+* Pointer to the start of the virtual function table to be
+* associated with the new Table. If this is NULL, a pointer
+* to the (static) virtual function table for the Table class
+* is used instead.
+* name
+* Pointer to a constant null-terminated character string which
+* contains the name of the class to which the new object
+* belongs (it is this pointer value that will subsequently be
+* returned by the astGetClass method).
+*
+* If the "vtab" parameter is NULL, the "name" value is ignored
+* and a pointer to the string "Table" is used instead.
+
+* Returned Value:
+* A pointer to the new Table.
+
+* Notes:
+* - A null pointer will be returned if this function is invoked
+* with the global error status set, or if it should fail for any
+* reason.
+*-
+*/
+
+/* Local Variables: */
+ astDECLARE_GLOBALS /* Pointer to thread-specific global data */
+ AstTable *new; /* Pointer to the new Table */
+
+/* Initialise. */
+ new = NULL;
+
+/* Check the global error status. */
+ if ( !astOK ) return new;
+
+/* Get a pointer to the thread specific global data structure. */
+ astGET_GLOBALS(channel);
+
+/* If a NULL virtual function table has been supplied, then this is
+ the first loader to be invoked for this Table. In this case the
+ Table belongs to this class, so supply appropriate values to be
+ passed to the parent class loader (and its parent, etc.). */
+ if ( !vtab ) {
+ size = sizeof( AstTable );
+ vtab = &class_vtab;
+ name = "Table";
+
+/* If required, initialise the virtual function table for this class. */
+ if ( !class_init ) {
+ astInitTableVtab( vtab, name );
+ class_init = 1;
+ }
+ }
+
+/* Invoke the parent class loader to load data for all the ancestral
+ classes of the current one, returning a pointer to the resulting
+ partly-built Table. */
+ new = astLoadKeyMap( mem, size, (AstKeyMapVtab *) vtab, name,
+ channel );
+
+ if ( astOK ) {
+
+/* Read input data. */
+/* ================ */
+/* Request the input Channel to read all the input data appropriate to
+ this class into the internal "values list". */
+ astReadClassData( channel, "Table" );
+
+/* Now read each individual data item from this list and use it to
+ initialise the appropriate instance variable(s) for this class. */
+
+/* The number of rows. */
+ new->nrow = astReadInt( channel, "nrow", 0 );
+
+/* KeyMap holding columns definitions. */
+ new->columns = astReadObject( channel, "columns", NULL );
+
+/* KeyMap holding parameter definitions. */
+ new->parameters = astReadObject( channel, "params", NULL );
+
+/* If an error occurred, clean up by deleting the new Table. */
+ if ( !astOK ) new = astDelete( new );
+ }
+
+/* Return the new Table pointer. */
+ return new;
+}
+
+/* Virtual function interfaces. */
+/* ============================ */
+/* These provide the external interface to the virtual functions defined by
+ this class. Each simply checks the global error status and then locates and
+ executes the appropriate member function, using the function pointer stored
+ in the object's virtual function table (this pointer is located using the
+ astMEMBER macro defined in "object.h").
+
+ Note that the member function may not be the one defined here, as it may
+ have been over-ridden by a derived class. However, it should still have the
+ same interface. */
+
+void astAddColumn_( AstTable *this, const char *name, int type,
+ int ndim, int *dims, const char *unit, int *status ) {
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,AddColumn))(this,name,type,ndim,dims,unit,status);
+}
+void astAddParameter_( AstTable *this, const char *name, int *status ) {
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,AddParameter))(this,name,status);
+}
+void astRemoveColumn_( AstTable *this, const char *name, int *status ){
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,RemoveColumn))(this,name,status);
+}
+void astRemoveParameter_( AstTable *this, const char *name, int *status ){
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,RemoveParameter))(this,name,status);
+}
+void astRemoveRow_( AstTable *this, int index, int *status ){
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,RemoveRow))(this,index,status);
+}
+void astPurgeRows_( AstTable *this, int *status ){
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,PurgeRows))(this,status);
+}
+int astGetNcolumn_( AstTable *this, int *status ) {
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,GetNcolumn))( this, status );
+}
+int astGetNparameter_( AstTable *this, int *status ) {
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,GetNparameter))( this, status );
+}
+const char *astColumnName_( AstTable *this, int index, int *status ){
+ if ( !astOK ) return NULL;
+ return (**astMEMBER(this,Table,ColumnName))(this,index,status);
+}
+const char *astParameterName_( AstTable *this, int index, int *status ){
+ if ( !astOK ) return NULL;
+ return (**astMEMBER(this,Table,ParameterName))(this,index,status);
+}
+int astGetColumnType_( AstTable *this, const char *column, int *status ){
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,GetColumnType))(this,column,status);
+}
+const char *astGetColumnUnit_( AstTable *this, const char *column, int *status ){
+ if ( !astOK ) return NULL;
+ return (**astMEMBER(this,Table,GetColumnUnit))(this,column,status);
+}
+int astGetColumnLenC_( AstTable *this, const char *column, int *status ){
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,GetColumnLenC))(this,column,status);
+}
+int astGetColumnLength_( AstTable *this, const char *column, int *status ){
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,GetColumnLength))(this,column,status);
+}
+int astGetColumnNdim_( AstTable *this, const char *column, int *status ){
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,GetColumnNdim))(this,column,status);
+}
+void astColumnShape_( AstTable *this, const char *column, int mxdim,
+ int *ndim, int *dims, int *status ){
+ if ( !astOK ) return;
+ (**astMEMBER(this,Table,ColumnShape))( this, column, mxdim, ndim,
+ dims, status );
+}
+AstKeyMap *astColumnProps_( AstTable *this, int *status ){
+ if ( !astOK ) return NULL;
+ return (**astMEMBER(this,Table,ColumnProps))(this,status);
+}
+AstKeyMap *astParameterProps_( AstTable *this, int *status ){
+ if ( !astOK ) return NULL;
+ return (**astMEMBER(this,Table,ParameterProps))(this,status);
+}
+int astHasColumn_( AstTable *this, const char *column, int *status ){
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,HasColumn))(this,column,status);
+}
+int astHasParameter_( AstTable *this, const char *parameter, int *status ){
+ if ( !astOK ) return 0;
+ return (**astMEMBER(this,Table,HasParameter))(this,parameter,status);
+}