In the command-line client, forbid
[svn.git] / subversion / libsvn_ra_serf / xml.c
blob580ab6f71400ff05440a83cb398ef98db136c0a6
1 /*
2 * xml.c : standard XML parsing routines for ra_serf
4 * ====================================================================
5 * Copyright (c) 2006 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
21 #include <apr_uri.h>
23 #include <expat.h>
25 #include <serf.h>
27 #include "svn_pools.h"
28 #include "svn_ra.h"
29 #include "svn_dav.h"
30 #include "svn_xml.h"
31 #include "../libsvn_ra/ra_loader.h"
32 #include "svn_config.h"
33 #include "svn_delta.h"
34 #include "svn_version.h"
35 #include "svn_path.h"
36 #include "svn_private_config.h"
38 #include "ra_serf.h"
41 void
42 svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
43 const char **attrs,
44 apr_pool_t *pool)
46 const char **tmp_attrs = attrs;
48 while (*tmp_attrs)
50 if (strncmp(*tmp_attrs, "xmlns", 5) == 0)
52 svn_ra_serf__ns_t *new_ns, *cur_ns;
53 int found = 0;
55 /* Have we already defined this ns previously? */
56 for (cur_ns = *ns_list; cur_ns; cur_ns = cur_ns->next)
58 if (strcmp(cur_ns->namespace, tmp_attrs[0] + 6) == 0)
60 found = 1;
61 break;
65 if (!found)
67 new_ns = apr_palloc(pool, sizeof(*new_ns));
68 new_ns->namespace = apr_pstrdup(pool, tmp_attrs[0] + 6);
69 new_ns->url = apr_pstrdup(pool, tmp_attrs[1]);
71 new_ns->next = *ns_list;
73 *ns_list = new_ns;
76 tmp_attrs += 2;
81 * Look up NAME in the NS_LIST list for previously declared namespace
82 * definitions and return a DAV_PROPS_T-tuple that has values.
84 svn_ra_serf__dav_props_t
85 svn_ra_serf__expand_ns(svn_ra_serf__ns_t *ns_list,
86 const char *name)
88 const char *colon;
89 svn_ra_serf__dav_props_t prop_name;
91 colon = strchr(name, ':');
92 if (colon)
94 svn_ra_serf__ns_t *ns;
96 prop_name.namespace = NULL;
98 for (ns = ns_list; ns; ns = ns->next)
100 if (strncmp(ns->namespace, name, colon - name) == 0)
102 prop_name.namespace = ns->url;
103 break;
107 if (!prop_name.namespace)
109 abort();
112 prop_name.name = colon + 1;
114 else
116 /* use default namespace for now */
117 prop_name.namespace = "";
118 prop_name.name = name;
121 return prop_name;
124 void
125 svn_ra_serf__expand_string(const char **cur, apr_size_t *cur_len,
126 const char *new, apr_size_t new_len,
127 apr_pool_t *pool)
129 if (!*cur)
131 *cur = apr_pstrmemdup(pool, new, new_len);
132 *cur_len = new_len;
134 else
136 char *new_cur;
138 /* append the data we received before. */
139 new_cur = apr_palloc(pool, *cur_len + new_len + 1);
141 memcpy(new_cur, *cur, *cur_len);
142 memcpy(new_cur + *cur_len, new, new_len);
144 /* NULL-term our new string */
145 new_cur[*cur_len + new_len] = '\0';
147 /* update our length */
148 *cur_len += new_len;
149 *cur = new_cur;
153 void svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket, const char *tag,
154 const char *value,
155 serf_bucket_alloc_t *bkt_alloc)
157 serf_bucket_t *tmp;
159 tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, bkt_alloc);
160 serf_bucket_aggregate_append(agg_bucket, tmp);
162 tmp = SERF_BUCKET_SIMPLE_STRING(tag, bkt_alloc);
163 serf_bucket_aggregate_append(agg_bucket, tmp);
165 tmp = SERF_BUCKET_SIMPLE_STRING_LEN(">", 1, bkt_alloc);
166 serf_bucket_aggregate_append(agg_bucket, tmp);
168 if (value)
170 tmp = SERF_BUCKET_SIMPLE_STRING(value, bkt_alloc);
171 serf_bucket_aggregate_append(agg_bucket, tmp);
174 tmp = SERF_BUCKET_SIMPLE_STRING_LEN("</", 2, bkt_alloc);
175 serf_bucket_aggregate_append(agg_bucket, tmp);
177 tmp = SERF_BUCKET_SIMPLE_STRING(tag, bkt_alloc);
178 serf_bucket_aggregate_append(agg_bucket, tmp);
180 tmp = SERF_BUCKET_SIMPLE_STRING_LEN(">", 1, bkt_alloc);
181 serf_bucket_aggregate_append(agg_bucket, tmp);
184 void
185 svn_ra_serf__xml_push_state(svn_ra_serf__xml_parser_t *parser,
186 int state)
188 svn_ra_serf__xml_state_t *new_state;
190 if (!parser->free_state)
192 new_state = apr_palloc(parser->pool, sizeof(*new_state));
193 apr_pool_create(&new_state->pool, parser->pool);
195 else
197 new_state = parser->free_state;
198 parser->free_state = parser->free_state->prev;
200 svn_pool_clear(new_state->pool);
203 if (parser->state)
205 new_state->private = parser->state->private;
206 new_state->ns_list = parser->state->ns_list;
208 else
210 new_state->private = NULL;
211 new_state->ns_list = NULL;
214 new_state->current_state = state;
216 /* Add it to the state chain. */
217 new_state->prev = parser->state;
218 parser->state = new_state;
221 void svn_ra_serf__xml_pop_state(svn_ra_serf__xml_parser_t *parser)
223 svn_ra_serf__xml_state_t *cur_state;
225 cur_state = parser->state;
226 parser->state = cur_state->prev;
227 cur_state->prev = parser->free_state;
228 parser->free_state = cur_state;