diff options
Diffstat (limited to 'src/isode/psap/uvec2ps.c')
-rw-r--r-- | src/isode/psap/uvec2ps.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/isode/psap/uvec2ps.c b/src/isode/psap/uvec2ps.c new file mode 100644 index 000000000..01667fb92 --- /dev/null +++ b/src/isode/psap/uvec2ps.c @@ -0,0 +1,206 @@ +/* uvec2ps.c - uvec-backed abstraction for PStreams */ + +#ifndef lint +static char *rcsid = "$Header$"; +#endif + +/* + * $Header$ + * + * + * $Log$ + * Revision 1.1 1994/06/10 03:35:26 eichin + * autoconfed isode for kerberos work + * + * Revision 1.1 1994/06/01 00:39:17 eichin + * add psap too + * + * Revision 8.0 91/07/17 12:47:29 isode + * Release 7.0 + * + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include <stdio.h> +#include "psap.h" +#include "tailor.h" + + +#define NPSUV 10 /* really should be NSPUV - 2 */ + +#define PSDU_MAGIC 64 /* threshold for scattering */ + +/* */ + +static int uvec_write (ps, data, n, in_line) +PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + register struct udvec *uv; + + if (in_line && n < PSDU_MAGIC) + in_line = 0; + if (in_line && ps -> ps_cur -> uv_base) + ps -> ps_cur++; + if (ps -> ps_cur >= ps -> ps_end) { + SLOG (psap_log, LLOG_DEBUG, NULLCP, + ("%d elements not enough for pe2uvec", ps -> ps_elems)); + ps -> ps_elems += NPSUV; + if ((uv = (struct udvec *) realloc ((char *) ps -> ps_head, + (unsigned) (ps -> ps_elems + * sizeof *uv))) + == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + + ps -> ps_cur = uv + (ps -> ps_cur - ps -> ps_head); + ps -> ps_end = (ps -> ps_head = uv) + ps -> ps_elems - 1; + } + + uv = ps -> ps_cur; + if (in_line) { + if (ps -> ps_cc == 0) { + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("first write in pe2uvec is inline")); + + return ps_seterr (ps, PS_ERR_EOF, NOTOK); + } + + uv -> uv_base = (char *) data, uv -> uv_len = n; + uv -> uv_inline = 1; + (++ps -> ps_cur) -> uv_base = NULL; + } + else { + if (n > ps -> ps_slop) { + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("insufficient slop in pe2uvec, at least %d octets short", + n - ps -> ps_slop)); + + return ps_seterr (ps, PS_ERR_EOF, NOTOK); + } + + if (uv -> uv_base == NULL) { + uv -> uv_base = ps -> ps_extra, uv -> uv_len = 0; + uv -> uv_inline = ps -> ps_cc > 0 ? 1 : 0; + } + + uv -> uv_len += n; + bcopy ((char *) data, ps -> ps_extra, n); + ps -> ps_extra += n, ps -> ps_slop -= n; + } + ps -> ps_cc += n; + + return n; +} + + +static int uvec_flush (ps) +register PS ps; +{ + if (ps -> ps_cur) { + if (ps -> ps_cur -> uv_base) + ps -> ps_cur++; + ps -> ps_cur -> uv_base = NULL; + } + + if (ps -> ps_slop != 0) + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("%d octets of slop remaining on pe2uvec flush", ps -> ps_slop)); + + return OK; +} + + +static int uvec_close (ps) +register PS ps; +{ + register struct udvec *uv; + + if (ps -> ps_head) { + for (uv = ps -> ps_head; uv -> uv_base; uv++) + if (!uv -> uv_inline) + free (uv -> uv_base); + free ((char *) ps -> ps_head); + } + + if (ps -> ps_extra && ps -> ps_cc == 0) + free (ps -> ps_extra); + + return OK; +} + +/* */ + +int uvec_open (ps) +register PS ps; +{ + ps -> ps_writeP = uvec_write; + ps -> ps_flushP = uvec_flush; + ps -> ps_closeP = uvec_close; + + return OK; +} + + +int uvec_setup (ps, len) +register PS ps; +int len; +{ + register struct udvec *uv; + + ps -> ps_elems = NPSUV; + if ((uv = (struct udvec *) calloc ((unsigned) ps -> ps_elems, sizeof *uv)) + == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + ps -> ps_end = (ps -> ps_head = ps -> ps_cur = uv) + ps -> ps_elems - 1; + + ps -> ps_cc = 0; + + if ((ps -> ps_slop = len) <= 0) + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("bad initial slop in pe2uvec, %d octets", len)); + + if ((ps -> ps_extra = malloc ((unsigned) len)) == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + + return OK; +} + +/* */ + +int ps_get_plen (pe) +register PE pe; +{ + register PElementLen len; + register PE p; + + len = 0; + switch (pe -> pe_form) { + case PE_FORM_PRIM: + case PE_FORM_ICONS: + if (pe -> pe_len >= PSDU_MAGIC) + len = pe -> pe_len; + break; + + case PE_FORM_CONS: + for (p = pe -> pe_cons; p; p = p -> pe_next) + len += ps_get_plen (p); + break; + } + + return len; +} |