190
158
if (entered_state == PROPVAL)
192
svn_ra_serf__xml_note(xes, PROPVAL, "ns", tag->namespace);
160
svn_ra_serf__xml_note(xes, PROPVAL, "ns", tag->xmlns);
193
161
svn_ra_serf__xml_note(xes, PROPVAL, "name", tag->name);
195
163
else if (entered_state == PROPSTAT)
197
ctx->ps_props = apr_hash_make(ctx->pool);
165
ctx->ps_props = apr_hash_make(svn_ra_serf__xml_state_pool(xes));
200
168
return SVN_NO_ERROR;
171
/* Set PROPS for NS:NAME VAL. Helper for propfind_closed */
173
set_ns_prop(apr_hash_t *ns_props,
174
const char *ns, const char *name,
175
const svn_string_t *val, apr_pool_t *result_pool)
177
apr_hash_t *props = svn_hash_gets(ns_props, ns);
181
props = apr_hash_make(result_pool);
182
ns = apr_pstrdup(result_pool, ns);
183
svn_hash_sets(ns_props, ns, props);
188
name = apr_pstrdup(result_pool, name);
189
val = svn_string_dup(val, result_pool);
192
svn_hash_sets(props, name, val);
204
195
/* Conforms to svn_ra_serf__xml_closed_t */
205
196
static svn_error_t *
326
297
SVN_ERR_ASSERT(leaving_state == PROPSTAT);
328
gathered = svn_ra_serf__xml_gather_since(xes, PROPSTAT);
299
gathered = svn_ra_serf__xml_gather_since(xes, RESPONSE);
330
301
/* If we've squirreled away a note that says we want to ignore
331
302
these properties, we'll do so. Otherwise, we need to copy
332
303
them from the temporary hash into the ctx->ret_props hash. */
333
304
if (! svn_hash_gets(gathered, "ignore-prop"))
335
SVN_ERR(svn_ra_serf__walk_all_paths(ctx->ps_props, ctx->rev,
336
copy_into_ret_props, ctx,
340
ctx->ps_props = NULL;
348
svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
354
apr_hash_t *ver_props, *path_props, *ns_props;
357
ver_props = apr_hash_get(props, &rev, sizeof(rev));
360
path_props = svn_hash_gets(ver_props, path);
364
ns_props = svn_hash_gets(path_props, ns);
306
apr_hash_index_t *hi_ns;
308
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
311
path = svn_hash_gets(gathered, "path");
315
for (hi_ns = apr_hash_first(scratch_pool, ctx->ps_props);
317
hi_ns = apr_hash_next(hi_ns))
367
val = svn_hash_gets(ns_props, name);
319
const char *ns = apr_hash_this_key(hi_ns);
320
apr_hash_t *props = apr_hash_this_val(hi_ns);
321
apr_hash_index_t *hi_prop;
323
svn_pool_clear(iterpool);
325
for (hi_prop = apr_hash_first(iterpool, props);
327
hi_prop = apr_hash_next(hi_prop))
329
const char *name = apr_hash_this_key(hi_prop);
330
const svn_string_t *value = apr_hash_this_val(hi_prop);
332
SVN_ERR(ctx->prop_func(ctx->prop_func_baton, path,
333
ns, name, value, iterpool));
337
svn_pool_destroy(iterpool);
376
svn_ra_serf__get_ver_prop(apr_hash_t *props,
382
const svn_string_t *val;
384
val = svn_ra_serf__get_ver_prop_string(props, path, rev, ns, name);
395
svn_ra_serf__get_prop_string(apr_hash_t *props,
400
return svn_ra_serf__get_ver_prop_string(props, path, SVN_INVALID_REVNUM,
405
svn_ra_serf__get_prop(apr_hash_t *props,
410
return svn_ra_serf__get_ver_prop(props, path, SVN_INVALID_REVNUM, ns, name);
414
svn_ra_serf__set_ver_prop(apr_hash_t *props,
415
const char *path, svn_revnum_t rev,
416
const char *ns, const char *name,
417
const svn_string_t *val, apr_pool_t *pool)
419
apr_hash_t *ver_props, *path_props, *ns_props;
421
ver_props = apr_hash_get(props, &rev, sizeof(rev));
424
ver_props = apr_hash_make(pool);
425
apr_hash_set(props, apr_pmemdup(pool, &rev, sizeof(rev)), sizeof(rev),
429
path_props = svn_hash_gets(ver_props, path);
433
path_props = apr_hash_make(pool);
434
path = apr_pstrdup(pool, path);
435
svn_hash_sets(ver_props, path, path_props);
437
/* todo: we know that we'll fail the next check, but fall through
438
* for now for simplicity's sake.
442
ns_props = svn_hash_gets(path_props, ns);
445
ns_props = apr_hash_make(pool);
446
ns = apr_pstrdup(pool, ns);
447
svn_hash_sets(path_props, ns, ns_props);
450
svn_hash_sets(ns_props, name, val);
454
svn_ra_serf__set_prop(apr_hash_t *props,
456
const char *ns, const char *name,
457
const svn_string_t *val, apr_pool_t *pool)
459
svn_ra_serf__set_ver_prop(props, path, SVN_INVALID_REVNUM, ns, name,
340
ctx->ps_props = NULL; /* Allocated in PROPSTAT state pool */
464
348
static svn_error_t *
465
349
setup_propfind_headers(serf_bucket_t *headers,
351
apr_pool_t *pool /* request pool */,
352
apr_pool_t *scratch_pool)
469
354
propfind_context_t *ctx = setup_baton;
621
504
return SVN_NO_ERROR;
626
* This helper function will block until the PROP_CTX indicates that is done
627
* or another error is returned.
630
svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
631
apr_pool_t *scratch_pool)
636
err = svn_ra_serf__context_run_one(handler, scratch_pool);
638
err2 = svn_ra_serf__error_on_status(handler->sline,
642
return svn_error_compose_create(err2, err);
646
* This is a blocking version of deliver_props.
649
svn_ra_serf__retrieve_props(apr_hash_t **results,
650
svn_ra_serf__session_t *sess,
651
svn_ra_serf__connection_t *conn,
655
const svn_ra_serf__dav_props_t *props,
656
apr_pool_t *result_pool,
657
apr_pool_t *scratch_pool)
659
svn_ra_serf__handler_t *handler;
661
*results = apr_hash_make(result_pool);
663
SVN_ERR(svn_ra_serf__deliver_props(&handler, *results, sess, conn, url,
664
rev, depth, props, NULL, result_pool));
665
SVN_ERR(svn_ra_serf__wait_for_props(handler, scratch_pool));
508
svn_ra_serf__deliver_svn_props(void *baton,
512
const svn_string_t *value,
513
apr_pool_t *scratch_pool)
515
apr_hash_t *props = baton;
516
apr_pool_t *result_pool = apr_hash_pool_get(props);
517
const char *prop_name;
519
prop_name = svn_ra_serf__svnname_from_wirename(ns, name, result_pool);
520
if (prop_name == NULL)
523
svn_hash_sets(props, prop_name, svn_string_dup(value, result_pool));
529
* Implementation of svn_ra_serf__prop_func_t that delivers all DAV properties
530
* in (const char * -> apr_hash_t *) on Namespace pointing to a second hash
531
* (const char * -> svn_string_t *) to the values.
534
deliver_node_props(void *baton,
538
const svn_string_t *value,
539
apr_pool_t *scratch_pool)
541
apr_hash_t *nss = baton;
543
apr_pool_t *result_pool = apr_hash_pool_get(nss);
545
props = svn_hash_gets(nss, ns);
549
props = apr_hash_make(result_pool);
551
ns = apr_pstrdup(result_pool, ns);
552
svn_hash_sets(nss, ns, props);
555
name = apr_pstrdup(result_pool, name);
556
svn_hash_sets(props, name, svn_string_dup(value, result_pool));
672
562
svn_ra_serf__fetch_node_props(apr_hash_t **results,
673
svn_ra_serf__connection_t *conn,
563
svn_ra_serf__session_t *session,
675
565
svn_revnum_t revision,
676
566
const svn_ra_serf__dav_props_t *which_props,
677
567
apr_pool_t *result_pool,
678
568
apr_pool_t *scratch_pool)
680
apr_hash_t *multiprops;
681
apr_hash_t *ver_props;
683
/* Note: a couple extra hash tables and whatnot get into RESULT_POOL.
684
Not a big deal at this point. Theoretically, we could fetch all
685
props into SCRATCH_POOL, then copy just the REVISION/URL props
686
into RESULT_POOL. Too much work for too little gain... */
687
SVN_ERR(svn_ra_serf__retrieve_props(&multiprops, conn->session, conn,
688
url, revision, "0", which_props,
689
result_pool, scratch_pool));
691
ver_props = apr_hash_get(multiprops, &revision, sizeof(revision));
692
if (ver_props != NULL)
694
*results = svn_hash_gets(ver_props, url);
695
if (*results != NULL)
699
return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
700
_("The PROPFIND response did not include "
701
"the requested properties"));
706
svn_ra_serf__walk_node_props(apr_hash_t *props,
707
svn_ra_serf__walker_visitor_t walker,
709
apr_pool_t *scratch_pool)
711
apr_pool_t *iterpool;
712
apr_hash_index_t *ns_hi;
714
iterpool = svn_pool_create(scratch_pool);
715
for (ns_hi = apr_hash_first(scratch_pool, props); ns_hi;
716
ns_hi = apr_hash_next(ns_hi))
720
apr_hash_index_t *name_hi;
722
/* NOTE: We do not clear ITERPOOL in this loop. Generally, there are
723
very few namespaces, so this loop will not have many iterations.
724
Instead, ITERPOOL is used for the inner loop. */
726
apr_hash_this(ns_hi, &ns_name, NULL, &ns_val);
728
for (name_hi = apr_hash_first(scratch_pool, ns_val); name_hi;
729
name_hi = apr_hash_next(name_hi))
732
const void *prop_name;
734
/* See note above, regarding clearing of this pool. */
735
svn_pool_clear(iterpool);
737
apr_hash_this(name_hi, &prop_name, NULL, &prop_val);
739
SVN_ERR(walker(baton, ns_name, prop_name, prop_val, iterpool));
742
svn_pool_destroy(iterpool);
749
svn_ra_serf__walk_all_props(apr_hash_t *props,
752
svn_ra_serf__walker_visitor_t walker,
754
apr_pool_t *scratch_pool)
756
apr_hash_t *ver_props;
757
apr_hash_t *path_props;
759
ver_props = apr_hash_get(props, &rev, sizeof(rev));
763
path_props = svn_hash_gets(ver_props, name);
767
return svn_error_trace(svn_ra_serf__walk_node_props(path_props,
774
svn_ra_serf__walk_all_paths(apr_hash_t *props,
776
svn_ra_serf__path_rev_walker_t walker,
780
apr_hash_index_t *path_hi;
781
apr_hash_t *ver_props;
783
ver_props = apr_hash_get(props, &rev, sizeof(rev));
790
for (path_hi = apr_hash_first(pool, ver_props); path_hi;
791
path_hi = apr_hash_next(path_hi))
794
const void *path_name;
795
apr_ssize_t path_len;
796
apr_hash_index_t *ns_hi;
798
apr_hash_this(path_hi, &path_name, &path_len, &path_props);
799
for (ns_hi = apr_hash_first(pool, path_props); ns_hi;
800
ns_hi = apr_hash_next(ns_hi))
805
apr_hash_index_t *name_hi;
806
apr_hash_this(ns_hi, &ns_name, &ns_len, &ns_val);
807
for (name_hi = apr_hash_first(pool, ns_val); name_hi;
808
name_hi = apr_hash_next(name_hi))
811
const void *prop_name;
812
apr_ssize_t prop_len;
814
apr_hash_this(name_hi, &prop_name, &prop_len, &prop_val);
816
SVN_ERR(walker(baton, path_name, path_len, ns_name, ns_len,
817
prop_name, prop_len, prop_val, pool));
571
svn_ra_serf__handler_t *handler;
573
props = apr_hash_make(result_pool);
575
SVN_ERR(svn_ra_serf__create_propfind_handler(&handler, session,
576
url, revision, "0", which_props,
578
props, scratch_pool));
580
SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
827
587
svn_ra_serf__svnname_from_wirename(const char *ns,
865
625
/* An unknown namespace, must be a custom property. */
866
return apr_pstrcat(result_pool, ns, name, (char *)NULL);
870
/* Conforms to svn_ra_serf__walker_visitor_t */
872
set_flat_props(void *baton,
875
const svn_string_t *value,
878
apr_hash_t *props = baton;
879
apr_pool_t *result_pool = apr_hash_pool_get(props);
880
const char *prop_name;
882
/* ### is VAL in the proper pool? */
884
prop_name = svn_ra_serf__svnname_from_wirename(ns, name, result_pool);
885
if (prop_name != NULL)
886
svn_hash_sets(props, prop_name, value);
893
svn_ra_serf__flatten_props(apr_hash_t **flat_props,
895
apr_pool_t *result_pool,
896
apr_pool_t *scratch_pool)
898
*flat_props = apr_hash_make(result_pool);
900
return svn_error_trace(svn_ra_serf__walk_node_props(
903
*flat_props /* baton */,
909
select_revprops(void *baton,
912
const svn_string_t *val,
913
apr_pool_t *scratch_pool)
915
apr_hash_t *revprops = baton;
916
apr_pool_t *result_pool = apr_hash_pool_get(revprops);
917
const char *prop_name;
919
/* ### copy NAME into the RESULT_POOL? */
920
/* ### copy VAL into the RESULT_POOL? */
922
if (strcmp(ns, SVN_DAV_PROP_NS_CUSTOM) == 0)
924
else if (strcmp(ns, SVN_DAV_PROP_NS_SVN) == 0)
925
prop_name = apr_pstrcat(result_pool, SVN_PROP_PREFIX, name, (char *)NULL);
926
else if (strcmp(ns, SVN_PROP_PREFIX) == 0)
927
prop_name = apr_pstrcat(result_pool, SVN_PROP_PREFIX, name, (char *)NULL);
928
else if (strcmp(ns, "") == 0)
932
/* do nothing for now? */
936
svn_hash_sets(revprops, prop_name, val);
943
svn_ra_serf__select_revprops(apr_hash_t **revprops,
946
apr_hash_t *all_revprops,
947
apr_pool_t *result_pool,
948
apr_pool_t *scratch_pool)
950
*revprops = apr_hash_make(result_pool);
952
return svn_error_trace(svn_ra_serf__walk_all_props(
953
all_revprops, name, rev,
954
select_revprops, *revprops,
626
return apr_pstrcat(result_pool, ns, name, SVN_VA_NULL);
960
630
* Contact the server (using CONN) to calculate baseline