summaryrefslogtreecommitdiff
path: root/src/ne_props.h
blob: fdeb8ffb29856a0358738ca6545d85da083242df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/* 
   WebDAV Properties manipulation
   Copyright (C) 1999-2006, Joe Orton <joe@manyfish.co.uk>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA

*/

#ifndef NE_PROPS_H
#define NE_PROPS_H

#include "ne_request.h"
#include "ne_207.h"

NE_BEGIN_DECLS

/* There are two interfaces for fetching properties. The first is
 * 'ne_simple_propfind', which is relatively simple, and easy to use,
 * but only lets you fetch FLAT properties, i.e. properties which are
 * just a string of bytes.  The complex interface is 'ne_propfind_*',
 * which is complicated, and hard to use, but lets you parse
 * structured properties, i.e.  properties which have XML content.  */

/* The 'ne_simple_propfind' interface. ***
 *
 * ne_simple_propfind allows you to fetch a set of properties for a
 * single resource, or a tree of resources.  You set the operation
 * going by passing these arguments:
 *
 *  - the session which should be used.
 *  - the URI and the depth of the operation (0, 1, infinite)
 *  - the names of the properties which you want to fetch
 *  - a results callback, and the userdata for the callback.
 *
 * For each resource found, the results callback is called, passing
 * you two things along with the userdata you passed in originally:
 *
 *   - the URI of the resource (const ne_uri *uri)
 *   - the properties results set (const ne_prop_result_set *results)
 * */

/* The name of a WebDAV property. 'nspace' may be NULL. */
typedef struct {
    const char *nspace, *name;
} ne_propname;

typedef struct ne_prop_result_set_s ne_prop_result_set;

/* Get the value of a given property. Will return NULL if there was an
 * error fetching this property on this resource.  Call
 * ne_propset_result to get the response-status if so.  */
const char *ne_propset_value(const ne_prop_result_set *set,
			      const ne_propname *propname);

/* Returns the status structure for fetching the given property on
 * this resource. This function will return NULL if the server did not
 * return the property (which is a server error). */
const ne_status *ne_propset_status(const ne_prop_result_set *set,
				      const ne_propname *propname);

/* Returns the private pointer for the given propset. */
void *ne_propset_private(const ne_prop_result_set *set);

/* Return language string of property (may be NULL). */
const char *ne_propset_lang(const ne_prop_result_set *set,
			     const ne_propname *pname);

/* ne_propset_iterate iterates over a properties result set,
 * calling the callback for each property in the set. userdata is
 * passed as the first argument to the callback. value may be NULL,
 * indicating an error occurred fetching this property: look at 
 * status for the error in that case.
 *
 * If the iterator returns non-zero, ne_propset_iterate will return
 * immediately with that value.
 */
typedef int (*ne_propset_iterator)(void *userdata,
				    const ne_propname *pname,
				    const char *value,
				    const ne_status *status);

/* Iterate over all the properties in 'set', calling 'iterator'
 * for each, passing 'userdata' as the first argument to callback.
 * 
 * Returns:
 *   whatever value iterator returns.
 */
int ne_propset_iterate(const ne_prop_result_set *set,
			ne_propset_iterator iterator, void *userdata);

/* Callback for handling the results of fetching properties for a
 * single resource (identified by URI 'uri').  The results are stored
 * in the result set 'results': use ne_propset_* to examine this
 * object.  */
typedef void (*ne_props_result)(void *userdata, const ne_uri *uri,
                                const ne_prop_result_set *results);

/* Fetch properties for a resource (if depth == NE_DEPTH_ZERO),
 * or a tree of resources (if depth == NE_DEPTH_ONE or _INFINITE).
 *
 * Names of the properties required must be given in 'props',
 * or if props is NULL, *all* properties are fetched.
 *
 * 'results' is called for each resource in the response, userdata is
 * passed as the first argument to the callback. It is important to
 * note that the callback is called as the response is read off the
 * socket, so don't do anything silly in it (e.g. sleep(100), or call
 * any functions which use this session).
 *
 * Note that if 'depth' is NE_DEPTH_INFINITY, some servers may refuse
 * the request.
 *
 * Returns NE_*.  */
int ne_simple_propfind(ne_session *sess, const char *path, int depth,
			const ne_propname *props,
			ne_props_result results, void *userdata);

/* The properties of a resource can be manipulated using ne_proppatch.
 * A single proppatch request may include any number of individual
 * "set" and "remove" operations, and is defined to have
 * "all-or-nothing" semantics, so either all the operations succeed,
 * or none do. */

/* A proppatch operation may either set a property to have a new
 * value, in which case 'type' must be ne_propset, and 'value' must be
 * non-NULL; or it can remove a property; in which case 'type' must be
 * ne_propremove, and 'value' is ignored.  In both cases, 'name' must
 * be set to the name of the property to alter. */
enum ne_proppatch_optype {
    ne_propset,
    ne_propremove
};
typedef struct {
    const ne_propname *name;
    enum ne_proppatch_optype type;
    const char *value;
} ne_proppatch_operation;

/* Execute a set of property operations 'ops' on 'path'. 'ops' is an
 * array terminated by an operation with a NULL 'name' field. Returns
 * NE_*. */
int ne_proppatch(ne_session *sess, const char *path,
		 const ne_proppatch_operation *ops);

/* Retrieve property names for the resources at 'path'.  'results'
 * callback is called for each resource.  Use 'ne_propset_iterate' on
 * the passed results object to retrieve the list of property names.
 * */
int ne_propnames(ne_session *sess, const char *path, int depth,
		 ne_props_result results, void *userdata);

/* The complex, you-do-all-the-work, property fetch interface:
 */

struct ne_propfind_handler_s;
typedef struct ne_propfind_handler_s ne_propfind_handler;

/* Retrieve the 'private' pointer for the current propset for the
 * given handler, as returned by the ne_props_create_complex callback
 * installed using 'ne_propfind_set_private'.  If this callback was
 * not registered, this function will return NULL.  */
void *ne_propfind_current_private(ne_propfind_handler *handler);

/* Create a PROPFIND handler, for the given resource or set of 
 * resources.
 *
 * Depth must be one of NE_DEPTH_*. */
ne_propfind_handler *
ne_propfind_create(ne_session *sess, const char *path, int depth);

/* Return the XML parser for the given handler (only need if you want
 * to handle complex properties). */
ne_xml_parser *ne_propfind_get_parser(ne_propfind_handler *handler);

/* This interface reserves the state integer range 'x' where 0 < x
 * and x < NE_PROPS_STATE_TOP. */
#define NE_PROPS_STATE_TOP (NE_207_STATE_TOP + 100)

/* Return the request object for the given handler.  You MUST NOT use
 * ne_set_request_body_* on this request object.  (this call is only
 * needed if for instance, you want to add extra headers to the
 * PROPFIND request).  The result of using the request pointer after
 * ne_propfind_destroy(handler) has been called is undefined. */
ne_request *ne_propfind_get_request(ne_propfind_handler *handler);

/* A "complex property" has a value which is structured XML. To handle
 * complex properties, you must set up and register an XML handler
 * which will understand the elements which make up such properties.
 * The handler must be registered with the parser returned by
 * 'ne_propfind_get_parser'.
 *
 * To store the parsed value of the property, a 'private' structure is
 * allocated in each propset (i.e. one per resource). When parsing the
 * property value elements, for each new resource encountered in the
 * response, the 'creator' callback is called to retrieve a 'private'
 * structure for this resource.  When the private structure is no longer
 * needed, the 'destructor' callback is called to deallocate any 
 * memory, if necessary.
 *
 * Whilst in XML element callbacks you will have registered to handle
 * complex properties, you can use the 'ne_propfind_current_private'
 * call to retrieve the pointer to this private structure.
 *
 * To retrieve this 'private' structure from the propset in the
 * results callback, simply call 'ne_propset_private'.
 * */
typedef void *(*ne_props_create_complex)(void *userdata, const ne_uri *uri);
typedef void (*ne_props_destroy_complex)(void *userdata, void *complex);

void ne_propfind_set_private(ne_propfind_handler *handler,
			     ne_props_create_complex creator,
			     ne_props_destroy_complex destructor,
			     void *userdata);

/* Fetch all properties.
 *
 * Returns NE_*. */
int ne_propfind_allprop(ne_propfind_handler *handler, 
			ne_props_result result, void *userdata);

/* Fetch all properties with names listed in array 'names', which is
 * terminated by a property with a NULL name field.  For each resource
 * encountered, the result callback will be invoked, passing in
 * 'userdata' as the first argument.
 *
 * Returns NE_*. */
int ne_propfind_named(ne_propfind_handler *handler, 
		      const ne_propname *names,
		      ne_props_result result, void *userdata);

/* Destroy a propfind handler after use. */
void ne_propfind_destroy(ne_propfind_handler *handler);

NE_END_DECLS

#endif /* NE_PROPS_H */