 
Cells
===========================================================================
 
   Last revised on 2017 MAR 13 by N. J. Bachman.
 
 
Abstract
--------------------------------------------------------
 
   Cells are SPICE data structures that are vectors of type double
   precision, integer, or character type carrying with them their own
   dimension and knowledge of how many components have been used.
 
 
Introduction
--------------------------------------------------------
 
   A ``CSPICE cell'' (or simply ``cell'') is a data structure intended to
   provide safe array access within C applications.
 
   A CSPICE cell consists of two components: a data array, and an
   associated C structure---called a ``SpiceCell''--- that maintains
   attribute information regarding the data array.
 
   The SpiceCell structure contains sufficient information to allow CSPICE
   cell API functions to access the data array ``safely,'' ensuring that
   out-of-range subscript conditions or mismatched data type errors are
   avoided. A SpiceCell acts as an array descriptor: rather than passing
   the address of a cells' data array between functions, a program normally
   passes the address of the associated SpiceCell.
 
   The SpiceCell structure contains the members:
 
      dtype:     Data type of cell: character,
                 integer, or double precision.
 
                 dtype has type
                 SpiceCellDataType.
 
      length:    For character cells, the
                 declared length of the
                 cell's string array.
 
      size:      The maximum number of data
                 items that can be stored in
                 the cell's data array.
 
      card:      The cell's "cardinality": the
                 number of data items currently
                 present in the cell.
 
      isSet:     Boolean flag indicating whether
                 the cell is a CSPICE set.
                 Sets have no duplicate data
                 items, and their data items are
                 stored in increasing order.
 
      adjust:    Boolean flag indicating whether
                 the cell's data area has
                 adjustable size.  Adjustable
                 size cell data areas are not
                 currently implemented.
 
      init:      Boolean flag indicating whether
                 the cell has been initialized.
 
      base:      is a void pointer to the
                 associated data array.  base
                 points to the start of the
                 control area of this array.
 
      data:      is a void pointer to the
                 first data slot in the
                 associated data array.  This
                 slot is the element following
                 the control area.
 
   The terms ``size'' and ``cardinality'' refer, respectively, to the
   maximum number of data elements the cell's data array can hold and the
   number of data elements currently in the data array.
 
   See the header file SpiceCel.h for details concerning the definition of
   this structure.
 
   The CSPICE cell's compact representation allows the user to declare,
   pass, and otherwise manipulate cells without having to keep track of
   separate pointers and dimensions for each cell array. Thus, a function
   to merge the contents of two arrays into a third, when coded using
   cells, looks like this
 
      merge ( &old, &new, &total );
 
   instead of like this
 
      merge ( old, n_old, new, n_new, max_total, total, &n_total  );
 
   This is especially convenient for arrays that need to be passed as
   arguments through several levels of subprograms. This also remedies one
   of the serious flaws in the implementation of C arrays---the inability
   of a subprogram to determine the size of an argument array into which it
   is to place values. Since the size of a cell is always available,
   functions that manipulate cells can always check for overflow
   conditions.
 
 
Naming Conventions
--------------------------------------------------------
 
   The type of a cell is the same as the type of the cell's data array. The
   three types are: Character, Double Precision, and Integer. Most CSPICE
   cell functions are type-independent. The few type-dependent functions
   have names ending with the suffixes
 
      c_c, d_c, i_c
 
   where the first character of the suffix indicates the data type. When
   referring to a class of type-dependent functions, we substitute an ``x''
   for the letter denoting type. Thus appndx_c refers to any of appndc_c,
   appndd_c, or appndi_c.
 
 
Declaring and Initializing Cells
--------------------------------------------------------
 
   CSPICE provides declaration macros to simplify the process of declaring
   and initializing CSPICE cells. There is one macro for each data type.
   The calling sequences are:
 
      SPICECHAR_CELL   ( name, size, length );
      SPICEDOUBLE_CELL ( name, size );
      SPICEINT_CELL    ( name, size );
 
   These macros declare both a SpiceCell and a data array having the
   capacity specified by size, and for character cells, length. The data
   array is given a name having the input parameter ``name'' as a
   substring. Normally applications will not refer to the data array by
   name.
 
   Note that these macros are coded so as to require a semicolon following
   each call.
 
   The data array created by the declaration macros is dimensioned so as to
   be compatible with SPICELIB cells. In SPICELIB, a ``cell array"' is an
   array dimensioned from LBCELL to CMAX, where LBCELL is the standard
   lower bound of a cell (currently -5) and CMAX is the maximum number of
   elements that the cell is allowed to contain at any one time---that is,
   the maximum cardinality of the cell. SPICELIB cell array elements
   indexed LBCELL through 0 constitute the ``control area'' of the
   cell---the portion where the cell's bookkeeping data are stored.
 
   Keeping CSPICE cells' data array dimensions compatible with those of
   SPICELIB cells simplifies passing CSPICE cell data arrays to f2c'd
   SPICELIB cell routines.
 
   CSPICE cell declaration macros always create cells and their data arrays
   with static storage duration.
 
   The members of a SpiceCell are initialized by the declaration macros; in
   particular the base pointer is set to the base address of the data
   array, and the data pointer is set to the address of the start of the
   data area (the first address following the control area) in the data
   array. Unlike SPICELIB cells, CSPICE cells require no initialization
   action on the user's part at run time.
 
   Every CSPICE cell starts out as a CSPICE ``set.'' The property of being
   a set (the data elements are sorted in increasing order and contain no
   duplicates) is maintained if the cell is modified using only CSPICE set
   functions. Unlike SPICELIB cells, CSPICE cells maintain a flag
   indicating whether they are in fact sets. See the SETS Required Reading,
   sets.req, for more information on CSPICE sets.
 
 
Using Cells
--------------------------------------------------------
 
   SPICELIB users can access their cells' data elements directly via array
   subscript notation. In CSPICE, an analogous capability is provided via
   access macros. These macros allow a user to fetch, assign, or reference
   CSPICE cells' data array elements. The name of each access macro ends in
   a letter (C, D, or I) indicating the data type of cells the macro is
   intended to act upon.
 
   The CSPICE character element reference macro returns a pointer to a
   specified data array element. The numeric element reference macros
   return a dereferenced array element. The macros' calling sequences are:
 
      SPICE_CELL_ELEM_C ( &cell, i );
      SPICE_CELL_ELEM_D ( &cell, i );
      SPICE_CELL_ELEM_I ( &cell, i );
 
   The character macro call
 
      SPICE_CELL_ELEM_C ( &cell, i );
 
   returns a pointer to the ith string of length
 
      cell.length
 
   in the cell's data array. However the type of the returned pointer is
   (SpiceChar *), not (SpiceChar (*)[cell.length]).
 
   The cell assignment macros have the calling sequences
 
      SPICE_CELL_SET_C ( item, i, &cell );
      SPICE_CELL_SET_D ( item, i, &cell );
      SPICE_CELL_SET_I ( item, i, &cell );
 
   The cell fetch macros have the calling sequences
 
      SPICE_CELL_GET_C ( &cell, i, lenout, item );
      SPICE_CELL_GET_D ( &cell, i, &item );
      SPICE_CELL_GET_I ( &cell, i, &item );
 
   Here lenout is an input SpiceInt argument indicating the amount of room
   in the output string item.
 
   CSPICE cells may be populated using the appndx_c functions. These
   routines ``append'' a datum to a cell: they insert a specified data item
   into the lowest-indexed free slot in the data area of the cell's data
   array. The appndx_c functions automatically update the cell's
   cardinality to reflect the addition of the new datum.
 
   To append three double precision numbers onto an empty double precision
   cell, we could use the code fragment
 
      #include "SpiceUsr.h"
        .
        .
        .
      SPICEDOUBLE_CELL ( x, 100 );
        .
        .
        .
      appndd_c ( 0.0, &x );
      appndd_c ( 0.0, &x );
      appndd_c ( 1.0, &x );
 
   Another function scard_c is used to adjust the cardinality of a cell.
   This is necessary when directly inserting items into or removing items
   from a cell, as shown below.
 
      #include "SpiceUsr.h"
        .
        .
        .
      SPICEDOUBLE_CELL ( x, 100 );
        .
        .
        .
      SPICE_CELL_SET_D ( 0.0, 0, &x );
      SPICE_CELL_SET_D ( 0.0, 1, &x );
      SPICE_CELL_SET_D ( 1.0, 2, &x );
 
      scard_c ( 3, &x );
 
   ssize_c and scard_c should always be used in lieu of altering the size
   and cardinality members of a SpiceCell directly.
 
   The function copy_c copies the elements of one cell to another cell.
   This can be useful for modifying temporary or working cells, or for
   saving copies of cells which are about to be changed. For example,
 
      #include "SpiceUsr.h"
        .
        .
        .
      SPICEDOUBLE_CELL ( x,    100 );
      SPICEDOUBLE_CELL ( temp, 100 );
        .
        .
        .
      copy_c ( &x, &temp );
 
   copies the contents of `x' into `temp'. In this case, the cells are the
   same size (each can hold up to 100 elements), so the operation will
   always succeed. In general, if the output cell is not large enough to
   hold the contents of the input cell, as many elements as will fit are
   inserted into the output cell, and the CSPICE error handling mechanism
   reports the number of excess elements.
 
   An extra check is performed when copy_c is used to copy character cells.
   In order to avoid truncation problems, copy_c verifies that the
   operation can be performed without losing any of the non-blank
   characters in the original cell. The loss of one or more non-blank
   characters is reported through the CSPICE error handling mechanism.
 
   The integer function card_c returns the cardinality of a cell. This may
   be used to determine whether a cell is empty or not. (The cardinality of
   an empty cell is zero.) It may also be used to assist in accessing the
   elements of a cell individually, as in the following example.
 
      printf ( "Winners of the Nobel Prize for Physics:\n" );
 
      for ( i = 0;  i < card_c(&nobel);  i++ )
      {
         printf ( "%s\n",  SPICE_CELL_ELEM_C ( &nobel, i )  );
      }
 
   The integer function size_c returns the size (maximum cardinality) of a
   cell. This is useful primarily for predicting situations in which
   overflow can occur, as in the following example.
 
      if (  card_c( &winners )  <=  size_c( &nobel )  )
      {
         copy_c ( &winners, &nobel );
      }
 
 
Character Cells
--------------------------------------------------------
 
   In SPICELIB cells, the size and cardinality of a cell are stored in the
   control area of the cell (elements LBCELL through 0). For numeric data
   types, this is accomplished by simple assignment. However, in the case
   of cell arrays of type character, the values for the size and
   cardinality must be encoded into character strings.
 
   This is done by storing the numbers in base CHBASE, where CHBASE is the
   number of distinct characters in the character set supported by the host
   machine and compiler. (In ASCII environments, CHBASE is always at least
   128, and may be as high as 256.) The numbers are encoded and decoded by
   subroutines ENCHAR and DECHAR respectively. The value of parameter
   MINLEN (declared in ENCHAR) constrains the minimum length of the
   elements in a cell array. The nominal value for MINLEN is 5.
 
   Because CSPICE relies on f2c'd Fortran routines to carry out some
   operations on cells, it is necessary for a character CSPICE cell's data
   array to be convertible to a SPICELIB character cell. To make this
   convenient, the string length of a CSPICE character cell should be at
   least MINLEN.
 
 
Cell-based data types
--------------------------------------------------------
 
   CSPICE contains several extended data types based on cells. For example,
   one family of functions uses cells to implement algebraic sets of all
   types (character, integer, double precision). Another uses double
   precision cells to manipulate collections of closed intervals of the
   real numbers, called windows.
 
   All of these data types are supported by functions designed to
   manipulate them. However, because they are based on cells, all of these
   data types can be manipulated by the general cell routines as well.
   Thus, copy_c can be used to copy sets and windows, just as it can be
   used to copy vanilla cells.
 
 
Summary
===========================================================================
 
   The following table summarizes the CSPICE cell functions.
 
         ssize_c ( size, cell )    Initialize (set the size of) a cell.
 
         scard_c ( card, cell )    Set the cardinality of a cell.
 
         size_c ( cell )           Return the size of a cell.
 
         card_c ( cell )           Return the cardinality of a cell.
 
         copy_c ( orig, copy )     Copy the contents of a cell.
 
         appndc_c ( item, cell )   Append a SpiceChar item to a cell.
 
         appndd_c ( item, cell )   Append a SpiceDouble item to a cell.
 
         appndi_c ( item, cell )   Append a SpiceInt item to a cell.
 
 
Appendix A --- Revision History
===========================================================================
 
 
2017 MAR 13 by N. J. Bachman
 
   Moved revision history to this appendix.
 
   Updated description of the element reference macros.
 
   Updated references to CSPICE cell ``append'' functions to name
   individual functions rather than to refer to them using the notation
 
      appndx_c
 
   Fixed typos.
 
 
2002 SEP 04 by N. J. Bachman
 
   Initial release for CSPICE.
 
