YAZ  5.23.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 
14 #if HAVE_CONFIG_H
15 #include <config.h>
16 #endif
17 
18 #include <stdio.h>
19 #include "odr-priv.h"
20 
30 int ber_enclen(ODR o, int len, int lenlen, int exact)
31 {
32  unsigned char octs[sizeof(int)];
33  int n = 0;
34  int lenpos, end;
35 
36  if (len < 0) /* Indefinite */
37  {
38  if (odr_putc(o, 0x80) < 0)
39  return 0;
40  return 0;
41  }
42  if (len <= 127 && (lenlen == 1 || !exact)) /* definite short form */
43  {
44  if (odr_putc(o, (unsigned char) len) < 0)
45  return 0;
46  return 1;
47  }
48  if (lenlen == 1)
49  {
50  if (odr_putc(o, 0x80) < 0)
51  return 0;
52  return 0;
53  }
54  /* definite long form */
55  do
56  {
57  octs[n++] = len;
58  len >>= 8;
59  }
60  while (len);
61  if (n >= lenlen)
62  return -1;
63  lenpos = odr_tell(o); /* remember length-of-length position */
64  if (odr_putc(o, 0) < 0) /* dummy */
65  return 0;
66  if (exact)
67  while (n < --lenlen) /* pad length octets */
68  if (odr_putc(o, 0) < 0)
69  return 0;
70  while (n--)
71  if (odr_putc(o, octs[n]) < 0)
72  return 0;
73  /* set length of length */
74  end = odr_tell(o);
75  odr_seek(o, ODR_S_SET, lenpos);
76  if (odr_putc(o, (end - lenpos - 1) | 0X80) < 0)
77  return 0;
78  odr_seek(o, ODR_S_END, 0);
79  return odr_tell(o) - lenpos;
80 }
81 
93 int ber_declen(const char *buf, int *len, int max)
94 {
95  const unsigned char *b = (const unsigned char *) buf;
96  int n;
97 
98  if (max < 1)
99  return -1;
100  if (*b == 0X80) /* Indefinite */
101  {
102  *len = -1;
103  return 1;
104  }
105  if (!(*b & 0X80)) /* Definite short form */
106  {
107  *len = (int) *b;
108  return 1;
109  }
110  if (*b == 0XFF) /* reserved value */
111  return -2;
112  /* indefinite long form */
113  n = *b & 0X7F;
114  if (n >= max)
115  return -1;
116  *len = 0;
117  b++;
118  while (--n >= 0)
119  {
120  *len <<= 8;
121  *len |= *(b++);
122  }
123  if (*len < 0)
124  return -2;
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:93
int odr_seek(ODR o, int whence, int offset)
Definition: odr_mem.c:117
#define odr_putc(o, c)
Definition: odr-priv.h:129
#define ODR_S_SET
Definition: odr.h:117
Internal ODR definitions.
#define ODR_S_END
Definition: odr.h:119
int ber_enclen(ODR o, int len, int lenlen, int exact)
Definition: ber_len.c:30
Definition: odr.h:124
#define odr_tell(o)
Definition: odr-priv.h:121