key-gen.c revision 251886
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 35/*** Keys for reps and strings. ***/ 36 37 38void 39svn_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 105int 106svn_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 121svn_boolean_t 122svn_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} 132