1/* svn_skel.h : interface to `skeleton' functions 2 * 3 * ==================================================================== 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 * ==================================================================== 21 */ 22 23#ifndef SVN_SKEL_H 24#define SVN_SKEL_H 25 26#include <apr_pools.h> 27 28#include "svn_string.h" 29 30#ifdef __cplusplus 31extern "C" { 32#endif /* __cplusplus */ 33 34 35/* What is a skel? */ 36 37/* Subversion needs to read a lot of structured data from database 38 records. Instead of writing a half-dozen parsers and getting lazy 39 about error-checking, we define a reasonably dense, open-ended 40 syntax for strings and lists, and then use that for the concrete 41 representation of files, directories, property lists, etc. This 42 lets us handle all the fussy character-by-character testing and 43 sanity checks all in one place, allowing the users of this library 44 to focus on higher-level consistency. 45 46 A `skeleton' (or `skel') is either an atom, or a list. A list may 47 contain zero or more elements, each of which may be an atom or a 48 list. 49 50 Here's a description of the syntax of a skel: 51 52 A "whitespace" byte is 9, 10, 12, 13, or 32 (ASCII tab, newline, 53 form feed, carriage return, or space). 54 55 A "digit" byte is 48 -- 57 (ASCII digits). 56 57 A "name" byte is 65 -- 90, or 97 -- 122 (ASCII upper- and 58 lower-case characters). 59 60 An atom has one the following two forms: 61 - any string of bytes whose first byte is a name character, and 62 which contains no whitespace characters, bytes 40 (ASCII '(') or 63 bytes 41 (ASCII ')') (`implicit-length form'), or 64 - a string of digit bytes, followed by exactly one whitespace 65 character, followed by N bytes, where N is the value of the digit 66 bytes as a decimal number (`explicit-length form'). 67 68 In the first case, the `contents' of the atom are the entire string 69 of characters. In the second case, the contents of the atom are 70 the N bytes after the count and whitespace. 71 72 A list consists of a byte 40 (ASCII '('), followed by a series of 73 atoms or lists, followed by a byte 41 (ASCII ')'). There may be 74 zero or more whitespace characters after the '(' and before the 75 ')', and between any pair of elements. If two consecutive elements 76 are atoms, they must be separated by at least one whitespace 77 character. */ 78 79 80/* The `skel' structure. */ 81 82/* A structure representing the results of parsing an array of bytes 83 as a skel. */ 84struct svn_skel_t { 85 86 /* True if the string was an atom, false if it was a list. 87 88 If the string is an atom, DATA points to the beginning of its 89 contents, and LEN gives the content length, in bytes. 90 91 If the string is a list, DATA and LEN delimit the entire body of 92 the list. */ 93 svn_boolean_t is_atom; 94 95 const char *data; 96 apr_size_t len; 97 98 /* If the string is a list, CHILDREN is a pointer to a 99 null-terminated linked list of skel objects representing the 100 elements of the list, linked through their NEXT pointers. */ 101 struct svn_skel_t *children; 102 struct svn_skel_t *next; 103}; 104typedef struct svn_skel_t svn_skel_t; 105 106 107 108/* Operations on skels. */ 109 110 111/* Parse the LEN bytes at DATA as the concrete representation of a 112 skel, and return a skel object allocated from POOL describing its 113 contents. If the data is not a properly-formed SKEL object, return 114 zero. 115 116 The returned skel objects point into the block indicated by DATA 117 and LEN; we don't copy the contents. */ 118svn_skel_t *svn_skel__parse(const char *data, apr_size_t len, 119 apr_pool_t *pool); 120 121 122/* Create an atom skel whose contents are the C string STR, allocated 123 from POOL. */ 124svn_skel_t *svn_skel__str_atom(const char *str, apr_pool_t *pool); 125 126 127/* Create an atom skel whose contents are the LEN bytes at ADDR, 128 allocated from POOL. */ 129svn_skel_t *svn_skel__mem_atom(const void *addr, apr_size_t len, 130 apr_pool_t *pool); 131 132 133/* Create an empty list skel, allocated from POOL. */ 134svn_skel_t *svn_skel__make_empty_list(apr_pool_t *pool); 135 136/* Duplicates the skel structure SRC_SKEL and if DUP_DATA is true also the 137 data it references in RESULT_POOL */ 138svn_skel_t *svn_skel__dup(const svn_skel_t *src_skel, svn_boolean_t dup_data, 139 apr_pool_t *result_pool); 140 141 142/* Prepend SKEL to LIST. */ 143void svn_skel__prepend(svn_skel_t *skel, svn_skel_t *list); 144 145 146/* Append SKEL to LIST. Note: this must traverse the LIST, so you 147 generally want to use svn_skel__prepend(). 148 149 NOTE: careful of the argument order here. */ 150void svn_skel__append(svn_skel_t *list, svn_skel_t *skel); 151 152 153/* Create an atom skel whose contents are the string representation 154 of the integer VALUE, allocated in RESULT_POOL, and then prepend 155 it to SKEL. */ 156void svn_skel__prepend_int(apr_int64_t value, 157 svn_skel_t *skel, 158 apr_pool_t *result_pool); 159 160 161/* Create an atom skel (allocated from RESULT_POOL) whose contents refer 162 to the string VALUE, then prepend it to SKEL. 163 164 NOTE: VALUE must have a lifetime *at least* that of RESULT_POOL. This 165 function does NOT copy it into RESULT_POOL. */ 166void svn_skel__prepend_str(const char *value, 167 svn_skel_t *skel, 168 apr_pool_t *result_pool); 169 170 171/* Parse SKEL as an integer and return the result in *N. 172 * SCRATCH_POOL is used for temporary memory. */ 173svn_error_t * 174svn_skel__parse_int(apr_int64_t *n, const svn_skel_t *skel, 175 apr_pool_t *scratch_pool); 176 177 178/* Return a string whose contents are a concrete representation of 179 SKEL. Allocate the string from POOL. */ 180svn_stringbuf_t *svn_skel__unparse(const svn_skel_t *skel, apr_pool_t *pool); 181 182 183/* Return true iff SKEL is an atom whose data is the same as STR. */ 184svn_boolean_t svn_skel__matches_atom(const svn_skel_t *skel, const char *str); 185 186 187/* Return the length of the list skel SKEL. Atoms have a length of -1. */ 188int svn_skel__list_length(const svn_skel_t *skel); 189 190 191/* Parse a `PROPLIST' SKEL into a regular hash of properties, 192 *PROPLIST_P, which has const char * property names, and 193 svn_string_t * values. Use RESULT_POOL for all allocations. */ 194svn_error_t * 195svn_skel__parse_proplist(apr_hash_t **proplist_p, 196 const svn_skel_t *skel, 197 apr_pool_t *result_pool); 198 199/* Parse a `IPROPS' SKEL into a depth-first ordered array of 200 svn_prop_inherited_item_t * structures *IPROPS. Use RESULT_POOL 201 for all allocations. */ 202svn_error_t * 203svn_skel__parse_iprops(apr_array_header_t **iprops, 204 const svn_skel_t *skel, 205 apr_pool_t *result_pool); 206 207/* Parse a `PROPLIST' SKEL looking for PROPNAME. If PROPNAME is found 208 then return its value in *PROVAL, allocated in RESULT_POOL. */ 209svn_error_t * 210svn_skel__parse_prop(svn_string_t **propval, 211 const svn_skel_t *skel, 212 const char *propname, 213 apr_pool_t *result_pool); 214 215/* Unparse a PROPLIST hash (which has const char * property names and 216 svn_string_t * values) into a `PROPLIST' skel *SKEL_P. Use POOL 217 for all allocations. */ 218svn_error_t * 219svn_skel__unparse_proplist(svn_skel_t **skel_p, 220 const apr_hash_t *proplist, 221 apr_pool_t *pool); 222 223/* Unparse INHERITED_PROPS, a depth-first ordered array of 224 svn_prop_inherited_item_t * structures, into a `IPROPS' skel *SKEL_P. 225 Use RESULT_POOL for all allocations. */ 226svn_error_t * 227svn_skel__unparse_iproplist(svn_skel_t **skel_p, 228 const apr_array_header_t *inherited_props, 229 apr_pool_t *result_pool, 230 apr_pool_t *scratch_pool); 231 232#ifdef __cplusplus 233} 234#endif /* __cplusplus */ 235 236#endif /* SVN_SKEL_H */ 237