rsspice 0.1.0

Pure Rust port of the SPICE Toolkit for space geometry
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
//
// GENERATED FILE
//

use super::*;
use crate::SpiceContext;
use f2rust_std::*;

const LNSIZE: i32 = 80;

/// String from pool
///
/// Retrieve the string starting at the FIDX element of the kernel
/// pool variable, where the string may be continued across several
/// components of the kernel pool variable.
///
/// # Brief I/O
///
/// ```text
///  VARIABLE  I/O  DESCRIPTION
///  --------  ---  --------------------------------------------------
///  ITEM       I   name of the kernel pool variable
///  FIDX       I   index of the first component of the string
///  CONTIN     I   character sequence used to indicate continuation
///  STRING     O   a full string concatenated across continuations
///  SIZE       O   the number of character in the full string value
///  LIDX       O   index of the last component of the string
///  FOUND      O   flag indicating success or failure of request
/// ```
///
/// # Detailed Input
///
/// ```text
///  ITEM     is the name of a kernel pool variable for which
///           the caller wants to retrieve a full (potentially
///           continued) string.
///
///  FIDX     is the index of the first component (the start) of
///           the string in ITEM.
///
///  CONTIN   is a sequence of characters which (if they appear as
///           the last non-blank sequence of characters in a
///           component of a value of a kernel pool variable)
///           indicate that the string associated with the
///           component is continued into the next literal
///           component of the kernel pool variable.
///
///           If CONTIN is blank, all of the components of ITEM
///           will be retrieved as a single string.
/// ```
///
/// # Detailed Output
///
/// ```text
///  STRING   is the full string starting at the FIDX element of the
///           kernel pool variable specified by ITEM.
///
///           Note that if STRING is not sufficiently long to hold
///           the fully continued string, the value will be
///           truncated. You can determine if STRING has been
///           truncated by examining the variable SIZE.
///
///  SIZE     is the index of last non-blank character of
///           continued string as it is represented in the
///           kernel pool. This is the actual number of characters
///           needed to hold the requested string. If STRING
///           contains a truncated portion of the full string,
///           RTRIM(STRING) will be less than SIZE.
///
///           If the value of STRING should be a blank, then
///           SIZE will be set to 1.
///
///  LIDX     is the index of the last component (the end) of
///           the retrieved string in ITEM.
///
///  FOUND    is a logical variable indicating success of the
///           request to retrieve the string.
/// ```
///
/// # Exceptions
///
/// ```text
///  1)  If the variable specified by ITEM is not present in the
///      kernel pool or is present but is not character valued, STRING
///      will be returned as a blank, SIZE will be returned with the
///      value 0 and FOUND will be set to .FALSE. In particular if NTH
///      is less than 1, STRING will be returned as a blank, SIZE will
///      be zero and FOUND will be .FALSE.
///
///  2)  If the variable specified has a blank string associated
///      with its full string starting at FIDX, STRING will be blank,
///      SIZE will be 1 and FOUND will be set to .TRUE.
///
///  3)  If STRING is not long enough to hold all of the characters
///      associated with the NTH string, it will be truncated on the
///      right.
///
///  4)  If the continuation character is a blank, every component
///      of the variable specified by ITEM will be inserted into
///      the output string.
///
///  5)  If the continuation character is blank, then a blank component
///      of a variable is treated as a component with no letters.
///      For example:
///
///         STRINGS = ( 'This is a variable'
///                     'with a blank'
///                     ' '
///                     'component.' )
///
///      Is equivalent to
///
///
///         STRINGS = ( 'This is a variable'
///                     'with a blank'
///                     'component.' )
///
///      from the point of view of SEPOOL if CONTIN is set to the
///      blank character.
/// ```
///
/// # Particulars
///
/// ```text
///   The SPICE Kernel Pool provides a very convenient interface
///   for supplying both numeric and textual data to user application
///   programs. However, any particular component of a character
///   valued component of a kernel pool variable is limited to 80
///   or fewer characters in length.
///
///   This routine allows you to overcome this limitation by
///   "continuing" a character component of a kernel pool variable.
///   To do this you need to select a continuation sequence
///   of characters and then insert this sequence as the last non-blank
///   set of characters that make up the portion of the component
///   that should be continued.
///
///   For example, you may decide to use the sequence '//' to indicate
///   that a string should be continued to the next component of
///   a kernel pool variable. Then set up the
///   kernel pool variable as shown below
///
///   LONG_STRINGS = ( 'This is part of the first component //'
///                    'that needs more than one line when //'
///                    'inserting it into the kernel pool.'
///                    'This is the second string that is split //'
///                    'up as several components of a kernel pool //'
///                    'variable.' )
///
///   When loaded into the kernel pool, the variable LONG_STRINGS
///   will have six literal components:
///
///      COMPONENT (1) = 'This is part of the first component //'
///      COMPONENT (2) = 'that needs more than one line when //'
///      COMPONENT (3) = 'inserting it into the kernel pool.'
///      COMPONENT (4) = 'This is the second string that is split //'
///      COMPONENT (5) = 'up as several components of a kernel pool //'
///      COMPONENT (6) = 'variable.'
///
///   These are the components that would be retrieved by the call
///
///      CALL GCPOOL ( 'LONG_STRINGS', 1, 6, N, COMPONENT, FOUND )
///
///   However, using the routine SEPOOL you can view the variable
///   LONG_STRINGS as having two long components.
///
///      STRING (1) = 'This is part of the first component that '
///  .   //           'needs more than one line when inserting '
///  .   //           'it into the kernel pool. '
///
///      STRING (2) = 'This is the second string that is split '
///  .   //           'up as several components of a kernel pool '
///  .   //           'variable. '
///
///
///   These string components would be retrieved by the following two
///   calls.
///
///      FIDX = 1
///      CALL SEPOOL ( 'LONG_STRINGS', FIDX, '//',
///     .                              STRING(1), SIZE, LIDX, FOUND )
///      FIDX = LIDX+1
///      CALL SEPOOL ( 'LONG_STRINGS', FIDX, '//',
///     .                              STRING(2), SIZE, LIDX, FOUND )
/// ```
///
/// # Examples
///
/// ```text
///  Example 1. Retrieving file names.
///
///   Suppose a you have used the kernel pool as a mechanism for
///   specifying SPK files to load at startup but that the full
///   names of the files are too long to be contained in a single
///   text line of a kernel pool assignment.
///
///   By selecting an appropriate continuation character ('*' for
///   example)  you can insert the full names of the SPK files
///   into the kernel pool and then retrieve them using this
///   routine.
///
///   First set up the kernel pool specification of the strings
///   as shown here:
///
///         SPK_FILES = ( 'this_is_the_full_path_specification_*'
///                       'of_a_file_with_a_long_name'
///                       'this_is_the_full_path_specification_*'
///                       'of_a_second_file_with_a_very_long_*'
///                       'name' )
///
///   Now to retrieve and load the SPK_FILES one at a time,
///   exercise the following loop.
///
///   INTEGER               FILSIZ
///   PARAMETER           ( FILSIZ = 255 )
///
///   CHARACTER*(FILSIZ)    FILE
///   INTEGER               I
///   INTEGER               LIDX
///
///   I = 1
///
///   CALL SEPOOL ( 'SPK_FILES', I, '*', FILE, SIZE, LIDX, FOUND )
///
///   DO WHILE ( FOUND .AND. RTRIM(FILE) .EQ. SIZE )
///
///      CALL SPKLEF ( FILE, HANDLE )
///      I = LIDX + 1
///      CALL SEPOOL ( 'SPK_FILES', I, '*', FILE, SIZE, LIDX, FOUND )
///   END DO
///
///   IF ( FOUND .AND. RTRIM(FILE) .NE. SIZE ) THEN
///      WRITE (*,*) 'The ', I, '''th file name was too long.'
///   END IF
///
///
///   Example 2. Retrieving all components as a string.
///
///
///   Occasionally, it may be useful to retrieve the entire
///   contents of a kernel pool variable as a single string. To
///   do this you can use the blank character as the
///   continuation character. For example if you place the
///   following assignment in a text kernel
///
///       COMMENT = (  'This is a long note '
///                    ' about the intended '
///                    ' use of this text kernel that '
///                    ' can be retrieved at run time.' )
///
///   you can retrieve COMMENT as single string via the call below.
///
///      CALL SEPOOL ( 'COMMENT', 1, ' ', COMMNT, SIZE, LIDX, FOUND )
///
///   The result will be that COMMNT will have the following value.
///
///      COMMNT = 'This is a long note about the intended use of '
///  .   //       'this text kernel that can be retrieved at run '
///  .   //       'time. '
///
///   Note that the leading blanks of each component of COMMENT are
///   significant, trailing blanks are not significant.
///
///   If COMMENT had been set as
///
///       COMMENT = (  'This is a long note '
///                    'about the intended '
///                    'use of this text kernel that '
///                    'can be retrieved at run time.' )
///
///   Then the call to SEPOOL above would have resulted in several
///   words being run together as shown below.
///
///
///      COMMNT = 'This is a long noteabout the intendeduse of '
///  .   //       'this text kernel thatcan be retrieved at run '
///  .   //       'time. '
///
///
///   resulted in several words being run together as shown below.
/// ```
///
/// # Author and Institution
///
/// ```text
///  J. Diaz del Rio    (ODC Space)
///  B.V. Semenov       (JPL)
///  W.L. Taber         (JPL)
/// ```
///
/// # Version
///
/// ```text
/// -    SPICELIB Version 1.0.1, 12-AUG-2021 (JDR)
///
///         Edited the header to comply with NAIF standard.
///
/// -    SPICELIB Version 1.0.0, 12-APR-2012 (WLT) (BVS)
/// ```
pub fn sepool(
    ctx: &mut SpiceContext,
    item: &str,
    fidx: i32,
    contin: &str,
    string: &mut str,
    size: &mut i32,
    lidx: &mut i32,
    found: &mut bool,
) -> crate::Result<()> {
    SEPOOL(
        item.as_bytes(),
        fidx,
        contin.as_bytes(),
        fstr::StrBytes::new(string).as_mut(),
        size,
        lidx,
        found,
        ctx.raw_context(),
    )?;
    ctx.handle_errors()?;
    Ok(())
}

//$Procedure SEPOOL ( String from pool )
pub fn SEPOOL(
    ITEM: &[u8],
    FIDX: i32,
    CONTIN: &[u8],
    STRING: &mut [u8],
    SIZE: &mut i32,
    LIDX: &mut i32,
    FOUND: &mut bool,
    ctx: &mut Context,
) -> f2rust_std::Result<()> {
    let mut PART = [b' '; LNSIZE as usize];
    let mut CFIRST: i32 = 0;
    let mut CLAST: i32 = 0;
    let mut COMP: i32 = 0;
    let mut CSIZE: i32 = 0;
    let mut N: i32 = 0;
    let mut PUTAT: i32 = 0;
    let mut ROOM: i32 = 0;
    let mut GOTIT: bool = false;
    let mut MORE: bool = false;

    // SPICELIB Variables
    //

    //
    // Standard SPICE error handling.
    //
    if RETURN(ctx) {
        return Ok(());
    }

    //
    // Return empty output if the input index is bad.
    //
    if (FIDX < 1) {
        *FOUND = false;
        fstr::assign(STRING, b" ");
        *SIZE = 0;
        *LIDX = 0;
        return Ok(());
    }

    //
    // Check in.
    //
    CHKIN(b"SEPOOL", ctx)?;

    //
    // Check if the first component exists. Return empty output if not.
    //
    GCPOOL(
        ITEM,
        FIDX,
        1,
        &mut N,
        CharArrayMut::from_mut(&mut PART),
        &mut GOTIT,
        ctx,
    )?;

    GOTIT = (GOTIT && (N > 0));

    if !GOTIT {
        *FOUND = false;
        fstr::assign(STRING, b" ");
        *SIZE = 0;
        *LIDX = 0;
        CHKOUT(b"SEPOOL", ctx)?;
        return Ok(());
    }

    //
    // Fetch the string using Bill's algorithm from STPOOL 'as is'.
    //
    ROOM = intrinsics::LEN(STRING);
    CSIZE = RTRIM(CONTIN);
    PUTAT = 1;

    COMP = FIDX;
    MORE = true;
    fstr::assign(STRING, b" ");
    N = 0;

    while MORE {
        GCPOOL(
            ITEM,
            COMP,
            1,
            &mut N,
            CharArrayMut::from_mut(&mut PART),
            &mut MORE,
            ctx,
        )?;

        MORE = (MORE && (N > 0));

        if MORE {
            *FOUND = true;

            CLAST = RTRIM(&PART);
            CFIRST = ((CLAST - CSIZE) + 1);

            if (CFIRST < 0) {
                if (PUTAT <= ROOM) {
                    fstr::assign(
                        fstr::substr_mut(STRING, PUTAT..),
                        fstr::substr(&PART, 1..=CLAST),
                    );
                }

                PUTAT = (PUTAT + CLAST);
                MORE = false;
            } else if fstr::ne(fstr::substr(&PART, CFIRST..=CLAST), CONTIN) {
                if (PUTAT <= ROOM) {
                    fstr::assign(
                        fstr::substr_mut(STRING, PUTAT..),
                        fstr::substr(&PART, 1..=CLAST),
                    );
                }
                PUTAT = (PUTAT + CLAST);
                MORE = false;
            } else if (CFIRST > 1) {
                if (PUTAT <= ROOM) {
                    fstr::assign(
                        fstr::substr_mut(STRING, PUTAT..),
                        fstr::substr(&PART, 1..=(CFIRST - 1)),
                    );
                }
                PUTAT = ((PUTAT + CFIRST) - 1);
            }
        }

        COMP = (COMP + 1);
    }

    //
    // We are done. Get the size of the full string and the index of its
    // last component and checkout.
    //
    *SIZE = (PUTAT - 1);
    *LIDX = (COMP - 1);

    CHKOUT(b"SEPOOL", ctx)?;

    Ok(())
}