YAZ 5.38.1
ber_len.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
5
13
14#if HAVE_CONFIG_H
15#include <config.h>
16#endif
17
18#include <stdio.h>
19#include <limits.h>
20#include "odr-priv.h"
21
31int ber_enclen(ODR o, int len, int lenlen, int exact)
32{
33 unsigned char octs[sizeof(int)];
34 int n = 0;
35 int lenpos, end;
36
37 if (len < 0) /* Indefinite */
38 {
39 if (odr_putc(o, 0x80) < 0)
40 return 0;
41 return 0;
42 }
43 if (len <= 127 && (lenlen == 1 || !exact)) /* definite short form */
44 {
45 if (odr_putc(o, (unsigned char) len) < 0)
46 return 0;
47 return 1;
48 }
49 if (lenlen == 1)
50 {
51 if (odr_putc(o, 0x80) < 0)
52 return 0;
53 return 0;
54 }
55 /* definite long form */
56 do
57 {
58 octs[n++] = len;
59 len >>= 8;
60 }
61 while (len);
62 if (n >= lenlen)
63 return -1;
64 lenpos = odr_tell(o); /* remember length-of-length position */
65 if (odr_putc(o, 0) < 0) /* dummy */
66 return 0;
67 if (exact)
68 while (n < --lenlen) /* pad length octets */
69 if (odr_putc(o, 0) < 0)
70 return 0;
71 while (n--)
72 if (odr_putc(o, octs[n]) < 0)
73 return 0;
74 /* set length of length */
75 end = odr_tell(o);
76 odr_seek(o, ODR_S_SET, lenpos);
77 if (odr_putc(o, (end - lenpos - 1) | 0X80) < 0)
78 return 0;
79 odr_seek(o, ODR_S_END, 0);
80 return odr_tell(o) - lenpos;
81}
82
94int ber_declen(const char *buf, int *len, int max)
95{
96 const unsigned char *b = (const unsigned char *) buf;
97 int n;
98
99 if (max < 1)
100 return -1;
101 if (*b == 0X80) /* Indefinite */
102 {
103 *len = -1;
104 return 1;
105 }
106 if (!(*b & 0X80)) /* Definite short form */
107 {
108 *len = (int) *b;
109 return 1;
110 }
111 if (*b == 0XFF) /* reserved value */
112 return -2;
113 /* definite long form */
114 n = *b & 0X7F;
115 if (n >= max)
116 return -1;
117 *len = 0;
118 b++;
119 while (--n >= 0)
120 {
121 if (*len > (INT_MAX - *b) / 256)
122 return -2; /* length too large to represent */
123 *len = *len * 256 + *b++;
124 }
125 return ((const char *) b - buf);
126}
127/*
128 * Local variables:
129 * c-basic-offset: 4
130 * c-file-style: "Stroustrup"
131 * indent-tabs-mode: nil
132 * End:
133 * vim: shiftwidth=4 tabstop=8 expandtab
134 */
135
int ber_declen(const char *buf, int *len, int max)
Definition ber_len.c:94
int ber_enclen(ODR o, int len, int lenlen, int exact)
Definition ber_len.c:31
Internal ODR definitions.
#define odr_tell(o)
Definition odr-priv.h:122
#define odr_putc(o, c)
Definition odr-priv.h:130
struct odr * ODR
Definition odr.h:121
#define ODR_S_SET
Definition odr.h:117
#define ODR_S_END
Definition odr.h:119
int odr_seek(ODR o, int whence, int offset)
Definition odr_mem.c:117