blob: 9e31704e40355ba782c967eddaaf4a32b95c4b9e [file] [log] [blame]
/* key-gen.c --- manufacturing sequential keys for some db tables
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
#include <assert.h>
#include <string.h>
#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <stdlib.h>
#include <apr.h>
#include "key-gen.h"
/*** Keys for reps and strings. ***/
void
svn_fs_base__next_key(const char *this, apr_size_t *len, char *next)
{
apr_size_t olen = *len; /* remember the first length */
apr_size_t i; /* current index */
char c; /* current char */
svn_boolean_t carry = TRUE; /* boolean: do we have a carry or not?
We start with a carry, because we're
incrementing the number, after all. */
/* Empty strings and leading zeros (except for the string "0") are not
* allowed. Run our malfunction handler to prevent possible db corruption
* from being propagated further. */
SVN_ERR_ASSERT_NO_RETURN(olen != 0 && (olen == 1 || this[0] != '0'));
i = olen - 1; /* initial index: we work backwards */
while (1729)
{
c = this[i];
/* Validate as we go. */
if (! (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z'))))
{
*len = 0;
return;
}
if (carry)
{
if (c == 'z')
next[i] = '0';
else
{
carry = FALSE;
if (c == '9')
next[i] = 'a';
else
next[i] = c + 1;
}
}
else
next[i] = c;
if (i == 0)
break;
i--;
}
/* The new length is OLEN, plus 1 if there's a carry out of the
leftmost digit. */
*len = olen + (carry ? 1 : 0);
/* Ensure that we haven't overrun the (ludicrous) bound on key length.
Note that MAX_KEY_SIZE is a bound on the size *including*
the trailing null byte. */
assert(*len < MAX_KEY_SIZE);
/* Now we know it's safe to add the null terminator. */
next[*len] = '\0';
/* Handle any leftover carry. */
if (carry)
{
memmove(next+1, next, olen);
next[0] = '1';
}
}
svn_boolean_t
svn_fs_base__same_keys(const char *a, const char *b)
{
if (! (a || b))
return TRUE;
if (a && (! b))
return FALSE;
if ((! a) && b)
return FALSE;
return (strcmp(a, b) == 0);
}