source: trunk/gsdl/packages/yaz/odr/ber_len.c@ 1343

Last change on this file since 1343 was 1343, checked in by johnmcp, 24 years ago

Added the YAZ toolkit source to the packages directory (for z39.50 stuff)

  • Property svn:keywords set to Author Date Id Revision
File size: 3.3 KB
Line 
1/*
2 * Copyright (C) 1995-2000, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
5 *
6 * $Log$
7 * Revision 1.1 2000/08/03 03:11:14 johnmcp
8 * Added the YAZ toolkit source to the packages directory (for z39.50 stuff)
9 *
10 * Revision 1.9 2000/02/29 13:44:55 adam
11 * Check for config.h (currently not generated).
12 *
13 * Revision 1.8 1999/11/30 13:47:11 adam
14 * Improved installation. Moved header files to include/yaz.
15 *
16 * Revision 1.7 1999/01/08 11:23:23 adam
17 * Added const modifier to some of the BER/ODR encoding routines.
18 *
19 * Revision 1.6 1995/09/29 17:12:17 quinn
20 * Smallish
21 *
22 * Revision 1.5 1995/09/27 15:02:55 quinn
23 * Modified function heads & prototypes.
24 *
25 * Revision 1.4 1995/05/16 08:50:45 quinn
26 * License, documentation, and memory fixes
27 *
28 *
29 */
30#if HAVE_CONFIG_H
31#include <config.h>
32#endif
33
34#include <stdio.h>
35#include <yaz/odr.h>
36
37/*
38 * Encode BER length octets. If exact, lenlen is the exact desired
39 * encoding size, else, lenlen is the max available space. Len < 0 =
40 * Indefinite encoding.
41 * Returns: >0 success, number of bytes encoded.
42 * Returns: =0 success, indefinite start-marker set. 1 byte encoded.
43 * Returns: -1 failure, out of bounds.
44 */
45int ber_enclen(ODR o, int len, int lenlen, int exact)
46{
47 unsigned char octs[sizeof(int)];
48 int n = 0;
49 int lenpos, end;
50
51#ifdef ODR_DEBUG
52 fprintf(stderr, "[len=%d]", len);
53#endif
54 if (len < 0) /* Indefinite */
55 {
56 if (odr_putc(o, 0x80) < 0)
57 return 0;
58#ifdef ODR_DEBUG
59 fprintf(stderr, "[indefinite]");
60#endif
61 return 0;
62 }
63 if (len <= 127 && (lenlen == 1 || !exact)) /* definite short form */
64 {
65 if (odr_putc(o, (unsigned char) len) < 0)
66 return 0;
67 return 1;
68 }
69 if (lenlen == 1)
70 {
71 if (odr_putc(o, 0x80) < 0)
72 return 0;
73 return 0;
74 }
75 /* definite long form */
76 do
77 {
78 octs[n++] = len;
79 len >>= 8;
80 }
81 while (len);
82 if (n >= lenlen)
83 return -1;
84 lenpos = odr_tell(o); /* remember length-of-length position */
85 if (odr_putc(o, 0) < 0) /* dummy */
86 return 0;
87 if (exact)
88 while (n < --lenlen) /* pad length octets */
89 if (odr_putc(o, 0) < 0)
90 return 0;
91 while (n--)
92 if (odr_putc(o, octs[n]) < 0)
93 return 0;
94 /* set length of length */
95 end = odr_tell(o);
96 odr_seek(o, ODR_S_SET, lenpos);
97 if (odr_putc(o, (end - lenpos - 1) | 0X80) < 0)
98 return 0;
99 odr_seek(o, ODR_S_END, 0);
100 return odr_tell(o) - lenpos;
101}
102
103/*
104 * Decode BER length octets. Returns number of bytes read or -1 for error.
105 * After return:
106 * len = -1 indefinite.
107 * len >= 0 Length.
108 */
109int ber_declen(const unsigned char *buf, int *len)
110{
111 const unsigned char *b = buf;
112 int n;
113
114 if (*b == 0X80) /* Indefinite */
115 {
116 *len = -1;
117#ifdef ODR_DEBUG
118 fprintf(stderr, "[len=%d]", *len);
119#endif
120 return 1;
121 }
122 if (!(*b & 0X80)) /* Definite short form */
123 {
124 *len = (int) *b;
125#ifdef ODR_DEBUG
126 fprintf(stderr, "[len=%d]", *len);
127#endif
128 return 1;
129 }
130 if (*b == 0XFF) /* reserved value */
131 return -1;
132 /* indefinite long form */
133 n = *b & 0X7F;
134 *len = 0;
135 b++;
136 while (n--)
137 {
138 *len <<= 8;
139 *len |= *(b++);
140 }
141#ifdef ODR_DEBUG
142 fprintf(stderr, "[len=%d]", *len);
143#endif
144 return (b - buf);
145}
Note: See TracBrowser for help on using the repository browser.