|
|
1.1 root 1: /* uvec2ps.c - uvec-backed abstraction for PStreams */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap/RCS/uvec2ps.c,v 7.0 89/11/23 22:13:58 mrose Rel $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap/RCS/uvec2ps.c,v 7.0 89/11/23 22:13:58 mrose Rel $
9: *
10: *
11: * $Log: uvec2ps.c,v $
12: * Revision 7.0 89/11/23 22:13:58 mrose
13: * Release 6.0
14: *
15: */
16:
17: /*
18: * NOTICE
19: *
20: * Acquisition, use, and distribution of this module and related
21: * materials are subject to the restrictions of a license agreement.
22: * Consult the Preface in the User's Manual for the full terms of
23: * this agreement.
24: *
25: */
26:
27:
28: /* LINTLIBRARY */
29:
30: #include <stdio.h>
31: #include "psap.h"
32: #include "tailor.h"
33:
34:
35: #define NPSUV 10 /* really should be NSPUV - 2 */
36:
37: #define PSDU_MAGIC 64 /* threshold for scattering */
38:
39: /* */
40:
41: static int uvec_write (ps, data, n, in_line)
42: PS ps;
43: PElementData data;
44: PElementLen n;
45: int in_line;
46: {
47: register struct udvec *uv;
48:
49: if (in_line && n < PSDU_MAGIC)
50: in_line = 0;
51: if (in_line && ps -> ps_cur -> uv_base)
52: ps -> ps_cur++;
53: if (ps -> ps_cur >= ps -> ps_end) {
54: SLOG (psap_log, LLOG_DEBUG, NULLCP,
55: ("%d elements not enough for pe2uvec", ps -> ps_elems));
56: ps -> ps_elems += NPSUV;
57: if ((uv = (struct udvec *) realloc ((char *) ps -> ps_head,
58: (unsigned) (ps -> ps_elems
59: * sizeof *uv)))
60: == NULL)
61: return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
62:
63: ps -> ps_cur = uv + (ps -> ps_cur - ps -> ps_head);
64: ps -> ps_end = (ps -> ps_head = uv) + ps -> ps_elems - 1;
65: }
66:
67: uv = ps -> ps_cur;
68: if (in_line) {
69: if (ps -> ps_cc == 0) {
70: SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
71: ("first write in pe2uvec is inline"));
72:
73: return ps_seterr (ps, PS_ERR_EOF, NOTOK);
74: }
75:
76: uv -> uv_base = (char *) data, uv -> uv_len = n;
77: uv -> uv_inline = 1;
78: (++ps -> ps_cur) -> uv_base = NULL;
79: }
80: else {
81: if (n > ps -> ps_slop) {
82: SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
83: ("insufficient slop in pe2uvec, at least %d octets short",
84: n - ps -> ps_slop));
85:
86: return ps_seterr (ps, PS_ERR_EOF, NOTOK);
87: }
88:
89: if (uv -> uv_base == NULL) {
90: uv -> uv_base = ps -> ps_extra, uv -> uv_len = 0;
91: uv -> uv_inline = ps -> ps_cc > 0 ? 1 : 0;
92: }
93:
94: uv -> uv_len += n;
95: bcopy ((char *) data, ps -> ps_extra, n);
96: ps -> ps_extra += n, ps -> ps_slop -= n;
97: }
98: ps -> ps_cc += n;
99:
100: return n;
101: }
102:
103:
104: static int uvec_flush (ps)
105: register PS ps;
106: {
107: if (ps -> ps_cur) {
108: if (ps -> ps_cur -> uv_base)
109: ps -> ps_cur++;
110: ps -> ps_cur -> uv_base = NULL;
111: }
112:
113: if (ps -> ps_slop != 0)
114: SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
115: ("%d octets of slop remaining on pe2uvec flush", ps -> ps_slop));
116:
117: return OK;
118: }
119:
120:
121: static int uvec_close (ps)
122: register PS ps;
123: {
124: register struct udvec *uv;
125:
126: if (ps -> ps_head) {
127: for (uv = ps -> ps_head; uv -> uv_base; uv++)
128: if (!uv -> uv_inline)
129: free (uv -> uv_base);
130: free ((char *) ps -> ps_head);
131: }
132:
133: if (ps -> ps_extra && ps -> ps_cc == 0)
134: free (ps -> ps_extra);
135:
136: return OK;
137: }
138:
139: /* */
140:
141: int uvec_open (ps)
142: register PS ps;
143: {
144: ps -> ps_writeP = uvec_write;
145: ps -> ps_flushP = uvec_flush;
146: ps -> ps_closeP = uvec_close;
147:
148: return OK;
149: }
150:
151:
152: int uvec_setup (ps, len)
153: register PS ps;
154: int len;
155: {
156: register struct udvec *uv;
157:
158: ps -> ps_elems = NPSUV;
159: if ((uv = (struct udvec *) calloc ((unsigned) ps -> ps_elems, sizeof *uv))
160: == NULL)
161: return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
162: ps -> ps_end = (ps -> ps_head = ps -> ps_cur = uv) + ps -> ps_elems - 1;
163:
164: ps -> ps_cc = 0;
165:
166: if ((ps -> ps_slop = len) <= 0)
167: SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
168: ("bad initial slop in pe2uvec, %d octets", len));
169:
170: if ((ps -> ps_extra = malloc ((unsigned) len)) == NULL)
171: return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
172:
173: return OK;
174: }
175:
176: /* */
177:
178: int ps_get_plen (pe)
179: register PE pe;
180: {
181: register PElementLen len;
182: register PE p;
183:
184: len = 0;
185: switch (pe -> pe_form) {
186: case PE_FORM_PRIM:
187: case PE_FORM_ICONS:
188: if (pe -> pe_len >= PSDU_MAGIC)
189: len = pe -> pe_len;
190: break;
191:
192: case PE_FORM_CONS:
193: for (p = pe -> pe_cons; p; p = p -> pe_next)
194: len += ps_get_plen (p);
195: break;
196: }
197:
198: return len;
199: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.