1251881Speter/* key-gen.c --- manufacturing sequential keys for some db tables 2251881Speter * 3251881Speter * ==================================================================== 4251881Speter * Licensed to the Apache Software Foundation (ASF) under one 5251881Speter * or more contributor license agreements. See the NOTICE file 6251881Speter * distributed with this work for additional information 7251881Speter * regarding copyright ownership. The ASF licenses this file 8251881Speter * to you under the Apache License, Version 2.0 (the 9251881Speter * "License"); you may not use this file except in compliance 10251881Speter * with the License. You may obtain a copy of the License at 11251881Speter * 12251881Speter * http://www.apache.org/licenses/LICENSE-2.0 13251881Speter * 14251881Speter * Unless required by applicable law or agreed to in writing, 15251881Speter * software distributed under the License is distributed on an 16251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17251881Speter * KIND, either express or implied. See the License for the 18251881Speter * specific language governing permissions and limitations 19251881Speter * under the License. 20251881Speter * ==================================================================== 21251881Speter */ 22251881Speter 23251881Speter#include <assert.h> 24251881Speter#include <string.h> 25251881Speter 26251881Speter#define APR_WANT_STRFUNC 27251881Speter#include <apr_want.h> 28251881Speter#include <stdlib.h> 29251881Speter#include <apr.h> 30251881Speter 31251881Speter#include "key-gen.h" 32251881Speter 33251881Speter 34251881Speter 35251881Speter/*** Keys for reps and strings. ***/ 36251881Speter 37251881Speter 38251881Spetervoid 39251881Spetersvn_fs_base__next_key(const char *this, apr_size_t *len, char *next) 40251881Speter{ 41251881Speter apr_size_t olen = *len; /* remember the first length */ 42251881Speter int i = olen - 1; /* initial index; we work backwards */ 43251881Speter char c; /* current char */ 44251881Speter svn_boolean_t carry = TRUE; /* boolean: do we have a carry or not? 45251881Speter We start with a carry, because we're 46251881Speter incrementing the number, after all. */ 47251881Speter 48251881Speter /* Leading zeros are not allowed, except for the string "0". */ 49251881Speter if ((*len > 1) && (this[0] == '0')) 50251881Speter { 51251881Speter *len = 0; 52251881Speter return; 53251881Speter } 54251881Speter 55251881Speter for (i = (olen - 1); i >= 0; i--) 56251881Speter { 57251881Speter c = this[i]; 58251881Speter 59251881Speter /* Validate as we go. */ 60251881Speter if (! (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z')))) 61251881Speter { 62251881Speter *len = 0; 63251881Speter return; 64251881Speter } 65251881Speter 66251881Speter if (carry) 67251881Speter { 68251881Speter if (c == 'z') 69251881Speter next[i] = '0'; 70251881Speter else 71251881Speter { 72251881Speter carry = FALSE; 73251881Speter 74251881Speter if (c == '9') 75251881Speter next[i] = 'a'; 76251881Speter else 77251881Speter next[i] = c + 1; 78251881Speter } 79251881Speter } 80251881Speter else 81251881Speter next[i] = c; 82251881Speter } 83251881Speter 84251881Speter /* The new length is OLEN, plus 1 if there's a carry out of the 85251881Speter leftmost digit. */ 86251881Speter *len = olen + (carry ? 1 : 0); 87251881Speter 88251881Speter /* Ensure that we haven't overrun the (ludicrous) bound on key length. 89251881Speter Note that MAX_KEY_SIZE is a bound on the size *including* 90251881Speter the trailing null byte. */ 91251881Speter assert(*len < MAX_KEY_SIZE); 92251881Speter 93251881Speter /* Now we know it's safe to add the null terminator. */ 94251881Speter next[*len] = '\0'; 95251881Speter 96251881Speter /* Handle any leftover carry. */ 97251881Speter if (carry) 98251881Speter { 99251881Speter memmove(next+1, next, olen); 100251881Speter next[0] = '1'; 101251881Speter } 102251881Speter} 103251881Speter 104251881Speter 105251881Speterint 106251881Spetersvn_fs_base__key_compare(const char *a, const char *b) 107251881Speter{ 108251881Speter int a_len = strlen(a); 109251881Speter int b_len = strlen(b); 110251881Speter int cmp; 111251881Speter 112251881Speter if (a_len > b_len) 113251881Speter return 1; 114251881Speter if (b_len > a_len) 115251881Speter return -1; 116251881Speter cmp = strcmp(a, b); 117251881Speter return (cmp ? (cmp / abs(cmp)) : 0); 118251881Speter} 119251881Speter 120251881Speter 121251881Spetersvn_boolean_t 122251881Spetersvn_fs_base__same_keys(const char *a, const char *b) 123251881Speter{ 124251881Speter if (! (a || b)) 125251881Speter return TRUE; 126251881Speter if (a && (! b)) 127251881Speter return FALSE; 128251881Speter if ((! a) && b) 129251881Speter return FALSE; 130251881Speter return (strcmp(a, b) == 0); 131251881Speter} 132