uuid.c revision 256281
125689Sjkh/* Licensed to the Apache Software Foundation (ASF) under one or more
225689Sjkh * contributor license agreements.  See the NOTICE file distributed with
325689Sjkh * this work for additional information regarding copyright ownership.
425689Sjkh * The ASF licenses this file to You under the Apache License, Version 2.0
525689Sjkh * (the "License"); you may not use this file except in compliance with
625689Sjkh * the License.  You may obtain a copy of the License at
725689Sjkh *
825689Sjkh *     http://www.apache.org/licenses/LICENSE-2.0
925689Sjkh *
1025689Sjkh * Unless required by applicable law or agreed to in writing, software
1125689Sjkh * distributed under the License is distributed on an "AS IS" BASIS,
1225689Sjkh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1325689Sjkh * See the License for the specific language governing permissions and
1414408Sjkh * limitations under the License.
1514408Sjkh */
1614408Sjkh
1714408Sjkh#include <stdio.h>      /* for sprintf */
1814408Sjkh
1914408Sjkh#include "apr.h"
2014408Sjkh#include "apr_uuid.h"
2114408Sjkh#include "apr_errno.h"
2214408Sjkh#include "apr_lib.h"
2314408Sjkh
2414408Sjkh
2514408SjkhAPU_DECLARE(void) apr_uuid_format(char *buffer, const apr_uuid_t *uuid)
2614408Sjkh{
2714408Sjkh    const unsigned char *d = uuid->data;
2814408Sjkh
2914408Sjkh    sprintf(buffer,
3038140Syokota            "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
3114408Sjkh            d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
3214408Sjkh            d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
3314408Sjkh}
3414408Sjkh
3514408Sjkh/* convert a pair of hex digits to an integer value [0,255] */
3614408Sjkh#if 'A' == 65
3714408Sjkhstatic unsigned char parse_hexpair(const char *s)
3814408Sjkh{
3914408Sjkh    int result;
4014408Sjkh    int temp;
4114408Sjkh
4214408Sjkh    result = s[0] - '0';
4314408Sjkh    if (result > 48)
4414408Sjkh	result = (result - 39) << 4;
4514408Sjkh    else if (result > 16)
4614408Sjkh	result = (result - 7) << 4;
4714408Sjkh    else
4814408Sjkh	result = result << 4;
4914408Sjkh
5014408Sjkh    temp = s[1] - '0';
5114408Sjkh    if (temp > 48)
5214408Sjkh	result |= temp - 39;
5314408Sjkh    else if (temp > 16)
5414408Sjkh	result |= temp - 7;
5514408Sjkh    else
5614408Sjkh	result |= temp;
5714408Sjkh
5814408Sjkh    return (unsigned char)result;
5914408Sjkh}
6014408Sjkh#else
6114408Sjkhstatic unsigned char parse_hexpair(const char *s)
6214408Sjkh{
6314408Sjkh    int result;
6414408Sjkh
6514408Sjkh    if (isdigit(*s)) {
6614408Sjkh        result = (*s - '0') << 4;
6714408Sjkh    }
6814408Sjkh    else {
6914408Sjkh        if (isupper(*s)) {
7014408Sjkh            result = (*s - 'A' + 10) << 4;
7114408Sjkh        }
7214408Sjkh        else {
7343334Syokota            result = (*s - 'a' + 10) << 4;
7414408Sjkh        }
7532822Syokota    }
7614408Sjkh
7714408Sjkh    ++s;
7814408Sjkh    if (isdigit(*s)) {
7914408Sjkh        result |= (*s - '0');
8014408Sjkh    }
8114408Sjkh    else {
8214408Sjkh        if (isupper(*s)) {
8314408Sjkh            result |= (*s - 'A' + 10);
8414408Sjkh        }
8514408Sjkh        else {
8614408Sjkh            result |= (*s - 'a' + 10);
8714408Sjkh        }
8814408Sjkh    }
8914408Sjkh
9014408Sjkh    return (unsigned char)result;
9114408Sjkh}
9214408Sjkh#endif
9314408Sjkh
9414408SjkhAPU_DECLARE(apr_status_t) apr_uuid_parse(apr_uuid_t *uuid,
9514408Sjkh                                         const char *uuid_str)
9614408Sjkh{
9714408Sjkh    int i;
9814408Sjkh    unsigned char *d = uuid->data;
9914408Sjkh
10014408Sjkh    for (i = 0; i < 36; ++i) {
10114408Sjkh	char c = uuid_str[i];
10214408Sjkh	if (!apr_isxdigit(c) &&
10314408Sjkh	    !(c == '-' && (i == 8 || i == 13 || i == 18 || i == 23)))
10414408Sjkh            /* ### need a better value */
10514408Sjkh	    return APR_BADARG;
10614408Sjkh    }
10718194Ssos    if (uuid_str[36] != '\0') {
10814408Sjkh        /* ### need a better value */
10914408Sjkh	return APR_BADARG;
11043334Syokota    }
11114408Sjkh
11214408Sjkh    d[0] = parse_hexpair(&uuid_str[0]);
11314408Sjkh    d[1] = parse_hexpair(&uuid_str[2]);
11414408Sjkh    d[2] = parse_hexpair(&uuid_str[4]);
11514408Sjkh    d[3] = parse_hexpair(&uuid_str[6]);
11614408Sjkh
11714408Sjkh    d[4] = parse_hexpair(&uuid_str[9]);
11814408Sjkh    d[5] = parse_hexpair(&uuid_str[11]);
11914408Sjkh
12014408Sjkh    d[6] = parse_hexpair(&uuid_str[14]);
12114408Sjkh    d[7] = parse_hexpair(&uuid_str[16]);
12243334Syokota
12314408Sjkh    d[8] = parse_hexpair(&uuid_str[19]);
12414408Sjkh    d[9] = parse_hexpair(&uuid_str[21]);
12514408Sjkh
12643334Syokota    for (i = 6; i--;)
127	d[10 + i] = parse_hexpair(&uuid_str[i*2+24]);
128
129    return APR_SUCCESS;
130}
131