CFITSIO provides easy-to-use support for reading and writing data in variable length fields of a binary table. The variable length columns have TFORMn keyword values of the form `1Pt(len)' where `t' is the datatype code (e.g., I, J, E, D, etc.) and `len' is an integer specifying the maximum length of the vector in the table. If the value of `len' is not specified when the table is created (e.g., if the TFORM keyword value is simply specified as '1PE' instead of '1PE(400) ), then CFITSIO will automatically scan the table when it is closed to determine the maximum length of the vector and will append this value to the TFORMn value.
The same routines which read and write data in an ordinary fixed length binary table extension are also used for variable length fields, however, the routine parameters take on a slightly different interpretation as described below.
All the data in a variable length field is written into an area called the `heap' which follows the main fixed-length FITS binary table. The size of the heap, in bytes, is specified by the PCOUNT keyword in the FITS header. When creating a new binary table, the initial value of PCOUNT should usually be set to zero. CFITSIO will recompute the size of the heap as the data is written and will automatically update the PCOUNT keyword value when the table is closed. Thus, application programs usually do not need to worry about the heap size, except when inserting a new binary table HDU in front of other existing HDUs in the FITS file (with ffibin). In this specific case the correct final value of PCOUNT must be specified when the HDU is initially created so that the correct amount of space will be inserted into the FITS file.
By default the heap data area starts immediately after the last row of the fixed-length table. (This default starting location may be overridden by the THEAP keyword, but this is not recommended). Thus when writing variable length arrays the number of rows in the table should be correctly specified (with the NAXIS2 keyword) at the time the table is first created. This differs from the simpler case of tables that only contain fixed-length columns where the number of rows in the table does not have to be explicitly defined until just before the table is closed. It is still possible to insert additional rows into a binary table containing variable-length columns (with the ffirow routine), however, the performance may be rather slow due to all the internal shuffling of the data that must be performed.
When writing to a variable length field the entire array of values for a given row of the table must be written with a single call to ffpcl_. The total length of the array is given by nelements + firstelem - 1. Additional elements cannot be appended to an existing vector at a later time since any attempt to do so will simply overwrite all the previously written data. Note also that the new data will be written to a new area of the heap and the heap space used by the previous write cannot be reclaimed. For this reason each row of a variable length field should only be written once. An exception to this general rule occurs when setting elements of an array as undefined. One must first write a dummy value into the array with ffpcl_, and then call ffpclu to flag the desired elements as undefined. (Do not use the ffpcn_ family of routines with variable length fields). Note that the rows of a table may be written in any order.
When writing to a variable length ASCII character field (e.g., TFORM = '1PA') only a single character string can be written. The `firstelem' and `nelements' parameter values in the ffpcls routine are ignored and the number of characters to write is simply determined by the length of the input null-terminated character string.
The ffpdes routine is useful in situations where multiple rows of a variable length column have the identical array of values. One can simply write the array once for the first row, and then use ffpdes to write the same descriptor values into the other rows; all the rows will then point to the same storage location thus saving disk space.
When reading from a variable length array field one can only read as many elements as actually exist in that row of the table; reading does not automatically continue with the next row of the table as occurs when reading an ordinary fixed length table field. Attempts to read more than this will cause an error status to be returned. One can determine the number of elements in each row of a variable column with the ffgdes routine.