DAS Required Reading |
Table of ContentsDAS Required Reading Abstract Notes for CSPICE users Intended audience Related Documents Introduction DAS Concepts Logical Addresses Read and Write Access Access to Non-Native DAS Files File Handles The DAS Comment Area Internal File Names Binary and Transfer DAS files Buffering Using Multiple DAS Files Concurrently DAS vs DAF Using the DAS Subsystem Creating a New DAS File Writing DAS Files Writing to an Existing DAS file Reading DAS Files Converting Between Binary and Transfer Format Annotating DAS Files Mapping Between Handles, File Names, and Units Obtaining a DAS File Summary Using Scratch DAS Files DAS Architecture Overview of DAS Architecture The File Record Reserved Records Comment Records Directory Records Data Records DAS Routines Summary of Mnemonics Summary of Calling Sequences Examples Storing a Symbol Table in a DAS File Appendix A --- Revision History 2021 DEC 31 by B. V. Semenov. 2021 NOV 01 by N. J. Bachman. 2017 MAR 23 by N. J. Bachman. 2009 APR 01 by B. V. Semenov. 2002 JAN 15 by N. J. Bachman DAS Required Reading
Abstract
Notes for CSPICE users
At this time, the CSPICE DAS subsystem consists primarily of modules translated from Fortran via f2c; the only DAS interface C wrappers are for opening and closing DAS files, and for comment area access. For a given platform, DAS files used by the Fortran and C SPICE Toolkits are identical. Intended audience
Related Documents
Introduction
The purpose of the DAS subsystem is to provide SPICELIB users with a simple way to create and efficiently use their own portable, high-level, binary, direct access file formats. The DAS architecture is meant to serve as a foundation for these high-level formats, providing services and capabilities required by all of them. The principal advantage of building a new file format based on DAS is that most of the new access routines---the new code needed to support reading, writing, and porting files having the new format---can be built out of DAS routines. Thus a great deal of the design, coding, documentation and testing that accompanies the development of new access routines is automatically eliminated. In addition, because files conforming to the new format are also DAS files, they inherit the features common to all DAS files:
This simple view of the organization of data within a DAS file is independent of the order in which data are written to the file when it is created: double precision numbers, integers, and characters can be written to the file in an interleaved fashion, but the data of each type will still appear to be contiguous to a program reading the file. The DAS suite of routines includes routines that convert DAS files between binary and transfer formats. DAS files in transfer format can be easily ported between computer systems having different binary numeric and character data representations. The SPICE Toolkit's TOBIN, TOXFR, and SPACIT utilities allow users to carry out these conversions via command-line or menu-based programs. Therefore, any high-level file format based on DAS can be ported using existing SPICE utilities. The task of adding annotation, sometimes called ``comments'' or ``metadata,'' to data files is also solved by using the DAS format. The SPICE Toolkit's COMMNT utility can insert annotation into, or extract annotation from, any DAS file, so this capability is automatically available for any files having a format based on DAS. Because speed of file access can be important for programs that use large files, the DAS subsystem buffers in memory data that it reads from or writes to a DAS file. This buffering operation is completely independent of the I/O mechanism of the computer system on which a DAS-based application program runs. User-written access routines for any file format based on DAS will automatically support I/O buffering simply by calling DAS routines to carry out their I/O operations. DAS ConceptsLogical Addresses
The DAS logical address of a given word is the index of that word within its virtual array. When necessary to avoid ambiguity, we'll use the phrases ``integer logical address,'' ``double precision logical address,'' or ``character logical address'' to denote logical addresses of words of each data type. Logical addresses themselves, wherever they're used in DAS routines, are represented by integers. The valid range of indices for each non-empty virtual array starts at 1 and ends at the word count for that array. There are no ``holes'' in the arrays; every logical address in the valid range for an array points to data. This property of the virtual arrays is enforced by the mechanism by which DAS files are populated with data: data may be placed in a virtual array either by appending or by updating a range of valid logical addresses. Random write access to array addresses outside of the valid range is not supported. The word counts for each logical array can be obtained via the routine DASLLA (``DAS, last logical addresses''). The ordering of the data within each virtual array is controlled by the order in which data are appended to that array. Each append operation adds the contents of an array in memory to the DAS virtual array of the same data type. An append operation appends the elements of the array in memory, preserving order, to a contiguous range of logical addresses, starting with the successor of the highest logical address already occupied in the virtual array. In the case of arrays of strings, the order of characters within an array increases from left to right, and all characters within an array element precede those belonging to any higher-indexed element. Read and Write Access
A program selects the access type of a DAS file by opening it with a call to the appropriate DAS routine: DASOPR opens files for read access; DASOPW opens existing DAS files for write access; and DASONW opens a new DAS file for write access. The routine DASOPS opens a new scratch DAS file for write access. ``Opening'' a DAS file via one of the DAS file opening functions makes the file available for I/O, but the file is not necessarily physically opened from the perspective of the host file system. SPICE manages DAS files opened by any of these functions so the files behave as though they're physically open, as far as user application software is concerned. For convenience, we still use the term ``open'' to refer to a DAS file that has been made available for read or write access by a call to a DAS file open function. A program is allowed to open a DAS file for read access multiple times during a single run, but once a file is opened for write access, any subsequent attempts to open it before it has been closed again cause an error to be signaled. The file access restrictions imposed by the DAS subsystem do not pertain to access of a single DAS file by multiple programs. Limitations on this type of file access are system-dependent. However, NAIF recommends avoiding arrangements involving access by multiple programs to a DAS file that has been opened for writing by any one of them. Access to Non-Native DAS Files
Reading non-native DAS files may be substantially slower than reading native files; the performance cost of run-time translation depends in part on the fraction of read operations that reference buffered data. Writing non-native DAS files is not supported. Non-native DAS files must be converted to native format in order to update or add to their data, or to modify their comment areas. See the Convert User's Guide (convert.ug) or the BINGO User's Guide for details. File Handles
There is a one-to-one correspondence between file handles and DAS files that are known to a program. In particular, when a DAS file is opened for read access multiple times during a single program run, the same handle is returned each time. The DAS subsystem does not recycle handles: once a file handle is assigned to a file, that integer will not be assigned to a different file during the same program run, even if the file to which the handle was assigned has been closed. At any time, a list of handles of open DAS files can be obtained by calling the DAS utility DASHOF. The DAS Comment Area
The contents of the comment area must be printable text. The comment area is line-oriented; text inserted into the comment area can be retrieved with the original line breaks preserved. The DAS file architecture itself imposes no limits on lengths of comment lines. However, one of the SPICE Toolkit DAS comment area writer routines, DASACU, does have a 255 character limit. In general, as the length of comment lines increases, the portability of the formatting of the comment text decreases. Limiting comment line lengths to 80 characters, and avoiding use of tab characters, enhances the probability that comments will appear as intended when displayed. Internal File Names
The internal file name provides a mechanism for attaching an identifier to a DAS file in a manner independent of the file system on which the DAS file was created. The internal file name capability existed before the DAS comment area feature was developed; the comment area provides much greater flexibility in annotating DAS files. NAIF suggests the comment area, rather than the internal file name, be used for system-independent file identification. Binary and Transfer DAS files
No SPICELIB routines other than the DAS conversion routines themselves depend on the DAS transfer format, and this format is not considered part of the DAS subsystem specification. Non-SPICELIB applications should avoid reliance on the specific format of DAS transfer files; this format may be updated by NAIF, though any previous transfer formats will continue to be supported. The transfer format has the property of preserving all of the character, double precision, and integer information in the virtual arrays of DAS files; in particular, the full precision of all numeric quantities is preserved when a binary DAS file is converted to transfer format and then back to binary format on the same computer. Buffering
Because the DAS subsystem buffers records, successive reads from or writes to the same record are generally more efficient than they would be if file I/O were performed in response to each read or write request. Because the DAS subsystem uses its own declared storage for buffering, this capability is guaranteed to be supported, regardless of the I/O buffering capabilities of the computer system on which the DAS subsystem is used. The buffering performed by the DAS subsystem is automatic, and the existence of this feature can normally be safely ignored. The cases where it must be taken into account are:
In the second case, adjusting the sizes of the buffer arrays in DASRWR may improve performance. The sizes of the arrays are parameterized, so it is easy to change them. However, modifying SPICELIB code can create a maintenance burden for the owner of the modified code, because in order to accept a SPICELIB update (which could contain bug fixes), it will be necessary to modify the new versions of any previously modified SPICELIB routines. Using Multiple DAS Files Concurrently
Accessing multiple DAS files concurrently may affect a program's speed of execution, since all of the files compete for the same space in the DAS record buffers. DAS vs DAF
On the other hand, the DAF subsystem provides higher-level services that are not built into DAS: in the DAF subsystem, the data are partitioned into a linked list of virtual arrays, each one having its own name and descriptor, and the subsystem provides routines to manipulate the arrays and their descriptive information. As of the N0066 version of the SPICE Toolkit, a virtual array capability for DAS files is provided by the SPICE DLA subsystem. The DLA file format is a special case of the DAS format. DLA files enable user application software to view the data in a DAS file as a doubly linked list of virtual arrays, also called ``segments,'' where each segment may have character, double precision, and integer components. See the DLA Required Reading, dla.req, for details. Using the DAS Subsystem
In the code examples shown in this chapter, we'll display a brief phrase describing the function of each DAS routine that appears in the code, as shown below:
CALL DASCLS ( HANDLE ) {Close DAS file} Creating a New DAS File
CALL DASOPN ( FNAME, FTYPE, IFNAME, NCOMR, HANDLE ) {Open new DAS file}Here FNAME, FTYPE, IFNAME and NCOMR are inputs, and HANDLE is an output. FNAME is the name of the new file to be created, IFNAME is the internal file name of the new file, and NCOMR is the number of comment records to reserve. HANDLE is the integer handle assigned to the DAS file by DASOPN. After this call, the DAS file is ready to be populated with data. Writing DAS Files
The routines DASADC, DASADD, and DASADI are used to add data to DAS files. These routines append data to the file's character, double precision, or integer logical arrays. As an example, we'll add some data of each type to the file FNAME from the example above. We'll start out with integer data. DASADI adds the contents of an integer array to a DAS file. In the call below, the argument HANDLE identifies the file, the number 100 is the number of elements in the data array, and DATAI is an array of integers whose contents are to be appended to the file's integer virtual array.
DO I = 1, 100 DATAI(I) = I END DO CALL DASADI ( HANDLE, 100, DATAI ) {Add data, integer}DASADD is the double precision analog of DASADI. Since the logical arrays of different data types are independent, the double precision data from the array DATAD will occupy double precision logical addresses 1 through 100.
DO I = 1, 100 DATAD(I) = DBLE(I) END DO CALL DASADD ( HANDLE, 100, DATAD ) {Add data, double precision}DASADC is the character analog of DASADI. The second argument to DASADC indicates the total number of character logical addresses to be filled. DASADC has two additional input arguments that DASADI and DASADD do not have: begin and end substring bounds that indicate from which portion of the array of input strings to transfer data. In this case, we'll presume that the array DATAC is declared
CHARACTER*(80) DATAC ( 2 ) DATAC(1) = 'Here''s the first line of character data.' DATAC(2) = 'And here''s the second line.'The call below will write the contents of elements 1:2 of DATAC to DAS logical character addresses 1:160, because all of the characters of each element of DATAC are written to the file.
CALL DASADC ( HANDLE, 160, 1, 80, DATAC ) {Add data, character}If we don't wish to write out all 80 characters of each element of DATAC, we can use different substring bounds in the call to DASADC. As an example, we'll add two more lines to the file, this time using only characters 1 through 50 in each element of DATAC:
DATAC(1) = 'This is the third line.' DATAC(2) = 'This is the fourth line.' CALL DASADC ( HANDLE, 100, 1, 50, DATAC ) {Add data, character}This call added only 100 characters to the file. We can continue to add data of any type to the file at this point. As an example, we'll add 100 more integers to the file.
DO I = 1, 100 DATAI(I) = I + 100 END DO CALL DASADI ( HANDLE, 100, DATAI ) {Add data, integer}In addition to appending data to the virtual arrays in a DAS file, you can update array elements whose values have already been set. The DAS update routines are DASUDC, DASUDD, and DASUDI, which accept input arrays of character strings, double precision numbers, and integers, respectively. It is not always convenient to set the values of the elements of a DAS file's virtual arrays in strictly increasing order; using the update capability, a program can fill in array elements with placeholder values, then update those values when their actual values are known. To continue the example, we could update the first 100 integers in the file by negating them:
DO I = 1, 100 DATA(I) = -I END DO CALL DASUDI ( HANDLE, 1, 100, DATA ) {Update data, integer}The routines DASUDD and DASUDC update double precision and character data in an analogous way. To complete the new DAS file we've created, we close it using the routine DASCLS:
CALL DASCLS ( HANDLE ) {Close DAS file}DAS files should never be closed directly by a Fortran CLOSE statement. In particular, DAS files that have been written to may not contain all of the data written unless DASCLS is used to close them. At this point, the virtual arrays in our example DAS file have the following contents:
Integer virtual array --------------------- +-----+ Integer logical address #1 | -1 | +-----+ . . . +-----+ Integer logical address #100 |-100 | +-----+ Integer logical address #101 | 101 | +-----+ . . . +-----+ Integer logical address #200 | 200 | +-----+ Double precision virtual array ------------------------------ +-----+ Double precision logical address #1 |1.D0 | +-----+ . . . +-----+ Double precision logical address #100 |1.D2 | +-----+ Character virtual array ----------------------- +---+ Character logical address #1 | H | +---+ | e | +---+ | r | +---+ | e | +---+ | ' | +---+ | s | +---+ . . . +---+ Character logical address #80 | | +---+ Character logical address #81 | A | +---+ | n | +---+ | d | +---+ . . . +---+ Character logical address #160 | | +---+ Character logical address #161 | T | +---+ | h | +---+ | i | +---+ | s | +---+ . . . +---+ Character logical address #210 | | +---+ Character logical address #211 | T | +---+ | h | +---+ | i | +---+ | s | +---+ . . . +---+ Character logical address #260 | | +---+ Writing to an Existing DAS file
CALL DASOPW ( FNAME, HANDLE ) {Open DAS file for writing}After this call, the DASADx and DASUDx routines can be used to add data to the file and update data in the file. When the modification of the DAS file is complete, the file should be closed using DASCLS. Reading DAS Files
We'll continue our example by showing the results of reading the file we created. We start out by reading a range of integer addresses. After the following sequence of calls, the array DATAI will contain the integers 101 through 200.
CALL DASOPR ( FNAME, HANDLE ) {Open DAS file for reading} CALL DASRDI ( HANDLE, 101, 200, DATAI ) {Read data, integer}The following call will fill the array DATAI with the integers -1 through -100:
CALL DASRDI ( HANDLE, 1, 100, DATAI ) {Read data, integer}We can retrieve the double precision data from the file using DASRDD. The following call will fill the array DATAD with the values 1.D0 through 1.D2:
CALL DASRDD ( HANDLE, 1, 100, DATAD ) {Read data, double precision}Now for the character data: we'll read the data written by DASADC using DASRDC. After the call
CALL DASRDC ( HANDLE, 1, 160, 1, 80, DATAC ) {Read data, character}the array DATAC (whose elements have a length of 80 characters) will contain the lines
DATAC(1) = 'Here''s the first line of character data.' DATAC(2) = 'And here''s the second line.'Both elements of DATAC will be padded with trailing blanks. A second call
CALL DASRDC ( HANDLE, 161, 260, 1, 50, DATAC )will make the substring assignments
DATAC(1)(1:50) = 'This is the third line.' DATAC(2)(1:50) = 'This is the fourth line.'The character substrings DATAC(1)(51:80) and DATAC(2)(51:80) are left unchanged by this call. Converting Between Binary and Transfer Format
DASBT DASTBDASBT converts a binary DAS file to transfer format.
CALL DASBT ( DAS, XFRLUN ) {Convert DAS to transfer file}. DASTB is the inverse of this routine.
CALL DASTB( XFRLUN, DAS ) {Convert transfer file to DAS}Since the SPICE Toolkit utility programs TOBIN and TOXFR are able to convert between binary and transfer DAS formats, SPICE Toolkit users should rarely need to make direct use of these conversion routines. Annotating DAS Files
Mapping Between Handles, File Names, and Units
CALL DASHFN ( HANDLE, FNAME ) { Handle to file name } CALL DASHLU ( HANDLE, UNIT ) { Handle to logical unit }For completeness, the inverse mapping routines are supplied:
CALL DASFNH ( FNAME, HANDLE ) { File name to handle } CALL DASLUH ( UNIT, HANDLE ) { Logical unit to handle } Obtaining a DAS File Summary
CALL DASHFS ( HANDLE, NRESV, FREE, LASTLA, LASTRC, LASTWD ) { Handle to file summary }The desired information is in the output argument LASTLA, which is an array of the last logical addresses of character, double precision, and integer types, in that order. Given only this information, a program can read the contents of the file by using the DASRDx routines. The other arguments of DASHFS will probably be of interest only to programmers creating new DAS subroutines. See the header of DASHFS for further information. Using Scratch DAS Files
To obtain a scratch DAS file, use the routine DASOPS:
CALL DASOPS ( HANDLE ) { Open scratch DAS file }Here HANDLE is an output argument. DASOPS does not take a file name input argument because ANSI Standard Fortran 77 does not allow assignment of file names to scratch files. Since the file is temporary, there is no need to give it an internal file name or to reserve records in it. As with any other DAS file, scratch DAS files should be closed by calling DASCLS. Application programs that need large amounts of temporary work space and that must be able to access that work space randomly can take advantage of the DAS subsystem: scratch DAS files are direct access files, provide buffered read and write access, and have the same simple interface as do permanent DAS files. DAS Architecture
Overview of DAS Architecture
NWC = 1024 NWD = 128 NWI = 256Each record in a DAS file is dedicated to a specific purpose; records either contain data or control information that describes the structure and contents of the file. The types of records are:
Every DAS file contains one file record, which is always the first record of the DAS file. Comment records are optional. All DAS files contain at least one directory record, and useful DAS files also contain at least one data record. The diagram below shows how records of different types are grouped within a general binary DAS file. The parenthesized numbers at the right indicate the number of records within the named group on the left.
+------------------------+ | file record | ( 1 ) +------------------------+ | reserved records | ( NRESVR ) +------------------------+ | | | | | comment records | ( NCOMR ) | | | | +------------------------+ | first data directory | ( 1 ) +------------------------+ | data records | | | ( variable ) | | +------------------------+ . . . +------------------------+ | last data directory | ( 1 ) +------------------------+ | data records | | | ( variable ) | | +------------------------+Normally, when a new DAS file is closed, the data records are segregated into contiguous sets of records of each data type present in the file. The format of a DAS file after this re-organization is shown below:
+------------------------+ | file record | ( 1 ) +------------------------+ | reserved records | ( variable ) +------------------------+ | comment records | | | ( variable ) | | +------------------------+ | first data directory | ( 1 ) +------------------------+ | character data records | | | ( variable ) | | +------------------------+ | d.p. data records | | | ( variable ) | | +------------------------+ | integer data records | | | ( variable ) | | +------------------------+The purpose of the re-organization is to simplify the process of mapping logical addresses to physical locations in the file, thereby speeding up access to data. Note that the structure of the re-organized DAS file is just a special case of the general structure. All of the DAS routines that make explicit use of the structure of DAS files are equipped to work with the general structure: it is never assumed that data segregation has taken place. The File Record
DAS/The contents of the file record are organized as follows:
+-----------------------------------------------------+ |IDWORD|IFNAME|NRR|NRC|NCR|NCC|BFF|<nulls>|FTP|<nulls>| +-----------------------------------------------------+where the abbreviations represent:
Reserved Records
Reserved records play no role in DAS operations, but their number must be known by the DAS subsystem. The number is set when a DAS file is created, and is automatically updated at run time if reserved records are added by calling DASARR. Comment Records
Directory Records
Each directory record describes the data types of a number of data records that follow. Each directory also contains, for each data type, the lowest and highest logical address occurring in any of the records described by the directory. The directories in a DAS file form a doubly linked list: each directory contains forward and backward pointers to the next and previous directories. Thus the list of directory records in a DAS can be viewed as shown below:
NIL ^ +---------------------------------------------------+ | | | `-----| | | First Directory Record | .---->| | | .--| | | | +---------------------------------------------------+ | | . | | . | | . | | +---------------------------------------------------+ | `->| | `-----| | | Second Directory Record | .---->| | | .--| | | | +---------------------------------------------------+ | | . . . . . . . . . | | | | +---------------------------------------------------+ | `->| | `-----| | | Last Directory Record | | | .--| | | +---------------------------------------------------+ V NILAfter data segregation, the list of directories contains a single record. The structure of each directory record is as follows:
+-----------------------------------------------------------------+ | <pointers> | <address ranges> | <cluster descriptors> | +-----------------------------------------------------------------+where the
<pointers>section looks like
+-----------------------------------------+ | <backward pointer> | <forward pointer> | +-----------------------------------------+the
<address ranges>section looks like
+-------------------------------------------+ | <char range> | <d.p. range> | <int range> | +-------------------------------------------+and each range looks like one of:
+------------------------------------------------+ | <lowest char address> | <highest char address> | +------------------------------------------------+ +------------------------------------------------+ | <lowest d.p. address> | <highest d.p. address> | +------------------------------------------------+ +------------------------------------------------+ | <lowest int address> | <highest int address> | +------------------------------------------------+When the set of data records described by a directory record contains no data of a given type, the address range corresponding to that type is 0:0. Following the pointers and address range information is a sequence of cluster descriptors. ``Clusters'' are maximal, contiguous sequences of data records of a given data type. By ``maximal'' we mean that each cluster is preceded and followed by a record that is not a data record of the cluster's type. Each cluster descriptor indicates the data type and record count of the cluster it describes. Successive cluster descriptors map to successive clusters of data records in the file, as shown below:
+---------------------------------------------------+ | . . . | DESCR(i) | DESCR(i+1) | . . . | Directory +---------------|----------|------------------------+ | . | | . | | . | +---------------|----------|------------------------+ | | | | Data records | V | Cluster (i) | | | | +--------------------------|------------------------+ | | | | V Cluster (i+1) | | | | | | | +---------------------------------------------------+ . . .Note that although the number of cluster descriptors in a directory record is limited, the number of records described by a directory is virtually arbitrary, because the number of records in each cluster may vary. In particular, after data segregation is performed, a DAS file contains only three clusters and requires a single directory in order to describe those clusters. The cluster descriptors are implemented using a run-length encoding scheme. The first element of the series of descriptors occupies two integers; these represent a type code and a count. The rest of the descriptors are just signed counts; the data types of the clusters they describe are determined by the sign of the count and the data type of the previous descriptor. Data Records
Within each DAS data record, word numbers start at one and increase up to NWI, NWD, or NWC: the number of words in an integer, double precision, or character data record. The organization of data records can be thought of as follows:
Character records ----------------- +------------------------------------+ | | | ... | | +------------------------------------+ 1 2 NWC Double precision records ------------------------ +--------------------------------+ | | | ... | | +--------------------------------+ 1 2 NWD Integer records --------------- +--------------------------------+ | | | ... | | +--------------------------------+ 1 2 NWIEach data word in a DAS file is unambiguously specified by its type, the number of the record containing it, and its word number. DAS RoutinesSummary of Mnemonics
A2L Map logical address to physical location AC Add comments from buffer to file ACR Add comment records to file ACU Add comment records from logical unit to DAS file ADC Add character data to file ADD Add double precision data to file ADI Add integer data to file BT Convert binary to transfer format file CLS Close file CUD Create and update directories DC Delete comments EC Extract DAS comments into buffer ECU Extract DAS comments to logical unit FM File manager FNH Map file name to handle HAM Map file handle to access method HFN Map handle to file name HFS Map handle to file summary HLU Map handle to logical unit HOF Return handles of open DAS files IOC Low-level character record I/O IOD Low-level double precision record I/O IOI Low-level integer record I/O LLA Last logical addresses of each data type LLC Low-level file close LUH Map logical unit to handle ONW Open a new DAS file. OPN Open a new DAS file (obsolete: use DASONW) OPR Open a DAS file for reading OPS Open a scratch DAS file OPW Open an existing DAS file for writing RCR Remove comment records RDC Read character data RDD Read double precision data RDI Read integer data RFR Read file record RRC Perform buffered read of character record RRD Perform buffered read of double precision record RRI Perform buffered read of integer record RWR Read and write records SDR Segregate data records SIH Signal invalid handles TB Convert transfer format file to binary UDC Update character data UDD Update double precision data UDI Update integer data UFS Update file summary URC Update character record URD Update double precision record URI Update integer record WBR Write buffered records WFR Write file record WRC Perform buffered write of character record WRD Perform buffered write of double precision record WRI Perform buffered write of integer record Summary of Calling Sequences
The following routines are intended for use by both SPICELIB users' application programs and by SPICELIB routines. Opening and closing files:
DASONW ( FNAME, FTYPE, IFNAME, NCOMR, HANDLE ) DASOPN ( FNAME, IFNAME, NRESV, HANDLE ) DASOPW ( FNAME, HANDLE ) DASOPR ( FNAME, HANDLE ) DASOPS ( HANDLE ) DASCLS ( HANDLE )Adding data to files:
DASADC ( HANDLE, N, BPOS, EPOS, DATA ) DASADD ( HANDLE, N, DATA ) DASADI ( HANDLE, N, DATA )Updating data in files:
DASUDC ( HANDLE, FIRST, LAST, BPOS, EPOS, DATA ) DASUDD ( HANDLE, FIRST, LAST, DATA ) DASUDI ( HANDLE, FIRST, LAST, DATA )Reading data from files:
DASRDC ( HANDLE, FIRST, LAST, BPOS, EPOS, DATA ) DASRDD ( HANDLE, FIRST, LAST, DATA ) DASRDI ( HANDLE, FIRST, LAST, DATA )Mapping between file names, handles, and logical units:
DASHLU ( HANDLE, UNIT ) DASHFN ( HANDLE, FNAME ) DASLUH ( UNIT, HANDLE ) DASFNH ( FNAME, HANDLE )Conversion between binary and transfer format:
DASBT ( BINARY, UNIT ) DASTB ( UNIT, BINARY )File record (and internal file name) access:
DASRFR ( HANDLE, IDWORD, IFNAME, NRESVR, NRESVC, NCOMR, NCOMC ) DASWFR ( HANDLE, IDWORD, IFNAME, NRESVR, NRESVC, NCOMR, NCOMC )File summary access:
DASHFS ( HANDLE, NRESVR, NRESVC, NCOMR, NCOMC, FREE, LASTLA, LASTRC, LASTWD ) DASLLA ( HANDLE, LASTC, LASTD, LASTI ) DASUFS ( HANDLE, NRESVR, NRESVC, NCOMR, NCOMC, FREE, LASTLA, LASTRC, LASTWD )Adding and extracting comment records:
DASAC ( HANDLE, N, BUFFER ) DASACR ( HANDLE, N ) DASACU ( COMLUN, BEGMRK, ENDMRK, INSBLN, HANDLE ) DASEC ( HANDLE, BUFSIZ, N, BUFFER, DONE ) DASECU ( HANDLE, UNIT, FOUND )The following routines are considered to be utilities and generally will not need to be called by application programs. Buffered writing, updating, and reading of records:
DASWRC ( HANDLE, RECNO, RECC ) DASWRD ( HANDLE, RECNO, RECD ) DASWRI ( HANDLE, RECNO, RECI ) DASURC ( HANDLE, RECNO, FIRST, LAST, DATAC ) DASURD ( HANDLE, RECNO, FIRST, LAST, DATAD ) DASURI ( HANDLE, RECNO, FIRST, LAST, DATAI ) DASRRC ( HANDLE, RECNO, FIRST, LAST, DATAC ) DASRRD ( HANDLE, RECNO, FIRST, LAST, DATAD ) DASRRI ( HANDLE, RECNO, FIRST, LAST, DATAI )Flushing buffer contents to files:
DASWBR ( HANDLE )Low-level file I/O:
DASIOC ( ACTION, UNIT, RECNO, RECC ) DASIOD ( ACTION, UNIT, RECNO, RECD ) DASIOI ( ACTION, UNIT, RECNO, RECI )Logical address to physical location mapping:
DASA2L ( HANDLE, TYPE, ADDRSS, CLBASE, CLSIZE, RECNO, WORDNO )Directory creation and updating:
DASCUD ( HANDLE, TYPE, NWORDS )Segregating data records:
DASSDR ( HANDLE )File handle verification:
DASHOF ( HSET ) DASSIH ( HANDLE, ACCESS ) DASHAM ( HANDLE, ACCESS )Low-level file close utility:
DASLLC ( HANDLE )The following routines are umbrella subroutines. These should never be called, but their headers may be of interest to general SPICELIB users, since they contain ``global'' documentation pertaining to the routines' entry points.
DASFM DASRWR ExamplesStoring a Symbol Table in a DAS File
An important fact about user-designed, DAS-based formats is illustrated by this example: the high level format of a file must be understood by the code that reads the file, as well as the code that writes it. Therefore, most non-trivial user-designed formats will need to include a data structure that describes the rest of the file, thereby allowing the user's file reader to know how to read the file. In the following example, this data structure is very simple: it is a series of three integers whose meanings are known to the reader. A SPICELIB double precision symbol consists of three arrays: an array of symbol names, an array of integers that serves to map names to their associated values, and an array of double precision values. WRSYMD adds the contents of a symbol table to a DAS file opened by the calling application. For each symbol, WRSYMD will add to the DAS file the symbol's name, the count of the values associated with that symbol, and the values associated with the symbol. In addition, the number of symbols in the symbol table, the total number of values associated with the symbols, and the length of the strings containing the symbols' names will be added to the file. The logical format of the resulting file can be thought of as follows:
+----------------+ +----------------+ +----------------+ | Symbol Names | | Symbol Count | | D.P. Values | | | +----------------+ | Associated | | | | Value Count | | With Symbols | | | +----------------+ | | | | | Name Length | | (possibly | | | +----------------+ | multiple | | | | | | values per | | | | Value Counts | | symbol) | | | | For Each Symbol| | | | | | | | | | | | | | | | | | | | | | | +----------------+ | | | | | | +----------------+ | | | | | | +----------------+ DAS Character DAS integer DAS double precision virtual array virtual array virtual arrayThe source code of WRSYMD is shown below:
SUBROUTINE WRSYMD ( HANDLE, SYMNAM, SYMPTR, SYMVAL ) IMPLICIT NONE C C Write a double precision symbol table to a DAS file. C INTEGER LBCELL PARAMETER ( LBCELL = - 5) INTEGER HANDLE CHARACTER*(*) SYMNAM ( LBCELL : * ) INTEGER SYMPTR ( LBCELL : * ) DOUBLE PRECISION SYMVAL ( LBCELL : * ) C$ Brief_I/O C C VARIABLE I/O DESCRIPTION C -------- --- ---------------------------------------------- C HANDLE I Handle of DAS file opened for writing. C SYMSYM, C SYMPTR, C SYMVAL I Components of the symbol table. C C C SPICELIB functions C INTEGER CARDC INTEGER CARDD INTEGER SYDIMD LOGICAL RETURN C C Local parameters C INTEGER MAXVAL PARAMETER ( MAXVAL = 5000 ) C C Local variables C DOUBLE PRECISION VALUES ( MAXVAL ) INTEGER I INTEGER N INTEGER NAMLEN INTEGER NSYM INTEGER NVAL LOGICAL FOUND C C Standard SPICELIB error handling. C IF ( RETURN() ) THEN RETURN END IF CALL CHKIN ( 'WRSYMD' ) C C Write the symbol and symbol value counts to the file. Also C write out the length of the symbol name strings, so a reader C program can know how many characters to read to obtain each C name. C NSYM = CARDC (SYMNAM) NVAL = CARDD (SYMVAL) NAMLEN = LEN ( SYMNAM(1) ) CALL DASADI ( HANDLE, 1, NSYM ) CALL DASADI ( HANDLE, 1, NVAL ) CALL DASADI ( HANDLE, 1, NAMLEN ) C C Now write out the symbol table entries. For each symbol, C we'll append the symbol's name to the DAS's virtual character C array, the value count to the virtual integer array, and the C values to the virtual double precision array. C DO I = 1, NSYM C C Look up the values associated with each symbol. We don't C need to check the FOUND flag because we already know the C symbols exist. Check the count of values; we must be able C to fit them into our local VALUES array. C N = SYDIMD ( SYMNAM(I), SYMNAM, SYMPTR, SYMVAL ) IF ( N .GT. MAXVAL ) THEN CALL SETMSG ( 'Symbol # has too many values: ' . // 'value count = #; array size = ' . // '#.' ) CALL ERRCH ( '#', SYMNAM(I) ) CALL ERRINT ( '#', N ) CALL ERRINT ( '#', MAXVAL ) CALL SIGERR ( 'ARRAYOVERFLOW' ) CALL CHKOUT ( 'WRSYMD' ) RETURN END IF CALL SYGETD ( SYMNAM(I), . SYMNAM, SYMPTR, SYMVAL, . N, VALUES, FOUND ) C C Add the symbol's name to the DAS file. C CALL DASADC ( HANDLE, NAMLEN, 1, NAMLEN, SYMNAM(I) ) C C Now the value count. C CALL DASADI ( HANDLE, 1, N ) C C Finally, the values themselves. C CALL DASADD ( HANDLE, N, VALUES ) END DO CALL CHKOUT ( 'WRSYMD' ) RETURN ENDThe symbol table placed in a DAS file by WRSYMD may be extracted by RDSYMD, shown below:
SUBROUTINE RDSYMD ( HANDLE, SYMNAM, SYMPTR, SYMVAL ) IMPLICIT NONE C C Read a double precision symbol table from a DAS file. C INTEGER LBCELL PARAMETER ( LBCELL = - 5) INTEGER HANDLE CHARACTER*(*) SYMNAM ( LBCELL : * ) INTEGER SYMPTR ( LBCELL : * ) DOUBLE PRECISION SYMVAL ( LBCELL : * ) C$ Brief_I/O C C VARIABLE I/O DESCRIPTION C -------- --- ---------------------------------------------- C HANDLE I Handle of DAS file opened for writing. C SYMSYM, C SYMPTR, C SYMVAL O Components of the symbol table. These cells C are presumed to be initialized on input. C C C SPICELIB functions C LOGICAL RETURN C C Local parameters C INTEGER CHAR PARAMETER ( CHAR = 1 ) INTEGER DP PARAMETER ( DP = 2 ) INTEGER INT PARAMETER ( INT = 3 ) INTEGER MAXVAL PARAMETER ( MAXVAL = 5000 ) INTEGER MAXLEN PARAMETER ( MAXLEN = 80 ) C C Local variables C CHARACTER*(MAXLEN) VARNAM DOUBLE PRECISION VALUES ( MAXVAL ) INTEGER FIRST ( 3 ) INTEGER I INTEGER L INTEGER LAST ( 3 ) INTEGER N INTEGER NAMLEN INTEGER NSYM INTEGER NVAL C C Standard SPICELIB error handling. C IF ( RETURN() ) THEN RETURN END IF CALL CHKIN ( 'RDSYMD' ) C C Read the symbol and symbol value counts from the file. Also C get the length of the symbol name strings. C CALL DASRDI ( HANDLE, 1, 1, NSYM ) CALL DASRDI ( HANDLE, 2, 2, NVAL ) CALL DASRDI ( HANDLE, 3, 3, NAMLEN ) C C Now read the symbols, their value counts, and their values. C Add each symbol to the output symbol table. C C Obtain the length of the names in the symbol table. Check C that the elements of the input name array are long enough. C L = LEN ( SYMNAM(1) ) IF ( L .LT. NAMLEN ) THEN CALL SETMSG ( 'Name array has width #; required width ' . // 'is #' ) CALL ERRINT ( '#', L ) CALL ERRINT ( NAMLEN ) CALL SIGERR ( 'NAMEARRAYTOONARROW' ) CALL CHKOUT ( 'RDSYMD' ) RETURN END IF C C Initialize our logical address ranges. C CALL CLEARI ( 3, FIRST ) LAST(CHAR) = 0 LAST(DP) = 0 LAST(INT) = 3 DO I = 1, NSYM C C Obtain the symbol's name. C FIRST(CHAR) = LAST(CHAR) + 1 LAST (CHAR) = LAST(CHAR) + NAMLEN CALL DASRDC ( HANDLE, . FIRST(CHAR), LAST(CHAR), . 1, NAMLEN, VARNAM ) C C Now obtain the symbol's value count. C FIRST(INT) = LAST(INT) + 1 LAST (INT) = LAST(INT) + 1 CALL DASRDI ( HANDLE, FIRST(INT), LAST(INT), N ) IF ( N .GT. MAXVAL ) THEN CALL SETMSG ( 'Symbol # has too many values: ' . // 'value count = #; array size = ' . // '#.' ) CALL ERRCH ( '#', VARNAM ) CALL ERRINT ( '#', N ) CALL ERRINT ( '#', MAXVAL ) CALL SIGERR ( 'ARRAYOVERFLOW' ) CALL CHKOUT ( 'RDSYMD' ) RETURN END IF C C Now get the symbol's values. C FIRST(DP) = LAST(DP) + 1 LAST (DP) = LAST(DP) + N CALL DASRDD ( HANDLE, FIRST(DP), LAST(DP), VALUES ) C C Add the symbol to the output symbol table. C CALL SYPUTD ( VARNAM(1:NAMLEN), VALUES, N, . SYMNAM, SYMPTR, SYMVAL ) END DO CALL CHKOUT ( 'RDSYMD' ) RETURN END Appendix A --- Revision History2021 DEC 31 by B. V. Semenov.
2021 NOV 01 by N. J. Bachman.
2017 MAR 23 by N. J. Bachman.
2009 APR 01 by B. V. Semenov.
2002 JAN 15 by N. J. Bachman
|