Added state-handle and some support for asynchronous activities.
[yaz-moved-to-github.git] / odr / ber_len.c
1 #include <stdio.h>
2 #include <odr.h>
3
4 /*
5  * Encode BER length octets. If exact, lenlen is the exact desired
6  * encoding size, else, lenlen is the max available space. Len < 0 =
7  * Indefinite encoding.
8  * Returns: >0   success, number of bytes encoded.
9  * Returns: =0   success, indefinite start-marker set. 1 byte encoded.
10  * Returns: -1   failure, out of bounds.
11  */
12 int ber_enclen(unsigned char *buf, int len, int lenlen, int exact)
13 {
14     unsigned char *b = buf;
15     unsigned char octs[sizeof(int)];
16     int n = 0;
17
18 #ifdef ODR_DEBUG
19     fprintf(stderr, "[len=%d]", len);
20 #endif
21     if (len < 0)      /* Indefinite */
22     {
23         *b = 0X80;
24 #ifdef ODR_DEBUG
25         fprintf(stderr, "[indefinite]");
26 #endif
27         return 0;
28     }
29     if (len <= 127 && (lenlen == 1 || !exact)) /* definite short form */
30     {
31         *b = len;
32         return 1;
33     }
34     if (lenlen == 1)
35     {
36         *b = 0X80;
37         return 0;
38     }
39     /* definite long form */
40     do
41     {
42         octs[n++] = len;
43         len >>= 8;
44     }
45     while (len);
46     if (n >= lenlen)
47         return -1;
48     b++;
49     if (exact)
50         while (n < --lenlen)        /* pad length octets */
51             *(++b) = 0;
52     while (n--)
53         *(b++) = octs[n];
54     *buf = (b - buf - 1) | 0X80;
55     return b - buf;
56 }
57
58 /*
59  * Decode BER length octets. Returns number of bytes read or -1 for error.
60  * After return:
61  * len = -1   indefinite.
62  * len >= 0    Length.
63  */
64 int ber_declen(unsigned char *buf, int *len)
65 {
66     unsigned char *b = buf;
67     int n;
68
69     if (*b == 0X80)     /* Indefinite */
70     {
71         *len = -1;
72 #ifdef ODR_DEBUG
73         fprintf(stderr, "[len=%d]", *len);
74 #endif
75         return 1;
76     }
77     if (!(*b & 0X80))   /* Definite short form */
78     {
79         *len = (int) *b;
80 #ifdef ODR_DEBUG
81         fprintf(stderr, "[len=%d]", *len);
82 #endif
83         return 1;
84     }
85     if (*b == 0XFF)     /* reserved value */
86         return -1;
87     /* indefinite long form */ 
88     n = *b & 0X7F;
89     *len = 0;
90     b++;
91     while (n--)
92     {
93         *len <<= 8;
94         *len |= *(b++);
95     }
96 #ifdef ODR_DEBUG
97     fprintf(stderr, "[len=%d]", *len);
98 #endif
99     return (b - buf);
100 }