1 /** 2 * @copyright 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 * @endcopyright 22 * 23 * @file svn_string_private.h 24 * @brief Non-public string utility functions. 25 */ 26 27 28 #ifndef SVN_STRING_PRIVATE_H 29 #define SVN_STRING_PRIVATE_H 30 31 #include "svn_string.h" /* for svn_boolean_t, svn_error_t */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif /* __cplusplus */ 36 37 /** 38 * @defgroup svn_string String handling 39 * @{ 40 */ 41 42 43 /** Private functions. 44 * 45 * @defgroup svn_string_private Private functions 46 * @{ 47 */ 48 49 50 /** A self-contained memory buffer of known size. 51 * 52 * Intended to be used where a single variable-sized buffer is needed 53 * within an iteration, a scratch pool is available and we want to 54 * avoid the cost of creating another pool just for the iteration. 55 */ 56 typedef struct svn_membuf_t 57 { 58 /** The a pool from which this buffer was originally allocated, and is not 59 * necessarily specific to this buffer. This is used only for allocating 60 * more memory from when the buffer needs to grow. 61 */ 62 apr_pool_t *pool; 63 64 /** pointer to the memory */ 65 void *data; 66 67 /** total size of buffer allocated */ 68 apr_size_t size; 69 } svn_membuf_t; 70 71 72 /* Initialize a memory buffer of the given size */ 73 void 74 svn_membuf__create(svn_membuf_t *membuf, apr_size_t size, apr_pool_t *pool); 75 76 /* Ensure that the given memory buffer has at least the given size */ 77 void 78 svn_membuf__ensure(svn_membuf_t *membuf, apr_size_t size); 79 80 /* Resize the given memory buffer, preserving its contents. */ 81 void 82 svn_membuf__resize(svn_membuf_t *membuf, apr_size_t size); 83 84 /* Zero-fill the given memory */ 85 void 86 svn_membuf__zero(svn_membuf_t *membuf); 87 88 /* Zero-fill the given memory buffer up to the smaller of SIZE and the 89 current buffer size. */ 90 void 91 svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size); 92 93 /* Inline implementation of svn_membuf__zero. 94 * Note that PMEMBUF is evaluated only once. 95 */ 96 #define SVN_MEMBUF__ZERO(pmembuf) \ 97 do \ 98 { \ 99 svn_membuf_t *const _m_b_f_ = (pmembuf); \ 100 memset(_m_b_f_->data, 0, _m_b_f_->size); \ 101 } \ 102 while(0) 103 104 /* Inline implementation of svn_membuf__nzero 105 * Note that PMEMBUF and PSIZE are evaluated only once. 106 */ 107 #define SVN_MEMBUF__NZERO(pmembuf, psize) \ 108 do \ 109 { \ 110 svn_membuf_t *const _m_b_f_ = (pmembuf); \ 111 const apr_size_t _s_z_ = (psize); \ 112 if (_s_z_ > _m_b_f_->size) \ 113 memset(_m_b_f_->data, 0, _m_b_f_->size); \ 114 else \ 115 memset(_m_b_f_->data, 0, _s_z_); \ 116 } \ 117 while(0) 118 119 #ifndef SVN_DEBUG 120 /* In non-debug mode, just use these inlie replacements */ 121 #define svn_membuf__zero(B) SVN_MEMBUF__ZERO((B)) 122 #define svn_membuf__nzero(B, S) SVN_MEMBUF__NZERO((B), (S)) 123 #endif 124 125 126 /** Returns the #svn_string_t information contained in the data and 127 * len members of @a strbuf. This is effectively a typecast, converting 128 * @a strbuf into an #svn_string_t. This first will become invalid and must 129 * not be accessed after this function returned. 130 */ 131 svn_string_t * 132 svn_stringbuf__morph_into_string(svn_stringbuf_t *strbuf); 133 134 /** Like apr_strtoff but provided here for backward compatibility 135 * with APR 0.9 */ 136 apr_status_t 137 svn__strtoff(apr_off_t *offset, const char *buf, char **end, int base); 138 139 /** Number of chars needed to represent signed (19 places + sign + NUL) or 140 * unsigned (20 places + NUL) integers as strings. 141 */ 142 #define SVN_INT64_BUFFER_SIZE 21 143 144 /** Writes the @a number as string into @a dest. The latter must provide 145 * space for at least #SVN_INT64_BUFFER_SIZE characters. Returns the number 146 * chars written excluding the terminating NUL. 147 */ 148 apr_size_t 149 svn__ui64toa(char * dest, apr_uint64_t number); 150 151 /** Writes the @a number as string into @a dest. The latter must provide 152 * space for at least #SVN_INT64_BUFFER_SIZE characters. Returns the number 153 * chars written excluding the terminating NUL. 154 */ 155 apr_size_t 156 svn__i64toa(char * dest, apr_int64_t number); 157 158 /** Returns a decimal string for @a number allocated in @a pool. Put in 159 * the @a seperator at each third place. 160 */ 161 char * 162 svn__ui64toa_sep(apr_uint64_t number, char seperator, apr_pool_t *pool); 163 164 /** Returns a decimal string for @a number allocated in @a pool. Put in 165 * the @a seperator at each third place. 166 */ 167 char * 168 svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool); 169 170 /** 171 * Computes the similarity score of STRA and STRB. Returns the ratio 172 * of the length of their longest common subsequence and the average 173 * length of the strings, normalized to the range [0..1000]. 174 * The result is equivalent to Python's 175 * 176 * difflib.SequenceMatcher.ratio 177 * 178 * Optionally sets *RLCS to the length of the longest common 179 * subsequence of STRA and STRB. Using BUFFER for temporary storage, 180 * requires memory proportional to the length of the shorter string. 181 * 182 * The LCS algorithm used is described in, e.g., 183 * 184 * http://en.wikipedia.org/wiki/Longest_common_subsequence_problem 185 * 186 * Q: Why another LCS when we already have one in libsvn_diff? 187 * A: svn_diff__lcs is too heavyweight and too generic for the 188 * purposes of similarity testing. Whilst it would be possible 189 * to use a character-based tokenizer with it, we really only need 190 * the *length* of the LCS for the similarity score, not all the 191 * other information that svn_diff__lcs produces in order to 192 * make printing diffs possible. 193 * 194 * Q: Is there a limit on the length of the string parameters? 195 * A: Only available memory. But note that the LCS algorithm used 196 * has O(strlen(STRA) * strlen(STRB)) worst-case performance, 197 * so do keep a rein on your enthusiasm. 198 */ 199 unsigned int 200 svn_cstring__similarity(const char *stra, const char *strb, 201 svn_membuf_t *buffer, apr_size_t *rlcs); 202 203 /** 204 * Like svn_cstring__similarity, but accepts svn_string_t's instead 205 * of NUL-terminated character strings. 206 */ 207 unsigned int 208 svn_string__similarity(const svn_string_t *stringa, 209 const svn_string_t *stringb, 210 svn_membuf_t *buffer, apr_size_t *rlcs); 211 212 213 /** @} */ 214 215 /** @} */ 216 217 218 #ifdef __cplusplus 219 } 220 #endif /* __cplusplus */ 221 222 #endif /* SVN_STRING_PRIVATE_H */ 223