From: Sebastian Hammer Date: Tue, 18 Apr 1995 08:15:11 +0000 (+0000) Subject: Added dynamic memory allocation on encoding (whew). Code is now somewhat X-Git-Tag: YAZ.1.8~1061 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=aa82967af8f06004b567ad1ed40c67b056c44e7b Added dynamic memory allocation on encoding (whew). Code is now somewhat neater. We'll make the same change for decoding one day. --- diff --git a/odr/Makefile b/odr/Makefile index 5aa20a9..07c2a9a 100644 --- a/odr/Makefile +++ b/odr/Makefile @@ -1,13 +1,13 @@ # Copyright (C) 1994, Index Data I/S # All rights reserved. # Sebastian Hammer, Adam Dickmeiss -# $Id: Makefile,v 1.16 1995-04-17 09:37:41 quinn Exp $ +# $Id: Makefile,v 1.17 1995-04-18 08:15:11 quinn Exp $ SHELL=/bin/sh INCLUDE=-I../include -I. LIBDIR=../lib LIBINCLUDE=-L$(LIBDIR) -CFLAGS= -g -Wall -pedantic -ansi #-DODR_DEBUG +CFLAGS= -g -Wall -pedantic -ansi -DODR_DEBUG DEFS=$(INCLUDE) LIB=$(LIBDIR)/libodr.a LIBS=-lodr diff --git a/odr/ber_any.c b/odr/ber_any.c index cad4e19..2e1de76 100644 --- a/odr/ber_any.c +++ b/odr/ber_any.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_any.c,v $ - * Revision 1.8 1995-04-17 09:37:42 quinn + * Revision 1.9 1995-04-18 08:15:12 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.8 1995/04/17 09:37:42 quinn * *** empty log message *** * * Revision 1.7 1995/03/17 10:17:39 quinn @@ -51,14 +55,8 @@ int ber_any(ODR o, Odr_any **p) o->left -= res; return 1; case ODR_ENCODE: - if ((*p)->len > o->left) - { - o->error = OSPACE; + if (odr_write(o, (*p)->buf, (*p)->len) < 0) return 0; - } - memcpy(o->bp , (*p)->buf, (*p)->len); - o->bp += (*p)->len; - o->left -= (*p)->len; return 1; default: o->error = OOTHER; return 0; } diff --git a/odr/ber_bit.c b/odr/ber_bit.c index 4549f74..db58414 100644 --- a/odr/ber_bit.c +++ b/odr/ber_bit.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_bit.c,v $ - * Revision 1.3 1995-03-08 12:12:04 quinn + * Revision 1.4 1995-04-18 08:15:13 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.3 1995/03/08 12:12:04 quinn * Added better error checking. * * Revision 1.2 1995/02/03 17:04:31 quinn @@ -63,25 +67,14 @@ int ber_bitstring(ODR o, Odr_bitmask *p, int cons) o->left -= len; return 1; case ODR_ENCODE: - if ((res = ber_enclen(o->bp, p->top + 2, 5, 0)) < 0) - { - o->error = OOTHER; + if ((res = ber_enclen(o, p->top + 2, 5, 0)) < 0) return 0; - } - o->bp += res; - o->left -= res; - if (p->top + 2 > o->left) - { - o->error = OSPACE; + if (odr_putc(o, 0) < 0) /* no unused bits here */ return 0; - } - *(o->bp++) = 0; /* no unused bits here */ - o->left--; if (p->top < 0) return 1; - memcpy(o->bp, p->bits, p->top + 1); - o->bp += p->top + 1; - o->left -= p->top +1; + if (odr_write(o, p->bits, p->top + 1) < 0) + return 0; return 1; case ODR_PRINT: return 1; default: o->error = OOTHER; return 0; diff --git a/odr/ber_bool.c b/odr/ber_bool.c index 6161b33..233de65 100644 --- a/odr/ber_bool.c +++ b/odr/ber_bool.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_bool.c,v $ - * Revision 1.4 1995-03-21 10:17:27 quinn + * Revision 1.5 1995-04-18 08:15:14 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.4 1995/03/21 10:17:27 quinn * Fixed little bug in decoder. * * Revision 1.3 1995/03/08 12:12:06 quinn @@ -29,23 +33,13 @@ int ber_boolean(ODR o, int *val) switch (o->direction) { case ODR_ENCODE: - if (!o->left) - { - o->error = OSPACE; - return 0; - } - if (ber_enclen(o->bp, 1, 1, 1) != 1) - { - o->error = OOTHER; - return 0; - } - o->bp++; - o->left--; - *(o->bp++) = (unsigned char) *val; + if (ber_enclen(o, 1, 1, 1) != 1) + return 0; + if (odr_putc(o, *val) < 0) + return 0; #ifdef ODR_DEBUG fprintf(stderr, "[val=%d]\n", *val); #endif - o->left--; return 1; case ODR_DECODE: if ((res = ber_declen(o->bp, &len)) < 0) diff --git a/odr/ber_int.c b/odr/ber_int.c index 4f036c4..46422d3 100644 --- a/odr/ber_int.c +++ b/odr/ber_int.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_int.c,v $ - * Revision 1.5 1995-03-27 15:01:44 quinn + * Revision 1.6 1995-04-18 08:15:14 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.5 1995/03/27 15:01:44 quinn * Added include of sys/types to further portability * * Revision 1.4 1995/03/08 12:12:07 quinn @@ -26,7 +30,7 @@ #include /* for htons... */ #include -static int ber_encinteger(unsigned char *buf, int val, int maxlen); +static int ber_encinteger(ODR o, int val); static int ber_decinteger(unsigned char *buf, int *val); int ber_integer(ODR o, int *val) @@ -45,13 +49,8 @@ int ber_integer(ODR o, int *val) o->left -= res; return 1; case ODR_ENCODE: - if ((res = ber_encinteger(o->bp, *val, o->left)) <= 0) - { - o->error = OSPACE; + if ((res = ber_encinteger(o, *val)) < 0) return 0; - } - o->bp += res; - o->left -= res; return 1; case ODR_PRINT: return 1; default: o->error = OOTHER; return 0; @@ -61,31 +60,32 @@ int ber_integer(ODR o, int *val) /* * Returns: number of bytes written or -1 for error (out of bounds). */ -int ber_encinteger(unsigned char *buf, int val, int maxlen) +int ber_encinteger(ODR o, int val) { - unsigned char *b = buf, *lenpos; + int lenpos; int a, len; union { int i; unsigned char c[sizeof(int)]; } tmp; - lenpos = b; - maxlen--; - b++; + lenpos = odr_tell(o); + if (odr_putc(o, 0) < 0) /* dummy */ + return -1; tmp.i = htonl(val); /* ensure that that we're big-endian */ for (a = 0; a < sizeof(int) - 1; a++) /* skip superfluous octets */ if (!((tmp.c[a] == 0 && !(tmp.c[a+1] & 0X80)) || (tmp.c[a] == 0XFF && (tmp.c[a+1] & 0X80)))) break; - if ((len = sizeof(int) - a) > maxlen) + len = sizeof(int) - a; + if (odr_write(o, (unsigned char*) tmp.c + a, len) < 0) return -1; - memcpy(b, tmp.c + a, len); - b += len; - if (ber_enclen(lenpos, len, 1, 1) != 1) + odr_seek(o, ODR_S_SET, lenpos); + if (ber_enclen(o, len, 1, 1) != 1) return -1; + odr_seek(o, ODR_S_END, 0); #ifdef ODR_DEBUG fprintf(stderr, "[val=%d]", val); #endif - return b - buf; + return 0; } /* diff --git a/odr/ber_len.c b/odr/ber_len.c index e8bf070..ee70563 100644 --- a/odr/ber_len.c +++ b/odr/ber_len.c @@ -9,18 +9,19 @@ * Returns: =0 success, indefinite start-marker set. 1 byte encoded. * Returns: -1 failure, out of bounds. */ -int ber_enclen(unsigned char *buf, int len, int lenlen, int exact) +int ber_enclen(ODR o, int len, int lenlen, int exact) { - unsigned char *b = buf; unsigned char octs[sizeof(int)]; int n = 0; + int lenpos, end; #ifdef ODR_DEBUG fprintf(stderr, "[len=%d]", len); #endif if (len < 0) /* Indefinite */ { - *b = 0X80; + if (odr_putc(o, 0x80) < 0) + return 0; #ifdef ODR_DEBUG fprintf(stderr, "[indefinite]"); #endif @@ -28,12 +29,14 @@ int ber_enclen(unsigned char *buf, int len, int lenlen, int exact) } if (len <= 127 && (lenlen == 1 || !exact)) /* definite short form */ { - *b = len; + if (odr_putc(o, (unsigned char) len) < 0) + return 0; return 1; } if (lenlen == 1) { - *b = 0X80; + if (odr_putc(o, 0x80) < 0) + return 0; return 0; } /* definite long form */ @@ -45,14 +48,23 @@ int ber_enclen(unsigned char *buf, int len, int lenlen, int exact) while (len); if (n >= lenlen) return -1; - b++; + lenpos = odr_tell(o); /* remember length-of-length position */ + if (odr_putc(o, 0) < 0) /* dummy */ + return 0; if (exact) while (n < --lenlen) /* pad length octets */ - *(++b) = 0; + if (odr_putc(o, 0) < 0) + return 0; while (n--) - *(b++) = octs[n]; - *buf = (b - buf - 1) | 0X80; - return b - buf; + if (odr_putc(o, octs[n]) < 0) + return 0; + /* set length of length */ + end = odr_tell(o); + odr_seek(o, ODR_S_SET, lenpos); + if (odr_putc(o, (end - lenpos - 1) | 0X80) < 0) + return 0; + odr_seek(o, ODR_S_END, 0); + return odr_tell(o) - lenpos; } /* diff --git a/odr/ber_null.c b/odr/ber_null.c index 2fbaf6d..1d00305 100644 --- a/odr/ber_null.c +++ b/odr/ber_null.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_null.c,v $ - * Revision 1.3 1995-03-08 12:12:09 quinn + * Revision 1.4 1995-04-18 08:15:16 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.3 1995/03/08 12:12:09 quinn * Added better error checking. * * Revision 1.2 1995/02/09 15:51:46 quinn @@ -25,13 +29,8 @@ int ber_null(ODR o, int *val) switch (o->direction) { case ODR_ENCODE: - if (!o->left) - { - o->error = OSPACE; - return 0; - } - *(o->bp++) = 0X00; - o->left--; + if (odr_putc(o, 0X00) < 0) + return 0; #ifdef ODR_DEBUG fprintf(stderr, "[NULL]\n"); #endif diff --git a/odr/ber_oct.c b/odr/ber_oct.c index 9c8eda4..6f285ce 100644 --- a/odr/ber_oct.c +++ b/odr/ber_oct.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_oct.c,v $ - * Revision 1.6 1995-03-17 10:17:41 quinn + * Revision 1.7 1995-04-18 08:15:17 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.6 1995/03/17 10:17:41 quinn * Added memory management. * * Revision 1.5 1995/03/08 12:12:10 quinn @@ -69,23 +73,12 @@ int ber_octetstring(ODR o, Odr_oct *p, int cons) o->left -= len; return 1; case ODR_ENCODE: - if ((res = ber_enclen(o->bp, p->len, 5, 0)) < 0) - { - o->error = OOTHER; + if ((res = ber_enclen(o, p->len, 5, 0)) < 0) return 0; - } - o->bp += res; - o->left -= res; if (p->len == 0) return 1; - if (p->len > o->left) - { - o->error = OSPACE; + if (odr_write(o, p->buf, p->len) < 0) return 0; - } - memcpy(o->bp, p->buf, p->len); - o->bp += p->len; - o->left -= p->len; return 1; case ODR_PRINT: return 1; default: o->error = OOTHER; return 0; diff --git a/odr/ber_oid.c b/odr/ber_oid.c index 576edfd..6c2813d 100644 --- a/odr/ber_oid.c +++ b/odr/ber_oid.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_oid.c,v $ - * Revision 1.5 1995-03-20 12:18:22 quinn + * Revision 1.6 1995-04-18 08:15:18 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.5 1995/03/20 12:18:22 quinn * Fixed bug in ber_oid * * Revision 1.4 1995/03/08 12:12:11 quinn @@ -25,8 +29,7 @@ int ber_oidc(ODR o, Odr_oid *p) { - int len; - unsigned char *lenp; + int len, lenp, end; int pos, n, res, id; unsigned char octs[8]; @@ -81,9 +84,9 @@ int ber_oidc(ODR o, Odr_oid *p) case ODR_ENCODE: /* we'll allow ourselves the quiet luxury of only doing encodings shorter than 127 */ - lenp = o->bp; - o->bp++; - o->left--; + lenp = odr_tell(o); + if (odr_putc(o, 0) < 0) /* dummy */ + return 0; if (p[0] < 0 && p[1] <= 0) { o->error = ODATA; @@ -99,20 +102,23 @@ int ber_oidc(ODR o, Odr_oid *p) id >>= 7; } while (id); - if (n > o->left) + while (n--) { - o->error = OSPACE; - return 0; + unsigned char p; + + p = octs[n] | ((n > 0) << 7); + if (odr_putc(o, p) < 0) + return 0; } - o->left -= n; - while (n--) - *(o->bp++) = octs[n] | ((n > 0) << 7); } - if (ber_enclen(lenp, (o->bp - lenp) - 1, 1, 1) != 1) + end = odr_tell(o); + odr_seek(o, ODR_S_SET, lenp); + if (ber_enclen(o, (end - lenp) - 1, 1, 1) != 1) { o->error = OOTHER; return 0; } + odr_seek(o, ODR_S_END, 0); return 1; default: o->error = OOTHER; return 0; } diff --git a/odr/ber_tag.c b/odr/ber_tag.c index a0e39bb..49c1a34 100644 --- a/odr/ber_tag.c +++ b/odr/ber_tag.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ber_tag.c,v $ - * Revision 1.9 1995-03-15 08:37:18 quinn + * Revision 1.10 1995-04-18 08:15:18 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.9 1995/03/15 08:37:18 quinn * Fixed protocol bugs. * * Revision 1.8 1995/03/10 11:44:40 quinn @@ -58,10 +62,10 @@ int ber_tag(ODR o, void *p, int class, int tag, int *constructed, int opt) o->t_class = -1; if (o->stackp < 0) { + odr_seek(o, ODR_S_SET, 0); + o->ecb.top = 0; o->bp = o->buf; lclass = -1; - if (o->direction == ODR_ENCODE) - o->left = o->buflen; } switch (o->direction) { @@ -72,17 +76,11 @@ int ber_tag(ODR o, void *p, int class, int tag, int *constructed, int opt) o->error = OREQUIRED; return 0; } - if ((rd = ber_enctag(o->bp, class, tag, *constructed, o->left)) - <=0) - { - o->error = OSPACE; + if ((rd = ber_enctag(o, class, tag, *constructed)) < 0) return -1; - } - o->bp += rd; - o->left -= rd; #ifdef ODR_DEBUG - fprintf(stderr, "\n[class=%d,tag=%d,cons=%d,stackp=%d,left=%d]", class, tag, - *constructed, o->stackp, o->left); + fprintf(stderr, "\n[class=%d,tag=%d,cons=%d,stackp=%d]", class, tag, + *constructed, o->stackp); #endif return 1; case ODR_DECODE: @@ -130,32 +128,40 @@ int ber_tag(ODR o, void *p, int class, int tag, int *constructed, int opt) * BER-encode a class/tag/constructed package (identifier octets). Return * number of bytes encoded, or -1 if out of bounds. */ -int ber_enctag(unsigned char *buf, int class, int tag, int constructed, int len) +int ber_enctag(ODR o, int class, int tag, int constructed) { int cons = (constructed ? 1 : 0), n = 0; - unsigned char octs[sizeof(int)], *b = buf; + unsigned char octs[sizeof(int)], b; - *b = (class << 6) & 0XC0; - *b |= (cons << 5) & 0X20; + b = (class << 6) & 0XC0; + b |= (cons << 5) & 0X20; if (tag <= 30) { - *b |= tag & 0X1F; + b |= tag & 0X1F; + if (odr_putc(o, b) < 0) + return -1; return 1; } else { - *(b++) |= 0x1F; + b |= 0X1F; + if (odr_putc(o, b) < 0) + return -1; do { octs[n++] = tag & 0X7F; tag >>= 7; - if (n >= len) /* bounds check */ - return -1; } while (tag); while (n--) - *(b++) = octs[n] | ((n > 0) << 7); - return b - buf; + { + unsigned char oo; + + oo = octs[n] | ((n > 0) << 7); + if (odr_putc(o, oo) < 0) + return -1; + } + return 0; } } diff --git a/odr/odr.c b/odr/odr.c index 2691c65..4ee2025 100644 --- a/odr/odr.c +++ b/odr/odr.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: odr.c,v $ - * Revision 1.9 1995-04-10 10:23:11 quinn + * Revision 1.10 1995-04-18 08:15:20 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.9 1995/04/10 10:23:11 quinn * Smallish changes. * * Revision 1.8 1995/03/17 10:17:43 quinn @@ -77,6 +81,9 @@ ODR odr_createmem(int direction) r->direction = direction; r->print = stderr; r->buf = 0; + r->ecb.buf = 0; + r->ecb.size = r->ecb.pos = r->ecb.top = 0; + r->ecb.can_grow = 1; r->buflen = 0; r->mem = 0; odr_reset(r); @@ -87,6 +94,8 @@ void odr_reset(ODR o) { o->error = ONONE; o->bp = o->buf; + odr_seek(o, ODR_S_SET, 0); + o->ecb.top = 0; o->left = o->buflen; o->t_class = -1; o->t_tag = -1; @@ -99,6 +108,8 @@ void odr_reset(ODR o) void odr_destroy(ODR o) { odr_release_mem(o->mem); + if (o->ecb.buf && o->ecb.can_grow) + free(o->ecb.buf); if (o->print != stderr) fclose(o->print); free(o); @@ -108,10 +119,15 @@ void odr_setbuf(ODR o, char *buf, int len) { o->buf = o->bp = (unsigned char *) buf; o->buflen = o->left = len; + + o->ecb.buf = (unsigned char *) buf; + o->ecb.can_grow = 0; + o->ecb.top = o->ecb.pos = 0; + o->ecb.size = len; } char *odr_getbuf(ODR o, int *len) { - *len = o->bp - o->buf; - return (char *) o->buf; + *len = o->ecb.top; + return (char*) o->ecb.buf; } diff --git a/odr/odr_cons.c b/odr/odr_cons.c index 4b83085..1922aa0 100644 --- a/odr/odr_cons.c +++ b/odr/odr_cons.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: odr_cons.c,v $ - * Revision 1.9 1995-03-28 09:15:49 quinn + * Revision 1.10 1995-04-18 08:15:21 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.9 1995/03/28 09:15:49 quinn * Fixed bug in the printing mode * * Revision 1.8 1995/03/15 11:18:04 quinn @@ -58,14 +62,15 @@ int odr_constructed_begin(ODR o, void *p, int class, int tag) return 0; } o->stack[++(o->stackp)].lenb = o->bp; + o->stack[o->stackp].len_offset = odr_tell(o); #ifdef ODR_DEBUG fprintf(stderr, "[cons_begin(%d)]", o->stackp); #endif if (o->direction == ODR_ENCODE || o->direction == ODR_PRINT) { o->stack[o->stackp].lenlen = 1; - o->bp++; - o->left--; + if (odr_putc(o, 0) < 0) /* dummy */ + return 0; } else if (o->direction == ODR_DECODE) { @@ -78,6 +83,7 @@ int odr_constructed_begin(ODR o, void *p, int class, int tag) else return 0; o->stack[o->stackp].base = o->bp; + o->stack[o->stackp].base_offset = odr_tell(o); return 1; } @@ -96,6 +102,7 @@ int odr_constructed_more(ODR o) int odr_constructed_end(ODR o) { int res; + int pos; if (o->error) return 0; @@ -130,21 +137,19 @@ int odr_constructed_end(ODR o) o->stackp--; return 1; case ODR_ENCODE: - if ((res = ber_enclen(o->stack[o->stackp].lenb, - o->bp - o->stack[o->stackp].base, + pos = odr_tell(o); + odr_seek(o, ODR_S_SET, o->stack[o->stackp].len_offset); + if ((res = ber_enclen(o, pos - o->stack[o->stackp].base_offset, o->stack[o->stackp].lenlen, 1)) < 0) - { - o->error = OSPACE; return 0; - } + odr_seek(o, ODR_S_END, 0); if (res == 0) /* indefinite encoding */ { #ifdef ODR_DEBUG fprintf(stderr, "[cons_end(%d): indefinite]", o->stackp); #endif - *(o->bp++) = 0; - *(o->bp++) = 0; - o->left -= 2; + if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0) + return 0; } #ifdef ODR_DEBUG else diff --git a/odr/odr_mem.c b/odr/odr_mem.c index e57730a..95a8135 100644 --- a/odr/odr_mem.c +++ b/odr/odr_mem.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: odr_mem.c,v $ - * Revision 1.2 1995-03-17 10:17:52 quinn + * Revision 1.3 1995-04-18 08:15:21 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.2 1995/03/17 10:17:52 quinn * Added memory management. * * Revision 1.1 1995/03/14 10:27:40 quinn @@ -16,6 +20,8 @@ #include #include +/* ------------------------ NIBBLE MEMORY ---------------------- */ + #define ODR_MEM_CHUNK (10*1024) typedef struct odr_memblock @@ -53,9 +59,9 @@ static odr_memblock *get_block(int size) if (get < size) get = size; if (!(r = malloc(sizeof(*r)))) - return 0; + abort(); if (!(r->buf = malloc(r->size = get))) - return 0; + abort(); } r->top = 0; return r; @@ -93,3 +99,57 @@ void *odr_malloc(ODR o, int size) p->top += (size + (sizeof(long) - 1)) & ~(sizeof(long) - 1); return r; } + +/* ---------- memory management for data encoding ----------*/ + + +int odr_grow_block(odr_ecblock *b, int min_bytes) +{ + int togrow; + + if (!b->can_grow) + return -1; + if (!b->size) + togrow = 1024; + else + togrow = b->size; + if (togrow < min_bytes) + togrow = min_bytes; + if (b->size && !(b->buf = realloc(b->buf, b->size += togrow))) + abort(); + else if (!b->size && !(b->buf = malloc(b->size = togrow))) + abort(); +#ifdef ODR_DEBUG + fprintf(stderr, "New size for encode_buffer: %d\n", b->size); +#endif + return 0; +} + +int odr_write(ODR o, unsigned char *buf, int bytes) +{ + if (o->ecb.pos + bytes >= o->ecb.size && odr_grow_block(&o->ecb, bytes)) + { + o->error = OSPACE; + return -1; + } + memcpy(o->ecb.buf + o->ecb.pos, buf, bytes); + o->ecb.pos += bytes; + if (o->ecb.pos > o->ecb.top) + o->ecb.top = o->ecb.pos; + return 0; +} + +int odr_seek(ODR o, int whence, int offset) +{ + if (whence == ODR_S_CUR) + offset += o->ecb.pos; + else if (whence == ODR_S_END) + offset += o->ecb.top; + if (offset > o->ecb.size && odr_grow_block(&o->ecb, offset - o->ecb.size)) + { + o->error = OSPACE; + return -1; + } + o->ecb.pos = offset; + return 0; +} diff --git a/server/seshigh.c b/server/seshigh.c index 0f7621b..3edeba7 100644 --- a/server/seshigh.c +++ b/server/seshigh.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: seshigh.c,v $ - * Revision 1.18 1995-04-17 11:28:25 quinn + * Revision 1.19 1995-04-18 08:15:34 quinn + * Added dynamic memory allocation on encoding (whew). Code is now somewhat + * neater. We'll make the same change for decoding one day. + * + * Revision 1.18 1995/04/17 11:28:25 quinn * Smallish * * Revision 1.17 1995/04/10 10:23:36 quinn @@ -75,7 +79,7 @@ #include -#define ENCODE_BUFFER_SIZE 10000 +#define MAXRECORDSIZE 1024*1024 static int process_apdu(IOCHAN chan); static int process_initRequest(IOCHAN client, Z_InitRequest *req); @@ -137,9 +141,6 @@ association *create_association(IOCHAN channel, COMSTACK link) } else new->print = 0; - if (!(new->encode_buffer = malloc(ENCODE_BUFFER_SIZE))) - return 0; - odr_setbuf(new->encode, new->encode_buffer, ENCODE_BUFFER_SIZE); new->state = ASSOC_UNINIT; new->input_buffer = 0; new->input_buffer_len = 0; @@ -157,7 +158,6 @@ void destroy_association(association *h) odr_destroy(h->encode); if (h->print) odr_destroy(h->print); - free(h->encode_buffer); if (h->input_buffer) free(h->input_buffer); if (h->backend) @@ -318,8 +318,8 @@ static int process_initRequest(IOCHAN client, Z_InitRequest *req) * This is not so hot. The big todo for ODR is dynamic memory allocation * on encoding. */ - if (assoc->maximumRecordSize > ENCODE_BUFFER_SIZE - 1000) - assoc->maximumRecordSize = ENCODE_BUFFER_SIZE - 1000; + if (assoc->maximumRecordSize > MAXRECORDSIZE) + assoc->maximumRecordSize = MAXRECORDSIZE; assoc->preferredMessageSize = *req->preferredMessageSize; if (assoc->preferredMessageSize > assoc->maximumRecordSize) assoc->preferredMessageSize = assoc->maximumRecordSize; @@ -328,7 +328,7 @@ static int process_initRequest(IOCHAN client, Z_InitRequest *req) resp.result = &result; resp.implementationId = "YAZ"; resp.implementationName = "Index Data/YAZ Generic Frontend Server"; - resp.implementationVersion = "$Revision: 1.18 $"; + resp.implementationVersion = "$Revision: 1.19 $"; resp.userInformationField = 0; if (!z_APDU(assoc->encode, &apdup, 0)) { @@ -336,7 +336,7 @@ static int process_initRequest(IOCHAN client, Z_InitRequest *req) odr_errlist[odr_geterror(assoc->encode)]); return -1; } - odr_getbuf(assoc->encode, &assoc->encoded_len); + assoc->encode_buffer = odr_getbuf(assoc->encode, &assoc->encoded_len); odr_reset(assoc->encode); iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT); return 0; @@ -645,7 +645,7 @@ static int process_searchRequest(IOCHAN client, Z_SearchRequest *req) odr_errlist[odr_geterror(assoc->encode)]); return -1; } - odr_getbuf(assoc->encode, &assoc->encoded_len); + assoc->encode_buffer = odr_getbuf(assoc->encode, &assoc->encoded_len); odr_reset(assoc->encode); iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT); return 0; @@ -679,7 +679,7 @@ static int process_presentRequest(IOCHAN client, Z_PresentRequest *req) odr_errlist[odr_geterror(assoc->encode)]); return -1; } - odr_getbuf(assoc->encode, &assoc->encoded_len); + assoc->encode_buffer = odr_getbuf(assoc->encode, &assoc->encoded_len); odr_reset(assoc->encode); iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT); return 0; @@ -778,7 +778,7 @@ static int process_scanRequest(IOCHAN client, Z_ScanRequest *req) odr_errlist[odr_geterror(assoc->encode)]); return -1; } - odr_getbuf(assoc->encode, &assoc->encoded_len); + assoc->encode_buffer = odr_getbuf(assoc->encode, &assoc->encoded_len); odr_reset(assoc->encode); iochan_setflags(client, EVENT_OUTPUT | EVENT_EXCEPT); return 0;