BSD 4_3_Net_2 release
[unix-history] / usr / src / contrib / isode / psap / pe2ps.c
CommitLineData
9e8e5516
C
1/* pe2ps.c - presentation element to presentation stream */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/psap/RCS/pe2ps.c,v 7.1 91/02/22 09:36:01 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/psap/RCS/pe2ps.c,v 7.1 91/02/22 09:36:01 mrose Interim $
9 *
10 *
11 * $Log: pe2ps.c,v $
12 * Revision 7.1 91/02/22 09:36:01 mrose
13 * Interim 6.8
14 *
15 * Revision 7.0 89/11/23 22:12:56 mrose
16 * Release 6.0
17 *
18 */
19
20/*
21 * NOTICE
22 *
23 * Acquisition, use, and distribution of this module and related
24 * materials are subject to the restrictions of a license agreement.
25 * Consult the Preface in the User's Manual for the full terms of
26 * this agreement.
27 *
28 */
29
30
31/* LINTLIBRARY */
32
33#include <stdio.h>
34#include "psap.h"
35#include "tailor.h"
36
37/* \f DATA */
38
39static PElement pe_eoc = { PE_CLASS_UNIV, PE_FORM_PRIM, PE_UNIV_EOC, 0 };
40
41/* \f */
42
43int pe2ps_aux (ps, pe, eval)
44register PS ps;
45register PE pe;
46int eval;
47{
48 int result;
49
50 if (eval > 0)
51 switch (pe -> pe_form) {
52 case PE_FORM_PRIM:
53 case PE_FORM_ICONS:
54 break;
55
56 case PE_FORM_CONS:
57 (void) ps_get_abs (pe);
58 break;
59 }
60
61 if ((result = pe2ps_aux2 (ps, pe, eval)) != NOTOK)
62 result = ps_flush (ps);
63
64 return result;
65}
66
67
68static int pe2ps_aux2 (ps, pe, eval)
69register PS ps;
70register PE pe;
71int eval;
72{
73 register PE p;
74
75 if (pe -> pe_form == PE_FORM_ICONS) {
76 if (ps_write_aux (ps, pe -> pe_prim, pe -> pe_len, 1) == NOTOK)
77 return NOTOK;
78
79 return OK;
80 }
81
82 if (ps_write_id (ps, pe) == NOTOK || ps_write_len (ps, pe) == NOTOK)
83 return NOTOK;
84
85 switch (pe -> pe_form) {
86 case PE_FORM_PRIM:
87 if (ps_write_aux (ps, pe -> pe_prim, pe -> pe_len, 1) == NOTOK)
88 return NOTOK;
89 break;
90
91 case PE_FORM_CONS:
92 if (eval < 0)
93 break;
94 if (pe -> pe_len) {
95 for (p = pe -> pe_cons; p; p = p -> pe_next)
96 if (pe2ps_aux2 (ps, p, 0) == NOTOK)
97 return NOTOK;
98
99 if (pe -> pe_len == PE_LEN_INDF
100 && pe2ps_aux2 (ps, &pe_eoc, 0) == NOTOK)
101 return NOTOK;
102 }
103 break;
104 }
105
106 return OK;
107}
108
109/* \f */
110
111static int ps_write_id (ps, pe)
112register PS ps;
113register PE pe;
114{
115 byte buffer[1 + sizeof (PElementID)];
116 register byte *bp = buffer;
117 PElementForm form;
118 register PElementID id;
119
120 if ((form = pe -> pe_form) == PE_FORM_ICONS)
121 form = PE_FORM_CONS;
122 *bp = ((pe -> pe_class << PE_CLASS_SHIFT) & PE_CLASS_MASK)
123 | ((form << PE_FORM_SHIFT) & PE_FORM_MASK);
124
125 if ((id = pe -> pe_id) < PE_ID_XTND)
126 *bp++ |= id;
127 else {
128 register byte *ep;
129 register PElementID jd;
130
131 *bp |= PE_ID_XTND;
132
133 ep = buffer;
134 for (jd = id; jd != 0; jd >>= PE_ID_SHIFT)
135 ep++;
136
137 for (bp = ep; id != 0; id >>= PE_ID_SHIFT)
138 *bp-- = id & PE_ID_MASK;
139 for (bp = buffer + 1; bp < ep; bp++)
140 *bp |= PE_ID_MORE;
141
142 bp = ++ep;
143 }
144
145 if (ps_write (ps, buffer, bp - buffer) == NOTOK)
146 return NOTOK;
147
148 return OK;
149}
150
151/* \f */
152
153/* probably should integrate the non-PE_LEN_SMAX case with the algorithm in
154 num2prim() for a single, unified routine */
155
156static int ps_write_len (ps, pe)
157register PS ps;
158register PE pe;
159{
160 byte buffer[1 + sizeof (PElementLen)];
161 register byte *bp = buffer,
162 *ep;
163 register PElementLen len;
164
165 if ((len = pe -> pe_len) == PE_LEN_INDF)
166 *bp++ = PE_LEN_XTND;
167 else
168 if (len <= PE_LEN_SMAX)
169 *bp++ = len & 0xff;
170 else {
171 ep = buffer + sizeof buffer - 1;
172 for (bp = ep; len != 0 && buffer < bp; len >>= 8)
173 *bp-- = len & 0xff;
174 *bp = PE_LEN_XTND | ((ep - bp) & 0xff);
175 if (ps_write (ps, bp, ep - bp + 1) == NOTOK)
176 return NOTOK;
177
178 return OK;
179 }
180
181 if (ps_write (ps, buffer, bp - buffer) == NOTOK)
182 return NOTOK;
183
184 return OK;
185}