]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/subversion/subversion/libsvn_fs_base/key-gen.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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   int i = olen - 1;           /* initial index; we work backwards */
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   /* Leading zeros are not allowed, except for the string "0". */
49   if ((*len > 1) && (this[0] == '0'))
50     {
51       *len = 0;
52       return;
53     }
54
55   for (i = (olen - 1); i >= 0; i--)
56     {
57       c = this[i];
58
59       /* Validate as we go. */
60       if (! (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z'))))
61         {
62           *len = 0;
63           return;
64         }
65
66       if (carry)
67         {
68           if (c == 'z')
69             next[i] = '0';
70           else
71             {
72               carry = FALSE;
73
74               if (c == '9')
75                 next[i] = 'a';
76               else
77                 next[i] = c + 1;
78             }
79         }
80       else
81         next[i] = c;
82     }
83
84   /* The new length is OLEN, plus 1 if there's a carry out of the
85      leftmost digit. */
86   *len = olen + (carry ? 1 : 0);
87
88   /* Ensure that we haven't overrun the (ludicrous) bound on key length.
89      Note that MAX_KEY_SIZE is a bound on the size *including*
90      the trailing null byte. */
91   assert(*len < MAX_KEY_SIZE);
92
93   /* Now we know it's safe to add the null terminator. */
94   next[*len] = '\0';
95
96   /* Handle any leftover carry. */
97   if (carry)
98     {
99       memmove(next+1, next, olen);
100       next[0] = '1';
101     }
102 }
103
104
105 int
106 svn_fs_base__key_compare(const char *a, const char *b)
107 {
108   int a_len = strlen(a);
109   int b_len = strlen(b);
110   int cmp;
111
112   if (a_len > b_len)
113     return 1;
114   if (b_len > a_len)
115     return -1;
116   cmp = strcmp(a, b);
117   return (cmp ? (cmp / abs(cmp)) : 0);
118 }
119
120
121 svn_boolean_t
122 svn_fs_base__same_keys(const char *a, const char *b)
123 {
124   if (! (a || b))
125     return TRUE;
126   if (a && (! b))
127     return FALSE;
128   if ((! a) && b)
129     return FALSE;
130   return (strcmp(a, b) == 0);
131 }