su_tag.h 8.51 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3 4 5 6 7
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
8
 * This library is free software; you can redistribute it and/or
Pekka Pessi's avatar
Pekka Pessi committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

Pekka Pessi's avatar
Pekka Pessi committed
25 26
#ifndef SU_TAG_H
/** Defined when <sofia-sip/su_tag.h> has been included. */
Pekka Pessi's avatar
Pekka Pessi committed
27
#define SU_TAG_H
Pekka Pessi's avatar
Pekka Pessi committed
28 29

/**@SU_TAG
Pekka Pessi's avatar
Pekka Pessi committed
30
 * @file sofia-sip/su_tag.h  Object-oriented tags and tag list interface.
Pekka Pessi's avatar
Pekka Pessi committed
31 32
 *
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
33
 *
Pekka Pessi's avatar
Pekka Pessi committed
34 35 36 37
 * @date Created: Tue Feb 20 19:48:18 2001 ppessi
 */

#ifndef SU_CONFIG_H
38
#include <sofia-sip/su_config.h>
Pekka Pessi's avatar
Pekka Pessi committed
39 40 41
#endif

#ifndef SU_TYPES_H
42
#include <sofia-sip/su_types.h>
Pekka Pessi's avatar
Pekka Pessi committed
43 44 45
#endif

#ifndef SU_ALLOC_H
46
#include <sofia-sip/su_alloc.h>
Pekka Pessi's avatar
Pekka Pessi committed
47 48 49 50 51
#endif

#include <stdarg.h>
#include <stddef.h> /* ANSI C: size_t */

52 53
SOFIA_BEGIN_DECLS

Pekka Pessi's avatar
Pekka Pessi committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
/** Tag item type */
typedef struct tag_type_s const *tag_type_t;
/** Tag item value */
typedef intptr_t                 tag_value_t;

/** Tag list signature */
#define TAG_LIST tag_type_t tag, tag_value_t value, ...

/** Tag item. */
typedef struct {
  tag_type_t   t_tag;		/**< Tag */
  tag_value_t  t_value;		/**< Value */
} tagi_t;

/** Tag type class */
typedef struct tag_class_s const tag_class_t;

71
/** Tag structure.
Pekka Pessi's avatar
Pekka Pessi committed
72 73 74 75
 *
 * The tag structure contains the name, namespace and class of the tag. The
 * fourth field, @a tt_magic, is interpreted by the tag class.
 */
Pekka Pessi's avatar
Pekka Pessi committed
76
struct tag_type_s {
Pekka Pessi's avatar
Pekka Pessi committed
77 78 79
  char const    *tt_ns;		/**< Tag namespace (e.g., "sip" or "nua") */
  char const 	*tt_name;	/**< Tag name (e.g, "min_se")  */
  tag_class_t   *tt_class;	/**< Tag class defines the type of the value */
80
  tag_value_t    tt_magic;	/**< Class-specific data
Pekka Pessi's avatar
Pekka Pessi committed
81
				   (e.g., pointer to header class structure) */
Pekka Pessi's avatar
Pekka Pessi committed
82 83 84 85 86 87
};

/** Definition of tag type. */
typedef struct tag_type_s const tag_typedef_t[1];

/** End of tag list */
88
SOFIAPUBVAR tag_typedef_t tag_null;
Pekka Pessi's avatar
Pekka Pessi committed
89 90

/** Ignore tag item. */
91
SOFIAPUBVAR tag_typedef_t tag_skip;
Pekka Pessi's avatar
Pekka Pessi committed
92 93

/** Jump to another tag list */
94
SOFIAPUBVAR tag_typedef_t tag_next;
Pekka Pessi's avatar
Pekka Pessi committed
95 96

/** Any tag accepted when filtering. */
97
SOFIAPUBVAR tag_typedef_t tag_any;
Pekka Pessi's avatar
Pekka Pessi committed
98

99
/** Filter tag using function as argument.
100 101 102 103
 * @since New in @VERSION_1_12_2.
 */
SOFIAPUBVAR tag_typedef_t tag_filter;

104
/** Prototype for filtering function used with TAG_FILTER().
105 106 107 108
 * @since New in @VERSION_1_12_2.
 */
typedef int tag_filter_f(tagi_t const *filter, tagi_t const *dest);

109
/** @HI Initialize a tag item marking the end of list. Equivalent to TAG_END(). */
Pekka Pessi's avatar
Pekka Pessi committed
110 111
#define TAG_NULL()  (tag_type_t)0, (tag_value_t)0

112
/** @HI Initialize a tag item marking the end of list. Equivalent to TAG_NULL(). */
Pekka Pessi's avatar
Pekka Pessi committed
113 114 115 116 117 118 119 120 121 122 123
#define TAG_END()   (tag_type_t)0, (tag_value_t)0

/** @HI Initialize an empty tag item. */
#define TAG_SKIP(x)    tag_skip, (tag_value_t)(x)

/** @HI Initialize a tag item pointing to another tag list at @a next. */
#define TAG_NEXT(next) tag_next, (tag_value_t)(next)

/** @HI Initialize a filter tag item accepting any item. */
#define TAG_ANY()   tag_any,  (tag_value_t)0

124
/** @HI Initialize a @a item if condition is true;
Pekka Pessi's avatar
Pekka Pessi committed
125 126 127
 * otherwise, initialize an empty tag item. */
#define TAG_IF(condition, item) !(condition) ? tag_skip : item

128
/** @HI Initialize a filter tag item accepting any item.
129 130 131 132
 * @since New in @VERSION_1_12_2.
 */
#define TAG_FILTER(function)  tag_filter, tag_filter_v(function)

Pekka Pessi's avatar
Pekka Pessi committed
133
/** Convert tag item to a string  */
134
SOFIAPUBFUN int t_snprintf(tagi_t const *t, char b[], size_t size);
Pekka Pessi's avatar
Pekka Pessi committed
135 136

/** Convert string to a tag value */
137
SOFIAPUBFUN int t_scan(tag_type_t tt, su_home_t *home, char const *s,
138
		       tag_value_t *return_value);
Pekka Pessi's avatar
Pekka Pessi committed
139 140

/* Tagarg functions */
141 142
SOFIAPUBFUN tagi_t *tl_tlist(su_home_t *, tag_type_t, tag_value_t, ...);
SOFIAPUBFUN size_t tl_tmove(tagi_t *dst, size_t, tag_type_t, tag_value_t, ...);
143 144
SOFIAPUBFUN int tl_gets(tagi_t const lst[], tag_type_t, tag_value_t, ...);
SOFIAPUBFUN int tl_tgets(tagi_t lst[], tag_type_t, tag_value_t, ...);
145
SOFIAPUBFUN tagi_t *tl_tfilter(su_home_t *, tagi_t const lst[],
146 147
			       tag_type_t, tag_value_t, ...);
SOFIAPUBFUN int tl_tremove(tagi_t lst[], tag_type_t, tag_value_t, ...);
Pekka Pessi's avatar
Pekka Pessi committed
148 149

/* Low-level taglist manipulation functions */
150 151 152 153 154 155
SOFIAPUBFUN size_t tl_len(tagi_t const lst[]);
SOFIAPUBFUN size_t tl_xtra(tagi_t const lst[], size_t offset);
SOFIAPUBFUN tagi_t *tl_next(tagi_t const *lst);
SOFIAPUBFUN tagi_t *tl_move(tagi_t *dst, tagi_t const src[]);
SOFIAPUBFUN tagi_t *tl_dup(tagi_t dst[], tagi_t const lst[], void **bb);
SOFIAPUBFUN tagi_t *tl_adup(su_home_t *, tagi_t const lst[]);
156
SOFIAPUBFUN void tl_free(tagi_t list[]);
157

158 159
SOFIAPUBFUN tagi_t *tl_find(tagi_t const lst[], tag_type_t tt);
SOFIAPUBFUN tagi_t *tl_find_last(tagi_t const lst[], tag_type_t tt);
160 161 162 163 164
SOFIAPUBFUN tagi_t *tl_filter(tagi_t *, tagi_t const filter[],
			      tagi_t const lst[], void **b);
SOFIAPUBFUN tagi_t *tl_afilter(su_home_t *, tagi_t const filter[],
			       tagi_t const lst[]);

165
SOFIAPUBFUN tagi_t *tl_filtered_tlist(su_home_t *home, tagi_t const filter[],
166 167 168 169 170 171 172 173 174
				      tag_type_t, tag_value_t, ...);

SOFIAPUBFUN size_t  tl_vlen(va_list ap);
SOFIAPUBFUN tagi_t *tl_list(tag_type_t tag, tag_value_t value, ...);
SOFIAPUBFUN tagi_t *tl_vlist2(tag_type_t tag, tag_value_t value, va_list ap);
SOFIAPUBFUN tagi_t *tl_vlist(va_list ap);
SOFIAPUBFUN tagi_t *tl_llist(tag_type_t tag, tag_value_t value, ...);
SOFIAPUBFUN tagi_t *tl_vllist(tag_type_t tag, tag_value_t value, va_list ap);
SOFIAPUBFUN void    tl_vfree(tagi_t *t);
Pekka Pessi's avatar
Pekka Pessi committed
175 176 177 178 179

/** Align to pointer size */
#define SU_ALIGN(x) \
((sizeof(void *) - ((intptr_t)(x) & (sizeof(void *) - 1))) & (sizeof(void *) - 1))

180
#if SU_INLINE_TAG_CAST
Pekka Pessi's avatar
Pekka Pessi committed
181 182 183 184
su_inline tag_value_t tag_int_v(int v) { return (tag_value_t)v; }
su_inline tag_value_t tag_int_vr(int *vp) { return (tag_value_t)vp; }
su_inline tag_value_t tag_uint_v(unsigned v) { return (tag_value_t)v; }
su_inline tag_value_t tag_uint_vr(unsigned *vp) { return (tag_value_t)vp; }
185 186 187 188
su_inline tag_value_t tag_usize_v(usize_t v) { return (tag_value_t)v; }
su_inline tag_value_t tag_usize_vr(usize_t *vp) { return (tag_value_t)vp; }
su_inline tag_value_t tag_size_v(size_t v) { return (tag_value_t)v; }
su_inline tag_value_t tag_size_vr(size_t *vp) { return (tag_value_t)vp; }
Pekka Pessi's avatar
Pekka Pessi committed
189 190 191
su_inline tag_value_t tag_bool_v(int v) { return v != 0; }
su_inline tag_value_t tag_bool_vr(int *vp) { return (tag_value_t)vp; }
su_inline tag_value_t tag_ptr_v(void *v) { return (tag_value_t)v; }
192 193
su_inline tag_value_t tag_ptr_vr(void *vp, void *v)
  { (void)v; return(tag_value_t)vp; }
Pekka Pessi's avatar
Pekka Pessi committed
194
su_inline tag_value_t tag_cptr_v(void const *v) { return (tag_value_t)v; }
195
su_inline tag_value_t tag_cptr_vr(void *vp, void const *v)
196
  { (void)v; return(tag_value_t)vp; }
Pekka Pessi's avatar
Pekka Pessi committed
197 198 199 200 201 202
su_inline tag_value_t tag_cstr_v(char const *v) { return (tag_value_t)v; }
su_inline tag_value_t tag_cstr_vr(char const**vp) {return(tag_value_t)vp;}
su_inline tag_value_t tag_str_v(char const *v) { return (tag_value_t)v; }
su_inline tag_value_t tag_str_vr(char const **vp) {return(tag_value_t)vp;}
#if __cplusplus
extern "C++" {
203
  su_inline tag_value_t tag_ptr_v(void const *v)
Pekka Pessi's avatar
Pekka Pessi committed
204
  { return (tag_value_t)v; }
205
  su_inline tag_value_t tag_ptr_vr(void *vp, void const *p)
Pekka Pessi's avatar
Pekka Pessi committed
206
  { return (tag_value_t)vp; }
207 208
  su_inline tag_value_t tag_str_v(char *v) { return (tag_value_t)v; }
  su_inline tag_value_t tag_str_vr(char **vp) {return (tag_value_t)vp;}
Pekka Pessi's avatar
Pekka Pessi committed
209 210
}
#endif
211
su_inline tag_value_t tag_filter_v(tag_filter_f *v) {return(tag_value_t)v;}
Pekka Pessi's avatar
Pekka Pessi committed
212 213 214 215 216
#else
#define tag_int_v(v)   (tag_value_t)(v)
#define tag_int_vr(v)  (tag_value_t)(v)
#define tag_uint_v(v)  (tag_value_t)(v)
#define tag_uint_vr(v) (tag_value_t)(v)
Pekka Pessi's avatar
Pekka Pessi committed
217 218
#define tag_usize_v(v) (tag_value_t)(v)
#define tag_usize_vr(v) (tag_value_t)(v)
Michael Jerris's avatar
Michael Jerris committed
219 220
#define tag_size_v(v) (tag_value_t)(v)
#define tag_size_vr(v) (tag_value_t)(v)
Pekka Pessi's avatar
Pekka Pessi committed
221 222 223 224
#define tag_bool_v(v)  (tag_value_t)(v != 0)
#define tag_bool_vr(v) (tag_value_t)(v)
#define tag_ptr_v(v)   (tag_value_t)(v)
#define tag_ptr_vr(v,x) (tag_value_t)(v)
Pekka Pessi's avatar
Pekka Pessi committed
225 226
#define tag_cptr_v(v)   (tag_value_t)(v)
#define tag_cptr_vr(v,x) (tag_value_t)(v)
Pekka Pessi's avatar
Pekka Pessi committed
227 228 229 230
#define tag_cstr_v(v)  (tag_value_t)(v)
#define tag_cstr_vr(v) (tag_value_t)(v)
#define tag_str_v(v)   (tag_value_t)(v)
#define tag_str_vr(v)  (tag_value_t)(v)
231
#define tag_filter_v(v) (tag_value_t)(v)
Pekka Pessi's avatar
Pekka Pessi committed
232 233
#endif

234 235
SOFIA_END_DECLS

Pekka Pessi's avatar
Pekka Pessi committed
236
#endif /** !defined(SU_TAG_H) */