Planetary Data System
Label Library Light (L3)
User's Guide
Draft
January 20, 2006
Version 1.0
Jet
Propulsion Laboratory
JPL D-xxxxx
CHANGE LOG
Revision |
Date |
Description |
Author |
Version 1.0 |
|
Ported document from a plain text format to a word
document. Originally written by S. Hughes and D. Bernath in 1995. |
M. Cayanan |
TABLE OF CONTENTS
3.1.1 Label
Access Function Prototypes
3.1.1.1 Parsing
Function Prototypes
3.1.1.2 Object
Description Function Prototypes
3.1.1.2.3 OdlGetObjDescClassName
3.1.1.2.4 OdlGetObjDescChildCount
3.1.1.2.6 OdlFindObjDescParent
3.1.1.3 Keyword
Function Prototypes
3.1.2 Label
Modify/Write Function Prototypes
3.2 Label
Access Function Parameters and Values.
3.3 Return
and Error Status (TBD First Quarter 95)
3.4 Label
Library Design - Notes
This users's guide
describes the Beta Version of the PDS Label Library Light (L3). It describes a
set of library routines that allow the access and manipulation of PDS object
descriptions in ODL labels. This implementation was
based on requirements [2] extrapolated from the original ODL label library and
new requirements gathered from the PDS discipline nodes.
This introduction
continues with a section on available platforms, definitions, and the list of
functions that are described in this document. Section two of this document includes
a brief discussion of the scope of the proposed library. Section three
describes the implementation and includes four sub-sections: the C function
prototypes, function parameter descriptions, error and return status codes, and
design notes. Appendix A includes an example of a simple program and library
function calls. Appendix B list
differences that exist between the design document and
the actual implementation. Appendix C includes the definitions of the OBJDESC
and KEYWORD "C" structures used to build the ODL parse tree.
The label library light (L3) code has been
successfully tested on the following platforms:
SUN
SPARC10 SUNOS_4.1.3 K&R
C Compiler
GNU
C Compiler (ansi option)
The label library light (L3) code has been
ported to the following platforms. Testing is continuing:
Macintosh
IBM PC
DEC VAX VMS
DEC ALPHA
The label library
parses and allows manipulation ODL labels. The following example ODL label and
definitions will help in the understanding the subsequent library functions.
RECORD_TYPE = FIXED_LENGTH
RECORD_BYTES = 1000
FILE_RECORDS = 814
/* Image Object */
OBJECT = IMAGE
LINES = 800
LINE_SAMPLES = 800
SAMPLE_BITS = 8
SAMPLE_TYPE =
UNSIGNED_INTEGER
END_OBJECT
Figure 1. Example ODL Label
An ODL label is an
ASCII file that can either be attached to or detached from the data it is
describing. Figure 1 illustrates a
partial attached label for a spacecraft camera image. In this label the first
three statements describe the file in which the label and the data are
contained. This part of the label is considered part of the
"implicit" FILE object. The following six statements describe an
image in the file by explicitly declaring an IMAGE object and supplying four attributes
of that image. The ODL language specification can be found in the PDS Standards
Reference. [5]
A ODL <statement> is expressed
syntactically as <keyword>=<value> where <keyword> is the
name of a data element and where <value> is a character string to be
assigned to the data element. The <value> must meet semantic constraints
specified in the PDS Standards Reference [5]. A value delimited by
"{" and "}" represents a SET and a value
delimited by "(" and ")"
represents a SEQUENCE. Both SET and SEQUENCE are classified as collections.
An ODL
<keyword> is the token to the left of the equal ("=") sign in
the <keyword>=<value> statement. In approved PDS labels, it is the
name of a data element defined in the Planetary Science Data Dictionary (PSDD)
[6]. It typically represents an attribute of an object.
An ODL <object
description> consists of the set of ODL statements delimited by the
"OBJECT = <class name>" and ”END_OBJECT
= <class name>" statements. Once parsed, the keyword names and
values are stored in a OBJDESC structure.
The <class
name> of the object is the value in the "OBJECT = <class
name>" statement and specifies the general classification of the object
described. A list of all approved
PDS objects can be
found in [5].
An ODL
<object> is the instantiation of an ODL object description. Instantiation
occurs within a software tool that parses ODL object descriptions (labels) and
instantiates the
object with the specified attributes and a set of
functions that manipulate the object.
An ODL <data
object> is the instantiation of an ODL object description. A ODL data object is distinct from an ODL object (see above)
since it has associated data. (e.g image)
Instantiation
occurs within a software tool that parses ODL object descriptions and
instantiates the object with the specified attributes, data, and a set of
functions that
manipulate the object.
The following is a
list of the functions described in this document:
3.1.1 Label Access Function Prototypes
3.1.1.1 Parsing Function Prototypes
3.1.1.2 Object Description Function Prototypes
3.1.1.2.3 OdlGetObjDescClassName
3.1.1.2.4 OdlGetObjDescChildCount
3.1.1.2.6 OdlFindObjDescParent
3.1.1.3 Keyword Function Prototypes
3.1.2 Label Modify/Write Prototypes
This user's guide
describes a set of library routines that allow the access and manipulation of
PDS object descriptions in ODL labels. For a detailed discussion of the
proposed
overall PDS software architecture please see [1]
and [4].
As a guideline, the
functionality of the library routines is limited to that which can be
generalized across all approved PDS objects. By generalizing, we are defining a
library
interface that will not change as PDS objects are
modified or added.
As an example of
the proposed scope of the library functionality, a user can use the library to
parse the ODL label for the Galileo IMAGE object included in appendix A, find the IMAGE object description in the resultant tree structure,
and retrieve the value of SAMPLE_TYPE in character string format.
The label library
design is presented in four sections. The first section contains the actual
design in the form of function prototypes. The remaining sections include
function parameter descriptions, error and return status codes, and design
notes.
Function Prototype
OBJDESC *OdlParseLabelFile (filespec,
errfilespec, expand, nomsgs)
char
*filespec, *errfilespec;
MASK expand;
unsigned
short nomsgs;
Description
This routine returns a pointer to an ODL tree that represents a parsed
ODL label, given the name of a file that contains an ODL label in ASCII format.
This routine
will optionally expand ^STRUCTURE pointers. (See section 3.4 for parameter
values and descriptions.)
WARNING: This function allocates memory. It
can be deallocated using
OdlFreeTree.
Function Prototype
OBJDESC *OdlExpandLabelFile (objdescptr,
errfilespec, expand, nomsgs)
OBJDESC *objdescptr;
char *errfilespec;
MASK expand;
unsigned short
nomsgs;
Description
This routine returns a pointer to a new ODL tree that represents a
parsed ODL label, given the pointer to a ^STRUCTURE keyword in an existing ODL
tree. This routine will optionally
expand nested ^STRUCTURE pointers. The new ODL tree is included as a sub-tree
in the existing tree. (See section 3.2 for parameter values and descriptions.)
WARNING: This function allocates memory. It
can be deallocated using
OdlFreeTree.
Function Prototype
OBJDESC *OdlParseLabelString (odlstring,
errfilespec, expand, nomsgs)
char *odlstring,
*errfilespec;
MASK expand;
unsigned short
nomsgs;
Description
This routine returns a pointer to an ODL tree that represents a parsed
ODL label, given a pointer to a character string containing an ODL label in
ASCII format.
This routine will optionally expand ^STRUCTURE pointers. (See section
3.2 for parameter values and descriptions.)
WARNING: This function allocates memory. It
can be deallocated using OdlFreeTree.
Function Prototype
OBJDESC *OdlFindObjDesc (objdescptr,
classname, kwdname, kwdvalue, position, scope)
OBJDESC *objdescptr;
char
*classname, *kwdname, *kwdvalue;
unsigned
long position
unsigned
short scope;
Description
This routine returns a pointer to the first occurrence of an object
description that meets the constraints supplied in classname, kwdname,
kwdvalue, position, and scope. A pointer to an ODL object description must be
supplied. Class name may include a wildcard '*' for generic class name
searches. Keyword name and value may be used to select an object description
using any attribute (e.g. NAME). Position indicates the nth occurrence of the object
description that meets the constraints specified. Both position and scope are
relative to the ODL object
description pointer. (See section 3.2 for parameter values
and descriptions. See section 3.4 note 3 for a discussion on constraints.)
Function Prototypes
char *OdlGetLabelVersion (objdescptr)
OBJDESC
*objdescptr;
Description
This routine returns a pointer to
the PDS version number in character string format, given an ODL tree pointer. This
value is determined from the PDS_VERSION_NUMBER keyword.
Function Prototypes
char *OdlGetObjDescClassName (objdescptr)
OBJDESC
*objdescptr;
Description
This routine returns a pointer to
the object description class name in character string format, given a pointer
to an object description in an ODL tree.
Function Prototypes
int
OdlGetObjDescChildCount (objdescptr)
OBJDESC *objdescptr;
Description
This routine returns the number of
child objects, given a pointer to the parent object in an ODL tree.
Function Prototypes
int OdlGetObjDescLevel (objdescptr)
OBJDESC
*objdescptr;
Description
This routine returns level number
of the object description, given a pointer to an object description in an ODL
tree. The 'root' object is at level zero (0).
Function Prototype
OBJDESC
*OdlFindObjDescParent (objdescptr)
OBJDESC
*objdescptr;
Description
This routine returns a pointer to
the parent object description, given a pointer to a child object description in
an ODL tree.
Function Prototype
KEYWORD
*OdlFindKwd (objdescptr, kwdname, kwdvalue, position, scope)
OBJDESC *objdescptr;
char *kwdname,
*kwdvalue;
unsigned long position;
unsigned short
scope;
Description
This routine returns a pointer to
the first occurrence of a keyword that meets the constraints supplied in
kwdname, kwdvalue, position, and scope. A pointer to an ODL object description
must be supplied and may be the ROOT object description. Keyword names and values
may include a wildcard '*' for generic searches. Position indicates the nth
occurrence of the keyword meeting the constraints specified. Both position and
scope are relative to the ODL object description pointer. (See section 3.2 for parameter values and
descriptions. See section 3.4 note 3 for a discussion on constraints.)
Function Prototype
KEYWORD *OdlNextKwd (kwdptr, kwdname,
kwdvalue, position, scope)
KEYWORD *kwdptr;
char *kwdname,
*kwdvalue;
unsigned long position;
unsigned short
scope;
Description
This routine returns a pointer to
the first occurrence of a keyword that meets the constraints supplied in
kwdname, kwdvalue, position, and scope. A pointer to an ODL keyword must be
supplied. Keyword names and values may include a wildcard '*' for generic
searches. Position indicates the nth occurrence of the keyword meeting the
constraints specified. NOTE: Use a position value of two
(2) to get
the next occurrence. Both position and scope are relative to the ODL keyword
pointer. (See section 3.2 for parameter values and descriptions. See section
3.4 note 3 for a discussion on constraints.)
Function Prototype
KEYWORD *OdlGetFirstKwd (objdescptr)
OBJDESC
*objdescptr;
Description
This routine returns a pointer to
the first keyword of an object description. A pointer to an ODL object
description must be supplied.
Function Prototype
KEYWORD *OdlGetNextKwd (kwdptr)
KEYWORD
*kwdptr;
Description
This routine returns a pointer to
the next keyword of an object description. A pointer to an ODL keyword must be
supplied.
Function Prototypes
char *OdlGetKwdValue (kwdptr)
KEYWORD
*kwdptr;
Description
This routine returns a pointer to
the value in character string format, given a pointer to a keyword in an ODL tree.
The value pointed to is the character string to the right of the equal sign whether the
string represents a scalar, set, or sequence.
Function Prototypes
unsigned short OdlGetKwdValueType (kwdptr)
KEYWORD
*kwdptr;
Description
This routine returns a value
indicating the type of the keyword value, given a pointer to a keyword in an
ODL tree. Value types are listed in section 3.2.
Function Prototypes
char *OdlGetKwdUnit (kwdptr)
KEYWORD
*kwdptr;
Description
This routine returns a pointer to
the units explicitly supplied with the keyword value, given a pointer to a
keyword in an ODL tree. (Note: units in ODL statements are optional and delimited
by '<>'.)
WARNING:
This function allocates memory for the return value that must be freed.
Function Prototypes
char *OdlGetKwdName (kwdptr)
KEYWORD
*kwdptr;
Description
This routine returns a pointer to
the name of the keyword in character string format, given a pointer to a
keyword in an ODL tree.
Function Prototype
OBJDESC *OdlFreeTree (objdescptr)
OBJDESC
*objdescptr;
Description
This routine frees the memory
allocated for storage of the ODL tree pointed to by the ODL tree pointer.
Function Prototype
OBJDESC *OdlCutObjDesc (object)
OBJDESC
*object;
Description
This routine cuts an ODL object
structure out of an ODL tree and returns a pointer to it. All references to it
in the tree are removed, and all references to the original
tree
within the object are removed.
Function Prototype
OBJDESC *OdlPasteObjDesc (new_object, parent_object)
OBJDESC
*new_object;
OBJDESC
*parent_object;
Description
This routine adds an object to a
tree as the last child of the parent_object.
Function Prototype
OBJDESC *OdlPasteObjDescBefore (new_object, old_object)
OBJDESC
*new_object;
OBJDESC
*old_object;
Description
This routine adds an object to a
tree as the left sibling of the old_object.
Function Prototype
OBJDESC *OdlPasteObjDescAfter (new_object, old_object)
OBJDESC
*new_object;
OBJDESC
*old_object;
Description
This routine adds an object to a
tree as the right sibling of the old_object.
Function Prototype
OBJDESC *OdlCopyObjDesc (object)
OBJDESC
*object;
Description
This routine makes a copy of an
object and returns a pointer to the copy. All fields are duplicated except for
references to the original tree, which are removed.
Function Prototype
OBJDESC *OdlNewObjDesc
(object_class, pre_comment, line_comment, post_comment, end_comment, file_name,
is_a_group, line_number)
char
*object_class;
char *pre_comment;
char *line_comment;
char *post_comment;
char *end_comment;
char *file_name;
short is_a_group;
long line_number;
Description
This routine creates a new object
structure and initializes its fields with the values passed in.
Function Prototype
void OdlAdjustObjDescLevel (object)
OBJDESC
*object;
Description
This routine changes the nesting
level of an object and all of its subobjects so they fit in with their place in
the overall ODL tree. This is particularly useful when objects are cut from one tree and
pasted into another tree, perhaps higher or lower in the nesting hierarchy then they
were in the original tree.
Function Prototype
KEYWORD *OdlCutKwd (keyword)
KEYWORD
*keyword;
Description
This routine removes a keyword from
an object and returns a pointer to it. All references to the object within the
keyword are removed, and all references to the keyword within the object are
removed.
Function Prototype
KEYWORD *OdlPasteKwd (keyword, object)
KEYWORD
*keyword;
OBJDESC
*object;
Description
This routine
adds a keyword to the end of an object's keyword list.
Function Prototype
KEYWORD *OdlPasteKwdBefore (new_keyword, old_keyword)
KEYWORD
*new_keyword;
KEYWORD
*old_keyword;
Description
This routine
adds a keyword to an object as the left sibling of the old_keyword.
Function Prototype
KEYWORD *OdlPasteKwdAfter (new_keyword, old_keyword)
KEYWORD
*new_keyword;
KEYWORD
*old_keyword;
Description
This routine adds
a keyword to an object as the right sibling of the old_keyword.
Function Prototype
KEYWORD *OdlCopyKwd (keyword)
KEYWORD
*keyword;
Description
This routine makes a copy of a
keyword and returns a pointer to it. All of the keyword's fields are duplicated
except for references to the parent object, which are
removed.
Function Prototype
KEYWORD *OdlNewKwd (keyword_name, value_text, pre_comment,
line_comment,
file_name, line_number)
Description
This routine creates a new keyword
structure, initializes its fields with the values passed in, and returns a
pointer to it.
Function Prototype
KEYWORD *OdlFreeAllKwds (object)
OBJDESC
*object;
Description
This routine frees all memory used
by an object's keywords. When it's finished, all references to keywords are
gone from the object. The return value is always NULL.
Function Prototype
KEYWORD
*OdlFreeKwd (keyword)
KEYWORD
*keyword;
Description
This routine frees the memory used by a
keyword. The return value is always a pointer to the right sibling of the
keyword.
Function Prototype
char *OdlGetFileName (keyword, start_location, start_location_type)
KEYWORD
*keyword;
unsigned long *start_location;
unsigned short *start_location_type;
Description
This routine extracts the file name
from a "^" keyword, allocates storage for it, and returns a pointer
to this new character string. It also returns information about
where the
data actually begins in the file.
For example, lets say we're looking
at a label in a file called test.lbl, and we want to get the file name
associated the FNAME keyword. Here are the possible values this keyword might
have, and what information would be returned for each possibility:
^FNAME = 17
file name : test.lbl (attached)
*start_location : 17
*start_location type : ODL_RECORD_LOCATION
^FNAME = 29
<RECORD>
file name : test.lbl (attached)
*start_location : 29
*start_location type : ODL_RECORD_LOCATION
^FNAME = 197
<RECORDS>
file name : test.lbl (attached)
*start_location : 197
*start_location type : ODL_RECORD_LOCATION
^FNAME = 346 <BYTE>
file name : test.lbl (attached)
*start_location : 346
*start_location type : ODL_BYTE_LOCATION
^FNAME =
2189 <BYTES>
file name : test.lbl (detached)
*start_location : 2189
*start_location type : ODL_BYTE_LOCATION
^FNAME =
"file_name.dat"
file name : file_name.dat (detached)
*start_location : 1
*start_location type : ODL_RECORD_LOCATION
^FNAME =
("file_name.dat", 17)
file name : file_name.dat (detached)
*start_location : 17
*start_location type : ODL_RECORD_LOCATION
^FNAME =
("file_name.dat", 29 <RECORD>)
file name : file_name.dat (detached)
*start_location : 29
*start_location type : ODL_RECORD_LOCATION
^FNAME =
("file_name.dat", 197 <RECORDS>)
file name : file_name.dat (detached)
*start_location : 197
*start_location type :
ODL_RECORD_LOCATION
^FNAME =
("file_name.dat", 346 <BYTE>)
file name : file_name.dat (detached)
*start_location : 346
*start_location type : ODL_BYTE_LOCATION
^FNAME =
("file_name.dat", 2189 <BYTES>)
file name : file_name.dat (detached)
*start_location : 2189
*start_location type : ODL_BYTE_LOCATION
Function Prototype
void OdlPrintHierarchy (object, message_fname, message_fptr)
OBJDESC
*object;
char *message_fname;
FILE
*message_fptr;
Description
This routine
prints the object hierarchy to a message file.
Function Prototype
void OdlPrintLabel (object, message_fname, message_fptr, root_level)
OBJDESC
*object;
char *message_fname;
FILE
*message_fptr;
unsigned long root_level;
Description
This routine prints the ODL tree to
a message file, in ODL format, unless the global odl_suppress_messages flag is
set.
NULL |
NULL as a value to a parameter implies that the parameter is to be ignored. NULL is defined to have a value of zero (0). |
classname |
classname is a character string that provides the class name to be used as a constraint in a search. The object's class name is the value in the OBJECT = <class name> ODL statement. (see note 1 and note 2)
|
errfilespec |
errfilespec is a character string that identifies the file
into which parser errors will be written. If the file previously exists, then the error messages are appended to the existing file. If NULL is specified, then the error messages are written to stdout. |
expand |
expand is a mask (typedef
unsigned short MASK) which specifies whether or not the specified ODL files
are to be expanded. ODL_EXPAND_STRUCTURE - expand ^STRUCTURE and
^*_STRUCTURE keywords only ODL_EXPAND_CATALOG - expand ^CATALOG keywords only ODL_EXPAND_STRUCTURE | ODL_EXPAND_CATALOG - expand both the ^STRUCTURE and ^CATALOG keywords (the "|" character is the logical "or" of both values). |
filespec |
filespec is a character string
that represents a file specification. File specifications are assumed to be
valid for the host system. If they are not, an error status is returned.
NOTE: An exception exists for file specifications supplied for ^STRUCTURE.
PDS standards do not allow directory path names to be included. The rules for
finding files referenced by ^STRUCTURE are documented in the PDS standards. |
kwdname |
kwdname is a character string
that provides the keyword name to be used as a constraint in a search. (see
note 1 and note 2) |
kwdptr |
kwdptr is a pointer to a keyword
within an ODL tree. |
kwdvalue |
kwdvalue is a character string that provides the keyword
value to be used as a constraint for a search (see note 1 and note 2) |
nomsgs |
nomsgs is a flag that indicates
whether or not error messages are to be written. A value of TRUE or (1)
indicates that error messages will not be written even if an error message
file has been specified. |
objdescptr |
objdescptr is a pointer to an
object description within an ODL tree. |
odlstring |
odlstring is a character string containing
ODL statements. |
position |
position indicates the nth occurrence of an entity that satisfies the specified constraints. For example, a pointer to the second occurrence of a COLUMN within a TABLE would be return from OdlFindObjDesc, given a pointer to the TABLE object, "COLUMN" as class name, and two (2) as position. One (1) and zero (0) supplied as values for position are
equivalent and indicate the first occurrence. NOTE: In a "find next" situation, a position
value of either NULL or one (1) will return either the object
description or keyword pointer passed to the routine since this would be the
first entity that matches the constraints. Use a position value of two (2) to
get the "next" matching entity. |
scope |
scope is an integer value that determines the context of the search. The entity being searched for dictates the interpretation of the values of scope. object description scope - The proposed values of scope for finding object descriptions restrict the tree search relative to the current OBJDESC pointer. These values are:
ODL_RECURSIVE_DOWN (0) - restrict to
subobjects of the current object
description and all their subobjects
recursively. (Expects an object
description pointer.)
ODL_TO_END (1) - no restrictions. The ODL
tree is searched exhaustively from the
given pointer to the end of the tree. ODL_CHILDREN_ONLY (2) -
restrict to
subobjects of the current object
description only. (Expects an object
description pointer.)
ODL_SIBLINGS_ONLY (3) - restrict to the
siblings of the current object
description. (Expects an object description pointer.) keyword scope - The proposed values of scope for finding keywords restrict the tree search relative to the current OBJDESC pointer. These values are: ODL_RECURSIVE_DOWN (0) -
restrict to the
keywords contained in the current object
description and the keywords contained in
the subobjects of the current object and
all of their subobjects recursively.
ODL_TO_END - (1) - No restriction. The
ODL tree is searched exhaustively from
the given pointer to the end of the tree.
ODL_CHILDREN_ONLY (2) - restrict to the
keywords contained in the current object
or subobjects of the current object
description.
ODL_SIBLINGS_ONLY (3) - restrict to the
keywords contained in the current object
or siblings of the current object description.
ODL_THIS_OBJECT (4) - restrict to the
keywords contained in the current object
description only. |
valuetype |
valuetype indicates the data type of a keyword's value.
ODL_UNKNOWN 0
ODL_INTEGER 1
ODL_REAL 2
ODL_SYMBOL 3
ODL_TEXT 4
ODL_DATE 5
ODL_DATE_TIME 6
ODL_SEQUENCE 7
ODL_SET 8 |
L3 functions return NULL when the function fails. A global
error status is currently being implemented. The following error values simply
suggest what could be returned.
Note: Routines that accept ODL tree pointers assume that the
pointer is valid for the function. (i.e. The
OdlFindObjDesc routine assumes a pointer to an object description has been
passed.)
Function Return
Status
if SUCCESS
<pointer to result>
else
<NULL>
Error Status -
(odlerrorstatus)
00 ->
10 ->
Warnings
11
-> no match
12
-> no next
13 ->
no parent
20 ->
Errors
21
-> illegal file name
22
-> file not found
23
-> severe syntax error
24
-> invalid objdescptr
1) Class names, keyword names, and keyword values passed as parameters to label library functions will be converted to upper case before comparison. ODL keyword values embedded in double quotes are an exception.
2) Class names, keyword names, and values used as search constraints in the find routines may all contain wildcard ('*') characters. For example, the strings "*TABLE" and "IMAGE*" supplied as class names to OdlFindObjDesc would both match "IMAGE_ENGINEERING_TABLE".
3) Find routines which allow more than one constraint for matching, such as OdlFindObjDesc, will find only those objects which match all non-null constraints. For example, if OdlFindObjDesc were called with a class name of "COLUMN" and a position value of 2, it will return the second COLUMN object. All other non-COLUMN objects in the given scope would be ignored.
Any search constraint with a null value will be ignored by the routine. For example, if OdlFindObjDesc were called with a value of 2 for position and NULLs for all other constraints, a pointer to the second object in the ODL tree would be returned.
The search path is depth first. (i.e. for a single parent with children and grandchildren, the children of child one are search before child two or its children.)
In a
"find next" situation, a position value of either NULL or one (1)
will return either the object description or keyword pointer passed to the
routine since this would be the first entity that matches the constraints. Use
a position value of two (2) to get the "next" matching entity.
CCSD3ZF0000100000001NJPL3IF0PDS200000001 = SFDU_LABEL
/* FILE FORMAT AND LENGTH */
...
OBJECT = IMAGE
LINES = 160
LINE_SAMPLES = 252
SAMPLE_TYPE =
UNSIGNED_INTEGER
SAMPLE_BITS = 8
SAMPLE_BIT_MASK =
2#11111111#
CHECKSUM = 2636242
END_OBJECT = IMAGE
...
END
{data}
-------
#include "lablib3.h"
OBJDESC *lp;
OBJDESC *op;
KEYWORD *kp;
main ()
{
/* open / parse
file - error messages to file */
lp = OdlParseLabelFile ("mdim.lbl",
"l3terr", NULL, NULL);
if (lp == NULL)
{
printf ("***Parse Failed\n");
exit (0);
}
/* find IMAGE
object */
op = OdlFindObjDesc (lp, "IMAGE",
NULL, NULL, 1, ODL_RECURSIVE_DOWN);
if (op == NULL)
{
printf ("***Find Object Failed\n");
exit (0);
}
printf ("OBJECT = %s\n",
OdlGetObjDescClassName(op));
/* find first
keyword */
kp = OdlGetFirstKwd (op);
if (kp == NULL)
{
printf ("***Find First Keyword Failed\n");
exit (0);
}
/*
find remaining keywords */
while (kp != NULL)
{
printf (" %s =
%s\n",
OdlGetKwdName (kp), OdlGetKwdValue (kp));
kp = OdlGetNextKwd (kp);
}
OdlFreeTree (lp);
}
Examples of L3
Function Calls
---GALILEO IMAGE FILE LABEL - FILE_NAME =
2000R.LBL---
CCSD3ZF0000100000001NJPL3IF0PDS200000001 = SFDU_LABEL
RECORD_TYPE = FIXED_LENGTH
RECORD_BYTES
= 1000
FILE_RECORDS = 814
^TELEMETRY_TABLE = ("2000R.IMG",3)
^IMAGE = ("2000R.IMG",15)
...
DATA_SET_ID = "GO-A/E-SSI-2-REDR-V1.0"
SPACECRAFT_NAME = "GALILEO ORBITER"
INSTRUMENT_NAME = SOLID_STATE_IMAGING
/*
Time tags and observation descriptors */
SPACECRAFT_CLOCK_START_COUNT = "01651920.00"
IMAGE_TIME = 1992-12-09T07:13:01.011Z
IMAGE_ID = E2W0914
ORBIT_NUMBER = 12869
OBSERVATION_ID = "E2WSZOOMMV01-000WDTL"
TARGET_NAME = "EARTH"
...
/*
Table Object (for telemetry table) */
OBJECT = TELEMETRY_TABLE
INTERCHANGE_FORMAT = BINARY
ROWS
= 1
COLUMNS = 86
ROW_BYTES = 1800
^STRUCTURE = "RTLMTAB.FMT"
END_OBJECT
/*
Image Object */
OBJECT = IMAGE
LINES = 800
LINE_SAMPLES = 800
SAMPLE_BITS = 8
SAMPLE_TYPE = UNSIGNED_INTEGER
...
END_OBJECT
END
---GALILEO TABLE FORMAT FILE - ^STRUCTURE
= "RTLMTAB.FMT"---
OBJECT = COLUMN
NAME
= RECORD_ID
DATA_TYPE = UNSIGNED_INTEGER
START_BYTE = 1
BYTES
= 1
DESCRIPTION = "Is always 0 for the telemetry record"
END_OBJECT
OBJECT = COLUMN
NAME
= FILE_NUMBER
DATA_TYPE = UNSIGNED_INTEGER
START_BYTE = 2
BYTES = 1
DESCRIPTION = "Tape file number. Not applicable for
CD-ROMs."
END_OBJECT
OBJECT = COLUMN
NAME
= MISSION_NAME
DATA_TYPE = CHARACTER
START_BYTE = 3
BYTES = 10
DESCRIPTION = "
END_OBJECT
...
---EXAMPLES OF FUNCTION CALLS---
Assume:
OBJDESC
*label_ptr, *table_ptr, *column_ptr, *image_ptr;
KEYWORD
*name_ptr, *first_ptr;
char name [31], value [11];
unsigned short valuetype;
1) Parse the file, expand the label, and create
a new error
message file.
label_ptr
= OdlParseLabelFile ("2000R.LBL", "error.lst",
ODL_EXPAND_STRUCTURE, NULL);
2) Find the TELEMETRY_TABLE object description.
table_ptr
= OdlFindObjDesc
(label_ptr, "*TABLE", NULL, NULL, 0,
ODL_RECURSIVE_DOWN);
3) Find the second column (FILE_NUMBER) in the
table.
column_ptr = OdlFindObjDesc
(table_ptr, "COLUMN", NULL, NULL, 2,
ODL_CHILDREN_ONLY);
4) Find the NAME keyword of the column.
name_ptr
= OdlFindKwd (column_ptr, "NAME", NULL, NULL,
ODL_THIS_OBJECT);
5) Get the name (i.e. FILE_NUMBER) of the
column.
strcpy (name, OdlGetKwdValue (name_ptr));
6) Find the next column (i.e. MISSION_NAME) in
the table.
column_ptr = OdlFindObjDesc
(column_ptr, "COLUMN", NULL, NULL, 2,
ODL_SIBLINGS_ONLY);
if (column_ptr !=
NULL)
7) Find the IMAGE object description.
image_ptr
= OdlFindObjDesc
(label_ptr, "IMAGE", NULL, NULL, NULL,
ODL_RECURSIVE_DOWN);
8) Find the first attribute of IMAGE. (i.e. LINES)
first_ptr
= OdlFindKwd (image_ptr, NULL, NULL, 1,
ODL_THIS_OBJECT);
if (first_ptr != NULL)
9) Get the name, value type, and value of the
first keyword
of IMAGE. (i.e. LINES, 1
(ODL_INTEGER), 800)
strcpy (name, OdlGetKwdName (first_ptr));
valuetype = OdlGetKwdValueType (first_ptr);
strcpy (value, OdlGetKwdValue (first_ptr));
10) Find the first format file anywhere in the label.
first_ptr
= OdlFindKwd (label_ptr, NULL, "*.FMT", NULL,
ODL_RECURSIVE_DOWN);
This appendix lists differences and their rationales that exist
between the design document and the actual implementation.
1) A nomsgs flag has been added to the parse
file functions
(OdlParseLabelFile, OdlParseLabelString, and
OdlExpandLabelFile) to indicate whether or not error
messages are to be suppressed. This approach is less
confusing than the approach suggested in the design.
2) The term "keyword" when used in a
function name has been
shortened to "kwd". This saves space and is
consistent
with the use of "obj" for "object".
3) The ODLTREE type definition has been changed
to either
OBJDESC or KEYWORD. An ODL tree resulting from parsing an
ODL file
consists of two type of nodes (structures)
either an OBJDESC node or a KEYWORD node.
4) The function OdlFindKwd is defined
differently due to
item 3 above. It now requires a pointer to an OBJDESC. In
order to find the next KEYWORD, the function OdlNextKwd
has been implemented.
This appendix contains the OBJDESC and KEYWORD structure and
Symbol
definitions used by the parser to build the ODL tree.
/*********************************************************/
/*
Symbol definitions
*/
/*********************************************************/
#define ODL_NOEXPAND 0
#define ODL_EXPAND_STRUCTURE 1
#define ODL_EXPAND_CATALOG 2
#define ODL_RECURSIVE_DOWN 0
#define ODL_TO_END 1
#define ODL_CHILDREN_ONLY 2
#define ODL_SIBLINGS_ONLY 3
#define ODL_THIS_OBJECT 4
#define ODL_RECORD_LOCATION 0
#define ODL_BYTE_LOCATION 1
#define ODL_UNKNOWN
0
#define ODL_INTEGER
1
#define ODL_REAL
2
#define ODL_SYMBOL
3
#define ODL_TEXT
4
#define ODL_DATE
5
#define ODL_DATE_TIME 6
#define ODL_SEQUENCE 7
#define ODL_SET 8
/***************************************************************/
/*
Typedefs
*/
/***************************************************************/
typedef struct Object_Structure
{
char *class;
char *pre_comment; /*
Comments before the OBJECT = line */
char *line_comment; /* Comments on the OBJECT = line */
char *post_comment; /* Comments before the END_OBJECT = line
*/
char *end_comment; /*
Comments on the OBJECT = line */
char *file_name;
char *appl1; /* free for your application */
char *appl2; /* free for your application */
unsigned short is_a_group;
unsigned long level;
unsigned long line_number;
unsigned long child_count;
struct Object_Structure *parent;
struct Object_Structure *left_sibling;
struct Object_Structure *right_sibling;
struct Object_Structure *first_child;
struct Object_Structure *last_child;
struct Keyword_Structure *first_keyword;
struct Keyword_Structure *last_keyword;
} OBJDESC;
typedef struct Keyword_Structure
{
char *name;
char *file_name;
char *value;
unsigned long size;
char *pre_comment;
/* Comments before the KEYWORD = line */
char *line_comment;
/* Comments on the KEYWORD = line
*/
char *appl1; /* free for your application */
char *appl2; /* free for your application */
unsigned short is_a_pointer;
unsigned short is_a_list;
unsigned long line_number;
struct Object_Structure *parent;
struct Keyword_Structure *left_sibling;
struct Keyword_Structure *right_sibling;
} KEYWORD;
==============================================================
References
[1]
DeMore, M.D., "Object Access: A Discussion of Software
Architecture", JPL Internal Document.
[2]
Hughes, J.S., etal, "Planetary Data System Label Library
Light
(L3) -
Requirements Document", JPL Internal Document, April
1993.
[3]
Hughes, J.S., etal, "Planetary Data System Label Library
Light
(L3) - Design
Document", JPL Internal Document, October 1993.
[4]
Requirements
and Design", Pre-Alpha Release Version,
Laboratory for
Atmospheric and Space Physics, August 1994.
[5]
_______, PDS Standards Reference, "JPL Internal
Document", JPL
D-7669; Part
2, Jet Propulsion Laboratory, November 1992.
[6]
Cribbs, M.A., Wagner, D.A., Planetary Science Data Dictionary,
"JPL
Internal Document", JPL D-7116; Rev C, Jet Propulsion
Laboratory,
November, 1992.
NOTE:
The PDS Standards Reference and Planetary Science Data Dictionary are
available on the World Wide Web under the PDS Home Page.