1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
8 * \brief Implements BER INTEGER encoding and decoding.
10 * This source file implements BER encoding and decoding of
21 #include <sys/types.h>
30 static int ber_encinteger(ODR o, Odr_int val);
31 static int ber_decinteger(const char *buf, Odr_int *val, int max);
33 int ber_integer(ODR o, Odr_int *val)
40 if ((res = ber_decinteger(o->op->bp, val, odr_max(o))) <= 0)
42 odr_seterror(o, OPROTO, 50);
48 if ((res = ber_encinteger(o, *val)) < 0)
54 odr_seterror(o, OOTHER, 51); return 0;
59 * Returns: number of bytes written or -1 for error (out of bounds).
61 int ber_encinteger(ODR o, Odr_int val)
63 unsigned long long uval = val;
64 unsigned char tmp[sizeof(uval)];
67 for (i = sizeof(uval); i > 0; )
72 for (i = 0; i < sizeof(uval)-1; i++)
73 if (!((tmp[i] == 0 && !(tmp[i+1] & 0x80))
75 (tmp[i] == 0xFF && (tmp[i+1] & 0x80))))
77 len = sizeof(uval) - i;
78 if (ber_enclen(o, len, 1, 1) != 1)
80 if (odr_write(o, (const char *) tmp + i, len) < 0)
86 * Returns: Number of bytes read or 0 if no match, -1 if error.
88 int ber_decinteger(const char *buf, Odr_int *val, int max)
90 unsigned long long uval = 0;
93 const unsigned char *b = (const unsigned char *) buf;
95 if ((res = ber_declen((const char *) b, &len, max)) < 0)
97 if (len+res > max || len < 0) /* out of bounds or indefinite encoding */
99 if (len > (int) sizeof(uval)) /* let's be reasonable, here */
104 for (i = 0; i < (int) sizeof(uval) - len; i++)
105 uval = (uval << 8) + 0xFF;
106 for (i = 0; i < len; i++)
107 uval = (uval << 8) + b[i];
110 return (const char *) b - buf;
115 * c-file-style: "Stroustrup"
116 * indent-tabs-mode: nil
118 * vim: shiftwidth=4 tabstop=8 expandtab