BSD 4_3_Net_2 development
[unix-history] / usr / src / contrib / isode / psap / ps2pe.c
CommitLineData
9e8e5516
C
1/* ps2pe.c - presentation stream to presentation element */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/psap/RCS/ps2pe.c,v 7.3 91/02/22 09:36:30 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/psap/RCS/ps2pe.c,v 7.3 91/02/22 09:36:30 mrose Interim $
9 *
10 *
11 * $Log: ps2pe.c,v $
12 * Revision 7.3 91/02/22 09:36:30 mrose
13 * Interim 6.8
14 *
15 * Revision 7.2 91/01/07 12:40:32 mrose
16 * update
17 *
18 * Revision 7.1 90/07/27 08:47:25 mrose
19 * update
20 *
21 * Revision 7.0 89/11/23 22:13:18 mrose
22 * Release 6.0
23 *
24 */
25
26/*
27 * NOTICE
28 *
29 * Acquisition, use, and distribution of this module and related
30 * materials are subject to the restrictions of a license agreement.
31 * Consult the Preface in the User's Manual for the full terms of
32 * this agreement.
33 *
34 */
35
36
37/* LINTLIBRARY */
38
39#include <stdio.h>
40#include "psap.h"
41#include "tailor.h"
42
43/* \f */
44
45PE ps2pe_aux (ps, top, all)
46register PS ps;
47int top,
48 all;
49{
50 register PElementLen len;
51 PElementClass class;
52 PElementForm form;
53 PElementID id;
54 register PE pe;
55
56 if (top && ps_prime (ps, 0) == NOTOK)
57 return NULLPE;
58
59 if (ps_read_id (ps, top, &class, &form, &id) == NOTOK)
60 return NULLPE;
61 if ((pe = pe_alloc (class, form, id)) == NULLPE)
62 return ps_seterr (ps, PS_ERR_NMEM, NULLPE);
63 if (ps_read_len (ps, &pe -> pe_len) == NOTOK)
64 goto you_lose;
65
66 if (all == 0)
67 return pe;
68 len = pe -> pe_len;
69 switch (pe -> pe_form) {
70 case PE_FORM_PRIM:
71 if (len == PE_LEN_INDF) {
72 (void) ps_seterr (ps, PS_ERR_INDF, NULLPE);
73 goto you_lose;
74 }
75 if (len > 0) {
76 if (ps -> ps_inline) { /* "ultra-efficiency"... */
77 if (ps -> ps_base == NULLCP || ps -> ps_cnt < len) {
78 (void) ps_seterr (ps, PS_ERR_EOF, NULLPE);
79 goto you_lose;
80 }
81 pe -> pe_inline = 1;
82 pe -> pe_prim = (PElementData) ps -> ps_ptr;
83 ps -> ps_ptr += len, ps -> ps_cnt -= len;
84 ps -> ps_byteno += len;
85 }
86 else {
87 if ((pe -> pe_prim = PEDalloc (len)) == NULLPED) {
88 (void) ps_seterr (ps, PS_ERR_NMEM, NULLPE);
89 goto you_lose;
90 }
91 if (ps_read (ps, pe -> pe_prim, len) == NOTOK) {
92#ifdef DEBUG
93 SLOG (psap_log, LLOG_DEBUG, NULLCP,
94 ("error reading primitive, %d bytes: %s",
95 len, ps_error (ps -> ps_errno)));
96#endif
97 goto you_lose;
98 }
99 }
100 }
101 break;
102
103 case PE_FORM_CONS:
104 if (len != 0 && ps_read_cons (ps, &pe -> pe_cons, len) == NOTOK)
105 goto you_lose;
106 break;
107 }
108
109 if (top && ps_prime (ps, -1) == NOTOK)
110 goto you_lose;
111
112 return pe;
113
114you_lose: ;
115#ifdef DEBUG
116 if (psap_log -> ll_events & LLOG_DEBUG) {
117 LLOG (psap_log, LLOG_PDUS, ("PE read thus far"));
118 pe2text (psap_log, pe, 1, NOTOK);
119 }
120#endif
121
122 pe_free (pe);
123 return NULLPE;
124}
125
126/* \f */
127
128static int pe_id_overshift = PE_ID_MASK << (PE_ID_BITS - PE_ID_SHIFT);
129
130
131int ps_read_id (ps, top, class, form, id)
132register PS ps;
133int top;
134register PElementClass *class;
135register PElementForm *form;
136register PElementID *id;
137{
138 byte c,
139 d;
140 register PElementID j;
141
142 if (ps_read (ps, &c, 1) == NOTOK) {
143 if (top && ps -> ps_errno == PS_ERR_EOF)
144 ps -> ps_errno = PS_ERR_NONE;
145 else {
146#ifdef DEBUG
147 SLOG (psap_log, LLOG_DEBUG, NULLCP,
148 ("error reading initial octet: %s", ps_error (ps -> ps_errno)));
149#endif
150 }
151
152 return NOTOK;
153 }
154
155 *class = (c & PE_CLASS_MASK) >> PE_CLASS_SHIFT;
156 *form = (c & PE_FORM_MASK) >> PE_FORM_SHIFT;
157 j = (c & PE_CODE_MASK);
158
159 if (j == PE_ID_XTND)
160 for (j = 0;; j <<= PE_ID_SHIFT) {
161 if (ps_read (ps, &d, 1) == NOTOK) {
162 if (ps -> ps_errno == PS_ERR_EOF)
163 ps -> ps_errno = PS_ERR_EOFID;
164 return NOTOK;
165 }
166
167 j |= d & PE_ID_MASK;
168 if (!(d & PE_ID_MORE))
169 break;
170 if (j & pe_id_overshift)
171 return ps_seterr (ps, PS_ERR_OVERID, NOTOK);
172 }
173 *id = j;
174 DLOG (psap_log, LLOG_DEBUG, ("class=%d form=%d id=%d",*class, *form, *id));
175
176 return OK;
177}
178
179/* \f */
180
181int ps_read_len (ps, len)
182register PS ps;
183register PElementLen *len;
184{
185 register int i;
186 register PElementLen j;
187 byte c;
188
189 if (ps_read (ps, &c, 1) == NOTOK) {
190#ifdef DEBUG
191 SLOG (psap_log, LLOG_DEBUG, NULLCP,
192 ("error reading initial length octet: %s",
193 ps_error (ps -> ps_errno)));
194#endif
195
196 return NOTOK;
197 }
198
199 if ((i = c) & PE_LEN_XTND) {
200 if ((i &= PE_LEN_MASK) > sizeof (PElementLen))
201 return ps_seterr (ps, PS_ERR_OVERLEN, NOTOK);
202
203 if (i) {
204 for (j = 0; i-- > 0;) {
205 if (ps_read (ps, &c, 1) == NOTOK) {
206 if (ps -> ps_errno == PS_ERR_EOF)
207 ps -> ps_errno = PS_ERR_EOFLEN;
208 return NOTOK;
209 }
210
211 j = (j << 8) | (c & 0xff);
212 }
213 *len = j;
214 }
215 else
216 *len = PE_LEN_INDF;
217 }
218 else
219 *len = i;
220#ifdef DEBUG
221 SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", *len));
222#endif
223
224 return OK;
225}
226
227/* \f */
228
229int ps_read_cons (ps, pe, len)
230register PS ps;
231register PE *pe;
232register PElementLen len;
233{
234 register int cc;
235 register PE p,
236 q;
237
238 cc = ps -> ps_byteno + len;
239
240 if ((p = ps2pe_aux (ps, 0, 1)) == NULLPE) {
241no_cons: ;
242#ifdef DEBUG
243 if (len == PE_LEN_INDF)
244 LLOG (psap_log, LLOG_DEBUG,
245 ("error building indefinite constructor, %s",
246 ps_error (ps -> ps_errno)));
247 else
248 LLOG (psap_log, LLOG_DEBUG,
249 ("error building constructor, stream at %d, wanted %d: %s",
250 ps -> ps_byteno, cc, ps_error (ps -> ps_errno)));
251#endif
252
253 return NOTOK;
254 }
255 *pe = p;
256
257 if (len == PE_LEN_INDF) {
258 if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
259 pe_free (p);
260 *pe = NULLPE;
261 return OK;
262 }
263 for (q = p; p = ps2pe_aux (ps, 0, 1); q = q -> pe_next = p) {
264 if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
265 pe_free (p);
266 return OK;
267 }
268 }
269
270 goto no_cons;
271 }
272
273 for (q = p;; q = q -> pe_next = p) {
274 if (cc < ps -> ps_byteno)
275 return ps_seterr (ps, PS_ERR_LEN, NOTOK);
276 if (cc == ps -> ps_byteno)
277 return OK;
278 if ((p = ps2pe_aux (ps, 0, 1)) == NULLPE)
279 goto no_cons;
280 }
281}