1 /*
2 *class++
3 * Name:
4 * Table
5
6 * Purpose:
7 * A 2-dimensional table of values.
8
9 * Constructor Function:
10 c astTable
11 f AST_TABLE
12
13 * Description:
14 * The Table class is a type of KeyMap that represents a two-dimensional
15 * table of values. The
16 c astMapGet... and astMapPut...
17 f AST_MAPGET... and AST_MAPPUT...
18 * methods provided by the KeyMap class should be used for storing and
19 * retrieving values from individual cells within a Table. Each entry
20 * in the KeyMap represents a single cell of the table and has an
21 * associated key of the form "<COL>(i)" where "<COL>" is the
22 * upper-case name of a table column and "i" is the row index (the
23 * first row is row 1). Keys of this form should always be used when
24 * using KeyMap methods to access entries within a Table.
25 *
26 * Columns must be declared using the
27 c astAddColumn
28 f AST_ADDCOLUMN
29 * method before values can be stored within them. This also fixes the
30 * type and shape of the values that may be stored in any cell of the
31 * column. Cells may contain scalar or vector values of any data type
32 * supported by the KeyMap class. Multi-dimensional arrays may also be
33 * stored, but these must be vectorised when storing and retrieving
34 * them within a table cell. All cells within a single column must
35 * have the same type and shape, as specified when the column is added
36 * to the Table.
37 *
38 * Tables may have parameters that describe global properties of the
39 * entire table. These are stored as entries in the parent KeyMap and
40 * can be access using the get and set method of the KeyMap class.
41 * However, parameters must be declared using the
42 c astAddParameter
43 f AST_ADDPARAMETER
44 * method before being accessed.
45 *
46 * Note - since accessing entries within a KeyMap is a relatively slow
47 * process, it is not recommended to use the Table class to store
48 * very large tables.
49
50 * Inheritance:
51 * The Table class inherits from the KeyMap class.
52
53 * Attributes:
54 * In addition to those attributes common to all KeyMaps, every
55 * Table also has the following attributes:
56 *
57 * - ColumnLenC(column): The largest string length of any value in a column
58 * - ColumnLength(column): The number of elements in each value in a column
59 * - ColumnNdim(column): The number of axes spanned by each value in a column
60 * - ColumnType(column): The data type of each value in a column
61 * - ColumnUnit(column): The unit string describing each value in a column
62 * - Ncolumn: The number of columns currently in the Table
63 * - Nrow: The number of rows currently in the Table
64 * - Nparameter: The number of global parameters currently in the Table
65
66 * Functions:
67 c In addition to those functions applicable to all KeyMaps, the
68 c following functions may also be applied to all Tables:
69 f In addition to those routines applicable to all KeyMaps, the
70 f following routines may also be applied to all Tables:
71 *
72 c - astAddColumn: Add a new column definition to a Table
73 c - astAddParameter: Add a new global parameter definition to a Table
74 c - astColumnName: Return the name of the column with a given index
75 c - astColumnShape: Return the shape of the values in a named column
76 c - astHasColumn: Checks if a column exists in a Table
77 c - astHasParameter: Checks if a global parameter exists in a Table
78 c - astParameterName: Return the name of the parameter with a given index
79 c - astPurgeRows: Remove all empty rows from a Table
80 c - astRemoveColumn: Remove a column from a Table
81 c - astRemoveParameter: Remove a global parameter from a Table
82 c - astRemoveRow: Remove a row from a Table
83 f - AST_ADDCOLUMN: Add a new column definition to a Table
84 f - AST_ADDPARAMETER: Add a new global parameter definition to a Table
85 f - AST_COLUMNNAME: Return the name of the column with a given index
86 f - AST_COLUMNSHAPE: Return the shape of the values in a named column
87 f - AST_HASCOLUMN: Checks if a column exists in a Table
88 f - AST_HASPARAMETER: Checks if a global parameter exists in a Table
89 f - AST_PARAMETERNAME: Return the name of the parameter with a given index
90 f - AST_PURGEROWS: Remove all empty rows from a Table
91 f - AST_REMOVECOLUMN: Remove a column from a Table
92 f - AST_REMOVEPARAMETER: Remove a global parameter from a Table
93 f - AST_REMOVEROW: Remove a row from a Table
94
95 * Copyright:
96 * Copyright (C) 2010-2011 Science & Technology Facilities Council.
97 * All Rights Reserved.
98
99 * Licence:
100 * This program is free software: you can redistribute it and/or
101 * modify it under the terms of the GNU Lesser General Public
102 * License as published by the Free Software Foundation, either
103 * version 3 of the License, or (at your option) any later
104 * version.
105 *
106 * This program is distributed in the hope that it will be useful,
107 * but WITHOUT ANY WARRANTY; without even the implied warranty of
108 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
109 * GNU Lesser General Public License for more details.
110 *
111 * You should have received a copy of the GNU Lesser General
112 * License along with this program. If not, see
113 * <http://www.gnu.org/licenses/>.
114
115 * Authors:
116 * DSB: David S. Berry (Starlink)
117
118 * History:
119 * 22-NOV-2010 (DSB):
120 * Original version.
121 * 13-MAY-2011 (DSB):
122 * Added support for table parameters.
123 * 16-NOV-2013 (DSB):
124 * Fix bug in forming keys in GetColumnLenC.
125 *class--
126 */
127
128 /* Module Macros. */
129 /* ============== */
130 /* Set the name of the class we are implementing. This indicates to
131 the header files that define class interfaces that they should make
132 "protected" symbols available. */
133 #define astCLASS Table
134
135 /* Fixed KeyMap entry names */
136 #define LENGTH "Length"
137 #define NAME "Name"
138 #define NROW "Nrow"
139 #define SHAPE "Shape"
140 #define SIZE "Size"
141 #define TYPE "Type"
142 #define UNIT "Unit"
143
144 /* A function macro that puts quotes around a value */
145 #define STRING(w) #w
146
147 /* Include files. */
148 /* ============== */
149 /* Interface definitions. */
150 /* ---------------------- */
151
152 #include "globals.h" /* Thread-safe global data access */
153 #include "error.h" /* Error reporting facilities */
154 #include "memory.h" /* Memory allocation facilities */
155 #include "object.h" /* Base Object class */
156 #include "keymap.h" /* Coordinate keymaps (parent class) */
157 #include "channel.h" /* I/O channels */
158 #include "table.h" /* Interface definition for this class */
159
160
161 /* Error code definitions. */
162 /* ----------------------- */
163 #include "ast_err.h" /* AST error codes */
164
165 /* C header files. */
166 /* --------------- */
167 #include <ctype.h>
168 #include <stdarg.h>
169 #include <stddef.h>
170 #include <stdio.h>
171 #include <string.h>
172
173
174 /* Module Variables. */
175 /* ================= */
176
177 /* Address of this static variable is used as a unique identifier for
178 member of this class. */
179 static int class_check;
180
181 /* Pointers to parent class methods which are extended by this class. */
182 static const char *(* parent_getattrib)( AstObject *, const char *, int * );
183 static void (* parent_setkeycase)( AstKeyMap *, int, int * );
184 static void (* parent_clearkeycase)( AstKeyMap *, int * );
185 static int (* parent_equal)( AstObject *, AstObject *, int * );
186 static int (* parent_getobjsize)( AstObject *, int * );
187 static int (* parent_mapget0a)( AstKeyMap *, const char *, AstObject * *, int *);
188 static int (* parent_mapget0c)( AstKeyMap *, const char *, const char **, int *);
189 static int (* parent_mapget0d)( AstKeyMap *, const char *, double *, int *);
190 static int (* parent_mapget0f)( AstKeyMap *, const char *, float *, int *);
191 static int (* parent_mapget0i)( AstKeyMap *, const char *, int *, int *);
192 static int (* parent_mapget0p)( AstKeyMap *, const char *, void **, int *);
193 static int (* parent_mapget0b)( AstKeyMap *, const char *, unsigned char *, int *);
194 static int (* parent_mapget0s)( AstKeyMap *, const char *, short int *, int *);
195 static int (* parent_mapget1a)( AstKeyMap *, const char *, int, int *, AstObject **, int * );
196 static int (* parent_mapget1c)( AstKeyMap *, const char *, int, int, int *, char *, int * );
197 static int (* parent_mapget1d)( AstKeyMap *, const char *, int, int *, double *, int * );
198 static int (* parent_mapget1f)( AstKeyMap *, const char *, int, int *, float *, int * );
199 static int (* parent_mapget1i)( AstKeyMap *, const char *, int, int *, int *, int * );
200 static int (* parent_mapget1p)( AstKeyMap *, const char *, int, int *, void **, int * );
201 static int (* parent_mapget1s)( AstKeyMap *, const char *, int, int *, short int *, int * );
202 static int (* parent_mapget1b)( AstKeyMap *, const char *, int, int *, unsigned char *, int * );
203 static int (* parent_mapgetelema)( AstKeyMap *, const char *, int, AstObject **, int * );
204 static int (* parent_mapgetelemc)( AstKeyMap *, const char *, int, int, char *, int * );
205 static int (* parent_mapgetelemd)( AstKeyMap *, const char *, int, double *, int * );
206 static int (* parent_mapgetelemf)( AstKeyMap *, const char *, int, float *, int * );
207 static int (* parent_mapgetelemi)( AstKeyMap *, const char *, int, int *, int * );
208 static int (* parent_mapgetelemp)( AstKeyMap *, const char *, int, void **, int * );
209 static int (* parent_mapgetelems)( AstKeyMap *, const char *, int, short int *, int * );
210 static int (* parent_mapgetelemb)( AstKeyMap *, const char *, int, unsigned char *, int * );
211 static int (* parent_testattrib)( AstObject *, const char *, int * );
212 static void (* parent_clearattrib)( AstObject *, const char *, int * );
213 static void (* parent_mapput0a)( AstKeyMap *, const char *, AstObject *, const char *, int *);
214 static void (* parent_mapput0c)( AstKeyMap *, const char *, const char *, const char *, int *);
215 static void (* parent_mapput0d)( AstKeyMap *, const char *, double, const char *, int *);
216 static void (* parent_mapput0f)( AstKeyMap *, const char *, float, const char *, int *);
217 static void (* parent_mapput0i)( AstKeyMap *, const char *, int, const char *, int *);
218 static void (* parent_mapput0p)( AstKeyMap *, const char *, void *, const char *, int *);
219 static void (* parent_mapput0b)( AstKeyMap *, const char *, unsigned char, const char *, int *);
220 static void (* parent_mapput0s)( AstKeyMap *, const char *, short int, const char *, int *);
221 static void (* parent_mapput1a)( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * );
222 static void (* parent_mapput1c)( AstKeyMap *, const char *, int, const char *const [], const char *, int * );
223 static void (* parent_mapput1d)( AstKeyMap *, const char *, int, const double *, const char *, int * );
224 static void (* parent_mapput1f)( AstKeyMap *, const char *, int, const float *, const char *, int * );
225 static void (* parent_mapput1i)( AstKeyMap *, const char *, int, const int *, const char *, int * );
226 static void (* parent_mapput1p)( AstKeyMap *, const char *, int, void *const [], const char *, int * );
227 static void (* parent_mapput1b)( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * );
228 static void (* parent_mapput1s)( AstKeyMap *, const char *, int, const short int *, const char *, int * );
229 static void (* parent_mapputelema)( AstKeyMap *, const char *, int, AstObject *, int * );
230 static void (* parent_mapputelemc)( AstKeyMap *, const char *, int, const char *, int * );
231 static void (* parent_mapputelemd)( AstKeyMap *, const char *, int, double, int * );
232 static void (* parent_mapputelemf)( AstKeyMap *, const char *, int, float, int * );
233 static void (* parent_mapputelemi)( AstKeyMap *, const char *, int, int, int * );
234 static void (* parent_mapputelemp)( AstKeyMap *, const char *, int, void *, int * );
235 static void (* parent_mapputelemb)( AstKeyMap *, const char *, int, unsigned char, int * );
236 static void (* parent_mapputelems)( AstKeyMap *, const char *, int, short int, int * );
237 static void (* parent_mapremove)( AstKeyMap *, const char *, int * );
238 static void (* parent_setattrib)( AstObject *, const char *, int * );
239 static void (* parent_mapputu)( AstKeyMap *, const char *, const char *, int * );
240
241 #if defined(THREAD_SAFE)
242 static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * );
243 #endif
244
245
246 /* Define macros for accessing each item of thread specific global data. */
247 #ifdef THREAD_SAFE
248
249 /* Define how to initialise thread-specific globals. */
250 #define GLOBAL_inits \
251 globals->Class_Init = 0; \
252 globals->GetAttrib_Buff[ 0 ] = 0;
253
254 /* Create the function that initialises global data for this module. */
255 astMAKE_INITGLOBALS(Table)
256
257 /* Define macros for accessing each item of thread specific global data. */
258 #define class_init astGLOBAL(Table,Class_Init)
259 #define class_vtab astGLOBAL(Table,Class_Vtab)
260 #define getattrib_buff astGLOBAL(Table,GetAttrib_Buff)
261
262
263
264 /* If thread safety is not needed, declare and initialise globals at static
265 variables. */
266 #else
267
268 static char getattrib_buff[ 101 ];
269
270 /* Define the class virtual function table and its initialisation flag
271 as static variables. */
272 static AstTableVtab class_vtab; /* Virtual function table */
273 static int class_init = 0; /* Virtual function table initialised? */
274
275 #endif
276
277 /* External Interface Function Prototypes. */
278 /* ======================================= */
279 /* The following functions have public prototypes only (i.e. no
280 protected prototypes), so we must provide local prototypes for use
281 within this module. */
282 AstTable *astTableId_( const char *, ... );
283
284 /* Prototypes for Private Member Functions. */
285 /* ======================================== */
286 static AstKeyMap *ColumnProps( AstTable *, int * );
287 static AstKeyMap *ParameterProps( AstTable *, int * );
288 static const char *ColumnName( AstTable *, int index, int * );
289 static const char *ParameterName( AstTable *, int index, int * );
290 static const char *GetColumnUnit( AstTable *, const char *, int * );
291 static const char *TypeString( int );
292 static int Equal( AstObject *, AstObject *, int * );
293 static int GetColumnLenC( AstTable *, const char *, int * );
294 static int GetColumnLength( AstTable *, const char *, int * );
295 static int GetColumnNdim( AstTable *, const char *, int * );
296 static int GetColumnType( AstTable *, const char *, int * );
297 static int GetNcolumn( AstTable *, int * );
298 static int GetNparameter( AstTable *, int * );
299 static int GetObjSize( AstObject *, int * );
300 static int HasColumn( AstTable *, const char *, int *);
301 static int HasParameter( AstTable *, const char *, int *);
302 static int MapGet0A( AstKeyMap *, const char *, AstObject **, int * );
303 static int MapGet0B( AstKeyMap *, const char *, unsigned char *, int * );
304 static int MapGet0C( AstKeyMap *, const char *, const char **, int * );
305 static int MapGet0D( AstKeyMap *, const char *, double *, int * );
306 static int MapGet0F( AstKeyMap *, const char *, float *, int * );
307 static int MapGet0I( AstKeyMap *, const char *, int *, int * );
308 static int MapGet0P( AstKeyMap *, const char *, void **, int * );
309 static int MapGet0S( AstKeyMap *, const char *, short int *, int * );
310 static int MapGet1A( AstKeyMap *, const char *, int, int *, AstObject **, int * );
311 static int MapGet1B( AstKeyMap *, const char *, int, int *, unsigned char *, int * );
312 static int MapGet1C( AstKeyMap *, const char *, int, int, int *, char *, int * );
313 static int MapGet1D( AstKeyMap *, const char *, int, int *, double *, int * );
314 static int MapGet1F( AstKeyMap *, const char *, int, int *, float *, int * );
315 static int MapGet1I( AstKeyMap *, const char *, int, int *, int *, int * );
316 static int MapGet1P( AstKeyMap *, const char *, int, int *, void **, int * );
317 static int MapGet1S( AstKeyMap *, const char *, int, int *, short int *, int * );
318 static int MapGetElemA( AstKeyMap *, const char *, int, AstObject **, int * );
319 static int MapGetElemB( AstKeyMap *, const char *, int, unsigned char *, int * );
320 static int MapGetElemC( AstKeyMap *, const char *, int, int, char *, int * );
321 static int MapGetElemD( AstKeyMap *, const char *, int, double *, int * );
322 static int MapGetElemF( AstKeyMap *, const char *, int, float *, int * );
323 static int MapGetElemI( AstKeyMap *, const char *, int, int *, int * );
324 static int MapGetElemP( AstKeyMap *, const char *, int, void **, int * );
325 static int MapGetElemS( AstKeyMap *, const char *, int, short int *, int * );
326 static int ParseKey( AstTable *, const char *, int, char *, int *, AstKeyMap **, const char *, int * );
327 static void AddColumn( AstTable *, const char *, int, int, int *, const char *, int * );
328 static void AddParameter( AstTable *, const char *, int * );
329 static void ColumnShape( AstTable *, const char *, int, int *, int *, int *);
330 static void Copy( const AstObject *, AstObject *, int * );
331 static void Delete( AstObject *, int * );
332 static void Dump( AstObject *, AstChannel *, int * );
333 static void MapPut0A( AstKeyMap *, const char *, AstObject *, const char *, int * );
334 static void MapPut0B( AstKeyMap *, const char *, unsigned char, const char *, int * );
335 static void MapPut0C( AstKeyMap *, const char *, const char *, const char *, int * );
336 static void MapPut0D( AstKeyMap *, const char *, double, const char *, int * );
337 static void MapPut0F( AstKeyMap *, const char *, float, const char *, int * );
338 static void MapPut0I( AstKeyMap *, const char *, int, const char *, int * );
339 static void MapPut0P( AstKeyMap *, const char *, void *, const char *, int * );
340 static void MapPut0S( AstKeyMap *, const char *, short int, const char *, int * );
341 static void MapPut1A( AstKeyMap *, const char *, int, AstObject *const [], const char *, int * );
342 static void MapPut1B( AstKeyMap *, const char *, int, const unsigned char *, const char *, int * );
343 static void MapPut1C( AstKeyMap *, const char *, int, const char *const [], const char *, int * );
344 static void MapPut1D( AstKeyMap *, const char *, int, const double *, const char *, int * );
345 static void MapPut1F( AstKeyMap *, const char *, int, const float *, const char *, int * );
346 static void MapPut1I( AstKeyMap *, const char *, int, const int *, const char *, int * );
347 static void MapPut1P( AstKeyMap *, const char *, int, void *const [], const char *, int * );
348 static void MapPut1S( AstKeyMap *, const char *, int, const short int *, const char *, int * );
349 static void MapPutElemA( AstKeyMap *, const char *, int, AstObject *, int * );
350 static void MapPutElemB( AstKeyMap *, const char *, int, unsigned char, int * );
351 static void MapPutElemC( AstKeyMap *, const char *, int, const char *, int * );
352 static void MapPutElemD( AstKeyMap *, const char *, int, double, int * );
353 static void MapPutElemF( AstKeyMap *, const char *, int, float, int * );
354 static void MapPutElemI( AstKeyMap *, const char *, int, int, int * );
355 static void MapPutElemP( AstKeyMap *, const char *, int, void *, int * );
356 static void MapPutElemS( AstKeyMap *, const char *, int, short int, int * );
357 static void MapPutU( AstKeyMap *, const char *, const char *, int * );
358 static void PurgeRows( AstTable *, int * );
359 static void RemoveColumn( AstTable *, const char *, int * );
360 static void RemoveParameter( AstTable *, const char *, int * );
361 static void RemoveRow( AstTable *, int, int * );
362 static void SetKeyCase( AstKeyMap *, int, int * );
363 static void ClearKeyCase( AstKeyMap *, int * );
364
365 #if defined(THREAD_SAFE)
366 static int ManageLock( AstObject *, int, int, AstObject **, int * );
367 #endif
368
369 static const char *GetAttrib( AstObject *, const char *, int * );
370 static int TestAttrib( AstObject *, const char *, int * );
371 static void ClearAttrib( AstObject *, const char *, int * );
372 static void SetAttrib( AstObject *, const char *, int * );
373
374 static int GetNrow( AstTable *, int * );
375 static void SetNrow( AstTable *, int, int * );
376
377 static int GetNcolumn( AstTable *, int * );
378 static int GetNparameter( AstTable *, int * );
379
380
381 /* Member functions. */
382 /* ================= */
AddColumn(AstTable * this,const char * name,int type,int ndim,int * dims,const char * unit,int * status)383 static void AddColumn( AstTable *this, const char *name, int type,
384 int ndim, int *dims, const char *unit, int *status ) {
385 /*
386 *++
387 * Name:
388 c astAddColumn
389 f AST_ADDCOLUMN
390
391 * Purpose:
392 * Add a new column definition to a table.
393
394 * Type:
395 * Public virtual function.
396
397 * Synopsis:
398 c #include "table.h"
399 c void astAddColumn( AstTable *this, const char *name, int type, int ndim,
400 c int *dims, const char *unit )
401 f CALL AST_ADDCOLUMN( THIS, NAME, TYPE, NDIM, DIMS, UNIT, STATUS )
402
403 * Class Membership:
404 * Table method.
405
406 * Description:
407 * Adds the definition of a new column to the supplied table. Initially,
408 * the column is empty. Values may be added subsequently using the
409 * methods of the KeyMap class.
410
411 * Parameters:
412 c this
413 f THIS = INTEGER (Given)
414 * Pointer to the Table.
415 c name
416 f NAME = CHARACTER * ( * ) (Given)
417 * The column name. Trailing spaces are ignored (all other spaces
418 * are significant). The supplied string is converted to upper case.
419 c type
420 f TYPE = INTEGER (Given)
421 * The data type associated with the column. See "Applicability:"
422 * below.
423 c ndim
424 f NDIM = INTEGER (Given)
425 * The number of dimensions spanned by the values stored in a single
426 * cell of the column. Zero if the column holds scalar values.
427 c dims
428 f DIMS( NDIM ) = INTEGER (Given)
429 * An array holding the the lengths of each of the axes spanned by
430 * the values stored in a single cell of the column. Ignored if the
431 * column holds scalara values.
432 c unit
433 f UNIT = CHARACTER * ( * ) (Given)
434 * A string specifying the units of the column. Supply a blank
435 * string if the column is unitless.
436 f STATUS = INTEGER (Given and Returned)
437 f The global status.
438
439 * Applicability:
440 * Table
441 * Tables can hold columns with any of the following data types -
442 * AST__INTTYPE (for integer), AST__SINTTYPE (for
443 c short int),
444 f INTEGER*2),
445 * AST__BYTETYPE (for
446 c unsigned bytes - i.e. unsigned chars),
447 f bytes),
448 * AST__DOUBLETYPE (for double
449 * precision floating point), AST__FLOATTYPE (for single
450 * precision floating point), AST__STRINGTYPE (for character string),
451 * AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for
452 * arbitrary C pointer) or AST__UNDEFTYPE (for undefined values
453 * created by
454 c astMapPutU).
455 f AST_MAPPUTU).
456 * FitsTable
457 * FitsTables can hold columns with any of the following data types -
458 * AST__INTTYPE (for integer), AST__SINTTYPE (for
459 c short int),
460 f INTEGER*2),
461 * AST__BYTETYPE (for
462 c unsigned bytes - i.e. unsigned chars),
463 f bytes),
464 * AST__DOUBLETYPE (for double
465 * precision floating point), AST__FLOATTYPE (for single
466 * precision floating point), AST__STRINGTYPE (for character string).
467
468 * Notes:
469 * - This
470 c function
471 f routine
472 * returns without action if a column already exists in the Table
473 * with the supplied name and properties. However an error is
474 * reported if any of the properties differ.
475
476 *--
477 */
478
479 /* Local Variables: */
480 AstKeyMap *cols; /* KeyMap holding all column details */
481 AstKeyMap *col_km; /* KeyMap holding new column details */
482 const char *oldunit; /* Pointer to the old coumn unit string */
483 int *olddims; /* Shape of pre-existing column */
484 int idim; /* Axis index */
485 int namlen; /* Used length of "name" */
486 int nval; /* Number of values returned */
487 int oldtype; /* Data type of pre-existing column */
488
489 /* Check the global error status. */
490 if ( !astOK ) return;
491
492 /* Verify supplied values. */
493 namlen = astChrLen( name );
494 if( namlen == 0 ) {
495 astError( AST__BADKEY, "astAddColumn(%s): Illegal blank column name "
496 "supplied.", status, astGetClass( this ) );
497
498 } else if( namlen > AST__MXCOLNAMLEN ) {
499 astError( AST__BADKEY, "astAddColumn(%s): Column name '%s' is too "
500 "long (must be no more than %d characters).", status,
501 astGetClass( this ), name, AST__MXCOLNAMLEN );
502
503 } else if( ndim < 0 ) {
504 astError( AST__NAXIN, "astAddColumn(%s): No of axes (%d) for values in "
505 "new column %s is invalid.", status, astGetClass( this ),
506 ndim, name );
507
508 } else if( TypeString( type ) == NULL ) {
509 astError( AST__NAXIN, "astAddColumn(%s): Bad data type supplied (%d) "
510 "for new column %s.", status, astGetClass( this ), type,
511 name );
512
513 } else {
514 for( idim = 0; idim < ndim; idim++ ) {
515 if( dims[ idim ] < 1 ) {
516 astError( AST__DIMIN, "astAddColumn(%s): Length of axis %d (%d) "
517 "for new column %s is invalid.", status,
518 astGetClass( this ), idim + 1, dims[ idim ], name );
519 break;
520 }
521 }
522 }
523
524 /* If there is already a column with the given name, check its properties
525 match the supplied properties. */
526 if( astOK ) {
527 cols = astColumnProps( this );
528 if( astMapGet0A( cols, name, &col_km ) ) {
529
530 astMapGet0I( col_km, TYPE, &oldtype );
531 if( oldtype != type && astOK ) {
532 astError( AST__OLDCOL, "astAddColumn(%s): A column called "
533 "%s already exists in the table with a different "
534 "data type (%s).", status, astGetClass( this ),
535 name, TypeString( oldtype ) );
536 }
537
538 if( !astMapGet0C( col_km, UNIT, &oldunit ) ) oldunit = "";
539 if( strcmp( oldunit, unit ) && astOK ) {
540 astError( AST__OLDCOL, "astAddColumn(%s): A column called "
541 "%s already exists in the table with a different "
542 "unit string ('%s').", status, astGetClass( this ),
543 name, oldunit );
544 }
545
546 if( ndim != astMapLength( col_km, SHAPE ) && astOK ) {
547 astError( AST__OLDCOL, "astAddColumn(%s): A column called "
548 "%s already exists in the table with a different "
549 "number of axes (%d).", status, astGetClass( this ),
550 name, astMapLength( col_km, SHAPE ) );
551 }
552
553 if( ndim > 0 && astOK ) {
554 olddims = astMalloc( sizeof( int )*ndim );
555 (void) astMapGet1I( col_km, SHAPE, ndim, &nval, olddims );
556 for( idim = 0; idim < ndim && astOK; idim++ ) {
557 if( dims[ idim ] != olddims[ idim ] ) {
558 astError( AST__OLDCOL, "astAddColumn(%s): A column called "
559 "%s already exists in the table with a different "
560 "shape.", status, astGetClass( this ), name );
561 }
562 }
563 olddims = astFree( olddims );
564 }
565
566 /* Otherwise, add a new column to the table. */
567 } else {
568
569 /* Add a suitable entry describing the column to the Columns KeyMap. */
570 col_km = astKeyMap( " ", status );
571 astMapPut0C( col_km, NAME, name, NULL );
572 astMapPut0I( col_km, TYPE, type, NULL );
573 if( ndim ) astMapPut1I( col_km, SHAPE, ndim, dims, NULL );
574 astMapPut0C( col_km, UNIT, unit, NULL );
575
576 /* Put the column KeyMap into the KeyMap holding details of all columns.
577 Use the column name as the key. */
578 astMapPut0A( cols, name, col_km, NULL );
579 }
580
581 /* Annul the local KeyMap pointers. */
582 col_km = astAnnul( col_km );
583 cols = astAnnul( cols );
584 }
585 }
586
AddParameter(AstTable * this,const char * name,int * status)587 static void AddParameter( AstTable *this, const char *name, int *status ) {
588 /*
589 *++
590 * Name:
591 c astAddParameter
592 f AST_ADDPARAMETER
593
594 * Purpose:
595 * Add a new global parameter definition to a table.
596
597 * Type:
598 * Public virtual function.
599
600 * Synopsis:
601 c #include "table.h"
602 c void astAddParameter( AstTable *this, const char *name )
603 f CALL AST_ADDPARAMETER( THIS, NAME, STATUS )
604
605 * Class Membership:
606 * Table method.
607
608 * Description:
609 * Adds the definition of a new global parameter to the supplied
610 * table. Note, this does not store a value for the parameter. To get
611 * or set the parameter value, the methods of the paremt KeyMap class
612 * should be used, using the name of the parameter as the key.
613
614 * Parameters:
615 c this
616 f THIS = INTEGER (Given)
617 * Pointer to the Table.
618 c name
619 f NAME = CHARACTER * ( * ) (Given)
620 * The parameter name. Trailing spaces are ignored (all other spaces
621 * are significant). The supplied string is converted to upper case.
622 f STATUS = INTEGER (Given and Returned)
623 f The global status.
624
625 * Notes:
626 * - Unlike columns, the definition of a parameter does not specify its type,
627 * size or dimensionality.
628
629 *--
630 */
631
632 /* Local Variables: */
633 AstKeyMap *pars; /* KeyMap holding all parameter details */
634 int namlen; /* Used length of "name" */
635
636 /* Check the global error status. */
637 if ( !astOK ) return;
638
639 /* Verify supplied values. */
640 namlen = astChrLen( name );
641 if( namlen == 0 ) {
642 astError( AST__BADKEY, "astAddParameter(%s): Illegal blank parameter name "
643 "supplied.", status, astGetClass( this ) );
644
645 } else if( namlen > AST__MXCOLNAMLEN ) {
646 astError( AST__BADKEY, "astAddParameter(%s): Parameter name '%s' is too "
647 "long (must be no more than %d characters).", status,
648 astGetClass( this ), name, AST__MXCOLNAMLEN );
649 }
650
651 /* Do nothing if there is already a parameter with the given name. */
652 if( astOK ) {
653 pars = astParameterProps( this );
654 if( !astMapHasKey( pars, name ) ) {
655
656 /* Add a suitable entry to the Parameters KeyMap. The value is arbitrary
657 and currently unused. */
658 astMapPut0I( pars, name, 1, NULL );
659 }
660
661 /* Annul the local KeyMap pointer. */
662 pars = astAnnul( pars );
663 }
664 }
665
ClearAttrib(AstObject * this_object,const char * attrib,int * status)666 static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) {
667 /*
668 * Name:
669 * ClearAttrib
670
671 * Purpose:
672 * Clear an attribute value for a Table.
673
674 * Type:
675 * Private function.
676
677 * Synopsis:
678 * #include "table.h"
679 * void ClearAttrib( AstObject *this, const char *attrib )
680
681 * Class Membership:
682 * Table member function (over-rides the astClearAttrib protected
683 * method inherited from the KeyMap class).
684
685 * Description:
686 * This function clears the value of a specified attribute for a
687 * Table, so that the default value will subsequently be used.
688
689 * Parameters:
690 * this
691 * Pointer to the Table.
692 * attrib
693 * Pointer to a null terminated string specifying the attribute
694 * name. This should be in lower case with no surrounding white
695 * space.
696 */
697
698 /* Local Variables: */
699 AstTable *this;
700 int nc;
701 int len;
702
703 /* Check the global error status. */
704 if ( !astOK ) return;
705
706 /* Obtain a pointer to the Table structure. */
707 this = (AstTable *) this_object;
708
709 /* Get the length of the attribute string. */
710 len = strlen( attrib );
711
712 /* Check the attribute name and clear the appropriate attribute. */
713 /* None yet */
714
715 /* Define a macro to see if the attribute string matches any of the
716 read-only column attributes of this class. */
717 #define MATCH(attr) \
718 ( nc = 0, ( 0 == astSscanf( attrib, attr "(%*s)%n", &nc ) ) && \
719 ( nc >= len ) )
720
721 /* If the name was not recognised, test if it matches any of the
722 read-only attributes of this class. If it does, then report an
723 error. */
724 if ( !strcmp( attrib, "nrow" ) ||
725 !strcmp( attrib, "ncolumn" ) ||
726 !strcmp( attrib, "nparameter" ) ||
727 MATCH( "columnlenc" ) ||
728 MATCH( "columnlength" ) ||
729 MATCH( "columnndim" ) ||
730 MATCH( "columntype" ) ||
731 MATCH( "columnunit" ) ) {
732 astError( AST__NOWRT, "astClear: Invalid attempt to clear the \"%s\" "
733 "value for a %s.", status, attrib, astGetClass( this ) );
734 astError( AST__NOWRT, "This is a read-only attribute." , status);
735
736 /* If the attribute is still not recognised, pass it on to the parent
737 method for further interpretation. */
738 } else {
739 (*parent_clearattrib)( this_object, attrib, status );
740 }
741
742 #undef MATCH
743
744 }
745
ClearKeyCase(AstKeyMap * this,int * status)746 static void ClearKeyCase( AstKeyMap *this, int *status ) {
747 /*
748 * Name:
749 * ClearKeyCase
750
751 * Purpose:
752 * Clear the KeyCase attribute value for a Table.
753
754 * Type:
755 * Private function.
756
757 * Synopsis:
758 * #include "keymape.h"
759 * void ClearKeyCase( AstKeyMap *this, int *status )
760
761 * Class Membership:
762 * Table member function (over-rides the astClearKeyCase protected
763 * method inherited from the KeyMap class).
764
765 * Description:
766 * This function clears the value of the KeyCase attribute for a
767 * Table. For a Table, the KeyCase attribute cannot be changed so this
768 * function exits without action.
769
770 * Parameters:
771 * this
772 * Pointer to the Table.
773 */
774
775 }
776
ColumnName(AstTable * this,int index,int * status)777 static const char *ColumnName( AstTable *this, int index, int *status ) {
778 /*
779 *++
780 * Name:
781 c astColumnName
782 f AST_COLUMNNAME
783
784 * Purpose:
785 * Get the name of the column at a given index within the Table.
786
787 * Type:
788 * Public virtual function.
789
790 * Synopsis:
791 c #include "table.h"
792 c const char *astColumnName( AstTable *this, int index )
793 f RESULT = AST_COLUMNNAME( THIS, INDEX, STATUS )
794
795 * Class Membership:
796 * Table method.
797
798 * Description:
799 * This function returns a string holding the name of the column with
800 * the given index within the Table.
801 *
802 * This function is intended primarily as a means of iterating round all
803 * the columns in a Table. For this purpose, the number of columns in
804 * the Table is given by the Ncolumn attribute of the Table. This function
805 * could then be called in a loop, with the index value going from
806 c zero to one less than Ncolumn.
807 f one to Ncolumn.
808 *
809 * Note, the index associated with a column decreases monotonically with
810 * the age of the column: the oldest Column in the Table will have index
811 * one, and the Column added most recently to the Table will have the
812 * largest index.
813
814 * Parameters:
815 c this
816 f THIS = INTEGER (Given)
817 * Pointer to the Table.
818 c index
819 f INDEX = INTEGER (Given)
820 * The index into the list of columns. The first column has index
821 * one, and the last has index "Ncolumn".
822 f STATUS = INTEGER (Given and Returned)
823 f The global status.
824
825 * Returned Value:
826 c astColumnName()
827 c A pointer to a null-terminated string containing the
828 f AST_COLUMNNAME = CHARACTER * ( AST__SZCHR )
829 f The
830 * upper case column name.
831
832 * Notes:
833 c - The returned pointer is guaranteed to remain valid and the
834 c string to which it points will not be over-written for a total
835 c of 50 successive invocations of this function. After this, the
836 c memory containing the string may be re-used, so a copy of the
837 c string should be made if it is needed for longer than this.
838 c - A NULL pointer will be returned if this function is invoked
839 c with the AST error status set, or if it should fail for any
840 c reason.
841 f - A blank string will be returned if this function is invoked
842 f with STATUS set to an error value, or if it should fail for any
843 f reason.
844 *--
845 */
846
847 /* Local Variables: */
848 AstKeyMap *cols; /* KeyMap holding column definitions */
849 const char *result;
850
851 /* Check the global error status. */
852 if ( !astOK ) return NULL;
853
854 /* Get apointer to the KeyMap holding all column definitions. */
855 cols = astColumnProps( this );
856
857 /* Issue a more useful error message than that issued by astMapKey if the
858 index is invalid. */
859 if( index < 1 || index > astMapSize( cols ) ) {
860 astError( AST__MPIND, "astColumnName(%s): Cannot find column "
861 "%d (zero-based) of the %s - invalid index.", status,
862 astGetClass( this ), index, astGetClass( this ) );
863 }
864
865 /* Get the column name. */
866 result = astMapKey( cols, index - 1 );
867
868 /* Free resources. */
869 cols = astAnnul( cols );
870
871 /* Return a pointer to the required column name. */
872 return result;
873 }
874
ColumnProps(AstTable * this,int * status)875 static AstKeyMap *ColumnProps( AstTable *this, int *status ) {
876 /*
877 *+
878 * Name:
879 * astColumnProps
880
881 * Purpose:
882 * Returns a pointer to the KeyMap holding column properties.
883
884 * Type:
885 * Protected virtual function.
886
887 * Synopsis:
888 * #include "table.h"
889 * AstKeyMap *astColumnProps( AstTable *this )
890
891 * Class Membership:
892 * Table method.
893
894 * Description:
895 * This function returns a pointer to the KeyMap that holds
896 * definitions of all the coumns added to the Table.
897
898 * Parameters:
899 * this
900 * Pointer to the Table.
901
902 * Returned Value:
903 * A pointer to the KeyMap. It shpould be annulled using astAnnul
904 * when no longer needed.
905
906 *-
907 */
908
909 /* Check the global error status. */
910 if ( !astOK ) return NULL;
911
912 /* Return a cloned pointer to the required KeyMap. */
913 return astClone( this->columns );
914 }
915
ColumnShape(AstTable * this,const char * column,int mxdim,int * ndim,int * dims,int * status)916 static void ColumnShape( AstTable *this, const char *column, int mxdim,
917 int *ndim, int *dims, int *status ){
918 /*
919 *++
920 * Name:
921 c astColumnShape
922 f AST_COLUMNSHAPE
923
924 * Purpose:
925 * Returns the shape of the values in a named column.
926
927 * Type:
928 * Public virtual function.
929
930 * Synopsis:
931 c #include "table.h"
932 c void astColumnShape( AstTable *this, const char *column, int mxdim,
933 c int *ndim, int *dims )
934 f CALL AST_COLUMNSHAPE( THIS, COLUMN, MXDIM, NDIM, DIMS, STATUS )
935
936 * Class Membership:
937 * Table method.
938
939 * Description:
940 c This function
941 f This routine
942 * returns the number of dimensions spaned by each value in a named
943 * column of a Table, together with the length of each dimension.
944 * These are the values supplied when the column was created using
945 c astAddColumn.
946 f AST_ADDCOLUMN.
947
948 * Parameters:
949 c this
950 f THIS = INTEGER (Given)
951 * Pointer to the Table.
952 c column
953 f COLUMN = CHARACTER * ( * ) (Given)
954 * The character string holding the upper case name of the column. Trailing
955 * spaces are ignored.
956 c mxdim
957 f MXDIM = INTEGER (Given)
958 * The length of the
959 c "dims" array.
960 f DIMS array.
961 c ndim
962 f NDIM = INTEGER (Returned)
963 c Pointer to an int in which to return the
964 f The
965 * number of dimensions spanned by values in the named column.
966 * This will be zero if the column contains scalar values.
967 c dims
968 f DIMS( MXDIM ) = INTEGER (Returned)
969 c Pointer to an
970 f An
971 * array in which to return the length of each dimension. Any
972 * excess trailing elements will be filled with the value 1.
973 f STATUS = INTEGER (Given and Returned)
974 f The global status.
975
976 * Notes:
977 * - No error is reported if the requested column cannot be found in the
978 * given Table. A value of zero is returned for
979 c "ndim" and the supplied values in "dims"
980 f NDIM and the supplied values in DIMS
981 * are left unchanged.
982 * - A value of zero is returned for
983 c "ndim"
984 f NDIM
985 * if an error occurs.
986
987 *--
988 */
989
990 /* Local Variables: */
991 AstKeyMap *cols; /* Pointer to KeyMap holding all column info */
992 AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */
993 int idim; /* Axis index */
994
995 /* Initialise */
996 *ndim = 0;
997
998 /* Check the inherited status. */
999 if( !astOK ) return;
1000
1001
1002 /* Get the KeyMap holding information about the requested column. */
1003 cols = astColumnProps( this );
1004 if( astMapGet0A( cols, column, &col_km ) ) {
1005
1006 /* Get the shape of the column values. */
1007 (void) astMapGet1I( col_km, SHAPE, mxdim, ndim, dims );
1008
1009 /* Fill excess array elements with 1. */
1010 for( idim = *ndim; idim < mxdim; idim++ ) dims[ idim ] = 1;
1011
1012 /* Free resources. */
1013 col_km = astAnnul( col_km );
1014 }
1015 cols = astAnnul( cols );
1016
1017 /* If an error has occurred, set ndim to zero. */
1018 if( !astOK ) *ndim = 0;
1019
1020 }
1021
Equal(AstObject * this_object,AstObject * that_object,int * status)1022 static int Equal( AstObject *this_object, AstObject *that_object, int *status ) {
1023 /*
1024 * Name:
1025 * Equal
1026
1027 * Purpose:
1028 * Test if two Tables are equivalent.
1029
1030 * Type:
1031 * Private function.
1032
1033 * Synopsis:
1034 * #include "table.h"
1035 * int Equal( AstObject *this, AstObject *that, int *status )
1036
1037 * Class Membership:
1038 * Table member function (over-rides the astEqual protected
1039 * method inherited from the astKeyMap class).
1040
1041 * Description:
1042 * This function returns a boolean result (0 or 1) to indicate whether
1043 * two Tables are equivalent.
1044
1045 * Parameters:
1046 * this
1047 * Pointer to the first Object (a Table).
1048 * that
1049 * Pointer to the second Object.
1050 * status
1051 * Pointer to the inherited status variable.
1052
1053 * Returned Value:
1054 * One if the Tables are equivalent, zero otherwise.
1055
1056 * Notes:
1057 * - A value of zero will be returned if this function is invoked
1058 * with the global status set, or if it should fail for any reason.
1059 */
1060
1061 /* Local Variables: */
1062 AstKeyMap *this_km;
1063 AstKeyMap *that_km;
1064 AstTable *that;
1065 AstTable *this;
1066 int result;
1067
1068 /* Initialise. */
1069 result = 0;
1070
1071 /* Check the global error status. */
1072 if ( !astOK ) return result;
1073
1074 /* Obtain pointers to the two Table structures. */
1075 this = (AstTable *) this_object;
1076 that = (AstTable *) that_object;
1077
1078 /* Check the second object is a Table. We know the first is a
1079 Table since we have arrived at this implementation of the virtual
1080 function. */
1081 if( astIsATable( that ) ) {
1082
1083 /* Check the Tables are equal when compared as KeyMaps. */
1084 if( (*parent_equal)( this_object, that_object, status ) ) {
1085
1086 /* Check the Columns KeyMaps are equal. */
1087 this_km = astColumnProps( this );
1088 that_km = astColumnProps( that );
1089 result = astEqual( this_km, that_km );
1090 this_km = astAnnul( this_km );
1091 that_km = astAnnul( that_km );
1092
1093 /* Check the Parameter KeyMaps are equal. */
1094 this_km = astParameterProps( this );
1095 that_km = astParameterProps( that );
1096 result = astEqual( this_km, that_km );
1097 this_km = astAnnul( this_km );
1098 that_km = astAnnul( that_km );
1099 }
1100 }
1101
1102 /* If an error occurred, clear the result value. */
1103 if ( !astOK ) result = 0;
1104
1105 /* Return the result, */
1106 return result;
1107 }
1108
GetAttrib(AstObject * this_object,const char * attrib,int * status)1109 static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) {
1110 /*
1111 * Name:
1112 * GetAttrib
1113
1114 * Purpose:
1115 * Get the value of a specified attribute for a Table.
1116
1117 * Type:
1118 * Private function.
1119
1120 * Synopsis:
1121 * #include "table.h"
1122 * const char *GetAttrib( AstObject *this, const char *attrib, int *status )
1123
1124 * Class Membership:
1125 * Table member function (over-rides the protected astGetAttrib
1126 * method inherited from the KeyMap class).
1127
1128 * Description:
1129 * This function returns a pointer to the value of a specified
1130 * attribute for a Table, formatted as a character string.
1131
1132 * Parameters:
1133 * this
1134 * Pointer to the Table.
1135 * attrib
1136 * Pointer to a null terminated string containing the name of
1137 * the attribute whose value is required. This name should be in
1138 * lower case, with all white space removed.
1139 * status
1140 * Pointer to the inherited status variable.
1141
1142 * Returned Value:
1143 * - Pointer to a null terminated string containing the attribute
1144 * value.
1145
1146 * Notes:
1147 * - The returned string pointer may point at memory allocated
1148 * within the Table, or at static memory. The contents of the
1149 * string may be over-written or the pointer may become invalid
1150 * following a further invocation of the same function or any
1151 * modification of the Table. A copy of the string should
1152 * therefore be made if necessary.
1153 * - A NULL pointer will be returned if this function is invoked
1154 * with the global error status set, or if it should fail for any
1155 * reason.
1156 */
1157
1158 /* Local Variables: */
1159 astDECLARE_GLOBALS /* Pointer to thread-specific global data */
1160 char cname[ AST__MXCOLNAMLEN + 1 ]; /* Column name */
1161 AstTable *this; /* Pointer to the Table structure */
1162 const char *result; /* Pointer value to return */
1163 int ival; /* Int attribute value */
1164 int len; /* Length of attrib string */
1165 int nc; /* No. characters read by astSscanf */
1166
1167 /* Initialise. */
1168 result = NULL;
1169
1170 /* Check the global error status. */
1171 if ( !astOK ) return result;
1172
1173 /* Get a pointer to the thread specific global data structure. */
1174 astGET_GLOBALS(this_object);
1175
1176 /* Obtain a pointer to the Table structure. */
1177 this = (AstTable *) this_object;
1178
1179 /* Obtain the length of the attrib string. */
1180 len = strlen( attrib );
1181
1182 /* Compare "attrib" with each recognised attribute name in turn,
1183 obtaining the value of the required attribute. If necessary, write
1184 the value into "getattrib_buff" as a null terminated string in an
1185 appropriate format. Set "result" to point at the result string. */
1186
1187 /* Table properties */
1188 /* ================ */
1189
1190 /* Ncolumn */
1191 /* ------- */
1192 if( !strcmp( attrib, "ncolumn" ) ) {
1193 ival = astGetNcolumn( this );
1194 if ( astOK ) {
1195 (void) sprintf( getattrib_buff, "%d", ival );
1196 result = getattrib_buff;
1197 }
1198
1199 /* Nrow */
1200 /* ---- */
1201 } else if( !strcmp( attrib, "nrow" ) ) {
1202 ival = astGetNrow( this );
1203 if ( astOK ) {
1204 (void) sprintf( getattrib_buff, "%d", ival );
1205 result = getattrib_buff;
1206 }
1207
1208 /* Nparameter */
1209 /* ---------- */
1210 } else if( !strcmp( attrib, "nparameter" ) ) {
1211 ival = astGetNparameter( this );
1212 if ( astOK ) {
1213 (void) sprintf( getattrib_buff, "%d", ival );
1214 result = getattrib_buff;
1215 }
1216
1217
1218
1219 /* Column properties */
1220 /* ================= */
1221
1222 /* A macro that gives the scannf pattern to test for a given column
1223 property. Needed since the buffer length is defined by a macro
1224 (AST__MXCOLNAMLEN). */
1225 #define PATTERN(cnam,blen) #cnam "(%" STRING(blen) "[^()])%n"
1226
1227 /* ColumnNdim */
1228 } else if ( nc = 0,
1229 ( 1 == astSscanf( attrib, PATTERN(columnndim,AST__MXCOLNAMLEN),
1230 cname, &nc ) ) && ( nc >= len ) ) {
1231 ival = astGetColumnNdim( this, cname );
1232 if ( astOK ) {
1233 (void) sprintf( getattrib_buff, "%d", ival );
1234 result = getattrib_buff;
1235 }
1236
1237 /* ColumnLenC */
1238 } else if ( nc = 0,
1239 ( 1 == astSscanf( attrib, PATTERN(columnlenc,AST__MXCOLNAMLEN),
1240 cname, &nc ) ) && ( nc >= len ) ) {
1241 ival = astGetColumnLenC( this, cname );
1242 if ( astOK ) {
1243 (void) sprintf( getattrib_buff, "%d", ival );
1244 result = getattrib_buff;
1245 }
1246
1247 /* ColumnType */
1248 } else if ( nc = 0,
1249 ( 1 == astSscanf( attrib, PATTERN(columntype,AST__MXCOLNAMLEN),
1250 cname, &nc ) ) && ( nc >= len ) ) {
1251 ival = astGetColumnType( this, cname );
1252 if ( astOK ) {
1253 (void) sprintf( getattrib_buff, "%d", ival );
1254 result = getattrib_buff;
1255 }
1256
1257 /* ColumnLength */
1258 } else if ( nc = 0,
1259 ( 1 == astSscanf( attrib, PATTERN(columnlength,AST__MXCOLNAMLEN),
1260 cname, &nc ) ) && ( nc >= len ) ) {
1261 ival = astGetColumnLength( this, cname );
1262 if ( astOK ) {
1263 (void) sprintf( getattrib_buff, "%d", ival );
1264 result = getattrib_buff;
1265 }
1266
1267 /* ColumnUnit */
1268 } else if ( nc = 0,
1269 ( 1 == astSscanf( attrib, PATTERN(columnunit,AST__MXCOLNAMLEN),
1270 cname, &nc ) ) && ( nc >= len ) ) {
1271 result = astGetColumnUnit( this, cname );
1272
1273 #undef PATTERN
1274
1275
1276 /* Unknown attributes */
1277 /* ================== */
1278
1279 /* If the attribute name was not recognised, pass it on to the parent
1280 method for further interpretation. */
1281 } else {
1282 result = (*parent_getattrib)( this_object, attrib, status );
1283 }
1284
1285 /* Return the result. */
1286 return result;
1287 }
1288
GetColumnLenC(AstTable * this,const char * column,int * status)1289 static int GetColumnLenC( AstTable *this, const char *column, int *status ) {
1290 /*
1291 *+
1292 * Name:
1293 * astGetColumnLenC
1294
1295 * Purpose:
1296 * Get the maximum formatted length of any value in a column.
1297
1298 * Type:
1299 * Protected virtual function.
1300
1301 * Synopsis:
1302 * #include "table.h"
1303 * int astGetColumnLenC( AstTable *this, const char *column )
1304
1305 * Class Membership:
1306 * Table method.
1307
1308 * Description:
1309 * This function returns the minimum length which a character variable
1310 * must have in order to be able to store the longest value currently
1311 * present (at any row) in a specified column of the supplied Table. If
1312 * the named column holds vector values, then the returned value is
1313 * the length of the longest element of the vector value.
1314
1315 * Parameters:
1316 * this
1317 * Pointer to the Table.
1318 * column
1319 * The character string holding the upper-case name of the column.
1320 * Trailing spaces are ignored. An error is reported if the supplied
1321 * column is not found in the Table.
1322
1323 * Returned Value:
1324 * The length (i.e. number of characters) of the longest formatted
1325 * value associated with the named column. This does not include the
1326 * trailing null character.
1327
1328 * Notes:
1329 * - Automatic data type conversion occurs if the named column holds
1330 * numerical values.
1331 * - An error will be reported if named column does not exist or cannot
1332 * be formatted as a character
1333 * string.
1334 * - A function value of zero will be returned if an error has already
1335 * occurred, or if this function should fail for any reason.
1336
1337 *-
1338 */
1339
1340 /* Local Variables: */
1341 AstKeyMap *cols; /* KeyMap holding column definitions */
1342 char key[ AST__MXCOLKEYLEN ]; /* Current cell key string */
1343 int irow; /* Current row index */
1344 int len; /* Length needed to format current cell */
1345 int nrow; /* Number of rows in table */
1346 int result; /* Returned value */
1347
1348 /* Initialise */
1349 result = 0;
1350
1351 /* Check the global error status. */
1352 if ( !astOK ) return result;
1353
1354 /* Get the KeyMap holding information about all columns. */
1355 cols = astColumnProps( this );
1356
1357 /* Check the table contains the requested column. */
1358 if( astMapHasKey( cols, column ) ) {
1359
1360 /* Loop round all rows in the table. */
1361 nrow = astGetNrow( this );
1362 for( irow = 1; irow <= nrow; irow++ ) {
1363
1364 /* Format the cell name. */
1365 sprintf( key, "%.*s(%d)", (int) astChrLen(column), column, irow );
1366
1367 /* Get the maximum length needed to format a string in the current
1368 row/column. */
1369 len = astMapLenC( this, key );
1370
1371 /* Return the largest value found for any row. */
1372 if( len > result ) result = len;
1373 }
1374
1375 /* Report an error if the column does not exist. */
1376 } else if( astOK ) {
1377 astError( AST__BADCOL, "astGetColumnLenC(%s): No column named '%s' "
1378 "exists in the table.", status, astGetClass( this ), column );
1379 }
1380
1381 /* Free resources */
1382 cols = astAnnul( cols );
1383
1384 /* Return AST__BADTYPE if an error occurred. */
1385 if( !astOK ) result = 0;
1386
1387 /* Return the result. */
1388 return result;
1389 }
1390
GetColumnLength(AstTable * this,const char * column,int * status)1391 static int GetColumnLength( AstTable *this, const char *column, int *status ) {
1392 /*
1393 *+
1394 * Name:
1395 * astGetColumnLength
1396
1397 * Purpose:
1398 * Get the number of elements in each value in a column.
1399
1400 * Type:
1401 * Protected virtual function.
1402
1403 * Synopsis:
1404 * #include "table.h"
1405 * int astGetColumnLength( AstTable *this, const char *column )
1406
1407 * Class Membership:
1408 * Table method.
1409
1410 * Description:
1411 * This function returns the number of elements in each value stored
1412 * in a named column. Each value can be a scalar (in which case the
1413 * ColumnLength attribute has a value of 1), or a multi-dimensional
1414 * array ( in which case the ColumnLength value is equal to the
1415 * product of the array dimensions).
1416
1417 * Parameters:
1418 * this
1419 * Pointer to the Table.
1420 * column
1421 * The character string holding the upper-case name of the column.
1422 * Trailing spaces are ignored. An error is reported if the supplied
1423 * column is not found in the Table.
1424
1425 * Returned Value:
1426 * The number of elements in each column value.
1427
1428 * Notes:
1429 * - An error will be reported if named column does not exist or cannot
1430 * be formatted as a character
1431 * string.
1432 * - A function value of zero will be returned if an error has already
1433 * occurred, or if this function should fail for any reason.
1434
1435 *-
1436 */
1437
1438 /* Local Variables: */
1439 AstKeyMap *col_km; /* KeyMap holding requested column definition */
1440 AstKeyMap *cols; /* KeyMap holding all column definitions */
1441 int *dims; /* Pointer to array holding dimensions */
1442 int idim; /* Index of dimension */
1443 int ndim; /* Number of dimensions */
1444 int result; /* Returned value */
1445
1446 /* Initialise */
1447 result = 0;
1448
1449 /* Check the global error status. */
1450 if ( !astOK ) return result;
1451
1452 /* Get the KeyMap holding information about all columns. */
1453 cols = astColumnProps( this );
1454
1455 /* Get the KeyMap holding information about the requested column. */
1456 if( astMapGet0A( cols, column, &col_km ) ) {
1457
1458 /* If the Column properties includes the length, return it. Otherwise,
1459 calculate the length and store it in the KeyMap as a column property. */
1460 if( ! astMapGet0I( col_km, LENGTH, &result ) ) {
1461
1462 /* Get the number of axes spanned by each column value, and allocate an
1463 array big enough to hold the dimensions of these axes. */
1464 ndim = astMapLength( col_km, SHAPE );
1465 dims = astMalloc( sizeof( int )*ndim );
1466 if( astOK ) {
1467
1468 /* Get the dimensions. */
1469 astMapGet1I( col_km, SHAPE, ndim, &ndim, dims );
1470
1471 /* Find the number of elements. */
1472 result = 1;
1473 for( idim = 0; idim < ndim; idim++ ) {
1474 result *= dims[ idim ];
1475 }
1476
1477 /* Store the result in the column KeyMap. */
1478 astMapPut0I( col_km, LENGTH, result, NULL );
1479 }
1480 dims = astFree( dims );
1481 }
1482
1483 /* Free resources */
1484 col_km = astAnnul( col_km );
1485
1486 /* Report an error if the column does not exist. */
1487 } else if( astOK ) {
1488 astError( AST__BADCOL, "astGetColumnLength(%s): No column named '%s' "
1489 "exists in the table.", status, astGetClass( this ), column );
1490 }
1491
1492 /* Free resources */
1493 cols = astAnnul( cols );
1494
1495 /* Return AST__BADTYPE if an error occurred. */
1496 if( !astOK ) result = 0;
1497
1498 /* Return the result. */
1499 return result;
1500 }
1501
GetColumnNdim(AstTable * this,const char * column,int * status)1502 static int GetColumnNdim( AstTable *this, const char *column, int *status ) {
1503 /*
1504 *+
1505 * Name:
1506 * astGetColumnNdim
1507
1508 * Purpose:
1509 * Get the number of dimensions for a column in a Table.
1510
1511 * Type:
1512 * Protected virtual function.
1513
1514 * Synopsis:
1515 * #include "table.h"
1516 * int astGetColumnNdim( AstTable *this, const char *column )
1517
1518 * Class Membership:
1519 * Table method.
1520
1521 * Description:
1522 * This function attribute holds the number of axes spanned by each value
1523 * in a column. If each cell in the column is a scalar, ColumnNdim will
1524 * be zero. If each cell in the column is a 1D spectrum, ColumnNdim will
1525 * be one. If each cell in the column is a 2D image, ColumnNdim will be
1526 * two, etc.
1527
1528 * Parameters:
1529 * this
1530 * Pointer to the Table.
1531 * column
1532 * The character string holding the upper-case name of the column.
1533 * Trailing spaces are ignored. An error is reported if the supplied
1534 * column is not found in the Table.
1535
1536 * Returned Value:
1537 * The number of dimensions - zero for a scalar.
1538
1539 * Notes:
1540 * - A function value of zero will be returned if an error has
1541 * already occurred, or if this function should fail for any reason.
1542
1543 *-
1544 */
1545
1546 /* Local Variables: */
1547 AstKeyMap *cols; /* KeyMap holding column definitions */
1548 AstKeyMap *col_km; /* Pointer to KeyMap holding column info */
1549 int result; /* Returned value */
1550
1551 /* Initialise */
1552 result = 0;
1553
1554 /* Check the global error status. */
1555 if ( !astOK ) return result;
1556
1557 /* Get the KeyMap holding information about all columns. */
1558 cols = astColumnProps( this );
1559
1560 /* Get the KeyMap holding information about the requested column. */
1561 if( astMapGet0A( cols, column, &col_km ) ) {
1562
1563 /* Get the number of dimensions. */
1564 result = astMapLength( col_km, SHAPE );
1565
1566 /* Free resources */
1567 col_km = astAnnul( col_km );
1568
1569 /* Report an error if the column does not exist. */
1570 } else if( astOK ) {
1571 astError( AST__BADCOL, "astGetColumnNdim(%s): No column named '%s' "
1572 "exists in the table.", status, astGetClass( this ), column );
1573 }
1574 cols = astAnnul( cols );
1575
1576 /* Return AST__BADTYPE if an error occurred. */
1577 if( !astOK ) result = 0;
1578
1579 /* Return the result. */
1580 return result;
1581 }
1582
GetColumnType(AstTable * this,const char * column,int * status)1583 static int GetColumnType( AstTable *this, const char *column, int *status ) {
1584 /*
1585 *+
1586 * Name:
1587 * astGetColumnType
1588
1589 * Purpose:
1590 * Get the data type of a column in a Table.
1591
1592 * Type:
1593 * Protected virtual function.
1594
1595 * Synopsis:
1596 * #include "table.h"
1597 * int astGetColumnType( AstTable *this, const char *column )
1598
1599 * Class Membership:
1600 * Table method.
1601
1602 * Description:
1603 * This function returns a value indicating the data type of a
1604 * named column in a Table. This is the data type which was used
1605 * when the column was added to the Table using astAddColumn.
1606
1607 * Parameters:
1608 * this
1609 * Pointer to the Table.
1610 * column
1611 * The character string holding the upper-case name of the column.
1612 * Trailing spaces are ignored. An error is reported if the supplied
1613 * column is not found in the Table.
1614
1615 * Returned Value:
1616 * One of AST__INTTYPE (for integer), AST__SINTTYPE (for short int),
1617 * AST__BYTETYPE (for unsigned bytes - i.e. unsigned chars),
1618 * AST__DOUBLETYPE (for double precision floating point),
1619 * AST__FLOATTYPE (for single precision floating point), AST__STRINGTYPE
1620 * (for character string), AST__OBJECTTYPE (for AST Object pointer),
1621 * AST__POINTERTYPE (for arbitrary C pointer) or AST__UNDEFTYPE (for
1622 * undefined values created by astMapPutU).
1623
1624 * Notes:
1625 * - A function value of AST__BADTYPE will be returned if an error has
1626 * already occurred, or if this function should fail for any reason.
1627
1628 *-
1629 */
1630
1631 /* Local Variables: */
1632 AstKeyMap *cols; /* Pointer to KeyMap holding all column info */
1633 AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */
1634 int result; /* Returned value */
1635
1636 /* Initialise */
1637 result = AST__BADTYPE;
1638
1639 /* Check the global error status. */
1640 if ( !astOK ) return result;
1641
1642 /* Get the KeyMap holding information about the requested column. */
1643 cols = astColumnProps( this );
1644 if( astMapGet0A( cols, column, &col_km ) ) {
1645
1646 /* Get the column data type. */
1647 (void) astMapGet0I( col_km, TYPE, &result );
1648
1649 /* Annul the KeyMap pointer. */
1650 col_km = astAnnul( col_km );
1651
1652 /* Report an error if the column does not exist. */
1653 } else if( astOK ) {
1654 astError( AST__BADCOL, "astGetColumnType(%s): No column named '%s' "
1655 "exists in the table.", status, astGetClass( this ), column );
1656 }
1657 cols = astAnnul( cols );
1658
1659 /* Return AST__BADTYPE if an error occurred. */
1660 if( !astOK ) result = AST__BADTYPE;
1661
1662 /* Return the result. */
1663 return result;
1664 }
1665
GetColumnUnit(AstTable * this,const char * column,int * status)1666 static const char *GetColumnUnit( AstTable *this, const char *column, int *status ) {
1667 /*
1668 *+
1669 * Name:
1670 * astGetColumnUnit
1671
1672 * Purpose:
1673 * Get the unit string for a column in a Table.
1674
1675 * Type:
1676 * Protected virtual function.
1677
1678 * Synopsis:
1679 * #include "table.h"
1680 * const char *astGetColumnUnit( AstTable *this, const char *column )
1681
1682 * Class Membership:
1683 * Table method.
1684
1685 * Description:
1686 * This function returns the unit string for a named column in a Table.
1687 * This is the unit string that was provided when the column was added to
1688 * the Table using astAddColumn.
1689
1690 * Parameters:
1691 * this
1692 * Pointer to the Table.
1693 * column
1694 * The character string holding the upper-case name of the column.
1695 * Trailing spaces are ignored. An error is reported if the supplied
1696 * column is not found in the Table.
1697
1698 * Returned Value:
1699 * A pointer to a null-terminated string containing the column units.
1700
1701 *-
1702 */
1703
1704 /* Local Variables: */
1705 AstKeyMap *col_km; /* Pointer to KeyMap holding requested column info */
1706 AstKeyMap *cols; /* Pointer to KeyMap holding all column info */
1707 const char *result; /* Returned value */
1708
1709 /* Initialise */
1710 result = NULL;
1711
1712 /* Check the global error status. */
1713 if ( !astOK ) return result;
1714
1715 /* Get the KeyMap holding information about the requested column. */
1716 cols = astColumnProps( this );
1717 if( astMapGet0A( cols, column, &col_km ) ) {
1718
1719 /* Get the column unit string. */
1720 (void) astMapGet0C( col_km, UNIT, &result );
1721
1722 /* Annul the KeyMap pointer. */
1723 col_km = astAnnul( col_km );
1724
1725 /* Report an error if the column does not exist. */
1726 } else if( astOK ) {
1727 astError( AST__BADCOL, "astGetColumnUnit(%s): No column named '%s' "
1728 "exists in the table.", status, astGetClass( this ), column );
1729 }
1730 cols = astAnnul( cols );
1731
1732 /* Return NULL if an error occurred. */
1733 if( !astOK ) result = NULL;
1734
1735 /* Return the result. */
1736 return result;
1737 }
1738
GetNcolumn(AstTable * this,int * status)1739 static int GetNcolumn( AstTable *this, int *status ) {
1740 /*
1741 *+
1742 * Name:
1743 * astGetNcolumn
1744
1745 * Purpose:
1746 * Get the number of columns in a Table.
1747
1748 * Type:
1749 * Protected virtual function.
1750
1751 * Synopsis:
1752 * #include "table.h"
1753 * int astGetNcolumn( AstTable *this )
1754
1755 * Class Membership:
1756 * Table method.
1757
1758 * Description:
1759 * This function returns the number of columns currently in the Table.
1760
1761 * Parameters:
1762 * this
1763 * Pointer to the Table.
1764
1765 * Returned Value:
1766 * Number of columns.
1767
1768 * Notes:
1769 * - A value of zero will be returned if this function is invoked
1770 * with the global error status set, or if it should fail for any
1771 * reason.
1772 *-
1773 */
1774
1775 /* Local Variables: */
1776 AstKeyMap *cols;
1777 int result;
1778
1779 /* Check the global error status. */
1780 if ( !astOK ) return 0;
1781
1782 /* Get a pointer to the KeyMap holding the column definitions. */
1783 cols = astColumnProps( this );
1784
1785 /* Get the number of column definitions in the KeyMap. */
1786 result = astMapSize( cols );
1787
1788 /* Annul the KeyMap pointer. */
1789 cols = astAnnul( cols );
1790
1791 /* Return the result. */
1792 return result;
1793 }
1794
GetNparameter(AstTable * this,int * status)1795 static int GetNparameter( AstTable *this, int *status ) {
1796 /*
1797 *+
1798 * Name:
1799 * astGetNparameter
1800
1801 * Purpose:
1802 * Get the number of global parameters in a Table.
1803
1804 * Type:
1805 * Protected virtual function.
1806
1807 * Synopsis:
1808 * #include "table.h"
1809 * int astGetNparameter( AstTable *this )
1810
1811 * Class Membership:
1812 * Table method.
1813
1814 * Description:
1815 * This function returns the number of global parameters currently in the Table.
1816
1817 * Parameters:
1818 * this
1819 * Pointer to the Table.
1820
1821 * Returned Value:
1822 * Number of parameters.
1823
1824 * Notes:
1825 * - A value of zero will be returned if this function is invoked
1826 * with the global error status set, or if it should fail for any
1827 * reason.
1828 *-
1829 */
1830
1831 /* Local Variables: */
1832 AstKeyMap *pars;
1833 int result;
1834
1835 /* Check the global error status. */
1836 if ( !astOK ) return 0;
1837
1838 /* Get a pointer to the KeyMap holding the parameter definitions. */
1839 pars = astParameterProps( this );
1840
1841 /* Get the number of parameter definitions in the KeyMap. */
1842 result = astMapSize( pars );
1843
1844 /* Annul the KeyMap pointer. */
1845 pars = astAnnul( pars );
1846
1847 /* Return the result. */
1848 return result;
1849 }
1850
GetObjSize(AstObject * this_object,int * status)1851 static int GetObjSize( AstObject *this_object, int *status ) {
1852 /*
1853 * Name:
1854 * GetObjSize
1855
1856 * Purpose:
1857 * Return the in-memory size of an Object.
1858
1859 * Type:
1860 * Private function.
1861
1862 * Synopsis:
1863 * #include "table.h"
1864 * int GetObjSize( AstObject *this, int *status )
1865
1866 * Class Membership:
1867 * Table member function (over-rides the astGetObjSize protected
1868 * method inherited from the parent class).
1869
1870 * Description:
1871 * This function returns the in-memory size of the supplied Tables,
1872 * in bytes.
1873
1874 * Parameters:
1875 * this
1876 * Pointer to the Table.
1877 * status
1878 * Pointer to the inherited status variable.
1879
1880 * Returned Value:
1881 * The Table size, in bytes.
1882
1883 * Notes:
1884 * - A value of zero will be returned if this function is invoked
1885 * with the global status set, or if it should fail for any reason.
1886 */
1887
1888 /* Local Variables: */
1889 AstKeyMap *km; /* KeyMap holding column/parameter definitions */
1890 AstTable *this; /* Pointer to Table structure */
1891 int result; /* Result value to return */
1892
1893 /* Initialise. */
1894 result = 0;
1895
1896 /* Check the global error status. */
1897 if ( !astOK ) return result;
1898
1899 /* Obtain a pointers to the Table structure. */
1900 this = (AstTable *) this_object;
1901
1902 /* Invoke the GetObjSize method inherited from the parent KeyMap class, and
1903 then add on any components of the class structure defined by this class
1904 which are stored in dynamically allocated memory. */
1905 result = (*parent_getobjsize)( this_object, status );
1906
1907 km = astColumnProps( this );
1908 result += astGetObjSize( km );
1909 km = astAnnul( km );
1910
1911 km = astParameterProps( this );
1912 result += astGetObjSize( km );
1913 km = astAnnul( km );
1914
1915 /* If an error occurred, clear the result value. */
1916 if ( !astOK ) result = 0;
1917
1918 /* Return the result, */
1919 return result;
1920 }
1921
HasColumn(AstTable * this,const char * column,int * status)1922 static int HasColumn( AstTable *this, const char *column, int *status ){
1923 /*
1924 *++
1925 * Name:
1926 c astHasColumn
1927 f AST_HASCOLUMN
1928
1929 * Purpose:
1930 * Returns a flag indicating if a column is present in a Table.
1931
1932 * Type:
1933 * Public virtual function.
1934
1935 * Synopsis:
1936 c #include "table.h"
1937 c int astHasColumn( AstTable *this, const char *column )
1938 f RESULT = AST_HASCOLUMN( THIS, COLUMN, STATUS )
1939
1940 * Class Membership:
1941 * Table method.
1942
1943 * Description:
1944 c This function
1945 f This routine
1946 * returns a flag indicating if a named column exists in a Table, for
1947 * instance, by having been added to to the Table using
1948 c astAddColumn.
1949 f AST_ADDCOLUMN.
1950
1951 * Parameters:
1952 c this
1953 f THIS = INTEGER (Given)
1954 * Pointer to the Table.
1955 c column
1956 f COLUMN = CHARACTER * ( * ) (Given)
1957 * The character string holding the upper case name of the column. Trailing
1958 * spaces are ignored.
1959 f STATUS = INTEGER (Given and Returned)
1960 f The global status.
1961
1962 * Notes:
1963 * - A value of
1964 c zero
1965 f .FALSE.
1966 * is returned for if an error occurs.
1967
1968 *--
1969 */
1970
1971 /* Local Variables: */
1972 AstKeyMap *cols;
1973 int result;
1974
1975 /* Initialise */
1976 result = 0;
1977
1978 /* Check the inherited status. */
1979 if( !astOK ) return result;
1980
1981 /* Get the KeyMap holding information about all columns. */
1982 cols = astColumnProps( this );
1983
1984 /* Seeif it contains an entry for the named column. */
1985 result = astMapHasKey( cols, column );
1986
1987 /* Free resources. */
1988 cols = astAnnul( cols );
1989
1990 /* If an error has occurred, return zero. */
1991 if( !astOK ) result = 0;
1992 return result;
1993 }
1994
HasParameter(AstTable * this,const char * parameter,int * status)1995 static int HasParameter( AstTable *this, const char *parameter, int *status ){
1996 /*
1997 *++
1998 * Name:
1999 c astHasParameter
2000 f AST_HASPARAMETER
2001
2002 * Purpose:
2003 * Returns a flag indicating if a named global parameter is present in a Table.
2004
2005 * Type:
2006 * Public virtual function.
2007
2008 * Synopsis:
2009 c #include "table.h"
2010 c int astHasParameter( AstTable *this, const char *parameter )
2011 f RESULT = AST_HASPARAMETER( THIS, PARAMETER, STATUS )
2012
2013 * Class Membership:
2014 * Table method.
2015
2016 * Description:
2017 c This function
2018 f This routine
2019 * returns a flag indicating if a named parameter exists in a Table, for
2020 * instance, by having been added to to the Table using
2021 c astAddParameter.
2022 f AST_ADDPARAMETER.
2023
2024 * Parameters:
2025 c this
2026 f THIS = INTEGER (Given)
2027 * Pointer to the Table.
2028 c parameter
2029 f PARAMETER = CHARACTER * ( * ) (Given)
2030 * The character string holding the upper case name of the parameter. Trailing
2031 * spaces are ignored.
2032 f STATUS = INTEGER (Given and Returned)
2033 f The global status.
2034
2035 * Notes:
2036 * - A value of
2037 c zero
2038 f .FALSE.
2039 * is returned for if an error occurs.
2040
2041 *--
2042 */
2043
2044 /* Local Variables: */
2045 AstKeyMap *pars;
2046 int result;
2047
2048 /* Initialise */
2049 result = 0;
2050
2051 /* Check the inherited status. */
2052 if( !astOK ) return result;
2053
2054 /* Get the KeyMap holding information about all parameters. */
2055 pars = astParameterProps( this );
2056
2057 /* See if it contains an entry for the named parameter. */
2058 result = astMapHasKey( pars, parameter );
2059
2060 /* Free resources. */
2061 pars = astAnnul( pars );
2062
2063 /* If an error has occurred, return zero. */
2064 if( !astOK ) result = 0;
2065 return result;
2066 }
2067
astInitTableVtab_(AstTableVtab * vtab,const char * name,int * status)2068 void astInitTableVtab_( AstTableVtab *vtab, const char *name, int *status ) {
2069 /*
2070 *+
2071 * Name:
2072 * astInitTableVtab
2073
2074 * Purpose:
2075 * Initialise a virtual function table for a Table.
2076
2077 * Type:
2078 * Protected function.
2079
2080 * Synopsis:
2081 * #include "table.h"
2082 * void astInitTableVtab( AstTableVtab *vtab, const char *name )
2083
2084 * Class Membership:
2085 * Table vtab initialiser.
2086
2087 * Description:
2088 * This function initialises the component of a virtual function
2089 * table which is used by the Table class.
2090
2091 * Parameters:
2092 * vtab
2093 * Pointer to the virtual function table. The components used by
2094 * all ancestral classes will be initialised if they have not already
2095 * been initialised.
2096 * name
2097 * Pointer to a constant null-terminated character string which contains
2098 * the name of the class to which the virtual function table belongs (it
2099 * is this pointer value that will subsequently be returned by the Object
2100 * astClass function).
2101 *-
2102 */
2103
2104 /* Local Variables: */
2105 astDECLARE_GLOBALS /* Pointer to thread-specific global data */
2106 AstObjectVtab *object; /* Pointer to Object component of Vtab */
2107 AstKeyMapVtab *keymap; /* Pointer to KeyMap component of Vtab */
2108
2109 /* Check the local error status. */
2110 if ( !astOK ) return;
2111
2112 /* Get a pointer to the thread specific global data structure. */
2113 astGET_GLOBALS(NULL);
2114
2115 /* Initialize the component of the virtual function table used by the
2116 parent class. */
2117 astInitKeyMapVtab( (AstKeyMapVtab *) vtab, name );
2118
2119 /* Store a unique "magic" value in the virtual function table. This
2120 will be used (by astIsATable) to determine if an object belongs
2121 to this class. We can conveniently use the address of the (static)
2122 class_check variable to generate this unique value. */
2123 vtab->id.check = &class_check;
2124 vtab->id.parent = &(((AstKeyMapVtab *) vtab)->id);
2125
2126 /* Initialise member function pointers. */
2127 /* ------------------------------------ */
2128 /* Store pointers to the member functions (implemented here) that provide
2129 virtual methods for this class. */
2130 vtab->AddColumn = AddColumn;
2131 vtab->AddParameter = AddParameter;
2132 vtab->ColumnName = ColumnName;
2133 vtab->ParameterName = ParameterName;
2134 vtab->ColumnProps = ColumnProps;
2135 vtab->ColumnShape = ColumnShape;
2136 vtab->GetColumnLenC = GetColumnLenC;
2137 vtab->GetColumnLength = GetColumnLength;
2138 vtab->GetColumnNdim = GetColumnNdim;
2139 vtab->GetColumnType = GetColumnType;
2140 vtab->GetColumnUnit = GetColumnUnit;
2141 vtab->GetNcolumn = GetNcolumn;
2142 vtab->GetNparameter = GetNparameter;
2143 vtab->GetNrow = GetNrow;
2144 vtab->HasColumn = HasColumn;
2145 vtab->HasParameter = HasParameter;
2146 vtab->ParameterProps = ParameterProps;
2147 vtab->PurgeRows = PurgeRows;
2148 vtab->RemoveColumn = RemoveColumn;
2149 vtab->RemoveParameter = RemoveParameter;
2150 vtab->RemoveRow = RemoveRow;
2151 vtab->SetNrow = SetNrow;
2152
2153 /* Save the inherited pointers to methods that will be extended, and
2154 replace them with pointers to the new member functions. */
2155 object = (AstObjectVtab *) vtab;
2156 keymap = (AstKeyMapVtab *) vtab;
2157
2158 parent_equal = object->Equal;
2159 object->Equal = Equal;
2160
2161 parent_getobjsize = object->GetObjSize;
2162 object->GetObjSize = GetObjSize;
2163
2164 parent_clearattrib = object->ClearAttrib;
2165 object->ClearAttrib = ClearAttrib;
2166
2167 parent_getattrib = object->GetAttrib;
2168 object->GetAttrib = GetAttrib;
2169
2170 parent_setattrib = object->SetAttrib;
2171 object->SetAttrib = SetAttrib;
2172
2173 parent_testattrib = object->TestAttrib;
2174 object->TestAttrib = TestAttrib;
2175
2176 #if defined(THREAD_SAFE)
2177 parent_managelock = object->ManageLock;
2178 object->ManageLock = ManageLock;
2179 #endif
2180
2181 parent_mapremove = keymap->MapRemove;
2182
2183 /* Define convenience macros for overriding methods inherited from the
2184 parent KeyMap class using all data type supported by KeyMap. */
2185 #define OVERRIDE(method,code,methodlc,codelc) \
2186 parent_##methodlc##codelc = keymap->method##code; \
2187 keymap->method##code = method##code; \
2188
2189 #define OVERRIDE_METHOD(method,methodlc) \
2190 OVERRIDE(method,A,methodlc,a) \
2191 OVERRIDE(method,P,methodlc,p) \
2192 OVERRIDE(method,C,methodlc,c) \
2193 OVERRIDE(method,D,methodlc,d) \
2194 OVERRIDE(method,F,methodlc,f) \
2195 OVERRIDE(method,I,methodlc,i) \
2196 OVERRIDE(method,S,methodlc,s) \
2197 OVERRIDE(method,B,methodlc,b)
2198
2199 /* Use these macros to override the required methods. */
2200 OVERRIDE_METHOD(MapPut0,mapput0)
2201 OVERRIDE_METHOD(MapGet0,mapget0)
2202 OVERRIDE_METHOD(MapPut1,mapput1)
2203 OVERRIDE_METHOD(MapGet1,mapget1)
2204 OVERRIDE_METHOD(MapPutElem,mapputelem)
2205 OVERRIDE_METHOD(MapGetElem,mapgetelem)
2206 OVERRIDE(MapPut,U,mapput,u)
2207 OVERRIDE(SetKeyCase,,setkeycase,)
2208 OVERRIDE(ClearKeyCase,,clearkeycase,)
2209
2210 /* Remove the macros. */
2211 #undef OVERRIDE_METHOD
2212 #undef OVERRIDE
2213
2214 /* Store replacement pointers for methods which will be over-ridden by
2215 new member functions implemented here. */
2216
2217 /* Declare the copy constructor, destructor and class dump function. */
2218 astSetCopy( vtab, Copy );
2219 astSetDelete( vtab, Delete );
2220 astSetDump( vtab, Dump, "Table", "Two-dimensional table of data values" );
2221
2222 /* If we have just initialised the vtab for the current class, indicate
2223 that the vtab is now initialised, and store a pointer to the class
2224 identifier in the base "object" level of the vtab. */
2225 if( vtab == &class_vtab ) {
2226 class_init = 1;
2227 astSetVtabClassIdentifier( vtab, &(vtab->id) );
2228 }
2229 }
2230
2231 #if defined(THREAD_SAFE)
ManageLock(AstObject * this_object,int mode,int extra,AstObject ** fail,int * status)2232 static int ManageLock( AstObject *this_object, int mode, int extra,
2233 AstObject **fail, int *status ) {
2234 /*
2235 * Name:
2236 * ManageLock
2237
2238 * Purpose:
2239 * Manage the thread lock on an Object.
2240
2241 * Type:
2242 * Private function.
2243
2244 * Synopsis:
2245 * #include "object.h"
2246 * AstObject *ManageLock( AstObject *this, int mode, int extra,
2247 * AstObject **fail, int *status )
2248
2249 * Class Membership:
2250 * Table member function (over-rides the astManageLock protected
2251 * method inherited from the parent class).
2252
2253 * Description:
2254 * This function manages the thread lock on the supplied Object. The
2255 * lock can be locked, unlocked or checked by this function as
2256 * deteremined by parameter "mode". See astLock for details of the way
2257 * these locks are used.
2258
2259 * Parameters:
2260 * this
2261 * Pointer to the Object.
2262 * mode
2263 * An integer flag indicating what the function should do:
2264 *
2265 * AST__LOCK: Lock the Object for exclusive use by the calling
2266 * thread. The "extra" value indicates what should be done if the
2267 * Object is already locked (wait or report an error - see astLock).
2268 *
2269 * AST__UNLOCK: Unlock the Object for use by other threads.
2270 *
2271 * AST__CHECKLOCK: Check that the object is locked for use by the
2272 * calling thread (report an error if not).
2273 * extra
2274 * Extra mode-specific information.
2275 * fail
2276 * If a non-zero function value is returned, a pointer to the
2277 * Object that caused the failure is returned at "*fail". This may
2278 * be "this" or it may be an Object contained within "this". Note,
2279 * the Object's reference count is not incremented, and so the
2280 * returned pointer should not be annulled. A NULL pointer is
2281 * returned if this function returns a value of zero.
2282 * status
2283 * Pointer to the inherited status variable.
2284
2285 * Returned Value:
2286 * A local status value:
2287 * 0 - Success
2288 * 1 - Could not lock or unlock the object because it was already
2289 * locked by another thread.
2290 * 2 - Failed to lock a POSIX mutex
2291 * 3 - Failed to unlock a POSIX mutex
2292 * 4 - Bad "mode" value supplied.
2293
2294 * Notes:
2295 * - This function attempts to execute even if an error has already
2296 * occurred.
2297 */
2298
2299 /* Local Variables: */
2300 AstTable *this; /* Pointer to Table structure */
2301 int result; /* Returned status value */
2302
2303 /* Initialise */
2304 result = 0;
2305
2306 /* Check the supplied pointer is not NULL. */
2307 if( !this_object ) return result;
2308
2309 /* Obtain a pointers to the Table structure. */
2310 this = (AstTable *) this_object;
2311
2312 /* Invoke the ManageLock method inherited from the parent class. */
2313 if( !result ) result = (*parent_managelock)( this_object, mode, extra,
2314 fail, status );
2315
2316 /* Invoke the astManageLock method on any Objects contained within
2317 the supplied Object. */
2318 if( !result && this->columns ) result = astManageLock( this->columns, mode, extra,
2319 fail );
2320
2321 if( !result && this->parameters ) result = astManageLock( this->parameters, mode, extra,
2322 fail );
2323
2324 /* Return the result. */
2325 return result;
2326 }
2327 #endif
2328
2329 /*
2330 * Name:
2331 * MapGet0<X>
2332
2333 * Purpose:
2334 * Get a scalar value from a cell of a Table.
2335
2336 * Type:
2337 * Private function.
2338
2339 * Synopsis:
2340 * #include "table.h"
2341 * int MapGet0<X>( AstKeyMap *this, const char *key, <X>type *value );
2342
2343 * Class Membership:
2344 * Table member function (over-rides the astMapGet0<X> method inherited
2345 * from the KeyMap class).
2346
2347 * Description:
2348 * This is a set of functions for retrieving a scalar value from a
2349 * cell of a Table. You should replace <X> in the generic function name
2350 * MapGet0<X> by an appropriate 1-character type code (see the "Data
2351 * Type Codes" section in the astMapGet0<X> docs). The stored value is
2352 * converted to the data type indiced by <X> before being returned (an
2353 * error is reported if it is not possible to convert the stored value
2354 * to the requested data type).
2355
2356 * Parameters:
2357 * this
2358 * Pointer to the Table.
2359 * key
2360 * A character string identifying the cell from which the value is
2361 * to be retrieved. It should have the form "COLNAME(irow)", where
2362 * "COLNAME" is replaced by the name of a column that has been
2363 * defined previously using the astAddColumn method, and "irow" is
2364 * an integer row index (the first row is row 1).
2365 * value
2366 * A pointer to a buffer in which to return the requested value.
2367 * If the requested cell is not found, or if it is found but has an
2368 * undefined value (see astMapPutU), then the contents of the buffer
2369 * on entry to this function will be unchanged on exit. For pointer
2370 * types ("A" and "C"), the buffer should be a suitable pointer, and
2371 * the address of this pointer should be supplied as the "value"
2372 * parameter.
2373 * status
2374 * Pointer to inherited status value.
2375
2376 * Returned Value:
2377 * A non-zero value is returned if the requested key name was found, and
2378 * does not have an undefined value (see astMapPutU). Zero is returned
2379 * otherwise.
2380
2381 * Notes:
2382 * - No error is reported if the requested cell cannot be found in the
2383 * given KeyMap, but a zero value will be returned as the function value.
2384 * The supplied buffer will be returned unchanged.
2385 * - Key names are case insensitive, and white space is considered
2386 * significant.
2387 * - If the stored value is a vector value, then the first value in
2388 * the vector will be returned.
2389 * - A string pointer returned by astMapGet0C is guaranteed to remain
2390 * valid and the string to which it points will not be over-written for
2391 * a total of 50 successive invocations of this function. After this,
2392 * the memory containing the string may be re-used, so a copy of
2393 * the string should be made if it is needed for longer than this.
2394 * - If the returned value is an AST Object pointer, the Object's reference
2395 * count is incremented by this call. Any subsequent changes made to
2396 * the Object using the returned pointer will be reflected in any
2397 * any other active pointers for the Object. The returned pointer
2398 * should be annulled using astAnnul when it is no longer needed.
2399 */
2400
2401 /* Define a macro to implement the function for a specific data type. */
2402 #define MAKE_MAPGET0(X,Xlc,Xtype,Itype) \
2403 static int MapGet0##X( AstKeyMap *this_keymap, const char *key, Xtype *value, \
2404 int *status ) { \
2405 \
2406 /* Local Variables: */ \
2407 AstTable *this; /* Pointer to Table structure */ \
2408 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
2409 int irow; /* Row index within key string */ \
2410 int result; /* Returned flag */ \
2411 \
2412 /* Initialise */ \
2413 result = 0; \
2414 \
2415 /* Check the global error status. */ \
2416 if ( !astOK ) return result; \
2417 \
2418 /* Get a pointer to the Table structure. */ \
2419 this = (AstTable *) this_keymap; \
2420 \
2421 /* If the key is the name of a global table parameter, use the parent \
2422 method to get the value of hte parameter. */ \
2423 if( astHasParameter( this, key ) ) { \
2424 result = (*parent_mapget0##Xlc)( this_keymap, key, value, status ); \
2425 \
2426 /* Check the supplied key looks like a table cell key, and get the \
2427 the column name and the row number. Also checks that the table \
2428 contains a column with the specified name. */ \
2429 } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \
2430 NULL, "astMapGet0" #X, status ) ) { \
2431 \
2432 /* If the row index is larger than the current number of rows in the \
2433 table, do nothing more. */ \
2434 if( irow <= astGetNrow( this ) ){ \
2435 \
2436 /* Use the astMapGet0<X> method in the parent keyMap class to get the \
2437 cell contents. */ \
2438 result = (*parent_mapget0##Xlc)( this_keymap, key, value, status ); \
2439 } \
2440 } \
2441 \
2442 /* If an error occurred, return zero. */ \
2443 if( !astOK ) result = 0; \
2444 \
2445 /* Return the result.*/ \
2446 return result; \
2447 }
2448
2449 /* Expand the above macro to generate a function for each required
2450 data type. */
MAKE_MAPGET0(I,i,int,AST__INTTYPE)2451 MAKE_MAPGET0(I,i,int,AST__INTTYPE)
2452 MAKE_MAPGET0(D,d,double,AST__DOUBLETYPE)
2453 MAKE_MAPGET0(F,f,float,AST__FLOATTYPE)
2454 MAKE_MAPGET0(C,c,const char *,AST__STRINGTYPE)
2455 MAKE_MAPGET0(A,a,AstObject *,AST__OBJECTTYPE)
2456 MAKE_MAPGET0(P,p,void *,AST__POINTERTYPE)
2457 MAKE_MAPGET0(S,s,short int,AST__SINTTYPE)
2458 MAKE_MAPGET0(B,b,unsigned char,AST__BYTETYPE)
2459
2460 /* Undefine the macro. */
2461 #undef MAKE_MAPGET0
2462
2463 /*
2464 * Name:
2465 * MapGet1<X>
2466
2467 * Purpose:
2468 * Get a vector value from a cell of a Table.
2469
2470 * Type:
2471 * Private function.
2472
2473 * Synopsis:
2474 * #include "table.h"
2475 * int MapGet1<X>( AstKeyMap *this, const char *key, int mxval,
2476 * int *nval, <X>type *value )
2477 * int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval,
2478 * int *nval, const char *value )
2479
2480 * Class Membership:
2481 * Table member function (over-rides the astMapGet1<X> method inherited
2482 * from the KeyMap class).
2483
2484 * Description:
2485 * This is a set of functions for retrieving a vector value from a
2486 * cell of a Table. You should replace <X> in the generic function name
2487 * MapGet1<X> by an appropriate 1-character type code (see the "Data
2488 * Type Codes" section in the astMapGet1<X> docs). The stored value is
2489 * converted to the data type indiced by <X> before being returned (an
2490 * error is reported if it is not possible to convert the stored value
2491 * to the requested data type).
2492 *
2493 * Note, the MapGet1C function has an extra parameter "l" which
2494 * specifies the maximum length of each string to be stored in the
2495 * "value" buffer (see the "astMapGet1C" docs).
2496
2497 * Parameters:
2498 * this
2499 * Pointer to the Table.
2500 * key
2501 * A character string identifying the cell from which the value is
2502 * to be retrieved. It should have the form "COLNAME(irow)", where
2503 * "COLNAME" is replaced by the name of a column that has been
2504 * defined previously using the astAddColumn method, and "irow" is
2505 * an integer row index (the first row is row 1).
2506 * mxval
2507 * The number of elements in the "value" array.
2508 * nval
2509 * The address of an integer in which to put the number of elements
2510 * stored in the "value" array. Any unused elements of the array are
2511 * left unchanged.
2512 * value
2513 * A pointer to an array in which to return the requested values.
2514 * If the requested cell is not found, or if it is found but has an
2515 * undefined value (see astMapPutU), then the contents of the buffer
2516 * on entry to this function will be unchanged on exit.
2517 * status
2518 * Pointer to inherited status value.
2519
2520 * Returned Value:
2521 * A non-zero value is returned if the requested key name was found, and
2522 * does not have an undefined value (see astMapPutU). Zero is returned
2523 * otherwise.
2524
2525 * MapGet1C:
2526 * The "value" buffer supplied to the MapGet1C function should be a
2527 * pointer to a character array with "mxval*l" elements, where "l" is
2528 * the maximum length of a string to be returned. The value of "l"
2529 * should be supplied as an extra parameter following "key" when
2530 * invoking MapGet1C, and should include space for a terminating
2531 * null character.
2532
2533 * Notes:
2534 * - No error is reported if the requested cell cannot be found in the
2535 * given KeyMap, but a zero value will be returned as the function value.
2536 * The supplied buffer will be returned unchanged.
2537 * - Key names are case insensitive, and white space is considered
2538 * significant.
2539 * - If the stored value is a scalar value, then the value will be
2540 * returned in the first element of the supplied array, and "nval"
2541 * will be returned set to 1.
2542 */
2543
2544 /* Define a macro to implement the function for a specific data type
2545 (excluding "C" since that needs an extra parameter). */
2546 #define MAKE_MAPGET1(X,Xlc,Xtype,Itype) \
2547 static int MapGet1##X( AstKeyMap *this_keymap, const char *key, int mxval, int *nval, \
2548 Xtype *value, int *status ) { \
2549 \
2550 /* Local Variables: */ \
2551 AstTable *this; /* Pointer to Table structure */ \
2552 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
2553 int irow; /* Row index within key string */ \
2554 int result; /* Returned flag */ \
2555 \
2556 /* Initialise */ \
2557 result = 0; \
2558 \
2559 /* Check the global error status. */ \
2560 if ( !astOK ) return result; \
2561 \
2562 /* Get a pointer to the Table structure. */ \
2563 this = (AstTable *) this_keymap; \
2564 \
2565 /* If the key is the name of a global table parameter, use the parent \
2566 method to get the value of hte parameter. */ \
2567 if( astHasParameter( this, key ) ) { \
2568 result = (*parent_mapget1##Xlc)( this_keymap, key, mxval, nval, \
2569 value, status ); \
2570 \
2571 /* Check the supplied key looks like a table cell key, and get the \
2572 the column name and the row number. Also checks that the table \
2573 contains a column with the specified name. */ \
2574 } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \
2575 NULL, "astMapGet1" #X, status ) ) { \
2576 \
2577 /* If the row index is larger than the current number of rows in the \
2578 table, do nothing more. */ \
2579 if( irow <= astGetNrow( this ) ){ \
2580 \
2581 /* Use the astMapGet1<X> method in the parent keyMap class to get the \
2582 cell contents. */ \
2583 result = (*parent_mapget1##Xlc)( this_keymap, key, mxval, nval, \
2584 value, status ); \
2585 } \
2586 } \
2587 \
2588 /* If an error occurred, return zero. */ \
2589 if( !astOK ) result = 0; \
2590 \
2591 /* Return the result.*/ \
2592 return result; \
2593 }
2594
2595 /* Expand the above macro to generate a function for each required
2596 data type. */
2597 MAKE_MAPGET1(I,i,int,AST__INTTYPE)
2598 MAKE_MAPGET1(D,d,double,AST__DOUBLETYPE)
2599 MAKE_MAPGET1(F,f,float,AST__FLOATTYPE)
2600 MAKE_MAPGET1(A,a,AstObject *,AST__OBJECTTYPE)
2601 MAKE_MAPGET1(P,p,void *,AST__POINTERTYPE)
2602 MAKE_MAPGET1(S,s,short int,AST__SINTTYPE)
2603 MAKE_MAPGET1(B,b,unsigned char,AST__BYTETYPE)
2604
2605 /* Undefine the macro. */
2606 #undef MAKE_MAPGET1
2607
2608
2609 static int MapGet1C( AstKeyMap *this_keymap, const char *key, int l, int mxval,
2610 int *nval, char *value, int *status ) {
2611 /*
2612 * Name:
2613 * MapGet1C
2614
2615 * Purpose:
2616 * Get a vector value from a cell of a Table.
2617
2618 * Type:
2619 * Private function.
2620
2621 * Synopsis:
2622 * #include "table.h"
2623 * int MapGet1C( AstKeyMap *this, const char *key, int l, int mxval,
2624 * int *nval, const char *value )
2625
2626 * Class Membership:
2627 * Table member function (over-rides the astMapGet1C method inherited
2628 * from the KeyMap class).
2629
2630 * Description:
2631 * This is the implementation of MapGet1<X> for <X> = "C". We
2632 * cannot use the MAKE_MAPGET1 macro for this because the string
2633 * version of this function has an extra parameter giving the maximum
2634 * length of each string which can be stored in the supplied buffer.
2635
2636 * Parameters:
2637 * (see MapGet1<X>)
2638 */
2639
2640 /* Local Variables: */
2641 AstTable *this; /* Pointer to Table structure */
2642 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */
2643 int irow; /* Row index within key string */
2644 int result; /* Returned flag */
2645
2646 /* Initialise */
2647 result = 0;
2648
2649 /* Check the global error status. */
2650 if ( !astOK ) return result;
2651
2652 /* Get a pointer to the Table structure. */
2653 this = (AstTable *) this_keymap;
2654
2655 /* If the key is the name of a global table parameter, use the parent
2656 method to get the value of hte parameter. */
2657 if( astHasParameter( this, key ) ) {
2658 result = (*parent_mapget1c)( this_keymap, key, l, mxval, nval,
2659 value, status );
2660
2661 /* Check the supplied key looks like a table cell key, and get the
2662 the column name and the row number. Also checks that the table
2663 contains a column with the specified name. */
2664 } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow,
2665 NULL, "astMapGet1C", status ) ) {
2666
2667 /* If the row index is larger than the current number of rows in the
2668 table, do nothing more. */
2669 if( irow <= astGetNrow( this ) ){
2670
2671 /* Use the astMapGet1<X> method in the parent keyMap class to get the
2672 cell contents. */
2673 result = (*parent_mapget1c)( this_keymap, key, l, mxval, nval,
2674 value, status );
2675 }
2676 }
2677
2678 /* If an error occurred, return zero. */
2679 if( !astOK ) result = 0;
2680
2681 /* Return the result.*/
2682 return result;
2683 }
2684
2685 /*
2686 * Name:
2687 * MapGetElem<X>
2688
2689 * Purpose:
2690 * Get a single element of a vector value from a cell of a Table.
2691
2692 * Type:
2693 * Private function.
2694
2695 * Synopsis:
2696 * #include "table.h"
2697 * int MapGetElem<X>( AstKeyMap *this, const char *key, int elem,
2698 * <X>type *value, int *status )
2699 * int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem,
2700 * char *value, int *status )
2701
2702 * Class Membership:
2703 * Table member function (over-rides the astMapGetElem<X> method inherited
2704 * from the KeyMap class).
2705
2706 * Description:
2707 * This is a set of functions for retrieving a single element of a vector
2708 * value from a cell of a Table. You should replace <X> in the generic
2709 * function name MapGetElem<X> by an appropriate 1-character type code
2710 * (see the "Data Type Codes" section in the astMapGetElem<X> docs). The
2711 * stored value is converted to the data type indiced by <X> before being
2712 * returned (an error is reported if it is not possible to convert the
2713 * stored value to the requested data type).
2714 *
2715 * Note, the MapGetElemC function has an extra parameter "l" which
2716 * specifies the maximum length of each string to be stored in the
2717 * "value" buffer (see the "MapGetElemC" docs).
2718
2719 * Parameters:
2720 * this
2721 * Pointer to the Table.
2722 * key
2723 * A character string identifying the cell from which the value is
2724 * to be retrieved. It should have the form "COLNAME(irow)", where
2725 * "COLNAME" is replaced by the name of a column that has been
2726 * defined previously using the astAddColumn method, and "irow" is
2727 * an integer row index (the first row is row 1).
2728 * elem
2729 * The index of the vector element to modify, starting at zero.
2730 * If the index is outside the range of the vector, an error will
2731 * be reported.
2732 * value
2733 * A pointer to a buffer in which to return the requested values.
2734 * If the requested cell is not found, or if it is found but has an
2735 * undefined value (see astMapPutU), then the contents of the buffer
2736 * on entry to this function will be unchanged on exit.
2737 * status
2738 * Pointer to inherited status value.
2739
2740 * Returned Value:
2741 * A non-zero value is returned if the requested key name was found, and
2742 * does not have an undefined value (see astMapPutU). Zero is returned
2743 * otherwise.
2744
2745 * MapGetElemC:
2746 * The "value" buffer supplied to the MapGetElemC function should be a
2747 * pointer to a character array with "l" elements, where "l" is
2748 * the maximum length of a string to be returned. The value of "l"
2749 * should be supplied as an extra parameter following "key" when
2750 * invoking MapGetElemC, and should include space for a terminating
2751 * null character.
2752
2753 * Notes:
2754 * - No error is reported if the requested cell cannot be found in the
2755 * given KeyMap, but a zero value will be returned as the function value.
2756 * The supplied buffer will be returned unchanged.
2757 * - Key names are case insensitive, and white space is considered
2758 * significant.
2759 * - If the stored value is a scalar value, then the value will be
2760 * returned in the first element of the supplied array, and "nval"
2761 * will be returned set to 1.
2762 */
2763
2764 /* Define a macro to implement the function for a specific data type
2765 (excluding "C" since that needs an extra parameter). */
2766 #define MAKE_MAPGETELEM(X,Xlc,Xtype,Itype) \
2767 static int MapGetElem##X( AstKeyMap *this_keymap, const char *key, int elem, \
2768 Xtype *value, int *status ) { \
2769 \
2770 /* Local Variables: */ \
2771 AstTable *this; /* Pointer to Table structure */ \
2772 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
2773 int irow; /* Row index within key string */ \
2774 int result; /* Returned flag */ \
2775 \
2776 /* Initialise */ \
2777 result = 0; \
2778 \
2779 /* Check the global error status. */ \
2780 if ( !astOK ) return result; \
2781 \
2782 /* Get a pointer to the Table structure. */ \
2783 this = (AstTable *) this_keymap; \
2784 \
2785 /* If the key is the name of a global table parameter, use the parent \
2786 method to get the value of hte parameter. */ \
2787 if( astHasParameter( this, key ) ) { \
2788 result = (*parent_mapgetelem##Xlc)( this_keymap, key, elem, \
2789 value, status ); \
2790 \
2791 /* Check the supplied key looks like a table cell key, and get the \
2792 the column name and the row number. Also checks that the table \
2793 contains a column with the specified name. */ \
2794 } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow, \
2795 NULL, "astMapGetElem" #X, status ) ) { \
2796 \
2797 /* If the row index is larger than the current number of rows in the \
2798 table, do nothing more. */ \
2799 if( irow <= astGetNrow( this ) ){ \
2800 \
2801 /* Use the astMapGetElem<X> method in the parent keyMap class to get the \
2802 cell contents. */ \
2803 result = (*parent_mapgetelem##Xlc)( this_keymap, key, elem, \
2804 value, status ); \
2805 } \
2806 } \
2807 \
2808 /* If an error occurred, return zero. */ \
2809 if( !astOK ) result = 0; \
2810 \
2811 /* Return the result.*/ \
2812 return result; \
2813 }
2814
2815 /* Expand the above macro to generate a function for each required
2816 data type. */
MAKE_MAPGETELEM(I,i,int,AST__INTTYPE)2817 MAKE_MAPGETELEM(I,i,int,AST__INTTYPE)
2818 MAKE_MAPGETELEM(D,d,double,AST__DOUBLETYPE)
2819 MAKE_MAPGETELEM(F,f,float,AST__FLOATTYPE)
2820 MAKE_MAPGETELEM(A,a,AstObject *,AST__OBJECTTYPE)
2821 MAKE_MAPGETELEM(P,p,void *,AST__POINTERTYPE)
2822 MAKE_MAPGETELEM(S,s,short int,AST__SINTTYPE)
2823 MAKE_MAPGETELEM(B,b,unsigned char,AST__BYTETYPE)
2824
2825 /* Undefine the macro. */
2826 #undef MAKE_MAPGETELEM
2827
2828 static int MapGetElemC( AstKeyMap *this_keymap, const char *key, int l,
2829 int elem, char *value, int *status ) {
2830 /*
2831 * Name:
2832 * MapGetElemC
2833
2834 * Purpose:
2835 * Get a single element of a vector value from a cell of a Table.
2836
2837 * Type:
2838 * Private function.
2839
2840 * Synopsis:
2841 * #include "table.h"
2842 * int MapGetElemC( AstKeyMap *this, const char *key, int l, int elem,
2843 * char *value, int *status )
2844
2845 * Class Membership:
2846 * Table member function (over-rides the astMapGetElemC method inherited
2847 * from the KeyMap class).
2848
2849 * Description:
2850 * This is the implementation of MapGetElem<X> for <X> = "C". We
2851 * cannot use the MAKE_MAPGETELEM macro for this because the string
2852 * version of this function has an extra parameter giving the maximum
2853 * length of each string which can be stored in the supplied buffer.
2854
2855 * Parameters:
2856 * (see MapGetElem<X>)
2857 */
2858
2859 /* Local Variables: */
2860 AstTable *this; /* Pointer to Table structure */
2861 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */
2862 int irow; /* Row index within key string */
2863 int result; /* Returned flag */
2864
2865 /* Initialise */
2866 result = 0;
2867
2868 /* Check the global error status. */
2869 if ( !astOK ) return result;
2870
2871 /* Get a pointer to the Table structure. */
2872 this = (AstTable *) this_keymap;
2873
2874 /* If the key is the name of a global table parameter, use the parent
2875 method to get the value of hte parameter. */
2876 if( astHasParameter( this, key ) ) {
2877 result = (*parent_mapgetelemc)( this_keymap, key, l, elem,
2878 value, status );
2879
2880 /* Check the supplied key looks like a table cell key, and get the
2881 the column name and the row number. Also checks that the table
2882 contains a column with the specified name. */
2883 } else if( ParseKey( this, key, astGetKeyError( this ), colname, &irow,
2884 NULL, "astMapGetElemC", status ) ) {
2885
2886 /* If the row index is larger than the current number of rows in the
2887 table, do nothing more. */
2888 if( irow <= astGetNrow( this ) ){
2889
2890 /* Use the astMapGetElem<X> method in the parent keyMap class to get the
2891 cell contents. */
2892 result = (*parent_mapgetelemc)( this_keymap, key, l, elem,
2893 value, status );
2894 }
2895 }
2896
2897 /* If an error occurred, return zero. */
2898 if( !astOK ) result = 0;
2899
2900 /* Return the result.*/
2901 return result;
2902 }
2903
2904 /*
2905 * Name:
2906 * MapPut0<X>
2907
2908 * Purpose:
2909 * Stores a scalar value in a cell of a Table.
2910
2911 * Type:
2912 * Private function.
2913
2914 * Synopsis:
2915 * #include "table.h"
2916 * void MapPut0<X>( AstKeyMap *this, const char *key, <X>type value,
2917 * const char *comment, int *status )
2918
2919 * Class Membership:
2920 * Table member function (over-rides the astMapPut0<X> method inherited
2921 * from the KeyMap class).
2922
2923 * Description:
2924 * This is a set of functions for storing a scalar value in a cell of
2925 * a Table. You should use a function which matches the data type of the
2926 * data you wish to add to the Table by replacing <X> in the generic
2927 * function name MapPut0<X> by an appropriate 1-character type code (see
2928 * the "Data Type Codes" section in the astMapPut0<X> docs).
2929
2930 * Parameters:
2931 * this
2932 * Pointer to the Table in which to store the supplied value.
2933 * key
2934 * A character string identifying the cell in which the value is
2935 * to be stored. It should have the form "COLNAME(irow)", where
2936 * "COLNAME" is replaced by the name of a column that has been
2937 * defined previously using the astAddColumn method, and "irow" is
2938 * an integer row index (the first row is row 1).
2939 * value
2940 * The value to be stored. The data type of this value should match
2941 * the 1-character type code appended to the function name (e.g. if
2942 * you are using astMapPut0A, the type of this value should be "pointer
2943 * to AstObject"). An error will be reported if this data type is
2944 * different to the data type assigned to the column when it was
2945 * created via astAddColumn.
2946 * comment
2947 * A pointer to a null-terminated comment string to be stored with the
2948 * value. A NULL pointer may be supplied, in which case no comment is
2949 * stored.
2950 * status
2951 * Pointer to inherited status value.
2952
2953 * Notes:
2954 * - Key names are case insensitive, and white space is considered
2955 * significant.
2956 * - The new value will replace any old value already stored in the
2957 * Table for the specified cell.
2958 * - If the stored value is an AST Object pointer, the Object's reference
2959 * count is incremented by this call. Any subsequent changes made to
2960 * the Object using the returned pointer will be reflected in any
2961 * any other active pointers for the Object, including any obtained
2962 * later using astMapget0A. The reference count for the Object will be
2963 * decremented when the KeyMap is destroyed, or the entry is removed or
2964 * over-written with a different pointer.
2965
2966 */
2967 /* Define a macro to implement the function for a specific data type. */
2968 #define MAKE_MAPPUT0(X,Xlc,Xtype,Itype,ValExp) \
2969 static void MapPut0##X( AstKeyMap *this_keymap, const char *key, Xtype value, \
2970 const char *comment, int *status ) { \
2971 \
2972 /* Local Variables: */ \
2973 AstKeyMap *col_km; /* KeyMap holding details of the requested column */ \
2974 AstTable *this; /* Pointer to Table structure */ \
2975 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
2976 int irow; /* Row index within key string */ \
2977 int type; /* Data type of the requested column */ \
2978 \
2979 /* Check the global error status. */ \
2980 if ( !astOK ) return; \
2981 \
2982 /* Get a pointer to the Table structure. */ \
2983 this = (AstTable *) this_keymap; \
2984 \
2985 /* If the key is the name of a global table parameter, use the parent \
2986 method to put the value of the parameter. */ \
2987 if( astHasParameter( this, key ) ) { \
2988 (*parent_mapput0##Xlc)( this_keymap, key, value, comment, status ); \
2989 \
2990 /* Check the supplied key looks like a table cell key, and get the \
2991 the column name and the row number. Also checks that the table \
2992 contains a column with the specified name. */ \
2993 } else if( ParseKey( this, key, 1, colname, &irow, &col_km, "astMapPut0" #X, \
2994 status ) ) { \
2995 \
2996 /* Check the column holds scalar values of the type implied by the <X> \
2997 code in the function name. */ \
2998 (void) astMapGet0I( col_km, TYPE, &type ); \
2999 if( type != Itype && astOK ) { \
3000 astError( AST__BADTYP, "astMapPut0" #X "(%s): Failed to store a " \
3001 #Xtype " value for cell \"%s\": column %s holds %s " \
3002 "values.", status, astGetClass( this ), key, colname, \
3003 TypeString( type ) ); \
3004 } \
3005 \
3006 if( astMapHasKey( col_km, SHAPE ) && astOK ) { \
3007 astError( AST__BADTYP, "astMapPut0" #X "(%s): Failed to store a " \
3008 "scalar value for cell \"%s\": column %s holds vector " \
3009 " values.", status, astGetClass( this ), key, colname ); \
3010 } \
3011 \
3012 /* If the row index is larger than the current number of rows in the \
3013 table, update the number of rows in the table. */ \
3014 if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \
3015 \
3016 /* Use the astMapPut0<X> method in the parent keyMap class to store the \
3017 new cell contents. */ \
3018 (*parent_mapput0##Xlc)( this_keymap, key, value, comment, status ); \
3019 \
3020 /* Free resources. */ \
3021 col_km = astAnnul( col_km ); \
3022 } \
3023 }
3024
3025 /* Expand the above macro to generate a function for each required
3026 data type. */
MAKE_MAPPUT0(I,i,int,AST__INTTYPE,value)3027 MAKE_MAPPUT0(I,i,int,AST__INTTYPE,value)
3028 MAKE_MAPPUT0(D,d,double,AST__DOUBLETYPE,value)
3029 MAKE_MAPPUT0(F,f,float,AST__FLOATTYPE,value)
3030 MAKE_MAPPUT0(C,c,const char *,AST__STRINGTYPE,astStore(NULL,value,strlen(value)+1))
3031 MAKE_MAPPUT0(A,a,AstObject *,AST__OBJECTTYPE,(value?astClone(value):NULL))
3032 MAKE_MAPPUT0(P,p,void *,AST__POINTERTYPE,value)
3033 MAKE_MAPPUT0(S,s,short int,AST__SINTTYPE,value)
3034 MAKE_MAPPUT0(B,b,unsigned char,AST__BYTETYPE,value)
3035
3036 /* Undefine the macro. */
3037 #undef MAKE_MAPPUT0
3038
3039 /*
3040 * Name:
3041 * MapPut1<X>
3042
3043 * Purpose:
3044 * Stores a vectorised value in a cell of a Table.
3045
3046 * Type:
3047 * Private function.
3048
3049 * Synopsis:
3050 * #include "table.h"
3051 * void MapPut1<X>( AstKeyMap *this, const char *key, int size,
3052 * const <X>type value[], const char *comment,
3053 * int *status );
3054
3055 * Class Membership:
3056 * Table member function (over-rides the astMapPut1<X> method inherited
3057 * from the KeyMap class).
3058
3059 * Description:
3060 * This is a set of functions for storing a vectorised value in a cell of
3061 * a Table. You should use a function which matches the data type of the
3062 * data you wish to add to the Table by replacing <X> in the generic
3063 * function name MapPut1<X> by an appropriate 1-character type code (see
3064 * the "Data Type Codes" section in the astMapPut1<X> docs).
3065
3066 * Parameters:
3067 * this
3068 * Pointer to the Table in which to store the supplied value.
3069 * key
3070 * A character string identifying the cell in which the value is
3071 * to be stored. It should have the form "COLNAME(irow)", where
3072 * "COLNAME" is replaced by the name of a column that has been
3073 * defined previously using the astAddColumn method, and "irow" is
3074 * an integer row index (the first row is row 1).
3075 * size
3076 * The number of elements in the supplied array of values.
3077 * value
3078 * The value to be stored. The data type of this value should match
3079 * the 1-character type code appended to the function name (e.g. if
3080 * you are using astMapPut0A, the type of this value should be "pointer
3081 * to AstObject"). An error will be reported if this data type is
3082 * different to the data type assigned to the column when it was
3083 * created via astAddColumn.
3084 * comment
3085 * A pointer to a null-terminated comment string to be stored with the
3086 * value. A NULL pointer may be supplied, in which case no comment is
3087 * stored.
3088 * status
3089 * Pointer to inherited status value.
3090
3091 * Notes:
3092 * - Key names are case insensitive, and white space is considered
3093 * significant.
3094 * - The new value will replace any old value already stored in the
3095 * Table for the specified cell.
3096
3097 */
3098
3099 /* Define a macro to implement the function for a specific data type. */
3100 #define MAKE_MAPPUT1(X,Xlc,Xtype,Itype,ValExp) \
3101 static void MapPut1##X( AstKeyMap *this_keymap, const char *key, int size, \
3102 Xtype value[], const char *comment, \
3103 int *status ) { \
3104 \
3105 /* Local Variables: */ \
3106 AstTable *this; /* Pointer to Table structure */ \
3107 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
3108 int irow; /* Row index within key string */ \
3109 \
3110 /* Check the global error status. */ \
3111 if ( !astOK ) return; \
3112 \
3113 /* Get a pointer to the Table structure. */ \
3114 this = (AstTable *) this_keymap; \
3115 \
3116 /* If the key is the name of a global table parameter, use the parent \
3117 method to put the value of the parameter. */ \
3118 if( astHasParameter( this, key ) ) { \
3119 (*parent_mapput1##Xlc)( this_keymap, key, size, value, \
3120 comment, status ); \
3121 \
3122 /* Check the supplied key looks like a table cell key, and get the \
3123 the column name and the row number. Also checks that the table \
3124 contains a column with the specified name. */ \
3125 } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPut1" #X, \
3126 status ) ) { \
3127 \
3128 /* Check the column holds vector values of the type implied by the <X> \
3129 code in the function name. */ \
3130 if( astGetColumnType( this, colname ) != Itype && astOK ) { \
3131 astError( AST__BADTYP, "astMapPut1" #X "(%s): Failed to store " \
3132 #Xtype " values for cell \"%s\": column %s holds %s values.", \
3133 status, astGetClass( this ), key, colname, \
3134 TypeString( astGetColumnType( this, colname ) ) ); \
3135 } \
3136 \
3137 /* Check the column holds vectors with length equal to the supplied vector. */ \
3138 if( astGetColumnLength( this, colname ) != size && astOK ) { \
3139 astError( AST__BADTYP, "astMapPut1" #X "(%s): Failed to " \
3140 "store a vector value for cell \"%s\": column " \
3141 "%s needs %d values per cell but %d were supplied.", \
3142 status, astGetClass( this ), key, colname, \
3143 astGetColumnLength( this, colname ), size ); \
3144 } \
3145 \
3146 /* If all is OK, update the number of rows in the table if required, and \
3147 store the vector in the parent KeyMap. */ \
3148 if( astOK ) { \
3149 if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \
3150 (*parent_mapput1##Xlc)( this_keymap, key, size, value, \
3151 comment, status ); \
3152 } \
3153 \
3154 } \
3155 }
3156
3157 /* Expand the above macro to generate a function for each required
3158 data type. */
3159 MAKE_MAPPUT1(D,d,const double,AST__DOUBLETYPE,value[i])
3160 MAKE_MAPPUT1(F,f,const float,AST__FLOATTYPE,value[i])
3161 MAKE_MAPPUT1(I,i,const int,AST__INTTYPE,value[i])
3162 MAKE_MAPPUT1(C,c,const char *const,AST__STRINGTYPE,astStore(NULL,value[i],strlen(value[i])+1))
3163 MAKE_MAPPUT1(A,a,AstObject *const,AST__OBJECTTYPE,(value[i]?astClone(value[i]):NULL))
3164 MAKE_MAPPUT1(P,p,void *const,AST__POINTERTYPE,value[i])
3165 MAKE_MAPPUT1(S,s,const short int,AST__SINTTYPE,value[i])
3166 MAKE_MAPPUT1(B,b,const unsigned char,AST__BYTETYPE,value[i])
3167
3168 /* Undefine the macro. */
3169 #undef MAKE_MAPPUT1
3170
3171 /*
3172 * Name:
3173 * MapPutElem<X>
3174
3175 * Purpose:
3176 * Put a value into an element of a vector value in a cell of a Table.
3177
3178 * Type:
3179 * Private function.
3180
3181 * Synopsis:
3182 * #include "table.h"
3183 * void MapPutElem<X>( AstKeyMap *this, const char *key, int elem,
3184 * <X>type *value, int *status )
3185
3186 * Class Membership:
3187 * Table member function (over-rides the astMapPutElem<X> method inherited
3188 * from the KeyMap class).
3189
3190 * Description:
3191 * This is a set of functions for storing a value in a single element
3192 * of a vector value stored in a cell of a Table. You should use a
3193 * function which matches the data type of the data you wish to add to
3194 * the Table by replacing <X> in the generic function name MapPutElem<X>
3195 * by an appropriate 1-character type code (see the "Data Type Codes"
3196 * section in the astMapPutElem<X> docs).
3197
3198 * Parameters:
3199 * this
3200 * Pointer to the Table in which to store the supplied value.
3201 * key
3202 * A character string identifying the cell in which the value is
3203 * to be stored. It should have the form "COLNAME(irow)", where
3204 * "COLNAME" is replaced by the name of a column that has been
3205 * defined previously using the astAddColumn method, and "irow" is
3206 * an integer row index (the first row is row 1).
3207 * elem
3208 * The index of the vector element to modify, starting at zero.
3209 * If the index is outside the range of the vector, an error will
3210 * be reported.
3211 * value
3212 * The value to be stored. The data type of this value should match
3213 * the 1-character type code appended to the function name (e.g. if
3214 * you are using astMapPut0A, the type of this value should be "pointer
3215 * to AstObject"). An error will be reported if this data type is
3216 * different to the data type assigned to the column when it was
3217 * created via astAddColumn.
3218 * status
3219 * Pointer to inherited status value.
3220
3221 * Notes:
3222 * - Key names are case insensitive, and white space is considered
3223 * significant.
3224 * - The new value will replace any old value already stored in the
3225 * Table for the specified cell.
3226 * - If the stored value is an AST Object pointer, the Object's reference
3227 * count is incremented by this call. Any subsequent changes made to
3228 * the Object using the returned pointer will be reflected in any
3229 * any other active pointers for the Object, including any obtained
3230 * later using astMapget0A. The reference count for the Object will be
3231 * decremented when the KeyMap is destroyed, or the entry is removed or
3232 * over-written with a different pointer.
3233
3234 */
3235 /* Define a macro to implement the function for a specific data type. */
3236
3237 #define MAKE_MAPPUTELEM(X,Xlc,Xtype,Itype) \
3238 static void MapPutElem##X( AstKeyMap *this_keymap, const char *key, int elem, \
3239 Xtype value, int *status ) { \
3240 \
3241 /* Local Variables: */ \
3242 AstTable *this; /* Pointer to Table structure */ \
3243 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */ \
3244 int irow; /* Row index within key string */ \
3245 int type; /* Data type of the requested column */ \
3246 \
3247 /* Check the global error status. */ \
3248 if ( !astOK ) return; \
3249 \
3250 /* Get a pointer to the Table structure. */ \
3251 this = (AstTable *) this_keymap; \
3252 \
3253 /* If the key is the name of a global table parameter, use the parent \
3254 method to put the value of the parameter. */ \
3255 if( astHasParameter( this, key ) ) { \
3256 (*parent_mapputelem##Xlc)( this_keymap, key, elem, value, \
3257 status ); \
3258 \
3259 /* Check the supplied key looks like a table cell key, and get the \
3260 the column name and the row number. Also checks that the table \
3261 contains a column with the specified name. */ \
3262 } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPutElem" #X, \
3263 status ) ) { \
3264 \
3265 /* Check the column holds vector values of the type implied by the <X> \
3266 code in the function name. */ \
3267 type = astGetColumnType( this, colname ); \
3268 if( type != Itype && astOK ) { \
3269 astError( AST__BADTYP, "astMapPutElem" #X "(%s): Failed to store a " \
3270 #Xtype " value in cell \"%s\": column %s holds %s values.", \
3271 status, astGetClass( this ), key, colname, \
3272 TypeString( type ) ); \
3273 } \
3274 \
3275 /* Check the column holds vectors with length equal to the supplied vector. */ \
3276 if( astGetColumnLength( this, colname ) <= elem && astOK ) { \
3277 astError( AST__BADTYP, "astMapPutElem" #X "(%s): Failed to " \
3278 "store a value for element %d (zero-based) of " \
3279 "cell \"%s\": column %s has only %d values per " \
3280 "cell.", status, astGetClass( this ), elem, key, \
3281 colname, astGetColumnLength( this, colname ) ); \
3282 } \
3283 \
3284 /* If all is OK, update the number of rows in the table if required, and \
3285 store the value in the parent KeyMap. */ \
3286 if( astOK ) { \
3287 if( irow > astGetNrow( this ) ) astSetNrow( this, irow ); \
3288 (*parent_mapputelem##Xlc)( this_keymap, key, elem, value, \
3289 status ); \
3290 } \
3291 } \
3292 }
3293
3294 /* Expand the above macro to generate a function for each required
3295 data type. */
3296 MAKE_MAPPUTELEM(I,i,int,AST__INTTYPE)
3297 MAKE_MAPPUTELEM(D,d,double,AST__DOUBLETYPE)
3298 MAKE_MAPPUTELEM(F,f,float,AST__FLOATTYPE)
3299 MAKE_MAPPUTELEM(A,a,AstObject *,AST__OBJECTTYPE)
3300 MAKE_MAPPUTELEM(P,p,void *,AST__POINTERTYPE)
3301 MAKE_MAPPUTELEM(C,c,const char *,AST__STRINGTYPE)
3302 MAKE_MAPPUTELEM(S,s,short int,AST__SINTTYPE)
3303 MAKE_MAPPUTELEM(B,b,unsigned char,AST__BYTETYPE)
3304
3305 /* Undefine the macro. */
3306 #undef MAKE_MAPPUTELEM
3307
3308 static void MapPutU( AstKeyMap *this_keymap, const char *key, const char *comment,
3309 int *status ) {
3310 /*
3311 * Name:
3312 * MapPutU
3313
3314 * Purpose:
3315 * Stores a undefined value in a cell of a Table.
3316
3317 * Type:
3318 * Private function.
3319
3320 * Synopsis:
3321 * #include "table.h"
3322 * void MapPutU( AstKeyMap *this, const char *key, const char *comment,
3323 * int *status )
3324
3325 * Class Membership:
3326 * Table member function (over-rides the astMapPutU method inherited
3327 * from the KeyMap class).
3328
3329 * Description:
3330 * This function adds a new cell to a Table, but no value is stored with
3331 * the cell. The cell therefore has a special data type represented by
3332 * symbolic constant AST__UNDEFTYPE.
3333 *
3334 * An example use is to add cells with undefined values to a Table
3335 * prior to locking them with the MapLocked attribute. Such cells
3336 * can act as placeholders for values that can be added to the KeyMap
3337 * later.
3338
3339 * Parameters:
3340 * this
3341 * Pointer to the Table in which to store the supplied value.
3342 * key
3343 * A character string identifying the cell in which the value is
3344 * to be stored. It should have the form "COLNAME(irow)", where
3345 * "COLNAME" is replaced by the name of a column that has been
3346 * defined previously using the astAddColumn method, and "irow" is
3347 * an integer row index (the first row is row 1).
3348 * comment
3349 * A pointer to a null-terminated comment string to be stored with the
3350 * value. A NULL pointer may be supplied, in which case no comment is
3351 * stored.
3352 * status
3353 * Pointer to inherited status value.
3354
3355 * Notes:
3356 * - Key names are case insensitive, and white space is considered
3357 * significant.
3358 * - The new undefined value will replace any old value already stored in
3359 * the Table for the specified cell.
3360
3361 */
3362
3363 /* Local Variables: */
3364 AstTable *this; /* Pointer to Table structure */
3365 char colname[ AST__MXCOLNAMLEN + 1 ]; /* Column name read from string */
3366 int irow; /* Row index within key string */
3367
3368 /* Check the global error status. */
3369 if ( !astOK ) return;
3370
3371 /* Get a pointer to the Table structure. */
3372 this = (AstTable *) this_keymap;
3373
3374 /* If the key is the name of a global table parameter, use the parent
3375 method to put the value of the parameter. */
3376 if( astHasParameter( this, key ) ) {
3377 (*parent_mapputu)( this_keymap, key, comment, status );
3378
3379 /* Check the supplied key looks like a table cell key, and get the
3380 the column name and the row number. Also checks that the table
3381 contains a column with the specified name. */
3382 } else if( ParseKey( this, key, 1, colname, &irow, NULL, "astMapPutU",
3383 status ) ) {
3384
3385 /* If the row index is larger than the current number of rows in the
3386 table, update the number of rows in the table. */
3387 if( irow > astGetNrow( this ) ) astSetNrow( this, irow );
3388
3389 /* Use the astMapPutU method in the parent keyMap class to store the
3390 new cell contents. */
3391 (*parent_mapputu)( this_keymap, key, comment, status );
3392 }
3393 }
3394
ParameterName(AstTable * this,int index,int * status)3395 static const char *ParameterName( AstTable *this, int index, int *status ) {
3396 /*
3397 *++
3398 * Name:
3399 c astParameterName
3400 f AST_PARAMETERNAME
3401
3402 * Purpose:
3403 * Get the name of the global parameter at a given index within the Table.
3404
3405 * Type:
3406 * Public virtual function.
3407
3408 * Synopsis:
3409 c #include "table.h"
3410 c const char *astParameterName( AstTable *this, int index )
3411 f RESULT = AST_PARAMETERNAME( THIS, INDEX, STATUS )
3412
3413 * Class Membership:
3414 * Table method.
3415
3416 * Description:
3417 * This function returns a string holding the name of the global parameter with
3418 * the given index within the Table.
3419 *
3420 * This function is intended primarily as a means of iterating round all
3421 * the parameters in a Table. For this purpose, the number of parameters in
3422 * the Table is given by the Nparameter attribute of the Table. This function
3423 * could then be called in a loop, with the index value going from
3424 c zero to one less than Nparameter.
3425 f one to Nparameter.
3426 *
3427 * Note, the index associated with a parameter decreases monotonically with
3428 * the age of the parameter: the oldest Parameter in the Table will have index
3429 * one, and the Parameter added most recently to the Table will have the
3430 * largest index.
3431
3432 * Parameters:
3433 c this
3434 f THIS = INTEGER (Given)
3435 * Pointer to the Table.
3436 c index
3437 f INDEX = INTEGER (Given)
3438 * The index into the list of parameters. The first parameter has index
3439 * one, and the last has index "Nparameter".
3440 f STATUS = INTEGER (Given and Returned)
3441 f The global status.
3442
3443 * Returned Value:
3444 c astParameterName()
3445 c A pointer to a null-terminated string containing the
3446 f AST_PARAMETERNAME = CHARACTER * ( AST__SZCHR )
3447 f The
3448 * upper case parameter name.
3449
3450 * Notes:
3451 c - The returned pointer is guaranteed to remain valid and the
3452 c string to which it points will not be over-written for a total
3453 c of 50 successive invocations of this function. After this, the
3454 c memory containing the string may be re-used, so a copy of the
3455 c string should be made if it is needed for longer than this.
3456 c - A NULL pointer will be returned if this function is invoked
3457 c with the AST error status set, or if it should fail for any
3458 c reason.
3459 f - A blank string will be returned if this function is invoked
3460 f with STATUS set to an error value, or if it should fail for any
3461 f reason.
3462 *--
3463 */
3464
3465 /* Local Variables: */
3466 AstKeyMap *pars; /* KeyMap holding parameter definitions */
3467 const char *result;
3468
3469 /* Check the global error status. */
3470 if ( !astOK ) return NULL;
3471
3472 /* Get apointer to the KeyMap holding all parameter definitions. */
3473 pars = astParameterProps( this );
3474
3475 /* Issue a more useful error message than that issued by astMapKey if the
3476 index is invalid. */
3477 if( index < 1 || index > astMapSize( pars ) ) {
3478 astError( AST__MPIND, "astParameterName(%s): Cannot find parameter "
3479 "%d (zero-based) of the %s - invalid index.", status,
3480 astGetClass( this ), index, astGetClass( this ) );
3481 }
3482
3483 /* Get the parameter name. */
3484 result = astMapKey( pars, index - 1 );
3485
3486 /* Free resources. */
3487 pars = astAnnul( pars );
3488
3489 /* Return a pointer to the required parameter name. */
3490 return result;
3491 }
3492
ParameterProps(AstTable * this,int * status)3493 static AstKeyMap *ParameterProps( AstTable *this, int *status ) {
3494 /*
3495 *+
3496 * Name:
3497 * astParameterProps
3498
3499 * Purpose:
3500 * Returns a pointer to the KeyMap holding parameter properties.
3501
3502 * Type:
3503 * Protected virtual function.
3504
3505 * Synopsis:
3506 * #include "table.h"
3507 * AstKeyMap *astParameterProps( AstTable *this )
3508
3509 * Class Membership:
3510 * Table method.
3511
3512 * Description:
3513 * This function returns a pointer to the KeyMap that holds
3514 * definitions of all the parameters added to the Table.
3515
3516 * Parameters:
3517 * this
3518 * Pointer to the Table.
3519
3520 * Returned Value:
3521 * A pointer to the KeyMap. It should be annulled using astAnnul
3522 * when no longer needed.
3523
3524 *-
3525 */
3526
3527 /* Check the global error status. */
3528 if ( !astOK ) return NULL;
3529
3530 /* Return a cloned pointer to the required KeyMap. */
3531 return astClone( this->parameters );
3532 }
3533
ParseKey(AstTable * this,const char * key,int report,char colname[AST__MXCOLNAMLEN+1],int * irow,AstKeyMap ** col_km,const char * method,int * status)3534 static int ParseKey( AstTable *this, const char *key, int report,
3535 char colname[ AST__MXCOLNAMLEN + 1 ], int *irow,
3536 AstKeyMap **col_km, const char *method, int *status ){
3537 /*
3538 * Name:
3539 * ParseKey
3540
3541 * Purpose:
3542 * Find the column name and row index in a KeyMap key.
3543
3544 * Type:
3545 * Private function.
3546
3547 * Synopsis:
3548 * #include "table.h"
3549 * int ParseKey( AstTable *this, const char *key, int report,
3550 * char colname[ AST__MXCOLNAMLEN + 1 ], int *irow,
3551 * AstKeyMap **col_km, const char *method, int *status )
3552
3553 * Class Membership:
3554 * Table member function
3555
3556 * Description:
3557 * This function checks that the supplied KeyMap key conforms to the
3558 * format expected for Table cells: i.e. "COLNAME(irow)", where
3559 * "COLNAME" is the name of a column and "irow" is an integer row
3560 * index (the first row is row 1), An error is reported if this is
3561 * not the case.
3562
3563 * Parameters:
3564 * this
3565 * Pointer to the table.
3566 * key
3567 * The key string to test.
3568 * report
3569 * If non-zero, an error will be reported if the key does not
3570 * correspond to a cell of an existing column. Otherwise, no
3571 * error will be reported.
3572 * colname
3573 * A buffer in which to return the column name.
3574 * irow
3575 * Address of an int in which to return the row index.
3576 * col_km
3577 * Address of a KeyMap pointer in which to return a pointer to the
3578 * KeyMap holding the information about the column. The returned
3579 * KeyMap pointer should be annulled using astAnnul when no lngerr
3580 * needed. If "col_km" is NULL, no KeyMap pointer is returned.
3581 * method
3582 * Pointer to a string holding the name of the method to include in
3583 * any error message.
3584 * status
3585 * Address of the inherited status value.
3586
3587 * Returned Value:
3588 * Zero is returned if the key is not a valid Table cell key, or if an
3589 * error occurs.
3590
3591 */
3592
3593 /* Local Variables: */
3594 AstKeyMap *cols; /* KeyMap holding column definitions */
3595 int result; /* Returned flag */
3596 int collen; /* Length of column name */
3597 int nctot; /* Number of characters read */
3598
3599 /* Initialise */
3600 result = 0;
3601
3602 /* Check the global error status. */
3603 if ( !astOK ) return result;
3604
3605 /* Check the supplied key looks like a table cell key, and extract the
3606 column name and row number. */
3607 nctot = 0;
3608 if( 1 == astSscanf( key, "%*[^(]%n(%d) %n", &collen, irow, &nctot )
3609 && ( nctot >= strlen( key ) ) ) {
3610
3611 /* Check the column name is not too long. */
3612 if( collen > AST__MXCOLNAMLEN ) {
3613 if( report ) {
3614 astError( AST__BADKEY, "%s(%s): Failed to store a value for cell "
3615 "\"%s\": column name is too long.", status, method,
3616 astGetClass( this ), key );
3617 }
3618
3619 /* Check the row index is positive. */
3620 } else if( *irow < 1 ) {
3621 if( report ) {
3622 astError( AST__BADKEY, "%s(%s): Failed to store a value for cell "
3623 "\"%s\": row index %d is invalid.", status, method,
3624 astGetClass( this ), key, *irow );
3625 }
3626
3627 /* If the key looks OK so far... */
3628 } else {
3629
3630 /* Convert the column name to upper case and store in the returned buffer. */
3631 astChrCase( key, colname, 1, collen + 1 );
3632 colname[ collen ] = 0;
3633
3634 /* check that the column exists in the Table, returning a pointer to the
3635 column KeyMap is reequired. */
3636 cols = astColumnProps( this );
3637 if( col_km ) {
3638 result = astMapGet0A( cols, colname, col_km );
3639 } else {
3640 result = astMapHasKey( cols, colname );
3641 }
3642 cols = astAnnul( cols );
3643
3644 /* Report an error if the table does not contain the specified column. */
3645 if( !result && astOK && report) {
3646 astError( AST__BADKEY, "%s(%s): Failed to store a value for "
3647 "cell \"%s\": the table does not contain a column "
3648 "called '%s'.", status, method, astGetClass( this ),
3649 key, colname );
3650 }
3651 }
3652
3653 /* Report an error if the cell key has the wrong format. */
3654 } else if( report ) {
3655 astError( AST__BADKEY, "%s(%s): Failed to store a value for cell "
3656 "\"%s\": the cell name is invalid.", status, method,
3657 astGetClass( this ), key );
3658 }
3659
3660 /* Return the result.*/
3661 return result;
3662 }
3663
PurgeRows(AstTable * this,int * status)3664 static void PurgeRows( AstTable *this, int *status ) {
3665 /*
3666 *++
3667 * Name:
3668 c astPurgeRows
3669 f AST_PURGEROWS
3670
3671 * Purpose:
3672 * Remove all empty rows from a table.
3673
3674 * Type:
3675 * Public virtual function.
3676
3677 * Synopsis:
3678 c #include "table.h"
3679 c void astPurgeRows( AstTable *this )
3680 f CALL AST_PURGEROWS( THIS, STATUS )
3681
3682 * Class Membership:
3683 * Table method.
3684
3685 * Description:
3686 * This function removes all empty rows from the Table, renaming
3687 * the key associated with each table cell accordingly.
3688
3689 * Parameters:
3690 c this
3691 f THIS = INTEGER (Given)
3692 * Pointer to the Table.
3693 f STATUS = INTEGER (Given and Returned)
3694 f The global status.
3695
3696 *--
3697 */
3698
3699 /* Local Variables: */
3700 char newkey[ AST__MXCOLKEYLEN + 1 ]; /* New cell key string */
3701 char oldkey[ AST__MXCOLKEYLEN + 1 ]; /* Old cell key string */
3702 const char *col; /* Column name */
3703 const char *key; /* Pointer to key string */
3704 const char *op; /* Pointer to opening parenthesis */
3705 int *w1; /* Work space pointer */
3706 int icol; /* Column index */
3707 int inew; /* New row index */
3708 int iold; /* Old row index */
3709 int ncol; /* Number of columns in table */
3710 int nrow; /* Number of rows in table */
3711 int reset; /* Start a new pass through the KeyMap? */
3712
3713 /* Check the global error status. */
3714 if ( !astOK ) return;
3715
3716 /* Get the number of rows in the table. */
3717 nrow = astGetNrow( this );
3718
3719 /* Create workspace to hold the number of defined values stored in each
3720 row. Initialise every row to have zero defined values. */
3721 w1 = astCalloc( nrow, sizeof( int ) );
3722 if( astOK ) {
3723
3724 /* Iterate round all keys in the KeyMap. */
3725 reset = 1;
3726 while( ( key = astMapIterate( this, reset ) ) && astOK ) {
3727 reset = 0;
3728
3729 /* Extract the row number from the key. */
3730 op = strchr( key, '(' );
3731 if( !op || astSscanf( op + 1, "%d", &iold ) != 1 ||
3732 iold > nrow ) {
3733 astError( AST__INTER, "astPurgeRows(%s): Illegal key '%s' "
3734 "found in a %s (internal programming error).",
3735 status, astGetClass( this ), key, astGetClass( this ) );
3736
3737 /* Increment the number of values in this row. Note row indices are
3738 one-based. */
3739 } else {
3740 w1[ iold - 1 ]++;
3741 }
3742 }
3743
3744 /* Loop round all columns in the Table. */
3745 ncol = astGetNcolumn( this );
3746 inew = nrow;
3747 for( icol = 1; icol <= ncol; icol++ ) {
3748
3749 /* Get the column name */
3750 col = astColumnName( this, icol );
3751
3752 /* Loop round all the old row numbers. Skip empty rows.*/
3753 inew = 0;
3754 for( iold = 0; iold < nrow; iold++ ) {
3755 if( w1[ iold ] > 0 ) {
3756
3757 /* Increment the row number to use in place of the old row number. If the
3758 old and new row numbers are the same, we do not need to rename the cell. */
3759 if( iold != inew++ ) {
3760
3761 /* For the old and new cell names */
3762 sprintf( oldkey, "%s(%d)", col, iold + 1 );
3763 sprintf( newkey, "%s(%d)", col, inew );
3764
3765 /* Rename the KeyMap entry. */
3766 astMapRename( this, oldkey, newkey );
3767 }
3768 }
3769 }
3770
3771 /* If all rows were used, we do not need to check any more columns. */
3772 if( iold == inew ) break;
3773 }
3774
3775 /* Store the new number of rows. */
3776 astSetNrow( this, inew );
3777 }
3778
3779 /* Free resources. */
3780 w1 = astFree( w1 );
3781
3782 }
3783
RemoveColumn(AstTable * this,const char * name,int * status)3784 static void RemoveColumn( AstTable *this, const char *name, int *status ) {
3785 /*
3786 *++
3787 * Name:
3788 c astRemoveColumn
3789 f AST_REMOVECOLUMN
3790
3791 * Purpose:
3792 * Remove a column from a table.
3793
3794 * Type:
3795 * Public virtual function.
3796
3797 * Synopsis:
3798 c #include "table.h"
3799 c void astRemoveColumn( AstTable *this, const char *name )
3800 f CALL AST_REMOVECOLUMN( THIS, NAME, STATUS )
3801
3802 * Class Membership:
3803 * Table method.
3804
3805 * Description:
3806 * This function removes a specified column from the supplied table.
3807 * The
3808 c function
3809 f routine
3810 * returns without action if the named column does not exist in the
3811 * Table (no error is reported).
3812
3813 * Parameters:
3814 c this
3815 f THIS = INTEGER (Given)
3816 * Pointer to the Table.
3817 c name
3818 f NAME = CHARACTER * ( * ) (Given)
3819 * The column name. Trailing spaces are ignored (all other spaces
3820 * are significant). Case is significant.
3821 f STATUS = INTEGER (Given and Returned)
3822 f The global status.
3823
3824 *--
3825 */
3826
3827 /* Local Variables: */
3828 AstKeyMap *cols; /* KeyMap holding column definitions */
3829 char key[ AST__MXCOLKEYLEN + 1 ]; /* Cell key string */
3830 int irow; /* Row index */
3831 int namlen; /* Used length of "name" */
3832 int nrow; /* Number of rows in table */
3833
3834 /* Check the global error status. */
3835 if ( !astOK ) return;
3836
3837 /* Verify supplied values. */
3838 namlen = astChrLen( name );
3839 if( namlen == 0 ) {
3840 astError( AST__BADKEY, "astRemoveColumn(%s): Illegal blank column name "
3841 "supplied.", status, astGetClass( this ) );
3842 }
3843
3844 /* Get the number of rows in the table. */
3845 nrow = astGetNrow( this );
3846
3847 /* If there is no column with the given name in the Table, do nothing more. */
3848 cols = astColumnProps( this );
3849 if( astOK && astMapHasKey( cols, name ) ) {
3850
3851 /* Remove the column description from the columns keymap. */
3852 astMapRemove( cols, name );
3853
3854 /* Remove any column cells with defined values from the parent KeyMap. */
3855 for( irow = 1; irow <= nrow; irow++ ) {
3856 sprintf( key, "%.*s(%d)", namlen, name, irow );
3857 (*parent_mapremove)( (AstKeyMap *) this, key, status );
3858 }
3859 }
3860 cols = astAnnul( cols );
3861 }
3862
RemoveParameter(AstTable * this,const char * name,int * status)3863 static void RemoveParameter( AstTable *this, const char *name, int *status ) {
3864 /*
3865 *++
3866 * Name:
3867 c astRemoveParameter
3868 f AST_REMOVEPARAMETER
3869
3870 * Purpose:
3871 * Remove a global parameter from a table.
3872
3873 * Type:
3874 * Public virtual function.
3875
3876 * Synopsis:
3877 c #include "table.h"
3878 c void astRemoveParameter( AstTable *this, const char *name )
3879 f CALL AST_REMOVEPARAMETER( THIS, NAME, STATUS )
3880
3881 * Class Membership:
3882 * Table method.
3883
3884 * Description:
3885 * This function removes a specified global parameter from the supplied table.
3886 * The
3887 c function
3888 f routine
3889 * returns without action if the named parameter does not exist in the
3890 * Table (no error is reported).
3891
3892 * Parameters:
3893 c this
3894 f THIS = INTEGER (Given)
3895 * Pointer to the Table.
3896 c name
3897 f NAME = CHARACTER * ( * ) (Given)
3898 * The parameter name. Trailing spaces are ignored (all other spaces
3899 * are significant). Case is significant.
3900 f STATUS = INTEGER (Given and Returned)
3901 f The global status.
3902
3903 *--
3904 */
3905
3906 /* Local Variables: */
3907 AstKeyMap *pars; /* KeyMap holding parameter definitions */
3908
3909 /* Check the global error status. */
3910 if ( !astOK ) return;
3911
3912 /* Verify supplied values. */
3913 if( astChrLen( name ) == 0 ) {
3914 astError( AST__BADKEY, "astRemoveParameter(%s): Illegal blank parameter name "
3915 "supplied.", status, astGetClass( this ) );
3916 }
3917
3918 /* If there is no parameter with the given name in the Table, do nothing more. */
3919 pars = astParameterProps( this );
3920 if( astOK && astMapHasKey( pars, name ) ) {
3921
3922 /* Remove the parameter description from the parameters keymap. */
3923 astMapRemove( pars, name );
3924
3925 /* Remove any entry holding the parameter value from the parent KeyMap. */
3926 (*parent_mapremove)( (AstKeyMap *) this, name, status );
3927 }
3928 pars = astAnnul( pars );
3929 }
3930
RemoveRow(AstTable * this,int index,int * status)3931 static void RemoveRow( AstTable *this, int index, int *status ) {
3932 /*
3933 *++
3934 * Name:
3935 c astRemoveRow
3936 f AST_REMOVEROW
3937
3938 * Purpose:
3939 * Remove a row from a table.
3940
3941 * Type:
3942 * Public virtual function.
3943
3944 * Synopsis:
3945 c #include "table.h"
3946 c void astRemoveRow( AstTable *this, int index )
3947 f CALL AST_REMOVEROW( THIS, INDEX, STATUS )
3948
3949 * Class Membership:
3950 * Table method.
3951
3952 * Description:
3953 * This function removes a specified row from the supplied table.
3954 * The
3955 c function
3956 f routine
3957 * returns without action if the row does not exist in the
3958 * Table (no error is reported).
3959
3960 * Parameters:
3961 c this
3962 f THIS = INTEGER (Given)
3963 * Pointer to the Table.
3964 c index
3965 f INDEX = INTEGER (Given)
3966 * The index of the row to be removed. The first row has index 1.
3967 f STATUS = INTEGER (Given and Returned)
3968 f The global status.
3969
3970 *--
3971 */
3972
3973 /* Local Variables: */
3974 AstKeyMap *cols; /* KeyMap holding column definitions */
3975 char key[ AST__MXCOLKEYLEN + 1 ]; /* Cell key string */
3976 const char *col; /* Column name */
3977 int icol; /* Column index */
3978 int ncol; /* Number of columns in table */
3979 int nrow; /* Number of rows in table */
3980
3981 /* Check the global error status. */
3982 if ( !astOK ) return;
3983
3984 /* Get the number of rows in the table. */
3985 nrow = astGetNrow( this );
3986
3987 /* Do nothing if the specified row is out of bounds. */
3988 if( index > 0 && index <= nrow ) {
3989
3990 /* Loop round all columns in the table. */
3991 cols = astColumnProps( this );
3992 ncol = astMapSize( cols );
3993 for( icol = 0; icol < ncol; icol++ ) {
3994 col = astMapKey( cols, icol );
3995
3996 /* Remove the cell of the current column at the requested row. */
3997 sprintf( key, "%s(%d)", col, index );
3998 (*parent_mapremove)( (AstKeyMap *) this, key, status );
3999 }
4000 cols = astAnnul( cols );
4001
4002 /* If the removed row was the last row, reduce the number of rows in the
4003 Table. */
4004 if( index == nrow ) astSetNrow( this, index - 1 );
4005 }
4006 }
4007
SetAttrib(AstObject * this_object,const char * setting,int * status)4008 static void SetAttrib( AstObject *this_object, const char *setting, int *status ) {
4009 /*
4010 * Name:
4011 * SetAttrib
4012
4013 * Purpose:
4014 * Set an attribute value for a Table.
4015
4016 * Type:
4017 * Private function.
4018
4019 * Synopsis:
4020 * #include "table.h"
4021 * void SetAttrib( AstObject *this, const char *setting, int *status )
4022
4023 * Class Membership:
4024 * Table member function (over-rides the astSetAttrib protected
4025 * method inherited from the KeyMap class).
4026
4027 * Description:
4028 * This function assigns an attribute value for a Table, the
4029 * attribute and its value being specified by means of a string of
4030 * the form:
4031 *
4032 * "attribute= value "
4033 *
4034 * Here, "attribute" specifies the attribute name and should be in
4035 * lower case with no white space present. The value to the right
4036 * of the "=" should be a suitable textual representation of the
4037 * value to be assigned and this will be interpreted according to
4038 * the attribute's data type. White space surrounding the value is
4039 * only significant for string attributes.
4040
4041 * Parameters:
4042 * this
4043 * Pointer to the Table.
4044 * setting
4045 * Pointer to a null terminated string specifying the new attribute
4046 * value.
4047 * status
4048 * Pointer to the inherited status variable.
4049 */
4050
4051 /* Local Variables: */
4052 AstTable *this; /* Pointer to the Table structure */
4053 int len; /* Length of setting string */
4054 int nc; /* Number of characters read by astSscanf */
4055
4056 /* Check the global error status. */
4057 if ( !astOK ) return;
4058
4059 /* Obtain a pointer to the Table structure. */
4060 this = (AstTable *) this_object;
4061
4062 /* Obtain the length of the setting string. */
4063 len = (int) strlen( setting );
4064
4065 /* Test for each recognised attribute in turn, using "astSscanf" to parse
4066 the setting string and extract the attribute value (or an offset to
4067 it in the case of string values). In each case, use the value set
4068 in "nc" to check that the entire string was matched. Once a value
4069 has been obtained, use the appropriate method to set it. */
4070 /* None as yet */
4071
4072 /* Define a macro to see if the setting string matches any of the
4073 read-only attributes of this class. */
4074 #define MATCH(attrib) \
4075 ( nc = 0, ( 0 == astSscanf( setting, attrib "=%*[^\n]%n", &nc ) ) && \
4076 ( nc >= len ) )
4077
4078 #define MATCH2(attrib) \
4079 ( nc = 0, ( 0 == astSscanf( setting, attrib "(%*s) =%*[^\n]%n", &nc ) ) && \
4080 ( nc >= len ) )
4081
4082 /* If the attribute was not recognised, use this macro to report an error
4083 if a read-only attribute has been specified. */
4084 if ( MATCH( "ncolumn" ) ||
4085 MATCH( "nparameter" ) ||
4086 MATCH( "nrow" ) ||
4087 MATCH2( "columnlenc" ) ||
4088 MATCH2( "columnlength" ) ||
4089 MATCH2( "columnndim" ) ||
4090 MATCH2( "columntype" ) ||
4091 MATCH2( "columnunit" ) ) {
4092 astError( AST__NOWRT, "astSet: The setting \"%s\" is invalid for a %s.", status,
4093 setting, astGetClass( this ) );
4094 astError( AST__NOWRT, "This is a read-only attribute." , status);
4095
4096 /* If the attribute is still not recognised, pass it on to the parent
4097 method for further interpretation. */
4098 } else {
4099 (*parent_setattrib)( this_object, setting, status );
4100 }
4101
4102 /* Undefine macros local to this function. */
4103 #undef MATCH
4104 #undef MATCH2
4105 }
4106
SetKeyCase(AstKeyMap * this,int keycase,int * status)4107 static void SetKeyCase( AstKeyMap *this, int keycase, int *status ) {
4108 /*
4109 * Name:
4110 * SetKeyCase
4111
4112 * Purpose:
4113 * Set a value for the KeyCase attribute value for a Table.
4114
4115 * Type:
4116 * Private function.
4117
4118 * Synopsis:
4119 * #include "keymape.h"
4120 * void SetKeyCase( AstKeyMap *this, int keycase, int *status )
4121
4122 * Class Membership:
4123 * Table member function (over-rides the astSetKeyCase protected
4124 * method inherited from the KeyMap class).
4125
4126 * Description:
4127 * This function assigns a new valeu to the KeyCase attribute for a
4128 * Table. For a Table, the KeyCase attribute cannot be changed so this
4129 * function exits without action.
4130
4131 * Parameters:
4132 * this
4133 * Pointer to the Table.
4134 * keycase
4135 * The new value to set.
4136 */
4137
4138 }
4139
TestAttrib(AstObject * this_object,const char * attrib,int * status)4140 static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) {
4141 /*
4142 * Name:
4143 * TestAttrib
4144
4145 * Purpose:
4146 * Test if a specified attribute value is set for a Table.
4147
4148 * Type:
4149 * Private function.
4150
4151 * Synopsis:
4152 * #include "table.h"
4153 * int TestAttrib( AstObject *this, const char *attrib, int *status )
4154
4155 * Class Membership:
4156 * Table member function (over-rides the astTestAttrib protected
4157 * method inherited from the KeyMap class).
4158
4159 * Description:
4160 * This function returns a boolean result (0 or 1) to indicate whether
4161 * a value has been set for one of a Table's attributes.
4162
4163 * Parameters:
4164 * this
4165 * Pointer to the Table.
4166 * attrib
4167 * Pointer to a null terminated string specifying the attribute
4168 * name. This should be in lower case with no surrounding white
4169 * space.
4170 * status
4171 * Pointer to the inherited status variable.
4172
4173 * Returned Value:
4174 * One if a value has been set, otherwise zero.
4175
4176 * Notes:
4177 * - A value of zero will be returned if this function is invoked
4178 * with the global status set, or if it should fail for any reason.
4179 */
4180
4181 /* Local Variables: */
4182 int len; /* Length of attribute string */
4183 int nc; /* Number of characters read by astSscanf */
4184 int result; /* Result value to return */
4185
4186 /* Initialise. */
4187 result = 0;
4188
4189 /* Check the global error status. */
4190 if ( !astOK ) return result;
4191
4192 /* Get the length of the attribute string. */
4193 len = strlen( attrib );
4194
4195 /* Check the attribute name and test the appropriate attribute. */
4196 /* None as yet */
4197
4198 /* Define a macro to see if the attribute string matches any of the
4199 read-only column attributes of this class. */
4200 #define MATCH(attr) \
4201 ( nc = 0, ( 0 == astSscanf( attrib, attr "(%*s)%n", &nc ) ) && \
4202 ( nc >= len ) )
4203
4204 /* If the name is not recognised, test if it matches any of the
4205 read-only attributes of this class. If it does, then return
4206 zero. */
4207 if ( !strcmp( attrib, "ncolumn" ) ||
4208 !strcmp( attrib, "nparameter" ) ||
4209 !strcmp( attrib, "nrow" ) ||
4210 MATCH( "columnlenc" ) ||
4211 MATCH( "columnlength" ) ||
4212 MATCH( "columnndim" ) ||
4213 MATCH( "columntype" ) ||
4214 MATCH( "columnunit" ) ) {
4215 result = 0;
4216
4217 /* If the attribute is still not recognised, pass it on to the parent
4218 method for further interpretation. */
4219 } else {
4220 result = (*parent_testattrib)( this_object, attrib, status );
4221 }
4222
4223 /* Return the result, */
4224 return result;
4225
4226 #undef MATCH
4227 }
4228
TypeString(int type)4229 static const char *TypeString( int type ) {
4230 /*
4231 * Name:
4232 * TypeString
4233
4234 * Purpose:
4235 * Return a pointer to a string describing a data type.
4236
4237 * Type:
4238 * Private function.
4239
4240 * Synopsis:
4241 * const char *TypeString( int type );
4242
4243 * Description:
4244 * This function returns a pointer to a string describing a data type.
4245
4246 * Parameters:
4247 * type
4248 * The integer data type code.
4249
4250 * Returned Value:
4251 * Pointer to a a string descirbing the data type (typically the C
4252 * data type).
4253
4254 */
4255
4256 /* Local Variables: */
4257 const char *result;
4258
4259 /* Compare the supplied type code against each supported value. */
4260 if( type == AST__INTTYPE ) {
4261 result = "int";
4262
4263 } else if( type == AST__BYTETYPE ) {
4264 result = "byte";
4265
4266 } else if( type == AST__DOUBLETYPE ) {
4267 result = "double";
4268
4269 } else if( type == AST__STRINGTYPE ) {
4270 result = "string";
4271
4272 } else if( type == AST__OBJECTTYPE ) {
4273 result = "Object";
4274
4275 } else if( type == AST__FLOATTYPE ) {
4276 result = "float";
4277
4278 } else if( type == AST__POINTERTYPE ) {
4279 result = "pointer";
4280
4281 } else if( type == AST__SINTTYPE ) {
4282 result = "short int";
4283
4284 } else if( type == AST__UNDEFTYPE ) {
4285 result = "undefined";
4286
4287 } else {
4288 result = NULL;
4289 }
4290
4291 /* Return the result. */
4292 return result;
4293 }
4294
4295
4296 /* Functions which access class attributes. */
4297 /* ---------------------------------------- */
4298 /* Implement member functions to access the attributes associated with
4299 this class using the macros defined for this purpose in the
4300 "object.h" file. For a description of each attribute, see the class
4301 interface (in the associated .h file). */
4302
4303 /*
4304 *att++
4305 * Name:
4306 * ColumnLenC(column)
4307
4308 * Purpose:
4309 * The largest string length of any value in a column
4310
4311 * Type:
4312 * Public attribute.
4313
4314 * Synopsis:
4315 * Integer, read-only.
4316
4317 * Description:
4318 * This attribute holds the minimum length which a character variable
4319 * must have in order to be able to store the longest value currently
4320 * present (at any row) in a specified column of the supplied Table.
4321 c This does not include room for a trailing null character.
4322 * The required column name should be placed inside the parentheses in
4323 * the attribute name. If the named column holds vector values, then
4324 * the attribute value is the length of the longest element of the
4325 * vector value.
4326
4327 * Applicability:
4328 * Table
4329 * All Tables have this attribute.
4330
4331 * Notes:
4332 * - If the named column holds numerical values, the length returned
4333 * is the length of the largest string that would be generated if the
4334 * column values were accessed as strings.
4335
4336 *att--
4337 */
4338
4339 /*
4340 *att++
4341 * Name:
4342 * ColumnLength(column)
4343
4344 * Purpose:
4345 * The number of elements in each value in a column
4346
4347 * Type:
4348 * Public attribute.
4349
4350 * Synopsis:
4351 * Integer, read-only.
4352
4353 * Description:
4354 * This attribute holds the number of elements in each value stored
4355 * in a named column. Each value can be a scalar (in which case the
4356 * ColumnLength attribute has a value of 1), or a multi-dimensional
4357 * array ( in which case the ColumnLength value is equal to the
4358 * product of the array dimensions).
4359
4360 * Applicability:
4361 * Table
4362 * All Tables have this attribute.
4363
4364 *att--
4365 */
4366
4367 /*
4368 *att++
4369 * Name:
4370 * ColumnNdim(column)
4371
4372 * Purpose:
4373 * The number of axes spanned by each value in a column
4374
4375 * Type:
4376 * Public attribute.
4377
4378 * Synopsis:
4379 * Integer, read-only.
4380
4381 * Description:
4382 * This attribute holds the number of axes spanned by each value in a
4383 * column. If each cell in the column is a scalar, ColumnNdim will be
4384 * zero. If each cell in the column is a 1D spectrum, ColumnNdim will
4385 * be one. If each cell in the column is a 2D image, ColumnNdim will be
4386 * two, etc. The required column name should be placed inside the
4387 * parentheses in the attribute name.
4388
4389 * Applicability:
4390 * Table
4391 * All Tables have this attribute.
4392
4393 *att--
4394 */
4395
4396 /*
4397 *att++
4398 * Name:
4399 * ColumnType(column)
4400
4401 * Purpose:
4402 * The data type of each value in a column
4403
4404 * Type:
4405 * Public attribute.
4406
4407 * Synopsis:
4408 * Integer, read-only.
4409
4410 * Description:
4411 * This attribute holds a integer value indicating the data type of
4412 * a named column in a Table. This is the data type which was used
4413 * when the column was added to the Table using astAddColumn. The
4414 * required column name should be placed inside the parentheses in
4415 * the attribute name.
4416 *
4417 * The attribute value will be one of AST__INTTYPE (for integer),
4418 * AST__SINTTYPE (for
4419 c short int),
4420 f INTEGER*2),
4421 * AST__BYTETYPE (for
4422 c unsigned bytes - i.e. unsigned chars),
4423 f bytes),
4424 * AST__DOUBLETYPE (for double
4425 * precision floating point), AST__FLOATTYPE (for single
4426 * precision floating point), AST__STRINGTYPE (for character string),
4427 * AST__OBJECTTYPE (for AST Object pointer), AST__POINTERTYPE (for
4428 * arbitrary C pointer) or AST__UNDEFTYPE (for undefined values
4429 * created by
4430 c astMapPutU).
4431 f AST_MAPPUTU).
4432
4433 * Applicability:
4434 * Table
4435 * All Tables have this attribute.
4436
4437 *att--
4438 */
4439
4440 /*
4441 *att++
4442 * Name:
4443 * Ncolumn
4444
4445 * Purpose:
4446 * The number of columns in the table.
4447
4448 * Type:
4449 * Public attribute.
4450
4451 * Synopsis:
4452 * Integer, read-only.
4453
4454 * Description:
4455 * This attribute holds the number of columns currently in the table. Columns
4456 * are added and removed using the
4457 c astAddColumn and astRemoveColumn
4458 f AST_ADDCOLUMN and AST_REMOVECOLUMN
4459 * functions.
4460
4461 * Applicability:
4462 * Table
4463 * All Tables have this attribute.
4464
4465 *att--
4466 */
4467
4468 /*
4469 *att++
4470 * Name:
4471 * Nparameter
4472
4473 * Purpose:
4474 * The number of global parameters in the table.
4475
4476 * Type:
4477 * Public attribute.
4478
4479 * Synopsis:
4480 * Integer, read-only.
4481
4482 * Description:
4483 * This attribute holds the number of global parameters currently in the table.
4484 * Parameters are added and removed using the
4485 c astAddParameter and astRemoveParameter
4486 f AST_ADDPARAMETER and AST_REMOVEPARAMETER
4487 * functions.
4488
4489 * Applicability:
4490 * Table
4491 * All Tables have this attribute.
4492
4493 *att--
4494 */
4495
4496 /*
4497 *att++
4498 * Name:
4499 * Nrow
4500
4501 * Purpose:
4502 * The number of rows in the table.
4503
4504 * Type:
4505 * Public attribute.
4506
4507 * Synopsis:
4508 * Integer, read-only.
4509
4510 * Description:
4511 * This attribute holds the index of the last row to which any
4512 * contents have been added using any of the
4513 * astMapPut...
4514 * AST_MAPPUT...
4515 * functions. The first row has index 1.
4516
4517 * Applicability:
4518 * Table
4519 * All Tables have this attribute.
4520
4521 *att--
4522 */
4523 astMAKE_GET(Table,Nrow,int,0,this->nrow)
astMAKE_SET(Table,Nrow,int,nrow,value)4524 astMAKE_SET(Table,Nrow,int,nrow,value)
4525
4526
4527
4528 /* Copy constructor. */
4529 /* ----------------- */
4530 static void Copy( const AstObject *objin, AstObject *objout, int *status ) {
4531 /*
4532 * Name:
4533 * Copy
4534
4535 * Purpose:
4536 * Copy constructor for Table objects.
4537
4538 * Type:
4539 * Private function.
4540
4541 * Synopsis:
4542 * void Copy( const AstObject *objin, AstObject *objout, int *status )
4543
4544 * Description:
4545 * This function implements the copy constructor for Table objects.
4546
4547 * Parameters:
4548 * objin
4549 * Pointer to the object to be copied.
4550 * objout
4551 * Pointer to the object being constructed.
4552 * status
4553 * Pointer to the inherited status variable.
4554
4555 * Returned Value:
4556 * void
4557
4558 * Notes:
4559 * - This constructor makes a deep copy, including a copy of the component
4560 * Mappings within the Table.
4561 */
4562
4563 /* Local Variables: */
4564 AstTable *in; /* Pointer to input Table */
4565 AstTable *out; /* Pointer to output Table */
4566
4567 /* Check the global error status. */
4568 if ( !astOK ) return;
4569
4570 /* Obtain pointers to the input and output Tables. */
4571 in = (AstTable *) objin;
4572 out = (AstTable *) objout;
4573
4574 /* Make copies of the component KeyMaps and store pointers to them in the
4575 output Table structure. */
4576 out->columns = in->columns ? astCopy( in->columns ) : NULL;
4577 out->parameters = in->parameters ? astCopy( in->parameters ) : NULL;
4578 }
4579
4580
4581 /* Destructor. */
4582 /* ----------- */
Delete(AstObject * obj,int * status)4583 static void Delete( AstObject *obj, int *status ) {
4584 /*
4585 * Name:
4586 * Delete
4587
4588 * Purpose:
4589 * Destructor for Table objects.
4590
4591 * Type:
4592 * Private function.
4593
4594 * Synopsis:
4595 * void Delete( AstObject *obj, int *status )
4596
4597 * Description:
4598 * This function implements the destructor for Table objects.
4599
4600 * Parameters:
4601 * obj
4602 * Pointer to the object to be deleted.
4603 * status
4604 * Pointer to the inherited status variable.
4605
4606 * Returned Value:
4607 * void
4608
4609 * Notes:
4610 * This function attempts to execute even if the global error status is
4611 * set.
4612 */
4613
4614 /* Local Variables: */
4615 AstTable *this; /* Pointer to Table */
4616
4617 /* Obtain a pointer to the Table structure. */
4618 this = (AstTable *) obj;
4619
4620 /* Annul the pointers to the component KeyMaps. */
4621 if( this->columns ) this->columns = astAnnul( this->columns );
4622 if( this->parameters ) this->parameters = astAnnul( this->parameters );
4623
4624 }
4625
4626
4627 /* Dump function. */
4628 /* -------------- */
Dump(AstObject * this_object,AstChannel * channel,int * status)4629 static void Dump( AstObject *this_object, AstChannel *channel, int *status ) {
4630 /*
4631 * Name:
4632 * Dump
4633
4634 * Purpose:
4635 * Dump function for Table objects.
4636
4637 * Type:
4638 * Private function.
4639
4640 * Synopsis:
4641 * void Dump( AstObject *this, AstChannel *channel, int *status )
4642
4643 * Description:
4644 * This function implements the Dump function which writes out data
4645 * for the Table class to an output Channel.
4646
4647 * Parameters:
4648 * this
4649 * Pointer to the Table whose data are being written.
4650 * channel
4651 * Pointer to the Channel to which the data are being written.
4652 * status
4653 * Pointer to the inherited status variable.
4654 */
4655
4656 /* Local Variables: */
4657 AstTable *this; /* Pointer to the Table structure */
4658
4659 /* Check the global error status. */
4660 if ( !astOK ) return;
4661
4662 /* Obtain a pointer to the Table structure. */
4663 this = (AstTable *) this_object;
4664
4665 /* Write out values representing the instance variables for the Table
4666 class. Note, the primitive data in the Table will be written out
4667 by the parent KeyMap Dump function. This function deals just with the
4668 extra information held in the Table structure. */
4669
4670 /* Write out the number of rows in the table. */
4671 astWriteInt( channel, "Nrow", 1, 1, astGetNrow( this ),
4672 "Number of rows in table" );
4673
4674 /* Write out the KeyMap holding definitions of each column. */
4675 if( this->columns ) {
4676 astWriteObject( channel, "Columns", 1, 0, this->columns, "KeyMap holding "
4677 "column definitions" );
4678 }
4679
4680 /* Write out the KeyMap holding definitions of each global parameter. */
4681 if( this->parameters ) {
4682 astWriteObject( channel, "Params", 1, 0, this->parameters, "KeyMap holding "
4683 "parameter definitions" );
4684 }
4685 }
4686
4687
4688
4689
4690
4691
4692 /* Standard class functions. */
4693 /* ========================= */
4694 /* Implement the astIsATable and astCheckTable functions using the macros
4695 defined for this purpose in the "object.h" header file. */
astMAKE_ISA(Table,KeyMap)4696 astMAKE_ISA(Table,KeyMap)
4697 astMAKE_CHECK(Table)
4698
4699 AstTable *astTable_( const char *options, int *status, ...) {
4700 /*
4701 *++
4702 * Name:
4703 c astTable
4704 f AST_TABLE
4705
4706 * Purpose:
4707 * Create a Table.
4708
4709 * Type:
4710 * Public function.
4711
4712 * Synopsis:
4713 c #include "table.h"
4714 c AstTable *astTable( const char *options, ... )
4715 f RESULT = AST_TABLE( OPTIONS, STATUS )
4716
4717 * Class Membership:
4718 * Table constructor.
4719
4720 * Description:
4721 * This function creates a new empty Table and optionally initialises
4722 * its attributes.
4723 *
4724 * The Table class is a type of KeyMap that represents a two-dimensional
4725 * table of values. The
4726 c astMapGet... and astMapPut...
4727 f AST_MAPGET... and AST_MAPPUT...
4728 * methods provided by the KeyMap class should be used for storing and
4729 * retrieving values from individual cells within a Table. Each entry
4730 * in the KeyMap represents a single cell of the table and has an
4731 * associated key of the form "<COL>(i)" where "<COL>" is the name of a
4732 * table column and "i" is the row index (the first row is row 1). Keys
4733 * of this form should always be used when using KeyMap methods to access
4734 * entries within a Table.
4735 *
4736 * Columns must be declared using the
4737 c astAddColumn
4738 f AST_ADDCOLUMN
4739 * method before values can be stored within them. This also fixes the
4740 * type and shape of the values that may be stored in any cell of the
4741 * column. Cells may contain scalar or vector values of any data type
4742 * supported by the KeyMap class. Multi-dimensional arrays may also be
4743 * stored, but these must be vectorised when storing and retrieving
4744 * them within a table cell. All cells within a single column must
4745 * have the same type and shape (specified when the column is declared).
4746 *
4747 * Tables may have parameters that describe global properties of the
4748 * entire table. These are stored as entries in the parent KeyMap and
4749 * can be access using the get and set method of the KeyMap class.
4750 * However, parameters must be declared using the
4751 c astAddParameter
4752 f AST_ADDPARAMETER
4753 * method before being accessed.
4754 *
4755 * Note - since accessing entries within a KeyMap is a relatively slow
4756 * process, it is not recommended to use the Table class to store
4757 * very large tables.
4758
4759 * Parameters:
4760 c options
4761 f OPTIONS = CHARACTER * ( * ) (Given)
4762 c Pointer to a null-terminated string containing an optional
4763 c comma-separated list of attribute assignments to be used for
4764 c initialising the new Table. The syntax used is identical to
4765 c that for the astSet function and may include "printf" format
4766 c specifiers identified by "%" symbols in the normal way.
4767 f A character string containing an optional comma-separated
4768 f list of attribute assignments to be used for initialising the
4769 f new Table. The syntax used is identical to that for the
4770 f AST_SET routine.
4771 c ...
4772 c If the "options" string contains "%" format specifiers, then
4773 c an optional list of additional arguments may follow it in
4774 c order to supply values to be substituted for these
4775 c specifiers. The rules for supplying these are identical to
4776 c those for the astSet function (and for the C "printf"
4777 c function).
4778 f STATUS = INTEGER (Given and Returned)
4779 f The global status.
4780
4781 * Returned Value:
4782 c astTable()
4783 f AST_TABLE = INTEGER
4784 * A pointer to the new Table.
4785
4786 * Notes:
4787 * - A null Object pointer (AST__NULL) will be returned if this
4788 c function is invoked with the AST error status set, or if it
4789 f function is invoked with STATUS set to an error value, or if it
4790 * should fail for any reason.
4791
4792 * Status Handling:
4793 * The protected interface to this function includes an extra
4794 * parameter at the end of the parameter list described above. This
4795 * parameter is a pointer to the integer inherited status
4796 * variable: "int *status".
4797
4798 *--
4799 */
4800
4801 /* Local Variables: */
4802 astDECLARE_GLOBALS /* Pointer to thread-specific global data */
4803 AstTable *new; /* Pointer to new Table */
4804 va_list args; /* Variable argument list */
4805
4806 /* Get a pointer to the thread specific global data structure. */
4807 astGET_GLOBALS(NULL);
4808
4809 /* Check the global status. */
4810 if ( !astOK ) return NULL;
4811
4812 /* Initialise the Table, allocating memory and initialising the
4813 virtual function table as well if necessary. */
4814 new = astInitTable( NULL, sizeof( AstTable ), !class_init, &class_vtab,
4815 "Table" );
4816
4817 /* If successful, note that the virtual function table has been
4818 initialised. */
4819 if ( astOK ) {
4820 class_init = 1;
4821
4822 /* Obtain the variable argument list and pass it along with the options string
4823 to the astVSet method to initialise the new Table's attributes. */
4824 va_start( args, status );
4825 astVSet( new, options, NULL, args );
4826 va_end( args );
4827
4828 /* If an error occurred, clean up by deleting the new object. */
4829 if ( !astOK ) new = astDelete( new );
4830 }
4831
4832 /* Return a pointer to the new Table. */
4833 return new;
4834 }
4835
astTableId_(const char * options,...)4836 AstTable *astTableId_( const char *options, ... ) {
4837 /*
4838 * Name:
4839 * astTableId_
4840
4841 * Purpose:
4842 * Create a Table.
4843
4844 * Type:
4845 * Private function.
4846
4847 * Synopsis:
4848 * #include "table.h"
4849 * AstTable *astTableId_( const char *options, ... )
4850
4851 * Class Membership:
4852 * Table constructor.
4853
4854 * Description:
4855 * This function implements the external (public) interface to the
4856 * astTable constructor function. It returns an ID value (instead
4857 * of a true C pointer) to external users, and must be provided
4858 * because astTable_ has a variable argument list which cannot be
4859 * encapsulated in a macro (where this conversion would otherwise
4860 * occur).
4861 *
4862 * The variable argument list also prevents this function from
4863 * invoking astTable_ directly, so it must be a re-implementation
4864 * of it in all respects, except for the final conversion of the
4865 * result to an ID value.
4866
4867 * Parameters:
4868 * As for astTable_.
4869
4870 * Returned Value:
4871 * The ID value associated with the new Table.
4872 */
4873
4874 /* Local Variables: */
4875 astDECLARE_GLOBALS /* Pointer to thread-specific global data */
4876 AstTable *new; /* Pointer to new Table */
4877 va_list args; /* Variable argument list */
4878
4879 int *status; /* Pointer to inherited status value */
4880
4881 /* Get a pointer to the inherited status value. */
4882 status = astGetStatusPtr;
4883
4884 /* Get a pointer to the thread specific global data structure. */
4885 astGET_GLOBALS(NULL);
4886
4887 /* Check the global status. */
4888 if ( !astOK ) return NULL;
4889
4890 /* Initialise the Table, allocating memory and initialising the
4891 virtual function table as well if necessary. */
4892 new = astInitTable( NULL, sizeof( AstTable ), !class_init, &class_vtab,
4893 "Table" );
4894
4895 /* If successful, note that the virtual function table has been
4896 initialised. */
4897 if ( astOK ) {
4898 class_init = 1;
4899
4900 /* Obtain the variable argument list and pass it along with the options string
4901 to the astVSet method to initialise the new Table's attributes. */
4902 va_start( args, options );
4903 astVSet( new, options, NULL, args );
4904 va_end( args );
4905
4906 /* If an error occurred, clean up by deleting the new object. */
4907 if ( !astOK ) new = astDelete( new );
4908 }
4909
4910 /* Return an ID value for the new Table. */
4911 return astMakeId( new );
4912 }
4913
astInitTable_(void * mem,size_t size,int init,AstTableVtab * vtab,const char * name,int * status)4914 AstTable *astInitTable_( void *mem, size_t size, int init,
4915 AstTableVtab *vtab, const char *name, int *status ) {
4916 /*
4917 *+
4918 * Name:
4919 * astInitTable
4920
4921 * Purpose:
4922 * Initialise a Table.
4923
4924 * Type:
4925 * Protected function.
4926
4927 * Synopsis:
4928 * #include "table.h"
4929 * AstTable *astInitTable( void *mem, size_t size, int init,
4930 * AstTableVtab *vtab, const char *name )
4931
4932 * Class Membership:
4933 * Table initialiser.
4934
4935 * Description:
4936 * This function is provided for use by class implementations to initialise
4937 * a new Table object. It allocates memory (if necessary) to accommodate
4938 * the Table plus any additional data associated with the derived class.
4939 * It then initialises a Table structure at the start of this memory. If
4940 * the "init" flag is set, it also initialises the contents of a virtual
4941 * function table for a Table at the start of the memory passed via the
4942 * "vtab" parameter.
4943
4944 * Parameters:
4945 * mem
4946 * A pointer to the memory in which the Table is to be initialised.
4947 * This must be of sufficient size to accommodate the Table data
4948 * (sizeof(Table)) plus any data used by the derived class. If a value
4949 * of NULL is given, this function will allocate the memory itself using
4950 * the "size" parameter to determine its size.
4951 * size
4952 * The amount of memory used by the Table (plus derived class data).
4953 * This will be used to allocate memory if a value of NULL is given for
4954 * the "mem" parameter. This value is also stored in the Table
4955 * structure, so a valid value must be supplied even if not required for
4956 * allocating memory.
4957 * init
4958 * A logical flag indicating if the Table's virtual function table is
4959 * to be initialised. If this value is non-zero, the virtual function
4960 * table will be initialised by this function.
4961 * vtab
4962 * Pointer to the start of the virtual function table to be associated
4963 * with the new Table.
4964 * name
4965 * Pointer to a constant null-terminated character string which contains
4966 * the name of the class to which the new object belongs (it is this
4967 * pointer value that will subsequently be returned by the astGetClass
4968 * method).
4969
4970 * Returned Value:
4971 * A pointer to the new Table.
4972
4973 * Notes:
4974 * - A null pointer will be returned if this function is invoked with the
4975 * global error status set, or if it should fail for any reason.
4976 *-
4977 */
4978
4979 /* Local Variables: */
4980 AstTable *new; /* Pointer to new Table */
4981
4982 /* Check the global status. */
4983 if ( !astOK ) return NULL;
4984
4985 /* If necessary, initialise the virtual function table. */
4986 if ( init ) astInitTableVtab( vtab, name );
4987
4988 /* Initialise. */
4989 new = NULL;
4990
4991 /* Initialise a KeyMap structure (the parent class) as the first component
4992 within the Table structure, allocating memory if necessary. Specify that
4993 the KeyMap should be defined in both the forward and inverse directions. */
4994 new = (AstTable *) astInitKeyMap( mem, size, 0, (AstKeyMapVtab *) vtab,
4995 name );
4996 if ( astOK ) {
4997
4998 /* Initialise the Table data. */
4999 /* ---------------------------- */
5000 new->nrow = 0;
5001 new->columns = astKeyMap( "KeyCase=0,Sortby=AgeDown", status );
5002 new->parameters = astKeyMap( "KeyCase=0,Sortby=AgeDown", status );
5003
5004 /* Tables require the KeyCase attribute to be zero. */
5005 (*parent_setkeycase)( (AstKeyMap *) new, 0, status );
5006
5007 /* If an error occurred, clean up by deleting the new Table. */
5008 if ( !astOK ) new = astDelete( new );
5009 }
5010
5011 /* Return a pointer to the new Table. */
5012 return new;
5013 }
5014
astLoadTable_(void * mem,size_t size,AstTableVtab * vtab,const char * name,AstChannel * channel,int * status)5015 AstTable *astLoadTable_( void *mem, size_t size, AstTableVtab *vtab,
5016 const char *name, AstChannel *channel, int *status ) {
5017 /*
5018 *+
5019 * Name:
5020 * astLoadTable
5021
5022 * Purpose:
5023 * Load a Table.
5024
5025 * Type:
5026 * Protected function.
5027
5028 * Synopsis:
5029 * #include "table.h"
5030 * AstTable *astLoadTable( void *mem, size_t size, AstTableVtab *vtab,
5031 * const char *name, AstChannel *channel )
5032
5033 * Class Membership:
5034 * Table loader.
5035
5036 * Description:
5037 * This function is provided to load a new Table using data read
5038 * from a Channel. It first loads the data used by the parent class
5039 * (which allocates memory if necessary) and then initialises a
5040 * Table structure in this memory, using data read from the input
5041 * Channel.
5042 *
5043 * If the "init" flag is set, it also initialises the contents of a
5044 * virtual function table for a Table at the start of the memory
5045 * passed via the "vtab" parameter.
5046
5047
5048 * Parameters:
5049 * mem
5050 * A pointer to the memory into which the Table is to be
5051 * loaded. This must be of sufficient size to accommodate the
5052 * Table data (sizeof(Table)) plus any data used by derived
5053 * classes. If a value of NULL is given, this function will
5054 * allocate the memory itself using the "size" parameter to
5055 * determine its size.
5056 * size
5057 * The amount of memory used by the Table (plus derived class
5058 * data). This will be used to allocate memory if a value of
5059 * NULL is given for the "mem" parameter. This value is also
5060 * stored in the Table structure, so a valid value must be
5061 * supplied even if not required for allocating memory.
5062 *
5063 * If the "vtab" parameter is NULL, the "size" value is ignored
5064 * and sizeof(AstTable) is used instead.
5065 * vtab
5066 * Pointer to the start of the virtual function table to be
5067 * associated with the new Table. If this is NULL, a pointer
5068 * to the (static) virtual function table for the Table class
5069 * is used instead.
5070 * name
5071 * Pointer to a constant null-terminated character string which
5072 * contains the name of the class to which the new object
5073 * belongs (it is this pointer value that will subsequently be
5074 * returned by the astGetClass method).
5075 *
5076 * If the "vtab" parameter is NULL, the "name" value is ignored
5077 * and a pointer to the string "Table" is used instead.
5078
5079 * Returned Value:
5080 * A pointer to the new Table.
5081
5082 * Notes:
5083 * - A null pointer will be returned if this function is invoked
5084 * with the global error status set, or if it should fail for any
5085 * reason.
5086 *-
5087 */
5088
5089 /* Local Variables: */
5090 astDECLARE_GLOBALS /* Pointer to thread-specific global data */
5091 AstTable *new; /* Pointer to the new Table */
5092
5093 /* Initialise. */
5094 new = NULL;
5095
5096 /* Check the global error status. */
5097 if ( !astOK ) return new;
5098
5099 /* Get a pointer to the thread specific global data structure. */
5100 astGET_GLOBALS(channel);
5101
5102 /* If a NULL virtual function table has been supplied, then this is
5103 the first loader to be invoked for this Table. In this case the
5104 Table belongs to this class, so supply appropriate values to be
5105 passed to the parent class loader (and its parent, etc.). */
5106 if ( !vtab ) {
5107 size = sizeof( AstTable );
5108 vtab = &class_vtab;
5109 name = "Table";
5110
5111 /* If required, initialise the virtual function table for this class. */
5112 if ( !class_init ) {
5113 astInitTableVtab( vtab, name );
5114 class_init = 1;
5115 }
5116 }
5117
5118 /* Invoke the parent class loader to load data for all the ancestral
5119 classes of the current one, returning a pointer to the resulting
5120 partly-built Table. */
5121 new = astLoadKeyMap( mem, size, (AstKeyMapVtab *) vtab, name,
5122 channel );
5123
5124 if ( astOK ) {
5125
5126 /* Read input data. */
5127 /* ================ */
5128 /* Request the input Channel to read all the input data appropriate to
5129 this class into the internal "values list". */
5130 astReadClassData( channel, "Table" );
5131
5132 /* Now read each individual data item from this list and use it to
5133 initialise the appropriate instance variable(s) for this class. */
5134
5135 /* The number of rows. */
5136 new->nrow = astReadInt( channel, "nrow", 0 );
5137
5138 /* KeyMap holding columns definitions. */
5139 new->columns = astReadObject( channel, "columns", NULL );
5140
5141 /* KeyMap holding parameter definitions. */
5142 new->parameters = astReadObject( channel, "params", NULL );
5143
5144 /* If an error occurred, clean up by deleting the new Table. */
5145 if ( !astOK ) new = astDelete( new );
5146 }
5147
5148 /* Return the new Table pointer. */
5149 return new;
5150 }
5151
5152 /* Virtual function interfaces. */
5153 /* ============================ */
5154 /* These provide the external interface to the virtual functions defined by
5155 this class. Each simply checks the global error status and then locates and
5156 executes the appropriate member function, using the function pointer stored
5157 in the object's virtual function table (this pointer is located using the
5158 astMEMBER macro defined in "object.h").
5159
5160 Note that the member function may not be the one defined here, as it may
5161 have been over-ridden by a derived class. However, it should still have the
5162 same interface. */
5163
astAddColumn_(AstTable * this,const char * name,int type,int ndim,int * dims,const char * unit,int * status)5164 void astAddColumn_( AstTable *this, const char *name, int type,
5165 int ndim, int *dims, const char *unit, int *status ) {
5166 if ( !astOK ) return;
5167 (**astMEMBER(this,Table,AddColumn))(this,name,type,ndim,dims,unit,status);
5168 }
astAddParameter_(AstTable * this,const char * name,int * status)5169 void astAddParameter_( AstTable *this, const char *name, int *status ) {
5170 if ( !astOK ) return;
5171 (**astMEMBER(this,Table,AddParameter))(this,name,status);
5172 }
astRemoveColumn_(AstTable * this,const char * name,int * status)5173 void astRemoveColumn_( AstTable *this, const char *name, int *status ){
5174 if ( !astOK ) return;
5175 (**astMEMBER(this,Table,RemoveColumn))(this,name,status);
5176 }
astRemoveParameter_(AstTable * this,const char * name,int * status)5177 void astRemoveParameter_( AstTable *this, const char *name, int *status ){
5178 if ( !astOK ) return;
5179 (**astMEMBER(this,Table,RemoveParameter))(this,name,status);
5180 }
astRemoveRow_(AstTable * this,int index,int * status)5181 void astRemoveRow_( AstTable *this, int index, int *status ){
5182 if ( !astOK ) return;
5183 (**astMEMBER(this,Table,RemoveRow))(this,index,status);
5184 }
astPurgeRows_(AstTable * this,int * status)5185 void astPurgeRows_( AstTable *this, int *status ){
5186 if ( !astOK ) return;
5187 (**astMEMBER(this,Table,PurgeRows))(this,status);
5188 }
astGetNcolumn_(AstTable * this,int * status)5189 int astGetNcolumn_( AstTable *this, int *status ) {
5190 if ( !astOK ) return 0;
5191 return (**astMEMBER(this,Table,GetNcolumn))( this, status );
5192 }
astGetNparameter_(AstTable * this,int * status)5193 int astGetNparameter_( AstTable *this, int *status ) {
5194 if ( !astOK ) return 0;
5195 return (**astMEMBER(this,Table,GetNparameter))( this, status );
5196 }
astColumnName_(AstTable * this,int index,int * status)5197 const char *astColumnName_( AstTable *this, int index, int *status ){
5198 if ( !astOK ) return NULL;
5199 return (**astMEMBER(this,Table,ColumnName))(this,index,status);
5200 }
astParameterName_(AstTable * this,int index,int * status)5201 const char *astParameterName_( AstTable *this, int index, int *status ){
5202 if ( !astOK ) return NULL;
5203 return (**astMEMBER(this,Table,ParameterName))(this,index,status);
5204 }
astGetColumnType_(AstTable * this,const char * column,int * status)5205 int astGetColumnType_( AstTable *this, const char *column, int *status ){
5206 if ( !astOK ) return 0;
5207 return (**astMEMBER(this,Table,GetColumnType))(this,column,status);
5208 }
astGetColumnUnit_(AstTable * this,const char * column,int * status)5209 const char *astGetColumnUnit_( AstTable *this, const char *column, int *status ){
5210 if ( !astOK ) return NULL;
5211 return (**astMEMBER(this,Table,GetColumnUnit))(this,column,status);
5212 }
astGetColumnLenC_(AstTable * this,const char * column,int * status)5213 int astGetColumnLenC_( AstTable *this, const char *column, int *status ){
5214 if ( !astOK ) return 0;
5215 return (**astMEMBER(this,Table,GetColumnLenC))(this,column,status);
5216 }
astGetColumnLength_(AstTable * this,const char * column,int * status)5217 int astGetColumnLength_( AstTable *this, const char *column, int *status ){
5218 if ( !astOK ) return 0;
5219 return (**astMEMBER(this,Table,GetColumnLength))(this,column,status);
5220 }
astGetColumnNdim_(AstTable * this,const char * column,int * status)5221 int astGetColumnNdim_( AstTable *this, const char *column, int *status ){
5222 if ( !astOK ) return 0;
5223 return (**astMEMBER(this,Table,GetColumnNdim))(this,column,status);
5224 }
astColumnShape_(AstTable * this,const char * column,int mxdim,int * ndim,int * dims,int * status)5225 void astColumnShape_( AstTable *this, const char *column, int mxdim,
5226 int *ndim, int *dims, int *status ){
5227 if ( !astOK ) return;
5228 (**astMEMBER(this,Table,ColumnShape))( this, column, mxdim, ndim,
5229 dims, status );
5230 }
astColumnProps_(AstTable * this,int * status)5231 AstKeyMap *astColumnProps_( AstTable *this, int *status ){
5232 if ( !astOK ) return NULL;
5233 return (**astMEMBER(this,Table,ColumnProps))(this,status);
5234 }
astParameterProps_(AstTable * this,int * status)5235 AstKeyMap *astParameterProps_( AstTable *this, int *status ){
5236 if ( !astOK ) return NULL;
5237 return (**astMEMBER(this,Table,ParameterProps))(this,status);
5238 }
astHasColumn_(AstTable * this,const char * column,int * status)5239 int astHasColumn_( AstTable *this, const char *column, int *status ){
5240 if ( !astOK ) return 0;
5241 return (**astMEMBER(this,Table,HasColumn))(this,column,status);
5242 }
astHasParameter_(AstTable * this,const char * parameter,int * status)5243 int astHasParameter_( AstTable *this, const char *parameter, int *status ){
5244 if ( !astOK ) return 0;
5245 return (**astMEMBER(this,Table,HasParameter))(this,parameter,status);
5246 }
5247