06d6102781c33b13608b4360b7c642061198b7b4
[yaz-moved-to-github.git] / src / odr-priv.h
1 /*
2  * Copyright (C) 1995-2005, Index Data ApS
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation, in whole or in part, for any purpose, is hereby granted,
6  * provided that:
7  *
8  * 1. This copyright and permission notice appear in all copies of the
9  * software and its documentation. Notices of copyright or attribution
10  * which appear at the beginning of any file must remain unchanged.
11  *
12  * 2. The name of Index Data or the individual authors may not be used to
13  * endorse or promote products derived from this software without specific
14  * prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19  * IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
20  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
22  * NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24  * OF THIS SOFTWARE.
25  *
26  * $Id: odr-priv.h,v 1.8 2005-09-09 10:30:35 adam Exp $
27  */
28
29 /**
30  * \file odr-priv.h
31  * \brief Internal ODR definitions
32  */
33
34 #ifndef ODR_PRIV_H
35
36 #define ODR_PRIV_H
37
38 #include <yaz/odr.h>
39 #include <yaz/yaz-util.h>
40
41 /** \brief Utility structure used by ber_tag */
42 struct Odr_ber_tag {
43     int lclass;
44     int ltag;
45     int br;
46     int lcons;
47 };
48
49 #define odr_max(o) ((o)->size - ((o)->bp - (o)->buf))
50 #define odr_offset(o) ((o)->bp - (o)->buf)
51
52 /**
53  * \brief stack for BER constructed items
54  *
55  * data structure for con stack.. a little peculiar. Since we can't
56  * deallocate memory we reuse stack items (popped items gets reused)
57  *
58  *\verbatim
59  *       +---+     +---+     +---+     +---+
60  * NULL -|p n|-----|p n|-----|p n|-----|p n|-- NULL
61  *       +---+     +---+     +---+     +---+
62  *         |                   |
63  *     stack_first         stack_top   reused item
64  *\endverbatim
65  */
66 struct odr_constack
67 {
68     const unsigned char *base;   /** starting point of data */
69     int base_offset;
70     int len;                     /** length of data, if known, else -1
71                                         (decoding only) */
72     const unsigned char *lenb;   /** where to encode length */
73     int len_offset;
74     int lenlen;                  /** length of length-field */
75     const char *name;            /** name of stack entry */
76
77     struct odr_constack *prev;   /** pointer back in stack */
78     struct odr_constack *next;   /** pointer forward */
79 };
80
81 #define ODR_MAX_STACK 2000
82
83 /**
84  * \brief ODR private data
85  */
86 struct Odr_private {
87     /* stack for constructed types (we above) */
88     struct odr_constack *stack_first; /** first member of allocated stack */
89     struct odr_constack *stack_top;   /** top of stack */
90
91
92     const char **tmp_names_buf;   /** array returned by odr_get_element_path */
93     int tmp_names_sz;                 /** size of tmp_names_buf */
94
95     struct Odr_ber_tag odr_ber_tag;   /** used by ber_tag */
96
97     yaz_iconv_t iconv_handle;
98     int error_id;
99     char element[80];
100     void (*stream_write)(ODR o, void *handle, int type,
101                          const char *buf, int len);
102     void (*stream_close)(void *handle);
103 };
104
105 #define ODR_STACK_POP(x) (x)->op->stack_top = (x)->op->stack_top->prev
106 #define ODR_STACK_EMPTY(x) (!(x)->op->stack_top)
107 #define ODR_STACK_NOT_EMPTY(x) ((x)->op->stack_top)
108
109 /* Private macro.
110  * write a single character at the current position - grow buffer if
111  * necessary.
112  * (no, we're not usually this anal about our macros, but this baby is
113  *  next to unreadable without some indentation  :)
114  */
115 #define odr_putc(o, c) \
116 ( \
117     ( \
118         (o)->pos < (o)->size ? \
119         ( \
120             (o)->buf[(o)->pos++] = (c), \
121             0 \
122         ) : \
123         ( \
124             odr_grow_block((o), 1) == 0 ? \
125             ( \
126                 (o)->buf[(o)->pos++] = (c), \
127                 0 \
128             ) : \
129             ( \
130                 (o)->error = OSPACE, \
131                 -1 \
132             ) \
133         ) \
134     ) == 0 ? \
135     ( \
136         (o)->pos > (o)->top ? \
137         ( \
138             (o)->top = (o)->pos, \
139             0 \
140         ) : \
141         0 \
142     ) : \
143         -1 \
144 )
145
146 #endif
147 /*
148  * Local variables:
149  * c-basic-offset: 4
150  * indent-tabs-mode: nil
151  * End:
152  * vim: shiftwidth=4 tabstop=8 expandtab
153  */
154