]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_fs_base/key-gen.c
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_fs_base / key-gen.c
1 /* key-gen.c --- manufacturing sequential keys for some db tables
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 #include <assert.h>
24 #include <string.h>
25
26 #define APR_WANT_STRFUNC
27 #include <apr_want.h>
28 #include <stdlib.h>
29 #include <apr.h>
30
31 #include "key-gen.h"
32
33
34 \f
35 /*** Keys for reps and strings. ***/
36
37
38 void
39 svn_fs_base__next_key(const char *this, apr_size_t *len, char *next)
40 {
41   apr_size_t olen = *len;     /* remember the first length */
42   apr_size_t i;               /* current index */
43   char c;                     /* current char */
44   svn_boolean_t carry = TRUE; /* boolean: do we have a carry or not?
45                                  We start with a carry, because we're
46                                  incrementing the number, after all. */
47
48   /* Empty strings and leading zeros (except for the string "0") are not
49    * allowed.  Run our malfunction handler to prevent possible db corruption
50    * from being propagated further. */
51   SVN_ERR_ASSERT_NO_RETURN(olen != 0 && (olen == 1 || this[0] != '0'));
52
53   i = olen - 1; /* initial index: we work backwords */
54   while (1729)
55     {
56       c = this[i];
57
58       /* Validate as we go. */
59       if (! (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z'))))
60         {
61           *len = 0;
62           return;
63         }
64
65       if (carry)
66         {
67           if (c == 'z')
68             next[i] = '0';
69           else
70             {
71               carry = FALSE;
72
73               if (c == '9')
74                 next[i] = 'a';
75               else
76                 next[i] = c + 1;
77             }
78         }
79       else
80         next[i] = c;
81
82       if (i == 0)
83         break;
84
85       i--;
86     }
87
88   /* The new length is OLEN, plus 1 if there's a carry out of the
89      leftmost digit. */
90   *len = olen + (carry ? 1 : 0);
91
92   /* Ensure that we haven't overrun the (ludicrous) bound on key length.
93      Note that MAX_KEY_SIZE is a bound on the size *including*
94      the trailing null byte. */
95   assert(*len < MAX_KEY_SIZE);
96
97   /* Now we know it's safe to add the null terminator. */
98   next[*len] = '\0';
99
100   /* Handle any leftover carry. */
101   if (carry)
102     {
103       memmove(next+1, next, olen);
104       next[0] = '1';
105     }
106 }
107
108
109 svn_boolean_t
110 svn_fs_base__same_keys(const char *a, const char *b)
111 {
112   if (! (a || b))
113     return TRUE;
114   if (a && (! b))
115     return FALSE;
116   if ((! a) && b)
117     return FALSE;
118   return (strcmp(a, b) == 0);
119 }