1 /*
2 
3 -Procedure ekgc_c  ( EK, get event data, character )
4 
5 -Abstract
6 
7    Return an element of an entry in a column of character
8    type in a specified row.
9 
10 -Disclaimer
11 
12    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
13    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
14    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
15    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
16    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
17    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
18    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
19    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
20    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
21    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
22 
23    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
24    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
25    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
26    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
27    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
28    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
29 
30    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
31    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
32    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
33    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
34 
35 -Required_Reading
36 
37    EK
38 
39 -Keywords
40 
41    ASSIGNMENT
42    EK
43 
44 */
45    #include "SpiceUsr.h"
46    #include "SpiceZfc.h"
47    #include "SpiceZst.h"
48    #include "SpiceZmc.h"
49 
ekgc_c(SpiceInt selidx,SpiceInt row,SpiceInt elment,SpiceInt lenout,SpiceChar * cdata,SpiceBoolean * null,SpiceBoolean * found)50    void ekgc_c ( SpiceInt          selidx,
51                  SpiceInt          row,
52                  SpiceInt          elment,
53                  SpiceInt          lenout,
54                  SpiceChar       * cdata,
55                  SpiceBoolean    * null,
56                  SpiceBoolean    * found  )
57 
58 /*
59 
60 -Brief_I/O
61 
62    Variable  I/O  Description
63    --------  ---  --------------------------------------------------
64    selidx     I   Index of parent column in SELECT clause.
65    row        I   Row to fetch from.
66    elment     I   Index of element, within column entry, to fetch.
67    lenout     I   Maximum length of column element.
68    cdata      O   Character string element of column entry.
69    null       O   Flag indicating whether column entry was null.
70    found      O   Flag indicating whether column was present in row.
71 
72 -Detailed_Input
73 
74    selidx         is the SELECT clause index of the column to fetch
75                   from.  The range of selidx is from 0 to one less than
76                   the number of columns in the SELECT clause.
77 
78    row            is the output row containing the entry to fetch
79                   from.  The range of row is from 0 to one less than
80                   the number of rows satisfying the previous query.
81 
82    elment         is the index of the element of the column entry
83                   to fetch.  The normal range of elment is from 0 to
84                   one less than the size of the column's entry, but
85                   elment is allowed to exceed the number of elements in
86                   the column entry; if it does, found is returned
87                   as SPICEFALSE.  This allows the caller to read data
88                   from the column entry in a loop without checking the
89                   number of available elements first.
90 
91                   Null values in variable-sized columns are
92                   considered to have size 1.
93 
94    lenout         is the maximum allowed length of a string that
95                   can be fetched into the string cdata.  This length
96                   must large enough to hold the specified element of the
97                   column entry, plus a null terminator.  If the column
98                   element is expected to have x characters, lenout needs
99                   to be x + 1.
100 
101 
102 -Detailed_Output
103 
104    cdata          is the requested element of the specified column
105                   entry.  If the entry is null, cdata is undefined.
106 
107                   If cdata is too short to accommodate the requested
108                   column entry element, the element is truncated on
109                   the right to fit cdata.
110 
111    null           is a logical flag indicating whether the entry
112                   belonging to the specified column in the specified
113                   row is null.
114 
115    found          is a logical flag indicating whether the specified
116                   element was found.  If the element does not exist,
117                   found is returned as SPICEFALSE.
118 
119 -Parameters
120 
121    None.
122 
123 -Exceptions
124 
125    1)  If the input argument elment is less than 0, found is returned as
126        SPICEFALSE, and the error SPICE(INVALIDINDEX) is signalled.
127        However, elment is allowed to be greater than or equal to
128        the number of elements in the specified column entry; this allows
129        the caller to read data from the column entry in a loop without
130        checking the number of available elements first.  If elment is
131        greater than or equal to the number of available elements, found
132        is returned as SPICEFALSE.
133 
134    2)  If selidx is outside of the range established by the
135        last query passed to eksrch_, the error SPICE(INVALIDINDEX)
136        will be signalled.
137 
138    3)  If the input argument row is less than 0 or greater than or
139        equal to the number of rows matching the query, found is returned
140        as SPICEFALSE, and the error SPICE(INVALIDINDEX) is signalled.
141 
142    4)  If the specified column does not have character type, the
143        error SPICE(INVALIDTYPE) is signalled.
144 
145    5)  If this routine is called when no E-kernels have been loaded,
146        the error SPICE(NOLOADEDFILES) is signalled.
147 
148 -Files
149 
150       The EK "query and fetch" suite of functions reads binary `sequence
151       component' EK files.  In order for a binary EK file to be
152       accessible to this routine, the file must be `loaded' via a call
153       to the function eklef_c.
154 
155       Text format EK files cannot be used by this routine; they must
156       first be converted by binary format by the NAIF Toolkit utility
157       SPACIT.
158 
159 -Particulars
160 
161    This routine allows retrieval of data from character columns.
162 
163    This routine returns one element at a time in order to save the
164    caller from imposing a limit on the size of the column entries
165    that can be handled.
166 
167 -Examples
168 
169    1)  Suppose the EK table TAB contains the following columns:
170 
171           Column name   Data Type   Size
172           -----------   ---------   ----
173           CHR_COL_1     CHR         1
174           CHR_COL_2     CHR         VARIABLE
175           CHR_COL_3     CHR         10
176 
177 
178        Suppose the query
179 
180           query = "SELECT CHR_COL_1 FROM TAB"
181 
182        is issued to ekfind_c via the call
183 
184           ekfind_c ( query, lenout, nmrows, error, errmsg );
185 
186        To fetch and dump column values from the rows that satisfy the
187        query, the loop below could be used.  Note that we don't check
188        the found flags returned by ekgc_c since we know that every
189        entry in column CHR_COL_1 contains one element.
190 
191           /.
192           Since CHR_COL_1 was the first column selected,
193           the selection index selidx is set to 0.
194           The column is scalar, so the element index eltidx
195           is set to 0.  The variable nmrows is the number of
196           matching rows returned by ekfind_c.
197           ./
198 
199           selidx = 0;
200           eltidx = 0;
201 
202           for ( row = 0;  row < nmrows;  row++ )
203           {
204              printf ( "\nRow = %d\n\n", row );
205 
206              /.
207              Fetch values from column CHR_COL_1.
208              ./
209              ekgc_c ( selidx,  row,      eltidx,  lenout,
210                       cval,    &isnull,  &found           );
211 
212              if ( isnull )
213              {
214                  printf ( "%s\n", "<null>" );
215              }
216              else
217              {
218                  printf ( "%s\n", cval );
219              }
220           }
221 
222 
223    2)  Suppose the EK table TAB is as in example 1, and we issue
224        the query
225 
226           query = "SELECT CHR_COL_1, CHR_COL_2, CHR_COL_3 FROM TAB"
227 
228        to ekfind_c via the call
229 
230           ekfind_c ( query, lenout, &nmrows, &error, errmsg );
231 
232        To fetch and dump column values from the rows that satisfy the
233        query, the loop below could be used.  Note that we don't check
234        the found flags returned by ekgc_c since we know in advance how
235        many elements are contained in each column entry we fetch.
236 
237 
238           for ( row = 0;  row < nmrows;  row++ )
239           {
240              printf ( "\nRow = %d\n\n", row );
241 
242              /.
243              Fetch values from column CHR_COL_1.  Since
244              CHR_COL_1 was the first column selected, the
245              selection index selidx is set to 0.
246              ./
247 
248              selidx = 0;
249              eltidx = 0;
250 
251              ekgc_c ( selidx,    row,      eltidx,  lenout,
252                       cvals[0],  &isnull,  &found           );
253 
254              printf ( "\nColumn = CHR_COL_1\n\n" );
255 
256              if ( isnull )
257              {
258                  printf ( "%s\n", "<null>" );
259              }
260              else
261              {
262                  printf ( "%s\n", cvals[0] );
263              }
264 
265 
266              /.
267              Fetch values from column CHR_COL_2 in the current
268              row.  Since CHR_COL_2 contains variable-size array
269              entries, we call eknelt_c to determine how many
270              elements to fetch.
271              ./
272              selidx = 1;
273 
274              eknelt_c ( selidx, row, &nelt );
275 
276              eltidx = 0;
277              isnull = SPICEFALSE;
278 
279              while (  ( eltidx < nelt ) && ( !isnull )  )
280              {
281 
282                 ekgc_c ( selidx,         row,      eltidx,  lenout,
283                          cvals[eltidx],  &isnull,  &found          );
284 
285                 eltidx++;
286 
287                 /.
288                 If the column entry is null, we'll be kicked
289                 out of this loop after the first iteration.
290                 ./
291              }
292 
293              printf ( "\nColumn = CHR_COL_2\n\n" );
294 
295              if ( isnull )
296              {
297                  printf ( "%s\n", "<null>" );
298              }
299              else
300              {
301                  for ( i = 0;  i < nelt;  i++ )
302                  {
303                     printf ( "%s\n", cvals[i] );
304                  }
305              }
306 
307 
308              /.
309              Fetch values from column CHR_COL_3 in the current
310              row.  We need not call eknelt_c since we know how
311              many elements are in each column entry.
312              ./
313              selidx = 2;
314              eltidx = 0;
315              isnull = SPICEFALSE;
316 
317 
318              while (  ( eltidx < 10 ) && ( !isnull )  )
319              {
320 
321                 ekgc_c ( selidx,         row,      eltidx,  lenout,
322                          cvals[eltidx],  &isnull,  &found          );
323 
324                 eltidx++;
325              }
326 
327 
328              printf ( "\nColumn = CHR_COL_3\n\n" );
329 
330              if ( isnull )
331              {
332                  printf ( "%s\n", "<null>" );
333              }
334              else
335              {
336                  for ( i = 0;  i < 10;  i++ )
337                  {
338                     printf ( "%s\n", cvals[i] );
339                  }
340              }
341 
342           }
343 
344    3)  See the Examples section of the query routine ekfind_c
345        for an example in which the names and data types of the
346        columns from which to fetch data are not known in advance.
347 
348 -Restrictions
349 
350    None.
351 
352 -Literature_References
353 
354    None.
355 
356 -Author_and_Institution
357 
358    N.J. Bachman   (JPL)
359 
360 -Version
361 
362    -CSPICE Version 1.1.0, 09-JUL-1998 (NJB)
363 
364        Bug fix:  now uses local logical variable to capture the
365        error flag value returned by the underlying f2c'd routine.
366 
367    -CSPICE Version 1.0.0, 27-MAR-1998
368 
369        Based on SPICELIB Version 1.1.0, 07-JUL-1996 (NJB)
370 
371 -Index_Entries
372 
373    fetch element from character column entry
374 
375 -&
376 */
377 
378 { /* Begin ekgc_c */
379 
380    /*
381    Local variables
382    */
383    logical                 fnd;
384 
385 
386    /*
387    Participate in error tracing.
388    */
389    chkin_c ( "ekgc_c" );
390 
391 
392    /*
393    Make sure the output string has at least enough room for one output
394    character and a null terminator.  Also check for a null pointer.
395    */
396    CHKOSTR ( CHK_STANDARD, "ekgc_c", cdata, lenout );
397 
398 
399    /*
400    Convert indices to Fortran-style; increment each index.
401    */
402    selidx ++;
403    row    ++;
404    elment ++;
405 
406 
407    /*
408    Call the f2c'd routine.
409    */
410    ekgc_  ( ( integer * ) &selidx,
411             ( integer * ) &row,
412             ( integer * ) &elment,
413             ( char    * ) cdata,
414             ( logical * ) null,
415             ( logical * ) &fnd,
416             ( ftnlen    ) lenout-1 );
417 
418    /*
419    Convert the Fortran string to a C string by placing a null after the
420    last non-blank character.  This operation is valid whether or not the
421    SPICELIB routine signaled an error.
422    */
423    F2C_ConvertStr ( lenout, cdata );
424 
425 
426    /*
427    Set the SpiceBoolean output found flag.
428    */
429 
430    *found  =  fnd;
431 
432 
433    chkout_c ( "ekgc_c" );
434 
435 } /* End ekgc_c */
436