138
/* Store the ASCII decimal representation of VALUE at DATA. Return
139
the length of the representation if all goes well; return zero if
140
the result doesn't fit in LEN bytes. */
142
putsize(char *data, apr_size_t len, apr_size_t value)
146
/* Generate the digits, least-significant first. */
152
data[i] = (value % 10) + '0';
158
/* Put the digits in most-significant-first order. */
162
for (left = 0, right = i-1; left < right; left++, right--)
165
data[left] = data[right];
174
142
/* Checking validity of skels. */
175
143
static svn_error_t *
173
is_valid_iproplist_skel(const svn_skel_t *skel)
175
int len = svn_skel__list_length(skel);
177
if ((len >= 0) && (len & 1) == 0)
181
for (elt = skel->children; elt; elt = elt->next)
186
if (elt->next == NULL)
191
if (! is_valid_proplist_skel(elt))
205
202
static svn_skel_t *parse(const char *data, apr_size_t len,
206
203
apr_pool_t *pool);
402
399
static apr_size_t estimate_unparsed_size(const svn_skel_t *skel);
403
400
static svn_stringbuf_t *unparse(const svn_skel_t *skel,
404
svn_stringbuf_t *str,
401
svn_stringbuf_t *str);
408
404
svn_stringbuf_t *
409
405
svn_skel__unparse(const svn_skel_t *skel, apr_pool_t *pool)
411
svn_stringbuf_t *str;
413
/* Allocate a string to hold the data. */
414
str = apr_palloc(pool, sizeof(*str));
416
str->blocksize = estimate_unparsed_size(skel) + 200;
417
str->data = apr_palloc(pool, str->blocksize);
420
return unparse(skel, str, pool);
408
= svn_stringbuf_create_ensure(estimate_unparsed_size(skel) + 200, pool);
410
return unparse(skel, str);
489
/* Append the concrete representation of SKEL to the string STR.
490
Grow S with new space from POOL as necessary. */
479
/* Append the concrete representation of SKEL to the string STR. */
491
480
static svn_stringbuf_t *
492
unparse(const svn_skel_t *skel, svn_stringbuf_t *str, apr_pool_t *pool)
481
unparse(const svn_skel_t *skel, svn_stringbuf_t *str)
494
483
if (skel->is_atom)
498
487
svn_stringbuf_appendbytes(str, skel->data, skel->len);
501
/* Append the length to STR. */
490
/* Append the length to STR. Ensure enough space for at least
492
char buf[200 + SVN_INT64_BUFFER_SIZE];
493
apr_size_t length_len;
505
length_len = putsize(buf, sizeof(buf), skel->len);
495
length_len = svn__ui64toa(buf, skel->len);
507
497
SVN_ERR_ASSERT_NO_RETURN(length_len > 0);
510
500
atom's contents. */
511
501
svn_stringbuf_ensure(str, str->len + length_len + 1 + skel->len);
512
502
svn_stringbuf_appendbytes(str, buf, length_len);
513
str->data[str->len++] = ' ';
503
svn_stringbuf_appendbyte(str, ' ');
514
504
svn_stringbuf_appendbytes(str, skel->data, skel->len);
519
/* Append a list to STR. */
509
/* Append a list to STR: an opening parenthesis, the list elements
510
* separated by a space, and a closing parenthesis. */
520
511
svn_skel_t *child;
522
/* Emit an opening parenthesis. */
523
svn_stringbuf_ensure(str, str->len + 1);
524
str->data[str->len++] = '(';
513
svn_stringbuf_appendbyte(str, '(');
526
/* Append each element. Emit a space between each pair of elements. */
527
515
for (child = skel->children; child; child = child->next)
529
unparse(child, str, pool);
532
svn_stringbuf_ensure(str, str->len + 1);
533
str->data[str->len++] = ' ';
519
svn_stringbuf_appendbyte(str, ' ');
537
/* Emit a closing parenthesis. */
538
522
svn_stringbuf_appendbyte(str, ')');
566
svn_skel_t *svn_skel__dup(const svn_skel_t *src_skel, svn_boolean_t dup_data,
567
apr_pool_t *result_pool)
569
svn_skel_t *skel = apr_pmemdup(result_pool, src_skel, sizeof(svn_skel_t));
571
if (dup_data && skel->data)
574
skel->data = apr_pmemdup(result_pool, skel->data, skel->len);
577
/* When creating a skel this would be NULL, 0 for a list.
578
When parsing a string to a skel this might point to real data
579
delimiting the sublist. We don't copy that from here. */
586
skel->children = svn_skel__dup(skel->children, dup_data, result_pool);
589
skel->next = svn_skel__dup(skel->next, dup_data, result_pool);
584
595
svn_skel__prepend(svn_skel_t *skel, svn_skel_t *list_skel)
596
607
svn_skel_t *skel,
597
608
apr_pool_t *result_pool)
599
const char *str = apr_psprintf(result_pool, "%" APR_INT64_T_FMT, value);
610
char *val_string = apr_palloc(result_pool, SVN_INT64_BUFFER_SIZE);
611
svn__i64toa(val_string, value);
601
svn_skel__prepend_str(str, skel, result_pool);
613
svn_skel__prepend_str(val_string, skel, result_pool);
708
720
return SVN_NO_ERROR;
724
svn_skel__parse_iprops(apr_array_header_t **iprops,
725
const svn_skel_t *skel,
726
apr_pool_t *result_pool)
730
/* Validate the skel. */
731
if (! is_valid_iproplist_skel(skel))
732
return skel_err("iprops");
734
/* Create the returned structure */
735
*iprops = apr_array_make(result_pool, 1,
736
sizeof(svn_prop_inherited_item_t *));
738
for (elt = skel->children; elt; elt = elt->next->next)
740
svn_prop_inherited_item_t *new_iprop = apr_palloc(result_pool,
742
svn_string_t *repos_parent = svn_string_ncreate(elt->data, elt->len,
744
SVN_ERR(svn_skel__parse_proplist(&(new_iprop->prop_hash), elt->next,
746
new_iprop->path_or_url = repos_parent->data;
747
APR_ARRAY_PUSH(*iprops, svn_prop_inherited_item_t *) = new_iprop;
713
753
svn_skel__parse_prop(svn_string_t **propval,
780
821
return SVN_NO_ERROR;
825
svn_skel__unparse_iproplist(svn_skel_t **skel_p,
826
const apr_array_header_t *inherited_props,
827
apr_pool_t *result_pool,
828
apr_pool_t *scratch_pool)
830
svn_skel_t *skel = svn_skel__make_empty_list(result_pool);
832
/* Create the skel. */
836
apr_hash_index_t *hi;
838
for (i = 0; i < inherited_props->nelts; i++)
840
svn_prop_inherited_item_t *iprop =
841
APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);
843
svn_skel_t *skel_list = svn_skel__make_empty_list(result_pool);
844
svn_skel_t *skel_atom;
846
/* Loop over hash entries */
847
for (hi = apr_hash_first(scratch_pool, iprop->prop_hash);
849
hi = apr_hash_next(hi))
856
apr_hash_this(hi, &key, &klen, &val);
860
svn_skel__prepend(svn_skel__mem_atom(value->data, value->len,
861
result_pool), skel_list);
864
svn_skel__prepend(svn_skel__mem_atom(key, klen, result_pool),
868
skel_atom = svn_skel__str_atom(
869
apr_pstrdup(result_pool, iprop->path_or_url), result_pool);
870
svn_skel__append(skel, skel_atom);
871
svn_skel__append(skel, skel_list);
875
/* Validate and return the skel. */
876
if (! is_valid_iproplist_skel(skel))
877
return skel_err("iproplist");