X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fber_int.c;h=e7ed6554438ae26dc33776b7a3d19140d90851a0;hp=ef1a0e03591248d1c44791a2af2f091117ada8e0;hb=fc9ad7425061fafd9340229aa006c4db115deee7;hpb=05c274ef315384faafcc5900c17468f0ea2474e6 diff --git a/src/ber_int.c b/src/ber_int.c index ef1a0e0..e7ed655 100644 --- a/src/ber_int.c +++ b/src/ber_int.c @@ -1,8 +1,6 @@ -/* - * Copyright (c) 1995-2004, Index Data +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2011 Index Data * See the file LICENSE for details. - * - * $Id: ber_int.c,v 1.2 2004-10-15 00:18:59 adam Exp $ */ /** @@ -19,95 +17,104 @@ #include +#if HAVE_SYS_TYPES_H +#include +#endif + #ifdef WIN32 #include -#else -#include -#include #endif #include "odr-priv.h" -static int ber_encinteger(ODR o, int val); -static int ber_decinteger(const unsigned char *buf, int *val, int max); +static int ber_encinteger(ODR o, Odr_int val); +static int ber_decinteger(const unsigned char *buf, Odr_int *val, int max); -int ber_integer(ODR o, int *val) +int ber_integer(ODR o, Odr_int *val) { int res; switch (o->direction) { - case ODR_DECODE: - if ((res = ber_decinteger(o->bp, val, odr_max(o))) <= 0) - { - odr_seterror(o, OPROTO, 50); - return 0; - } - o->bp += res; - return 1; - case ODR_ENCODE: - if ((res = ber_encinteger(o, *val)) < 0) - return 0; - return 1; - case ODR_PRINT: return 1; - default: odr_seterror(o, OOTHER, 51); return 0; + case ODR_DECODE: + if ((res = ber_decinteger(o->bp, val, odr_max(o))) <= 0) + { + odr_seterror(o, OPROTO, 50); + return 0; + } + o->bp += res; + return 1; + case ODR_ENCODE: + if ((res = ber_encinteger(o, *val)) < 0) + return 0; + return 1; + case ODR_PRINT: + return 1; + default: + odr_seterror(o, OOTHER, 51); return 0; } } /* * Returns: number of bytes written or -1 for error (out of bounds). */ -int ber_encinteger(ODR o, int val) +int ber_encinteger(ODR o, Odr_int val) { - int a, len; - union { int i; unsigned char c[sizeof(int)]; } tmp; - - tmp.i = htonl(val); /* ensure that that we're big-endian */ - for (a = 0; a < (int) 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)))) + unsigned long long uval = val; + unsigned char tmp[sizeof(uval)]; + int len; + size_t i; + for (i = sizeof(uval); i > 0; ) + { + tmp[--i] = uval; + uval >>= 8; + } + for (i = 0; i < sizeof(uval)-1; i++) + if (!((tmp[i] == 0 && !(tmp[i+1] & 0x80)) + || + (tmp[i] == 0xFF && (tmp[i+1] & 0x80)))) break; - len = sizeof(int) - a; + len = sizeof(uval) - i; if (ber_enclen(o, len, 1, 1) != 1) return -1; - if (odr_write(o, (unsigned char*) tmp.c + a, len) < 0) + if (odr_write(o, (unsigned char*) tmp + i, len) < 0) return -1; -#ifdef ODR_DEBUG - fprintf(stderr, "[val=%d]", val); -#endif return 0; } /* * Returns: Number of bytes read or 0 if no match, -1 if error. */ -int ber_decinteger(const unsigned char *buf, int *val, int max) +int ber_decinteger(const unsigned char *buf, Odr_int *val, int max) { + unsigned long long uval = 0; + int i, len; + int res; const unsigned char *b = buf; - unsigned char fill; - int res, len, remains; - union { int i; unsigned char c[sizeof(int)]; } tmp; if ((res = ber_declen(b, &len, max)) < 0) return -1; if (len+res > max || len < 0) /* out of bounds or indefinite encoding */ return -1; - if (len > (int) sizeof(int)) /* let's be reasonable, here */ + if (len > (int) sizeof(uval)) /* let's be reasonable, here */ return -1; - b+= res; - - remains = sizeof(int) - len; - memcpy(tmp.c + remains, b, len); - if (*b & 0X80) - fill = 0XFF; - else - fill = 0X00; - memset(tmp.c, fill, remains); - *val = ntohl(tmp.i); + b += res; + if (*b & 0x80) + for (i = 0; i < (int) sizeof(uval) - len; i++) + uval = (uval << 8) + 0xFF; + for (i = 0; i < len; i++) + uval = (uval << 8) + b[i]; + *val = uval; b += len; -#ifdef ODR_DEBUG - fprintf(stderr, "[val=%d]", *val); -#endif return b - buf; } +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +