Annotation of 43BSDReno/contrib/isode-beta/doc/manual/psap.tex, revision 1.1.1.1

1.1       root        1: % run this through LaTeX with the appropriate wrapper
                      2: 
                      3: %%% TODO: document
                      4: %%%    pe2ssdu, ssdu2pe, pe2text, pe2uvec
                      5: 
                      6: \chapter      {Encoding of Data-Structures}\label{libpsap}
                      7: The \man libpsap(3) library implements presentation syntax abstractions
                      8: for the machine-independent exchange of data structures.
                      9: There are two objects which are manipulated:
                     10: {\em presentation elements},
                     11: which represent a particular, arbitrarily complex, data structure;
                     12: and,
                     13: {\em presentation streams},
                     14: which represent an I/O path of these data structures.
                     15: 
                     16: \section      {Presentation Streams}
                     17: A presentation stream is an object,
                     18: similar to a \verb"FILE" object in \man stdio(3s),
                     19: which is used to read and write {\em presentation elements}.
                     20: The \verb"PStream" structure contains several elements,
                     21: only the most interesting are described here:
                     22: \begin{describe}
                     23: \item[\verb"ps\_errno":] the latest error to occur on the stream
                     24: (codes are listed in Table~\ref{PStreamReasons});
                     25: 
                     26: \item[\verb"ps\_addr":] the bottom-specific pointer;
                     27: 
                     28: \item[\verb"ps\_primeP":] the bottom-specific prime routine;
                     29: 
                     30: \item[\verb"ps\_readP":] the bottom-specific read routine;
                     31: 
                     32: \item[\verb"ps\_writeP":] the bottom-specific write routine;
                     33: and,
                     34: 
                     35: \item[\verb"ps\_flushP":] the bottom-specific flush routine;
                     36: and,
                     37: 
                     38: \item[\verb"ps\_closeP":] the bottom-specific close routine.
                     39: \end{describe}
                     40: \tagtable[tp]{3-1}{Presentation Stream Failure Codes}{PStreamReasons}
                     41: The typedef \verb"PS" is a pointer to an \verb"PStream" structure.
                     42: The \verb"ps_errno" element of the \verb"PStream" structure can be given as a
                     43: parameter to the routine \verb"ps_error" which returns a
                     44: null-terminated diagnostic string.
                     45: \begin{quote}\index{ps\_error}\small\begin{verbatim}
                     46: char   *ps_error (c)
                     47: int     c;
                     48: \end{verbatim}\end{quote}
                     49: 
                     50: \subsection    {Creating a Stream}
                     51: A \verb"PStream" structure is created by calling the procedure \verb"ps_alloc",
                     52: with the address of an integer-valued initialization routine.
                     53: \begin{quote}\index{ps\_alloc}\small\begin{verbatim}
                     54: PS      ps_alloc (init)
                     55: int   (*init) ();
                     56: \end{verbatim}\end{quote}
                     57: The \verb"ps_alloc" routine allocates a new structure and then calls the
                     58: initialization routine passed as a parameter,
                     59: which should initialize the elements of the structure.
                     60: The initialization routine should return the manifest constant \verb"OK" if
                     61: all went well;
                     62: otherwise it should return the manifest constant \verb"NOTOK" on error,
                     63: which results in \verb"ps_alloc" freeing the newly allocated structure and
                     64: then returning the value \verb"NULLPS".
                     65: 
                     66: Several standard initialization routines are available:
                     67: \begin{describe}
                     68: \item[\verb"std\_open":]  for presentation streams connected to \man stdio(3s)
                     69: \verb"FILE" objects;
                     70: \begin{quote}\index{std\_open}\small\begin{verbatim}
                     71: int     std_open (ps)
                     72: PS      ps;
                     73: \end{verbatim}\end{quote}
                     74: 
                     75: \item[\verb"str\_open":] for presentation streams connected to string objects.
                     76: \begin{quote}\index{str\_open}\small\begin{verbatim}
                     77: int     str_open (ps)
                     78: PS      ps;
                     79: \end{verbatim}\end{quote}
                     80: 
                     81: \item[\verb"fdx\_open":] for presentation streams connected to full-duplex
                     82: file descriptors.
                     83: \begin{quote}\index{fdx\_open}\small\begin{verbatim}
                     84: int     fdx_open (ps)
                     85: PS      ps;
                     86: \end{verbatim}\end{quote}
                     87: and,
                     88: 
                     89: \item[\verb"dg\_open":] for presentation streams connected to datagram-based
                     90: file descriptors.
                     91: \begin{quote}\index{dg\_open}\small\begin{verbatim}
                     92: int     dg_open (ps)
                     93: PS      ps;
                     94: \end{verbatim}\end{quote}
                     95: \end{describe}
                     96: Presentation streams which have been initialized by these routines will
                     97: automatically allocate additional resources when necessary,
                     98: to the limits allowed by the operating system
                     99: (e.g., repeated writes to a presentation stream connected to a string object
                    100: will result in additional memory being allocated).
                    101: In the current implementation,
                    102: presentation streams which have been initialized by these routines are
                    103: uni-directional.
                    104: That is,
                    105: the presentation stream may be used for reading, or writing, but not both.
                    106: 
                    107: After \verb"ps_alloc" successfully returns,
                    108: final initialization is performed by calling a setup routine, usually either
                    109: \begin{describe}
                    110: \item[\verb"std\_setup":] for file objects.
                    111: \begin{quote}\index{std\_setup}\small\begin{verbatim}
                    112: int     std_setup (ps, fp)
                    113: PS      ps;
                    114: FILE   *fp;
                    115: \end{verbatim}\end{quote}
                    116: The parameters to this procedure are:
                    117: \begin{describe}
                    118: \item[\verb"ps":] the presentation stream;
                    119: and,
                    120: 
                    121: \item[\verb"fp":] a pointer to the \verb"FILE" object to be bound to the
                    122: presentation stream.
                    123: \end{describe}
                    124: 
                    125: \item[\verb"str\_setup":] for string objects.
                    126: \begin{quote}\index{str\_setup}\small\begin{verbatim}
                    127: int     str_setup (ps, cp, cc, inline)
                    128: PS      ps;
                    129: char   *cp;
                    130: int     cc,
                    131:        inline;
                    132: \end{verbatim}\end{quote}
                    133: The parameters to this procedure are:
                    134: \begin{describe}
                    135: \item[\verb"ps":] the presentation stream;
                    136: 
                    137: \item[\verb"cp":] a pointer to the string to be bound to the presentation
                    138: stream
                    139: (use the manifest constant \verb"NULLCP" if the stream is to be written);
                    140: 
                    141: \item[\verb"cc":] the length of the string;
                    142: and,
                    143: 
                    144: \item[\verb"inline":] a magic argument,
                    145: always use \verb"0" unless you know what you're doing.
                    146: \end{describe}
                    147: 
                    148: \item[\verb"fdx\_setup":] for full-duplex file-descriptor objects.
                    149: \begin{quote}\index{fdx\_setup}\small\begin{verbatim}
                    150: int     fdx_setup (ps, fd)
                    151: PS      ps;
                    152: int     fd;
                    153: \end{verbatim}\end{quote}
                    154: The parameters to this procedure are:
                    155: \begin{describe}
                    156: \item[\verb"ps":] the presentation stream;
                    157: and,
                    158: 
                    159: \item[\verb"fd":] the file-descriptor.
                    160: \end{describe}
                    161: 
                    162: \item[\verb"dg\_setup":] for datagram objects.
                    163: \begin{quote}\index{dg\_setup}\small\begin{verbatim}
                    164: int     dg_setup (ps, fd, size, rfx, wfx)
                    165: PS      ps;
                    166: int     fd,
                    167:         size;
                    168: IFP     rfx,
                    169:         wfx;
                    170: \end{verbatim}\end{quote}
                    171: The parameters to this procedure are:
                    172: \begin{describe}
                    173: \item[\verb"ps":] the presentation stream;
                    174: 
                    175: \item[\verb"fd":] the file-descriptor;
                    176: 
                    177: \item[\verb"size":] the maximum datagram size;
                    178: and,
                    179: 
                    180: \item[\verb"rfx"/\verb"wfx":] routines to read and write datagrams.
                    181: \end{describe}
                    182: \end{describe}
                    183: After the setup routine successfully returns
                    184: (by returning the manifest constant \verb"OK"),
                    185: the presentation stream is ready for reading or writing.
                    186: 
                    187: \subsection    {Stream I/O}
                    188: Low-level I/O is done from/to the stream by the macros \verb"ps_read" and
                    189: \verb"ps_write",
                    190: which behave as if they were defined as:
                    191: \begin{quote}\index{ps\_read}\index{ps\_write}\small\begin{verbatim}
                    192: int     ps_read (ps, data, cc, inline)
                    193: PS      ps;
                    194: char   *data;
                    195: int     cc,
                    196:         inline;
                    197: 
                    198: int     ps_write (ps, data, cc, inline)
                    199: PS      ps;
                    200: char   *data;
                    201: int     cc,
                    202:         inline;
                    203: \end{verbatim}\end{quote}
                    204: The parameters to both of these macros are the same:
                    205: \begin{describe}
                    206: \item[\verb"ps":] the presentation stream;
                    207: 
                    208: \item[\verb"data":] the address of a character buffer;
                    209: 
                    210: \item[\verb"cc":] the number of characters to read/write from/to the buffer;
                    211: and,
                    212: 
                    213: \item[\verb"inline":] a magic argument,
                    214: always use \verb"0" unless you know what you're doing.
                    215: \end{describe}
                    216: These both call an internal routine, \verb"ps_io", which switches to the
                    217: object-specific read or write routine as appropriate.
                    218: The \verb"ps_io" procedure will call the object-specific routines as many
                    219: times as required to read/write the full number of \verb"cc" bytes from/to
                    220: the \verb"data" buffer.
                    221: 
                    222: \subsection    {Deleting a Stream}
                    223: The routine \verb"ps_free" is used to close and deallocate a presentation
                    224: stream.
                    225: \begin{quote}\index{ps\_free}\small\begin{verbatim}
                    226: void    ps_free (ps)
                    227: PS      ps;
                    228: \end{verbatim}\end{quote}
                    229: It takes a single parameter,
                    230: a pointer to the presentation stream to be freed.
                    231: This routine first calls the routine specified by the \verb"ps_closeP"
                    232: element in the \verb"PStream" structure (if any).
                    233: It then frees the structure itself.
                    234: 
                    235: \subsection    {Implementing Other Abstractions}
                    236: Let us briefly consider the internal protocol and uniform interface used in
                    237: the implementation of presentation streams.
                    238: 
                    239: The initialization routine given as an argument to \verb"ps_alloc" typically
                    240: initializes only the
                    241: \begin{quote}\small\begin{verbatim}
                    242: ps_primeP
                    243: ps_readP
                    244: ps_writeP
                    245: ps_flushP
                    246: ps_closeP
                    247: \end{verbatim}\end{quote}
                    248: elements in the \verb"PStream" structure.
                    249: 
                    250: The setup routine is entirely dependent on the particular object used to
                    251: realize the I/O abstraction for the presentation stream.
                    252: In most cases, it allocates a structure of its own and sets the
                    253: \verb"ps_addr" element to the address of the structure.
                    254: 
                    255: The \verb"ps_readP" and \verb"ps_writeP" elements of the \verb"PStream"
                    256: structure are used by the \verb"ps_io" routine as required for reading and
                    257: writing.
                    258: \begin{quote}\index{ps\_io}\small\begin{verbatim}
                    259: int     ps_io (ps, io, data, cc, inline)
                    260: PS      ps;
                    261: int   (*io) ();
                    262: char   *data;
                    263: int     cc,
                    264: \end{verbatim}\end{quote}
                    265: The parameters to these routines are identical to those for their counterpart
                    266: macros, \verb"ps_read" and \verb"ps_write",
                    267: with one exception:
                    268: \begin{describe}
                    269: \item[\verb"io":] the address of an integer-valued function which does the
                    270: actual reading or writing.
                    271: It is invoked as:
                    272: \begin{quote}\small\begin{verbatim}
                    273: int     n = (*io) (ps, data, len, inline);
                    274: \end{verbatim}\end{quote}
                    275: \end{describe}
                    276: where a return value of \verb"NOTOK" indicates an error occurred
                    277: (the routine should set the \verb"ps_errno" element of the presentation
                    278: stream);
                    279: \verb"OK" indicates that the end-of-file has been read;
                    280: and,
                    281: any other value is the number of bytes actually transferred
                    282: (which should be greater than \verb"0" but not greater than \verb"len").
                    283: 
                    284: For some packet-oriented applications,
                    285: it may be desirable to do a single ``read from the network'' before
                    286: reading the components of a presentation element.
                    287: The routine pointed to by the \verb"ps_primeP" element of the \verb"PStream"
                    288: structure is called by \verb"ps2pe" (described momentarily)
                    289: before any parts of the entire presentation element has been read.
                    290: The routine is invoked as:
                    291: \begin{quote}\small\begin{verbatim}
                    292: (*ps -> ps_primeP) (ps, waiting)
                    293: PS      ps;
                    294: int    waiting;
                    295: \end{verbatim}\end{quote}
                    296: The routine should return \verb"NOTOK" if an error occurred
                    297: (setting the \verb"ps_errno" element of the presentation stream in the
                    298: process);
                    299: otherwise,
                    300: if  data is already queued and \verb"waiting" is non-zero,
                    301: then \verb"DONE" is returned.
                    302: otherwise \verb"OK" is returned.
                    303: The routine \verb"ps_prime" may be called to explicitly ``prime the pump''
                    304: associated with a presentation element:
                    305: \begin{quote}\index{ps\_prime}\small\begin{verbatim}
                    306: int     ps_prime (ps)
                    307: PS      ps;
                    308: \end{verbatim}\end{quote}
                    309: This routine returns \verb"OK" on success,
                    310: or \verb"NOTOK" on failure.
                    311: 
                    312: In order to improve efficiency,
                    313: it may be desirable to have \verb"ps_writeP" buffer output.
                    314: The routine pointed to by the \verb"ps_flushP" element of the \verb"PStream"
                    315: structure is called by \verb"pe2ps" (described momentarily)
                    316: after the entire presentation element has been written.
                    317: The routine is invoked as:
                    318: \begin{quote}\small\begin{verbatim}
                    319: (*ps -> ps_flushP) (ps)
                    320: PS      ps;
                    321: \end{verbatim}\end{quote}
                    322: The routine should return \verb"NOTOK" if an error occurred
                    323: (setting the \verb"ps_errno" element of the presentation stream in the
                    324: process);
                    325: or \verb"OK" if everything was fine.
                    326: The routine \verb"ps_flush" may be called to explicitly flush any buffers
                    327: associated with a presentation element:
                    328: \begin{quote}\index{ps\_flush}\small\begin{verbatim}
                    329: int     ps_flush (ps)
                    330: PS      ps;
                    331: \end{verbatim}\end{quote}
                    332: This routine returns \verb"OK" on success,
                    333: or \verb"NOTOK" on failure.
                    334: 
                    335: Finally,
                    336: the \verb"ps_closeP" element of the \verb"PStream" structure is used by the
                    337: \verb"ps_free" routine to release any resources which the setup routine may
                    338: have allocated.
                    339: For example,
                    340: if the setup routine allocated a structure and set the \verb"ps_addr"
                    341: element of the presentation stream to point to that structure,
                    342: then the function pointed to by the \verb"ps_closeP" element should free that
                    343: structure,
                    344: and, as a matter of good programming practice, set \verb"ps_addr" to
                    345: \verb"NULL".
                    346: 
                    347: \section      {Presentation Stream I/O}
                    348: The routine \verb"ps2pe" can be used to read the next presentation element
                    349: from a presentation stream.
                    350: This routine returns a pointer to the presentation element or the manifest
                    351: constant \verb"NULLPE" on error.
                    352: (The typedef \verb"PE" is a pointer to a structure containing a presentation
                    353: element; presentation elements are described more fully later.)
                    354: \begin{quote}\index{ps2pe}\small\begin{verbatim}
                    355: PE      ps2pe (ps)
                    356: PS      ps;
                    357: \end{verbatim}\end{quote}
                    358: Similarly,
                    359: the routine \verb"pe2ps" can be used to write a presentation element at the end
                    360: of the presentation stream,
                    361: returning \verb"OK" if all went well, or \verb"NOTOK" otherwise.
                    362: \begin{quote}\index{pe2ps}\small\begin{verbatim}
                    363: int     pe2ps (ps, pe)
                    364: PS      ps;
                    365: PE      pe;
                    366: \end{verbatim}\end{quote}
                    367: On errors with either routine,
                    368: the \verb"ps_errno" element of the \verb"PStream" structure can be consulted
                    369: to see what happened
                    370: (see Table~\ref{PStreamReasons} on page~\pageref{PStreamReasons}).
                    371: 
                    372: When writing to a presentation stream,
                    373: the variable \verb"ps_len_strategy" controls how lengthy data structures
                    374: are represented by determining when the ``indefinite form'' is used to encode
                    375: the length of the data structure.
                    376: \begin{quote}\index{ps\_len\_strategy}\small\begin{verbatim}
                    377: int     ps_len_strategy;
                    378: \end{verbatim}\end{quote}
                    379: If this variable is equal to \verb"PS_LEN_SPAG" (the default),
                    380: then the indefinite form is used whenever the length field of the
                    381: presentation element can not be represented in one octet.
                    382: If the value instead is \verb"PS_LEN_INDF",
                    383: then the indefinite form is used regardless of the length of the
                    384: presentation element.
                    385: Otherwise,
                    386: if the value is \verb"PS_LEN_LONG",
                    387: then the indefinite form is never used.
                    388: 
                    389: The routine \verb"ps_get_abs" can be used to determine the total number of
                    390: octets that will be required to represent the presentation element
                    391: when written to a presentation stream.
                    392: This is useful for buffer management purposes.
                    393: \begin{quote}\index{ps\_get\_abs}\small\begin{verbatim}
                    394: int     ps_get_abs (pe)
                    395: PE      pe;
                    396: \end{verbatim}\end{quote}
                    397: 
                    398: \subsection    {Debugging}
                    399: For debugging purposes,
                    400: instead of treating a presentation stream as a binary object,
                    401: the routines \verb"pl2pe" and \verb"pe2pl" can be used.
                    402: \begin{quote}\index{pl2pe}\index{pe2pl}\small\begin{verbatim}
                    403: PE      pl2pe (ps)
                    404: PS      ps;
                    405: 
                    406: int     pe2pl (ps, pe)
                    407: PS      ps;
                    408: PE      pe;
                    409: \end{verbatim}\end{quote}
                    410: These translate between presentation {\em lists\/} and presentation elements.
                    411: A presentation list is identical to a presentation stream,
                    412: but instead of using a binary representation,
                    413: a list uses an ASCII text representation
                    414: with a simple LISP-like syntax.
                    415: 
                    416: \section      {Presentation Elements}
                    417: A presentation element is an object which is used to represent a
                    418: data structure in a machine-independent form.
                    419: The \verb"PElement" structure contains several elements,
                    420: only the most interesting are described here:
                    421: \begin{describe}
                    422: \item[\verb"pe\_errno":] the latest error to occur on the presentation element
                    423: (codes are listed in Table~\ref{PElementReasons});
                    424: 
                    425: \item[\verb"pe\_context":] the presentation context to which the element
                    426: belongs (consult Section~\ref{psap:context} on page~\pageref{psap:context} of
                    427: \voltwo/);
                    428: 
                    429: \item[\verb"pe\_class":] the class of this presentation element
                    430: (i.e., one of {\em universal}, {\em application-wide}, {\em context-specific},
                    431: or {\em private\/});
                    432: 
                    433: \item[\verb"pe\_form":] the form taken by this presentation element
                    434: (i.e., {\em primitive}, or {\em constructed\/});
                    435: 
                    436: \item[\verb"pe\_id":] the class-specific code identifying the type of this
                    437: presentation element;
                    438: 
                    439: \item[\verb"pe\_offset":] the offset of this presentation element in a
                    440: sequence;
                    441: and,
                    442: 
                    443: \item[\verb"pe\_next":] a pointer to the next presentation element in a
                    444: sequence.
                    445: \end{describe}
                    446: \tagtable[tp]{3-2}{Presentation Element Failure Codes}{PElementReasons}
                    447: As mentioned earlier,
                    448: the typedef \verb"PE" is a pointer to an \verb"PElement" structure.
                    449: With the exception of the \verb"pe_errno" element,
                    450: the elements of the \verb"PElement" structure are largely uninteresting to
                    451: the user of the \man libpsap(3) library.
                    452: The element \verb"pe_errno"
                    453: can be given as a parameter to the routine \verb"pe_error" which returns a
                    454: null-terminated diagnostic string.
                    455: \begin{quote}\index{pe\_error}\small\begin{verbatim}
                    456: char   *pe_error (c)
                    457: int     c;
                    458: \end{verbatim}\end{quote}
                    459: 
                    460: Once a presentation stream has been initialized and elements are being read,
                    461: there are several routines which can be used to translate between the
                    462: machine-independent representation of the element and machine-specific
                    463: objects such as integers, strings, and the like.
                    464: It is extremely important that programs use these routines to perform the
                    465: translation between objects.
                    466: They have been carefully coded to present a simple, uniform interface between
                    467: machine-specifics and the machine-independent encoding protocol.
                    468: 
                    469: \subsection    {Creating an Element}
                    470: A \verb"PElement" structure is created by calling the procedure
                    471: \verb"pe_alloc".
                    472: \begin{quote}\index{pe\_alloc}\small\begin{verbatim}
                    473: PE      pe_alloc (class, form, id)
                    474: PElementClass class;
                    475: PElementForm form;
                    476: PElementID id;
                    477: \end{verbatim}\end{quote}
                    478: This procedure takes three parameters:
                    479: \begin{describe}
                    480: \item[\verb"class":] the class of this presentation element.
                    481: The codes are:
                    482: 
                    483: \begin{tabular}{rp{3.0in}}
                    484: \tt PE\_CLASS\_UNIV&   Universal\\
                    485: \tt PE\_CLASS\_APPL&   Application-wide\\
                    486: \tt PE\_CLASS\_CONT&   Context-specific\\
                    487: \tt PE\_CLASS\_PRIV&   Private-use
                    488: \end{tabular}
                    489: 
                    490: \item[\verb"form":] the form of this presentation element
                    491: The codes are:
                    492: 
                    493: \begin{tabular}{rp{3.0in}}
                    494: \tt PE\_FORM\_PRIM&    Primitive\\
                    495: \tt PE\_FORM\_CONS&    Constructor
                    496: \end{tabular}
                    497: 
                    498: \item[\verb"id":] the class-specific code identifying the type of this
                    499: presentation element
                    500: (codes for the ``universal'' class are listed in Table~\ref{PElementIDs}).
                    501: \end{describe}
                    502: \tagtable[tp]{3-3}{Presentation Element Identifiers}{PElementIDs}
                    503: 
                    504: \subsection    {Deleting an Element}
                    505: The routine \verb"pe_free" is used to deallocate a presentation element.
                    506: \begin{quote}\index{pe\_free}\small\begin{verbatim}
                    507: void    pe_free (pe)
                    508: PE      pe;
                    509: \end{verbatim}\end{quote}
                    510: 
                    511: \[\fbox{\begin{tabular}{lp{0.8\textwidth}}
                    512: \bf NOTE:&     When using \verb"pe\_free" on a presentation element,
                    513:                care must be taken to remove any references to that
                    514:                presentation element in other structures.
                    515:                For example, if you have a sequence containing a sequence,
                    516:                and you free the child sequence,
                    517:                be sure to zero-out the parent's pointer to the child,
                    518:                otherwise subsequent calls using the parent will go romping
                    519:                through hyperspace.
                    520:                See \verb"pe\_extract" and \verb"pe\_expunge" below.
                    521: \end{tabular}}\]
                    522: 
                    523: \subsection    {Primitive Manipulation of Elements}
                    524: Two presentation elements can be compared with \verb"pe_cmp",
                    525: which takes two pointers to \verb"PElement" structures as arguments,
                    526: and returns \verb"0" if the two structures are identical,
                    527: \verb"1" otherwise.
                    528: \begin{quote}\index{pe\_cmp}\small\begin{verbatim}
                    529: int     pe_cmp (p, q)
                    530: PE      p,
                    531:         q;
                    532: \end{verbatim}\end{quote}
                    533: Further, an presentation element can be duplicated with \verb"pe_cpy".
                    534: This routine takes a pointer to an \verb"PElement" structure as an argument,
                    535: and  returns a pointer to a new \verb"PElement" structure,
                    536: or \verb"NULLPE" on error.
                    537: \begin{quote}\index{pe\_cpy}\small\begin{verbatim}
                    538: PE      pe_cpy (pe)
                    539: PE      pe;
                    540: \end{verbatim}\end{quote}
                    541: 
                    542: If a presentation element, \verb"pe", has a descendant \verb"r"
                    543: (which appears below \verb"pe" exactly once),
                    544: then \verb"pe_extract" can be used to destroy the relationship between
                    545: the two presentation elements without freeing either element.
                    546: \begin{quote}\index{pe\_extract}\small\begin{verbatim}
                    547: int     pe_extract (pe, r)
                    548: PE      pe,
                    549:         r;
                    550: \end{verbatim}\end{quote}
                    551: This routine returns non-zero if \verb"r" was descended from \verb"pe",
                    552: otherwise it returns zero.
                    553: The \verb"pe_expunge" routine is similar to \verb"pe_extract",
                    554: except that it always deallocates the parent element and returns the child
                    555: element found, if any.
                    556: \begin{quote}\index{pe\_expunge}\small\begin{verbatim}
                    557: PE      pe_expunge (pe, r)
                    558: PE      pe,
                    559:         r;
                    560: \end{verbatim}\end{quote}
                    561: These two routines are provided primarily for efficiency considerations.
                    562: They are extremely fragile.
                    563: Do not use them unless you know what you're doing.
                    564: 
                    565: Finally,
                    566: the \verb"pe_pullup" routine can be used to ``pull-up'' a constructor type
                    567: into a primitive.
                    568: \begin{quote}\index{pe\_pullup}\small\begin{verbatim}
                    569: int     pe_pullup (pe)
                    570: PE      pe;
                    571: \end{verbatim}\end{quote}
                    572: This routine returns \verb"OK" on success;
                    573: on failure it turns \verb"NOTOK",
                    574: usually due to a memory allocation failure.
                    575: 
                    576: \section      {Presentation Element Transformations}
                    577: We now discuss how machine-specific objects can be encoded in a
                    578: machine-independent fashion and vice-versa.
                    579: Routines of the form \verb"XXX2prim" all return a pointer to a presentation
                    580: element on success,
                    581: or \verb"NULLPE" on failure
                    582: (usually due to a failure in the memory allocator).
                    583: Routines of the form \verb"prim2XXX" all return an \verb"XXX"-valued object
                    584: on success,
                    585: or \verb"NOTOK" or \verb"NULLxxx" on failure
                    586: (depending on the object the routine normally returns).
                    587: On failure,
                    588: the \verb"pe_errno" element of the presentation element can be examined to
                    589: determine the reason for failure.
                    590: 
                    591: \subsection    {Boolean}
                    592: A {\em boolean\/} is an integer taking on the values \verb"0" or \verb"1".
                    593: The routine \verb"prim2flag" takes a pointer to an presentation element and
                    594: returns the boolean value encoded therein.
                    595: \begin{quote}\index{prim2flag}\small\begin{verbatim}
                    596: int     prim2flag (pe)
                    597: PE      pe;
                    598: \end{verbatim}\end{quote}
                    599: The routine \verb"bool2prim" is a macro which performs the inverse operation.
                    600: It behaves as if it was defined as:
                    601: \begin{quote}\index{bool2prim}\small\begin{verbatim}
                    602: PE      bool2prim (b)
                    603: int     b;
                    604: \end{verbatim}\end{quote}
                    605: In actuality,
                    606: \verb"bool2prim" calls the routine \verb"flag2prim" which builds a
                    607: presentation element containing the boolean value given and sets the
                    608: \verb"pe_class" and \verb"pe_id" fields of the presentation element to the
                    609: desired values.
                    610: \begin{quote}\index{flag2prim}\small\begin{verbatim}
                    611: PE      flag2prim (b, class, id)
                    612: int     b;
                    613: PElementClass class;
                    614: PElementID id;
                    615: \end{verbatim}\end{quote}
                    616: 
                    617: \subsection    {Integer}
                    618: An {\em integer\/} is a signed-quantity, whose precision is specific to a
                    619: particular host.
                    620: The routine \verb"prim2num" takes a pointer to a presentation element and
                    621: returns the integer value
                    622: encoded therein (if the value is \verb"NOTOK", check the \verb"pe_errno"
                    623: element of the \verb"PElement" structure to see if there really was an error).
                    624: \begin{quote}\index{prim2num}\small\begin{verbatim}
                    625: int     prim2num (pe)
                    626: PE      pe;
                    627: \end{verbatim}\end{quote}
                    628: The routine \verb"int2prim" is a macro which performs the inverse operation.
                    629: It behaves as if it was defined as:
                    630: \begin{quote}\index{int2prim}\small\begin{verbatim}
                    631: PE      int2prim (i)
                    632: int     i;
                    633: \end{verbatim}\end{quote}
                    634: In actuality,
                    635: \verb"int2prim" calls the routine \verb"num2prim" which builds a presentation
                    636: element containing the numeric value given and sets the \verb"pe_class" and
                    637: \verb"pe_id" fields of the presentation element to the desired values.
                    638: \begin{quote}\index{num2prim}\small\begin{verbatim}
                    639: PE      num2prim (i, class, id)
                    640: int     i;
                    641: PElementClass class;
                    642: PElementID id;
                    643: \end{verbatim}\end{quote}
                    644: 
                    645: \subsection    {Octetstring}
                    646: An {\em octetstring\/} is a pair of values:
                    647: a character pointer and an integer length.
                    648: The pointer addresses the first octet in the string
                    649: (which need not be null-terminated),
                    650: the length indicates how many octets are in the string.
                    651: The routine \verb"prim2str" takes a pointer to a presentation element and
                    652: allocates a new string (using the \man malloc(3) routine)
                    653: containing the value encoded therein.
                    654: \begin{quote}\index{prim2str}\small\begin{verbatim}
                    655: char   *prim2str (pe, len)
                    656: PE      pe;
                    657: int    *len;
                    658: \end{verbatim}\end{quote}
                    659: The routine \verb"oct2prim" is a macro which performs the inverse operation,
                    660: copying the original string (and not de-allocating it).
                    661: It behaves as if it was defined as:
                    662: \begin{quote}\index{oct2prim}\small\begin{verbatim}
                    663: PE      oct2prim (s, len)
                    664: char   *s;
                    665: int     len;
                    666: \end{verbatim}\end{quote}
                    667: In actuality,
                    668: \verb"oct2prim" calls the routine \verb"str2prim" which builds a presentation
                    669: element containing the string value given and sets the \verb"pe_class" and
                    670: \verb"pe_id" fields of the presentation element to the desired values.
                    671: \begin{quote}\index{str2prim}\small\begin{verbatim}
                    672: PE      str2prim (s, len, class, id)
                    673: char   *s;
                    674: int     len;
                    675: PElementClass class;
                    676: PElementID id;
                    677: \end{verbatim}\end{quote}
                    678: 
                    679: In addition to \verb"oct2prim",
                    680: there are several macros which manipulate octetstrings,
                    681: setting the class and id of the presentation element to the
                    682: appropriate value:
                    683: \[\begin{tabular}{|l|l|}
                    684: \hline
                    685:     \multicolumn{1}{|c|}{\bf Macro}&
                    686:                \multicolumn{1}{c|}{\bf String}\\
                    687: \hline
                    688:     \tt ia5s2prim&     IA5 string\\
                    689:     \tt nums2prim&     Numeric string\\
                    690:     \tt prts2prim&     Printable string\\
                    691:     \tt t61s2prim&     T.61 string\\
                    692:     \tt vtxs2prim&     Videotex string\\
                    693:     \tt gfxs2prim&     Graphics string\\
                    694:     \tt viss2prim&     Visible string\\
                    695:     \tt gens2prim&     General string\\
                    696:     \tt chrs2prim&     Character string\\
                    697:     \tt ode2prim&      Object descriptor\\
                    698: \hline
                    699: \end{tabular}\]
                    700: Each of these macros are defined in a similar manner to the \verb"oct2prim"
                    701: macro.\index{ia5s2prim}\index{nums2prim}\index{prts2prim}\index{t61s2prim}
                    702: \index{vtxs2prim}\index{gfxs2prim}\index{viss2prim}\index{gens2prim}   
                    703: \index{ode2prim}
                    704: 
                    705: \subsection    {Octetstrings revisited}\label{psap:qbuf}
                    706: For efficiency reasons,
                    707: it is often desirable to represent an octetstring using a \verb"qbuf"
                    708: structure.
                    709: Although the format of a \verb"qbuf" is described in Section~\ref{tsap:qbuf}
                    710: on page~\pageref{tsap:qbuf} of \voltwo/,
                    711: the \man libpsap(3) library provides several routines for ease of
                    712: manipulation.
                    713: 
                    714: The routine \verb"qb2prim" takes a linked-list of \verb"qbuf"s and builds a
                    715: presentation element with the \verb"pe_class" and \verb"pe_id" fields of the
                    716: presentation element set to the desired values:
                    717: \begin{quote}\index{qb2prim}\small\begin{verbatim}
                    718: PE      qb2prim (qb, class, id)
                    719: struct qbuf *qb;
                    720: PElementClass class;
                    721: PElementID id;
                    722: \end{verbatim}\end{quote}
                    723: \[\fbox{\begin{tabular}{lp{0.8\textwidth}}
                    724: \bf NOTE:&     The presentation element returned by \verb"qb2prim" contains
                    725:                pointers into the linked-list of \verb"qbuf"s.
                    726:                Therefore care must be taken not to delete any of the
                    727:                \verb"qbuf"s in the linked-list prior to the final use of the
                    728:                presentation element.  Note however, than the presentation
                    729:                element may be de-allocated at anytime without affecting
                    730:                the \verb"qbuf"s in the linked-list.
                    731: \end{tabular}}\]
                    732: 
                    733: 
                    734: The routine \verb"prim2qb" performs the inverse operation:
                    735: \begin{quote}\index{prim2qb}\small\begin{verbatim}
                    736: struct qbuf *prim2qb (pe)
                    737: PE      pe;
                    738: \end{verbatim}\end{quote}
                    739: 
                    740: When examining the contents of a \verb"qbuf",
                    741: it is most efficient to examine each \verb"qbuf" in the linked list,
                    742: as in:
                    743: \begin{quote}\small\begin{verbatim}
                    744: register struct qbuf *qp;
                    745: 
                    746: for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw)
                    747:     /* examine qp -> qb_data, qp -> qb_len here */ ;
                    748: \end{verbatim}\end{quote}
                    749: However,
                    750: some applications may wish to simply convert the \verb"qbuf" into one string
                    751: and examine it without worrying about traversing the linked list.
                    752: The routine \verb"qb2str" performs this function:
                    753: \begin{quote}\index{qb2str}\small\begin{verbatim}
                    754: char   *qb2str (qb)
                    755: struct qbuf *qb;
                    756: \end{verbatim}\end{quote}
                    757: The routine \verb"str2qb" performs the inverse operation,
                    758: converting a string to a \verb"qbuf".
                    759: \begin{quote}\index{str2qb}\small\begin{verbatim}
                    760: struct qbuf *str2qb (s, len, head)
                    761: char   *s;
                    762: int     len,
                    763:        head;
                    764: \end{verbatim}\end{quote}
                    765: The \verb"head" parameter indicates whether \verb"str2qb" should allocate a
                    766: \verb"qbuf" containing both the head of the linked list and one element
                    767: (\verb"head" is non-zero),
                    768: or just the element itself (\verb"head" is zero).
                    769: 
                    770: The routine \verb"qb_pullup" can be used to compact a linked list of
                    771: \verb"qbuf"s into a list containing the \verb"qbuf" head and one element:
                    772: \begin{quote}\index{qb\_pullup}\small\begin{verbatim}
                    773: int     qb_pullup (qb)
                    774: struct qbuf *qb;
                    775: \end{verbatim}\end{quote}
                    776: This routine returns the manifest constant \verb"NOTOK" on failure,
                    777: and \verb"OK" otherwise.
                    778: 
                    779: The routine \verb"qbuf2pe" is used to set-up a presentation stream which reads
                    780: from a linked list of \verb"qbuf"s and returns the presentation element
                    781: encoded therein:
                    782: \begin{quote}\index{qbuf2pe}\small\begin{verbatim}
                    783: PE      qbuf2pe (qb, len, result)
                    784: struct qbuf *qb;
                    785: int     len,
                    786:        *result;
                    787: \end{verbatim}\end{quote}
                    788: This routine returns a presentation element on success,
                    789: and \verb"NULLPE" on failure.
                    790: In the latter case, the parameter \verb"result" is updated to reflect the
                    791: presentation stream error.
                    792: 
                    793: Finally,
                    794: the routine \verb"qb_free" will deallocate a linked list of \verb"qbuf"s:
                    795: \begin{quote}\index{qb\_free}\small\begin{verbatim}
                    796: void    qb_free (qb)
                    797: \end{verbatim}\end{quote}
                    798: 
                    799: \subsection    {Bitvector}\label{psap:bits}
                    800: A {\em bitvector\/} is an arbitrarily long string of bits
                    801: (starting with bit \verb"0") with three operations:
                    802: \begin{describe}
                    803: \item[\verb"bit\_on":] which turns the indicated bit on;
                    804: \begin{quote}\index{bit\_on}\small\begin{verbatim}
                    805: int     bit_on (pe, bitno)
                    806: PE      pe;
                    807: int     bitno;
                    808: \end{verbatim}\end{quote}
                    809: 
                    810: \item[\verb"bit\_off":] which turns the indicated bit off;
                    811: \begin{quote}\index{bit\_off}\small\begin{verbatim}
                    812: int     bit_off (pe, bitno)
                    813: PE      pe;
                    814: int     bitno;
                    815: \end{verbatim}\end{quote}
                    816: and,
                    817: 
                    818: \item[\verb"bit\_test":] which returns a boolean value telling if the indicated
                    819: bit was on.
                    820: \begin{quote}\index{bit\_test}\small\begin{verbatim}
                    821: int     bit_test (pe, bitno)
                    822: PE      pe;
                    823: int     bitno;
                    824: \end{verbatim}\end{quote}
                    825: \end{describe}
                    826: The routine \verb"prim2bit" takes a pointer to a presentation element and
                    827: builds such an abstraction containing the value encoded therein.
                    828: \begin{quote}\index{prim2bit}\small\begin{verbatim}
                    829: PE      prim2bit (pe)
                    830: PE      pe;
                    831: \end{verbatim}\end{quote}
                    832: The routine \verb"bit2prim" performs the inverse operation.
                    833: \begin{quote}\index{bit2prim}\small\begin{verbatim}
                    834: PE      bit2prim (pe)
                    835: PE      pe;
                    836: \end{verbatim}\end{quote}
                    837: 
                    838: There are also some support routines useful mainly with \pgm{pepy}.
                    839: The routine \verb"strb2bitstr" takes a pointer to a character
                    840: string and an integer containing the number of bits and constructs
                    841: a presentation element as described above containing the bits.
                    842: \begin{quote}\index{strb2bitstr}\small\begin{verbatim}
                    843: PE      strb2bitstr (cp, length, class, id)
                    844: char   *cp;
                    845: int     length;
                    846: PElementClass class;
                    847: PElementID id;
                    848: \end{verbatim}\end{quote}
                    849: The inverse operation is handled by the function \verb"bitstr2strb".
                    850: This takes a presentation element containing a bit string and produces
                    851: a new character string with the appropriate bits set. The second
                    852: parameter will contain the number of valid bits on return.
                    853: \begin{quote}\index{bitstr2strb}\small\begin{verbatim}
                    854: char   *bitstr2strb (pe, length)
                    855: PE      pe;
                    856: int    *length;
                    857: \end{verbatim}\end{quote}
                    858: Finally, the routines \verb"int2strb" and \verb"strb2int" are provided to
                    859: convert an integer containing a bit list into a string of bits suitable for
                    860: input to \verb"strb2bitstr", and to perform the inverse operation
                    861: \begin{quote}\index{int2strb}\small\begin{verbatim}
                    862: char   *int2strb (n, length)
                    863: int     n;
                    864: int     length;
                    865: 
                    866: int     strb2int (cp, length)
                    867: char   *cp;
                    868: int     length;
                    869: \end{verbatim}\end{quote}
                    870: 
                    871: \subsection    {Object Identifier}\label{psap:oid}
                    872: An {\em object identifier\/} represents an ordered set of authoritative
                    873: designations used for identification.
                    874: Internally,
                    875: the \verb"OIDentifier" is used to represent this notion:
                    876: \begin{quote}\index{OIDentifier}\small\begin{verbatim}
                    877: typedef struct OIDentifier {
                    878:     int     oid_nelem;
                    879: 
                    880:     unsigned int *oid_elements;
                    881: }       OIDentifier, *OID;
                    882: #define NULLOID ((OID) 0)
                    883: \end{verbatim}\end{quote}
                    884: This structure contains two elements:
                    885: \begin{describe}
                    886: \item[\verb"oid\_elements"/\verb"oid\_nelem":] the (ordered) list of
                    887: sub-identifiers (and the number of elements in the list).
                    888: \end{describe}
                    889: 
                    890: Two object identifiers can be compared with \verb"oid_cmp",
                    891: which takes two pointers to \verb"OIDentifier" structures as arguments,
                    892: and returns \verb"0" if the two structures are identical,
                    893: \verb"1" otherwise.
                    894: \begin{quote}\index{oid\_cmp}\small\begin{verbatim}
                    895: int     oid_cmp (p, q)
                    896: OID     p,
                    897:         q;
                    898: \end{verbatim}\end{quote}
                    899: Further, an object identifier can be duplicated with \verb"oid_cpy".
                    900: This routine takes a pointer to an \verb"OIDentifier" structure as an argument,
                    901: and  returns a pointer to a new \verb"OIDentifier" structure,
                    902: or \verb"NULLOID" on error.
                    903: \begin{quote}\index{oid\_cpy}\small\begin{verbatim}
                    904: OID     oid_cpy (oid)
                    905: OID     oid;
                    906: \end{verbatim}\end{quote}
                    907: Simlarly, the routine \verb"oid_free" can be used to free an object
                    908: identifier which has been allocated.
                    909: \begin{quote}\index{oid\_free}\small\begin{verbatim}
                    910: void    oid_free (oid)
                    911: OID     oid;
                    912: \end{verbatim}\end{quote}
                    913: The routine \verb"sprintoid" can be used to return a null-terminated
                    914: string describing the object identifier.
                    915: \begin{quote}\index{sprintoid}\small\begin{verbatim}
                    916: char   *sprintoid (oid)
                    917: OID     oid;
                    918: \end{verbatim}\end{quote}
                    919: The default routine \verb"oid2ode"\index{oid2ode} is identical to the
                    920: \verb"sprintoid",
                    921: but is intended for user customization.
                    922: For example,
                    923: whilst \verb"sprintoid" should always be used when an object identifier should
                    924: be expressed in ``dot notation'',
                    925: the user may define a new \verb"oid2ode" which returns symbolic names,
                    926: if so desired.
                    927: 
                    928: The routine \verb"str2oid" can be used as the inverse of \verb"sprintoid":
                    929: \begin{quote}\index{str2oid}\small\begin{verbatim}
                    930: OID     str2oid (s)
                    931: char   *s;
                    932: \end{verbatim}\end{quote}
                    933: Finally,
                    934: the routine \verb"ode2oid" can be used to fetch an object identifier from the
                    935: \man isobjects(5) database described in Chapter~\ref{isobjects}.
                    936: \begin{quote}\index{oid\_free}\small\begin{verbatim}
                    937: OID     ode2oid (descriptor)
                    938: char   *descriptor;
                    939: \end{verbatim}\end{quote}
                    940: This routine performs a lookup using the \verb"getisobjectbyname" routine
                    941: and then returns a pointer to a static \verb"OIDentifier" structure
                    942: containing the desired information.
                    943: The routine returns \verb"NULLOID" on failure.
                    944: 
                    945: The routines \verb"prim2oid" and \verb"oid2prim" are used to translate
                    946: between a machine-specific internal form and the machine-independent form.
                    947: \begin{quote}\index{prim2oid}\index{oid2prim}\small\begin{verbatim}
                    948: OID     prim2oid (pe)
                    949: PE      pe;
                    950: 
                    951: PE      oid2prim (o)
                    952: OID     o;
                    953: \end{verbatim}\end{quote}
                    954: In actuality,
                    955: \verb"oid2prim" is really a macro which calls the routine \verb"obj2prim"
                    956: which builds a presentation element containing the object identifier given
                    957: and sets the \verb"pe_class" an \verb"pe_id" fields of the presentation element
                    958: to the desired values.
                    959: \begin{quote}\index{obj2prim}\small\begin{verbatim}
                    960: PE      obj2prim (o, class, id)
                    961: OID     o;
                    962: PElementClass class;
                    963: PElementID id;
                    964: \end{verbatim}\end{quote}
                    965: 
                    966: \subsection    {Timestring}
                    967: A {\em timestring\/} represents a date/time in many forms.
                    968: Currently, two forms are supported: {\em universal time\/} and
                    969: {\em generalized time}.
                    970: Internally,
                    971: the \verb"UTCtime" structure is used to represent both notions:
                    972: \begin{quote}\index{UTCtime}\small\begin{verbatim}
                    973: typedef struct UTCtime {
                    974:     int     ut_year;
                    975:     int     ut_mon;
                    976:     int     ut_mday;
                    977:     int     ut_hour;
                    978:     int     ut_min;
                    979:     int     ut_sec;
                    980: 
                    981:     int     ut_msec;
                    982: 
                    983:     int     ut_zone;
                    984: 
                    985:     int     ut_flags;
                    986: }       UTCtime, *UTC;
                    987: #define NULLUTC ((UTC) 0)
                    988: \end{verbatim}\end{quote}
                    989: This structure contains several elements:
                    990: \begin{describe}
                    991: \item[\verb"ut\_year":] the year,
                    992: either since the current century (e.g., \verb"86"),
                    993: or absolute (e.g., \verb"1986");
                    994: 
                    995: \item[\verb"ut\_mon":] the month of the year, in the range \verb"1..12";
                    996: 
                    997: \item[\verb"ut\_mday":] the day of the month, in the range \verb"1..31";
                    998: 
                    999: \item[\verb"ut\_hour":] the hour of the day, in the range \verb"0..23";
                   1000: 
                   1001: \item[\verb"ut\_min":] the minute of the hour, in the range \verb"0..59";
                   1002: 
                   1003: \item[\verb"ut\_sec":] (optionally) the second of the minute,
                   1004: in the range \verb"0..59";
                   1005: 
                   1006: \item[\verb"ut\_usec":] (optionally) fractions of a second, in microseconds;
                   1007: 
                   1008: \item[\verb"ut\_zone":] (optionally) the timezone, expressed as minutes from
                   1009: UT; and,
                   1010: 
                   1011: \item[\verb"ut\_flags":] various flags describing the timestring:
                   1012:     \begin{describe}
                   1013:     \item[\verb"UT\_ZONE":] the \verb"ut_zone" element is present; 
                   1014: 
                   1015:     \item[\verb"UT\_SEC":] the \verb"ut_sec" element is present; and,
                   1016: 
                   1017:     \item[\verb"UT\_USEC":] the \verb"ut_usec" element is present.
                   1018:     \end{describe}
                   1019: \end{describe}
                   1020: 
                   1021: The routine \verb"prim2utct" takes a pointer to a presentation element and
                   1022: returns the universal time encoded therein.
                   1023: \begin{quote}\index{prim2utct}\small\begin{verbatim}
                   1024: UTC     prim2utct (pe)
                   1025: PE      pe;
                   1026: \end{verbatim}
                   1027: \end{quote}
                   1028: The routine \verb"utct2prim" is a macro which performs the inverse operatoin.
                   1029: It behaves as if it was defined as:
                   1030: \begin{quote}\index{utct2prim}\small\begin{verbatim}
                   1031: PE      utct2prim (u)
                   1032: UTC     u;
                   1033: \end{verbatim}\end{quote}
                   1034: 
                   1035: The routine \verb"prim2gent" takes a pointer to a presentation element and
                   1036: returns the universal time encoded therein.
                   1037: \begin{quote}\index{prim2gent}\small\begin{verbatim}
                   1038: UTC     prim2gent (pe)
                   1039: PE      pe;
                   1040: \end{verbatim}
                   1041: \end{quote}
                   1042: The routine \verb"gent2prim" is a macro which performs the inverse operatoin.
                   1043: It behaves as if it was defined as:
                   1044: \begin{quote}\index{gent2prim}\small\begin{verbatim}
                   1045: PE      gent2prim (u)
                   1046: UTC     u;
                   1047: \end{verbatim}\end{quote}
                   1048: 
                   1049: In actuality,
                   1050: both \verb"utct2prim" and \verb"gent2prim" call the routine \verb"time2prim"
                   1051: which builds a
                   1052: presentation element containing the universal or general time given and sets
                   1053: the \verb"pe_class" an \verb"pe_id" fields of the presentation element to the
                   1054: desired values.
                   1055: \begin{quote}\index{time2prim}\small\begin{verbatim}
                   1056: PE      time2prim (ut, generalized, class, id)
                   1057: UTC     u;
                   1058: int    generalized;
                   1059: PElementClass class;
                   1060: PElementID id;
                   1061: \end{verbatim}\end{quote}
                   1062: 
                   1063: To get a null-terminated string representation of a \verb"UTCtime" structure,
                   1064: the macros \verb"utct2str" and \verb"gent2str" can be
                   1065: used.\index{utct2str}\index{gent2str}
                   1066: Each take a single argument, a pointer to a \verb"UTCtime" structure.
                   1067: These call the routine \verb"time2str":
                   1068: \begin{quote}\index{time2str}\small\begin{verbatim}
                   1069: char   *time2str (ut, generalized)
                   1070: UTC     u;
                   1071: int     generalized;
                   1072: \end{verbatim}\end{quote}
                   1073: Both call the routine \verb"prim2time":
                   1074: \begin{quote}\index{prim2time}\small\begin{verbatim}
                   1075: UTC     prim2time (pe, generalized)
                   1076: PE      pe;
                   1077: int     generalized;
                   1078: \end{verbatim}\end{quote}
                   1079: 
                   1080: The routines \verb"str2utct" and \verb"str2gent" perform the inverse
                   1081: operations:
                   1082: \begin{quote}\index{str2utct}\index{str2gent}\small\begin{verbatim}
                   1083: UTC     str2utct (cp, len)
                   1084: char   *cp;
                   1085: int     len;
                   1086: 
                   1087: UTC     str2gent (cp, len)
                   1088: char   *cp;
                   1089: int     len;
                   1090: \end{verbatim}\end{quote}
                   1091: Each take a character-pointer and a length-indicator as arguments and return a
                   1092: \verb"UTCtime" structure on success.
                   1093: Otherwise, the manifest constant \verb"NULLUTC" is returned.
                   1094: 
                   1095: There are also some utility routines to aid in converting between
                   1096: \verb"UTCtime" and \unix/ \verb"tm" time structures.
                   1097: The routine \verb"gtime" is the inverse of \man gmtime(3),
                   1098: it takes a time structure and returns a long-valued number.
                   1099: \begin{quote}\index{gtime}\small\begin{verbatim}
                   1100: long    gtime (tm)
                   1101: struct tm *tm;
                   1102: \end{verbatim}\end{quote}
                   1103: The routine \verb"ut2tm" returns a pointer to a static time structure
                   1104: which has been initialized by its \verb"UTC" argument.
                   1105: \begin{quote}\index{ut2tm}\small\begin{verbatim}
                   1106: struct tm *ut2tm (ut)
                   1107: UTC     ut;
                   1108: \end{verbatim}\end{quote}
                   1109: Finally, the routine \verb"tm2ut" performs the inverse operation,
                   1110: initializing a \verb"UTC" argument by using a time structure argument.
                   1111: \begin{quote}\index{tm2ut}\small\begin{verbatim}
                   1112: void     tm2ut (tm, ut)
                   1113: struct tm *tm;
                   1114: UTC     ut;
                   1115: \end{verbatim}\end{quote}
                   1116: 
                   1117: \subsection    {Sets and Sequences}
                   1118: Two list disciplines are implemented:
                   1119: {\em sets}, in which each member is distinguished by a unique identifier;
                   1120: and,
                   1121: {\em sequences}, in which each element is distinguished by its offset from
                   1122: the head of the list. It should be noted that these definitions of
                   1123: sets and sequences do not exactly match those defined in ASN.1. In
                   1124: particular, the ASN.1 structure \verb*"SET OF" must be defined as a
                   1125: type \verb"SET", but be built up with the \verb"seq_add" construct,
                   1126: as these elements all have the same type.
                   1127: On both types of lists,
                   1128: the macro \verb"first_member" returns the first member in the list,
                   1129: while \verb"next_member" returns the next member.
                   1130: These macros behave as if they were defined as:
                   1131: \begin{quote}\index{first\_member}\index{next\_member}\small\begin{verbatim}
                   1132: PE      first_member (head)
                   1133: PE      head;
                   1134: 
                   1135: PE      next_member (head, member)
                   1136: PE      head,
                   1137:         member;
                   1138: \end{verbatim}\end{quote}
                   1139: There are three operations on sets:
                   1140: \begin{describe}
                   1141: \item[\verb"set\_add":] adds a new member to the set;
                   1142: \begin{quote}\index{set\_add}\small\begin{verbatim}
                   1143: int     set_add (pe, r)
                   1144: PE      pe,
                   1145:         r;
                   1146: \end{verbatim}\end{quote}
                   1147: The routine \verb"set_addon" is an efficient version of \verb"set_add" that
                   1148: is used when adding several consecutive members to a set.\index{set\_addon}
                   1149: 
                   1150: \item[\verb"set\_del":] removes the identified member from the
                   1151: set;
                   1152: \begin{quote}\index{set\_del}\small\begin{verbatim}
                   1153: int     set_del (pe, class, id)
                   1154: PE      pe;
                   1155: PElementClass class;
                   1156: PElementID id;
                   1157: \end{verbatim}\end{quote}
                   1158: and,
                   1159: 
                   1160: \item[\verb"set\_find":] locates the identified member.
                   1161: \begin{quote}\index{set\_find}\small\begin{verbatim}
                   1162: PE      set_find (pe, class, id)
                   1163: PE      pe;
                   1164: PElementClass class;
                   1165: PElementID id;
                   1166: \end{verbatim}\end{quote}
                   1167: \end{describe}
                   1168: The routines \verb"prim2set" and \verb"set2prim" are used to translate between
                   1169: presentation elements and sets.
                   1170: \begin{quote}\index{prim2set}\index{set2prim}\small\begin{verbatim}
                   1171: PE      prim2set (pe)
                   1172: PE      pe;
                   1173: 
                   1174: PE      set2prim (pe)
                   1175: PE      pe;
                   1176: \end{verbatim}\end{quote}
                   1177: In Figure~\ref{stepTHRUset},
                   1178: a convenient way of stepping through all the members of a set is presented.
                   1179: \tagrind[tp]{grind3-1}{Stepping through a Sequence}{stepTHRUset}
                   1180: 
                   1181: There are three operations on sequences:
                   1182: \begin{describe}
                   1183: \item[\verb"seq\_add":] adds a new member \verb"r" to the sequence
                   1184: \verb"pe", at the given offset, an offset of \verb"-1" will add the
                   1185: element to the end of the sequence;
                   1186: \begin{quote}\index{seq\_add}\small\begin{verbatim}
                   1187: int     seq_add (pe, r, offset)
                   1188: PE      pe,
                   1189:         r;
                   1190: int     offset;
                   1191: \end{verbatim}\end{quote}
                   1192: The routine \verb"seq_addon" is an efficient version of \verb"seq_add" that
                   1193: is used when adding several consecutive elements to a set.\index{seq\_addon}
                   1194: 
                   1195: \item[\verb"seq\_del":] removes the identified member from the
                   1196: sequence;
                   1197: \begin{quote}\index{seq\_del}\small\begin{verbatim}
                   1198: int     seq_del (pe, offset)
                   1199: PE      pe;
                   1200: int     offset;
                   1201: \end{verbatim}\end{quote}
                   1202: and,
                   1203: 
                   1204: \item[\verb"seq\_find":] locates the identified element.
                   1205: \begin{quote}\index{seq\_find}\small\begin{verbatim}
                   1206: PE      seq_find (pe, offset)
                   1207: PE      pe;
                   1208: int     offset;
                   1209: \end{verbatim}\end{quote}
                   1210: \end{describe}
                   1211: The routines \verb"prim2seq" and \verb"seq2prim" are used to translate between
                   1212: presentation elements and sequences.
                   1213: \begin{quote}\index{prim2seq}\index{prim2seq}\small\begin{verbatim}
                   1214: PE      prim2seq (pe)
                   1215: PE      pe;
                   1216: 
                   1217: PE      seq2prim (pe)
                   1218: PE      pe;
                   1219: \end{verbatim}\end{quote}
                   1220: In Figure~\ref{stepTHRUsequence},
                   1221: a convenient way of stepping through all the members of a sequence is
                   1222: presented.
                   1223: \tagrind[tp]{grind3-2}{Stepping through a Set}{stepTHRUsequence}
                   1224: 
                   1225: \section      {Inline CONStructors}
                   1226: Please read the following important message.
                   1227: \[\fbox{\begin{tabular}{lp{0.8\textwidth}}
                   1228: \bf NOTE:&     The facilities described in this section are to be used only
                   1229:                as a last resort.
                   1230:                They are provided for compatibility with less-rich systems.
                   1231: \end{tabular}}\]
                   1232: 
                   1233: When interfacing external software on top of various libraries,
                   1234: such as \man librosap(3n),
                   1235: the Remote Operations library,
                   1236: arguments which are expected to be \verb"PElement"s may be available instead
                   1237: as the raw encoded octets.
                   1238: It is inefficent to convert this into a \verb"PElement",
                   1239: pass the structure to the library,
                   1240: which then just encodes it again.
                   1241: To avoid this behavior,
                   1242: the routine, \verb"str2pe", may be used:
                   1243: \begin{quote}\index{str2pe}\small\begin{verbatim}
                   1244: PE      str2pe (s, len, advance, result)
                   1245: char   *s;
                   1246: int     len,
                   1247:        *advance,
                   1248:        *result;
                   1249: \end{verbatim}\end{quote}
                   1250: The parameters to this procedure are:
                   1251: \begin{describe}
                   1252: \item[\verb"s"/\verb"len":] the encoded string (and its length);
                   1253: 
                   1254: \item[\verb"advance":] a pointer to an integer-valued location indicating
                   1255: how far to advance the string to find the next ASN.1 object
                   1256: (use the manifest constant \verb"NULLIP" if you aren't interested in this),
                   1257: and,
                   1258: 
                   1259: \item[\verb"result":] a pointer to an integer-valued location which indicates,
                   1260: if the call fails, the reason for the failure.
                   1261: \end{describe}
                   1262: On success,
                   1263: \verb"str2pe" returns a \verb"PElement" called an {\em Inline CONStructor}.
                   1264: This is a special kind of \verb"PElement" which really just contains a pointer
                   1265: to the original string.
                   1266: The underyling libraries now how to manipulate Inline CONStructors
                   1267: appropriately,
                   1268: e.g, when building an SSDU.
                   1269: On failure,
                   1270: \verb"str2pe" returns the manifest constant \verb"NULLPE" and the
                   1271: \verb"result" parameter contains an error code listed in Table
                   1272: Table~\ref{PStreamReasons} on page~\pageref{PStreamReasons}.
                   1273: 
                   1274: For the inverse operation,
                   1275: the appropriate library must be informed that the ASN.1 objects associated
                   1276: with incoming indications should be returned in Inline CONStructor form.
                   1277: This mechanism is still being refined,
                   1278: and is not currently documented.
                   1279: 
                   1280: However, the routine used by the libraries in order to unwrap an encoded
                   1281: string is available:
                   1282: \begin{quote}\index{qb2pe}\small\begin{verbatim}
                   1283: PE      qb2pe (qb, len, depth, result)
                   1284: struct qbuf *qb
                   1285: int     len,
                   1286:         depth,
                   1287:        *result;
                   1288: \end{verbatim}\end{quote}
                   1289: The parameters to this procedure are:
                   1290: \begin{describe}
                   1291: \item[\verb"qb"/\verb"len":] a doubly-linked list of \verb"qbuf"s containing,
                   1292: e.g., an SSDU, and the total length of the data in the \verb"qbuf"s;
                   1293: 
                   1294: \item[\verb"depth":] the level of unwrapping to permit;
                   1295: and,
                   1296: 
                   1297: \item[\verb"result":] a pointer to an integer-valued location which indicates,
                   1298: if the call fails, the reason for the failure.
                   1299: \end{describe}
                   1300: On success,
                   1301: \verb"qb2pe" returns a \verb"PElement" which may ultimately contain
                   1302: Inline CONStructors.
                   1303: On failure,
                   1304: \verb"qb2pe" returns the manifest constant \verb"NULLPE" and the
                   1305: \verb"result" parameter contains an error code listed in Table
                   1306: Table~\ref{PStreamReasons}.
                   1307: 
                   1308: \section      {Compiling and Loading}
                   1309: Programs which manipulate presentation streams or presentation elements
                   1310: should include the header file \verb"<isode/psap.h>".
                   1311: These programs should also be loaded with \verb"-lpsap" which contains the
                   1312: routines described in this chapter.
                   1313: 
                   1314: \section      {An Example}
                   1315: Let's consider how one might read a presentation stream 
                   1316: from the standard input.
                   1317: The process is simple:
                   1318: we create a new presentation stream and then start the loop which reads
                   1319: from the stream until it is exhausted.
                   1320: This is shown in Figure~\ref{stepTHRUpstream}.
                   1321: In our example,
                   1322: we assume that the routine \verb"error" results in the process being
                   1323: terminated after printing a diagnostic.
                   1324: \tagrind[tp]{grind3-3}{Stepping through a Presentation Stream}{stepTHRUpstream}
                   1325: 
                   1326: \section      {For Further Reading}
                   1327: The language for the Abstract Syntax Notation One (ASN.1) is specified in
                   1328: \cite{ISO.PP.Syntax} and \cite{CCITT.PP.Syntax},
                   1329: while the encoding rules are defined in \cite{ISO.PP.Encoding} and
                   1330: \cite{CCITT.PP.Syntax}.
                   1331: The older {\oldstyle 1984} CCITT recommendations,
                   1332: containing both definitions,
                   1333: is \cite{MHS.notation},
                   1334: which is often referred to as X.409.
                   1335: The ASN.1 is a superset of the X.409.
                   1336: 
                   1337: %%% \section  {Changes Since the Last Release}\label{psap:changes}
                   1338: %%% A brief summary of the major changes between v~\psaprevrsn/ and
                   1339: %%% v~\psapvrsn/ are now presented.
                   1340: %%% These are the user-visible changes only;
                   1341: %%% changes of a strictly internal nature are not discussed.
                   1342: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.