|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.