You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/07/20 00:03:35 UTC
svn commit: r1505046 - in /subversion/trunk: ./
subversion/include/private/svn_string_private.h
subversion/libsvn_subr/string.c
Author: stefan2
Date: Fri Jul 19 22:03:34 2013
New Revision: 1505046
URL: http://svn.apache.org/r1505046
Log:
Merge revisions r1453590,1454307 from branches/fsfs-format7.
These introduce base36 conversion routines.
Modified:
subversion/trunk/ (props changed)
subversion/trunk/subversion/include/private/svn_string_private.h
subversion/trunk/subversion/libsvn_subr/string.c
Propchange: subversion/trunk/
------------------------------------------------------------------------------
Merged /subversion/branches/fsfs-format7:r1453590,1454307
Modified: subversion/trunk/subversion/include/private/svn_string_private.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_string_private.h?rev=1505046&r1=1505045&r2=1505046&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_string_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_string_private.h Fri Jul 19 22:03:34 2013
@@ -175,6 +175,32 @@ svn__ui64toa_sep(apr_uint64_t number, ch
char *
svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool);
+
+/** Writes the @a number as base36-encoded string into @a dest. The latter
+ * must provide space for at least #SVN_INT64_BUFFER_SIZE characters.
+ * Returns the number chars written excluding the terminating NUL.
+ *
+ * @note The actual maximum buffer requirement is much shorter than
+ * #SVN_INT64_BUFFER_SIZE but introducing yet another constant is only
+ * marginally useful and may open the door to security issues when e.g.
+ * switching between base10 and base36 encoding.
+ */
+apr_size_t
+svn__ui64tobase36(char *dest, apr_uint64_t number);
+
+/** Returns the value of the base36 encoded unsigned integer starting at
+ * @a source. If @a next is not NULL, @a *next will be set to the first
+ * position after the integer.
+ *
+ * The data in @a source will be considered part of the number to parse
+ * as long as the characters are within the base36 range. If there are
+ * no such characters to begin with, 0 is returned. Inputs with more than
+ * #SVN_INT64_BUFFER_SIZE digits will not be fully parsed, i.e. the value
+ * of @a *next as well as the return value are undefined.
+ */
+apr_uint64_t
+svn__base36toui64(const char **next, const char *source);
+
/**
* Computes the similarity score of STRA and STRB. Returns the ratio
* of the length of their longest common subsequence and the average
Modified: subversion/trunk/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/string.c?rev=1505046&r1=1505045&r2=1505046&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/string.c (original)
+++ subversion/trunk/subversion/libsvn_subr/string.c Fri Jul 19 22:03:34 2013
@@ -1207,6 +1207,86 @@ svn__i64toa_sep(apr_int64_t number, char
return apr_pstrdup(pool, buffer);
}
+apr_size_t
+svn__ui64tobase36(char *dest, apr_uint64_t value)
+{
+ char *dest_start = dest;
+ if (value < 10)
+ {
+ /* pretty frequent and trivial case. Make it fast. */
+ *(dest++) = (char)(value) + '0';
+ }
+ else
+ {
+ char buffer[SVN_INT64_BUFFER_SIZE];
+ char *p = buffer;
+
+ /* write result as little-endian to buffer */
+ while (value > 0)
+ {
+ char c = (char)(value % 36);
+ value /= 36;
+
+ *p = (c <= 9) ? (c + '0') : (c - 10 + 'a');
+ ++p;
+ }
+
+ /* copy as big-endian to DEST */
+ while (p > buffer)
+ *(dest++) = *(--p);
+ }
+
+ *dest = '\0';
+ return dest - dest_start;
+}
+
+apr_uint64_t
+svn__base36toui64(const char **next, const char *source)
+{
+ apr_uint64_t result = 0;
+ apr_uint64_t factor = 1;
+ int i = 0;
+ char digits[SVN_INT64_BUFFER_SIZE];
+
+ /* convert digits to numerical values and count the number of places.
+ * Also, prevent buffer overflow. */
+ while (i < sizeof(digits))
+ {
+ char c = *source;
+ if (c < 'a')
+ {
+ /* includes detection of NUL terminator */
+ if (c < '0' || c > '9')
+ break;
+
+ c -= '0';
+ }
+ else
+ {
+ if (c < 'a' || c > 'z')
+ break;
+
+ c -= 'a' - 10;
+ }
+
+ digits[i++] = c;
+ source++;
+ }
+
+ /* fold digits into the result */
+ while (i > 0)
+ {
+ result += factor * (apr_uint64_t)digits[--i];
+ factor *= 36;
+ }
+
+ if (next)
+ *next = source;
+
+ return result;
+}
+
+
unsigned int
svn_cstring__similarity(const char *stra, const char *strb,
svn_membuf_t *buffer, apr_size_t *rlcs)
Re: svn commit: r1505046 - in /subversion/trunk: ./
subversion/include/private/svn_string_private.h subversion/libsvn_subr/string.c
Posted by Ivan Zhakov <iv...@visualsvn.com>.
On Sat, Jul 20, 2013 at 2:03 AM, <st...@apache.org> wrote:
> Author: stefan2
> Date: Fri Jul 19 22:03:34 2013
> New Revision: 1505046
>
> URL: http://svn.apache.org/r1505046
> Log:
> Merge revisions r1453590,1454307 from branches/fsfs-format7.
> These introduce base36 conversion routines.
>
> Modified:
> subversion/trunk/ (props changed)
> subversion/trunk/subversion/include/private/svn_string_private.h
> subversion/trunk/subversion/libsvn_subr/string.c
>
> Propchange: subversion/trunk/
> ------------------------------------------------------------------------------
> Merged /subversion/branches/fsfs-format7:r1453590,1454307
>
> Modified: subversion/trunk/subversion/include/private/svn_string_private.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_string_private.h?rev=1505046&r1=1505045&r2=1505046&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/include/private/svn_string_private.h (original)
> +++ subversion/trunk/subversion/include/private/svn_string_private.h Fri Jul 19 22:03:34 2013
> @@ -175,6 +175,32 @@ svn__ui64toa_sep(apr_uint64_t number, ch
> char *
> svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool);
>
> +
> +/** Writes the @a number as base36-encoded string into @a dest. The latter
> + * must provide space for at least #SVN_INT64_BUFFER_SIZE characters.
> + * Returns the number chars written excluding the terminating NUL.
> + *
> + * @note The actual maximum buffer requirement is much shorter than
> + * #SVN_INT64_BUFFER_SIZE but introducing yet another constant is only
> + * marginally useful and may open the door to security issues when e.g.
> + * switching between base10 and base36 encoding.
> + */
> +apr_size_t
> +svn__ui64tobase36(char *dest, apr_uint64_t number);
> +
> +/** Returns the value of the base36 encoded unsigned integer starting at
> + * @a source. If @a next is not NULL, @a *next will be set to the first
> + * position after the integer.
> + *
> + * The data in @a source will be considered part of the number to parse
> + * as long as the characters are within the base36 range. If there are
> + * no such characters to begin with, 0 is returned. Inputs with more than
> + * #SVN_INT64_BUFFER_SIZE digits will not be fully parsed, i.e. the value
> + * of @a *next as well as the return value are undefined.
> + */
> +apr_uint64_t
> +svn__base36toui64(const char **next, const char *source);
> +
Hi Stefan,
Simple tests would be useful IMHO.
--
Ivan Zhakov