libc: Add uuid implemenation

specified by OpenGroup here:
https://pubs.opengroup.org/onlinepubs/009629399/toc.htm

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I3bc585e7f4d41f6c2ea70e170276ab0d0399b088
This commit is contained in:
Xiang Xiao 2020-07-21 14:54:28 +08:00 committed by Brennan Ashton
parent 2b7528feae
commit 6c03a4e4d5
12 changed files with 799 additions and 0 deletions

108
include/uuid.h Normal file
View file

@ -0,0 +1,108 @@
/****************************************************************************
* include/uuid.h
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_UUID_H
#define __INCLUDE_UUID_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/types.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Status codes returned by the functions. */
#define uuid_s_ok 0
#define uuid_s_bad_version 1
#define uuid_s_invalid_string_uuid 2
#define uuid_s_no_memory 3
/* Length of a node address (an IEEE 802 address). */
#define UUID_NODE_LEN 6
/* Length of a UUID. */
#define UUID_STR_LEN 36
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/****************************************************************************
* A DCE 1.1 compatible source representation of UUIDs.
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | time_low |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | time_mid | time_hi_and_version |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |clk_seq_hi_res | clk_seq_low | node (0-1) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | node (2-5) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
****************************************************************************/
struct uuid
{
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clock_seq_hi_and_reserved;
uint8_t clock_seq_low;
uint8_t node[UUID_NODE_LEN];
};
typedef struct uuid uuid_t;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#if defined(__cplusplus)
extern "C"
{
#endif
int32_t uuid_compare(const uuid_t *, const uuid_t *, uint32_t *);
void uuid_create(uuid_t *, uint32_t *);
void uuid_create_nil(uuid_t *, uint32_t *);
int32_t uuid_equal(const uuid_t *, const uuid_t *, uint32_t *);
void uuid_from_string(const char *, uuid_t *, uint32_t *);
uint16_t uuid_hash(const uuid_t *, uint32_t *);
int32_t uuid_is_nil(const uuid_t *, uint32_t *);
void uuid_to_string(const uuid_t *, char **, uint32_t *);
void uuid_enc_le(void *, const uuid_t *);
void uuid_dec_le(const void *, uuid_t *);
void uuid_enc_be(void *, const uuid_t *);
void uuid_dec_be(const void *, uuid_t *);
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_UUID_H */

View file

@ -59,6 +59,7 @@ include tls/Make.defs
include uio/Make.defs
include unistd/Make.defs
include userfs/Make.defs
include uuid/Make.defs
include wchar/Make.defs
include wctype/Make.defs
include wqueue/Make.defs

28
libs/libc/uuid/Make.defs Normal file
View file

@ -0,0 +1,28 @@
############################################################################
# libs/libc/uuid/Make.defs
#
# 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.
#
############################################################################
CSRCS += lib_uuid_compare.c lib_uuid_create.c lib_uuid_create_nil.c
CSRCS += lib_uuid_equal.c lib_uuid_from_string.c lib_uuid_hash.c
CSRCS += lib_uuid_is_nil.c lib_uuid_stream.c lib_uuid_to_string.c
# Add the uuid directory to the build
DEPPATH += --dep-path uuid
VPATH += :uuid

View file

@ -0,0 +1,92 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_compare.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Pre-processor definitions
****************************************************************************/
/* A macro used to improve the readability of uuid_compare(). */
#define DIFF_RETURN(a, b, field) \
do \
{ \
if ((a)->field != (b)->field) \
{ \
return (a)->field < (b)->field ? -1 : 1; \
} \
} \
while (0)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_compare
*
* Description:
* Compare two UUIDs.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_compare.htm
*
****************************************************************************/
int32_t uuid_compare(const uuid_t *a, const uuid_t *b, uint32_t *status)
{
if (status != NULL)
{
*status = uuid_s_ok;
}
/* Deal with NULL or equal pointers. */
if (a == b)
{
return 0;
}
if (a == NULL)
{
return uuid_is_nil(b, NULL) ? 0 : -1;
}
if (b == NULL)
{
return uuid_is_nil(a, NULL) ? 0 : 1;
}
/* We have to compare the hard way. */
DIFF_RETURN(a, b, time_low);
DIFF_RETURN(a, b, time_mid);
DIFF_RETURN(a, b, time_hi_and_version);
DIFF_RETURN(a, b, clock_seq_hi_and_reserved);
DIFF_RETURN(a, b, clock_seq_low);
return memcmp(a->node, b->node, sizeof(a->node));
}

View file

@ -0,0 +1,70 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_create.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/random.h>
#include <stdlib.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_create_nil
*
* Description:
* Create an UUID.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_create.htm
*
****************************************************************************/
void uuid_create(uuid_t *u, uint32_t *status)
{
#ifdef CONFIG_CRYPTO_RANDOM_POOL
getrandom(u, sizeof(uuid_t));
#else
unsigned long *beg = (unsigned long *)u;
unsigned long *end = (unsigned long *)(u + 1);
while (beg < end)
{
*beg++ = rand();
}
#endif
u->clock_seq_hi_and_reserved &= ~(1 << 6);
u->clock_seq_hi_and_reserved |= (1 << 7);
u->time_hi_and_version &= ~(1 << 12);
u->time_hi_and_version &= ~(1 << 13);
u->time_hi_and_version |= (1 << 14);
u->time_hi_and_version &= ~(1 << 15);
if (status)
{
*status = uuid_s_ok;
}
}

View file

@ -0,0 +1,51 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_create_nil.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_create_nil
*
* Description:
* Create a nil UUID.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_create_nil.htm
*
****************************************************************************/
void uuid_create_nil(uuid_t *u, uint32_t *status)
{
memset(u, 0, sizeof(*u));
if (status)
{
*status = uuid_s_ok;
}
}

View file

@ -0,0 +1,70 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_equal.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_equal
*
* Description:
* Compare for equality.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_equal.htm
*
****************************************************************************/
int32_t uuid_equal(const uuid_t *a, const uuid_t *b, uint32_t *status)
{
if (status != NULL)
{
*status = uuid_s_ok;
}
/* Deal with equal or NULL pointers. */
if (a == b)
{
return 1;
}
if (a == NULL)
{
return uuid_is_nil(b, NULL);
}
if (b == NULL)
{
return uuid_is_nil(a, NULL);
}
/* Do a byte for byte comparison. */
return !memcmp(a, b, sizeof(uuid_t));
}

View file

@ -0,0 +1,113 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_from_string.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_from_string
*
* Description:
* convert a string representation of an UUID into a binary representation.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_from_string.htm
*
****************************************************************************/
void uuid_from_string(const char *s, uuid_t *u, uint32_t *status)
{
int n;
/* Short-circuit 2 special cases: NULL pointer and empty string. */
if (s == NULL || *s == '\0')
{
uuid_create_nil(u, status);
return;
}
/* Assume the worst. */
if (status != NULL)
{
*status = uuid_s_invalid_string_uuid;
}
/* The UUID string representation has a fixed length. */
if (strnlen(s, UUID_STR_LEN + 1) != UUID_STR_LEN)
{
return;
}
/* We only work with "new" UUIDs. New UUIDs have the form:
* 01234567-89ab-cdef-0123-456789abcdef
* The so called "old" UUIDs, which we don't support, have the form:
* 0123456789ab.cd.ef.01.23.45.67.89.ab
*/
if (s[8] != '-')
{
return;
}
n = sscanf(s,
"%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
&u->time_low, &u->time_mid, &u->time_hi_and_version,
&u->clock_seq_hi_and_reserved, &u->clock_seq_low, &u->node[0],
&u->node[1], &u->node[2], &u->node[3], &u->node[4], &u->node[5]);
/* Make sure we have all conversions. */
if (n != 11)
{
return;
}
/* We have a successful scan. Check semantics... */
n = u->clock_seq_hi_and_reserved;
if ((n & 0x80) != 0x00 && /* variant 0? */
(n & 0xc0) != 0x80 && /* variant 1? */
(n & 0xe0) != 0xc0) /* variant 2? */
{
if (status != NULL)
{
*status = uuid_s_bad_version;
}
}
else
{
if (status != NULL)
{
*status = uuid_s_ok;
}
}
}

View file

@ -0,0 +1,54 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_hash.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_hash
*
* Description:
* Generate a hash value.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_hash.htm
*
****************************************************************************/
uint16_t uuid_hash(const uuid_t *u, uint32_t *status)
{
if (status)
{
*status = uuid_s_ok;
}
/* Use the most frequently changing bits in the UUID as the hash
* value. This should yield a good enough distribution...
*/
return u ? u->time_low & 0xffff : 0;
}

View file

@ -0,0 +1,58 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_is_nil.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name uuid_is_nil()
*
* Description:
* Return whether the UUID is a nil UUID.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_is_nil.htm
*
****************************************************************************/
int32_t uuid_is_nil(const uuid_t *u, uint32_t *status)
{
static const uuid_t nil;
if (status)
{
*status = uuid_s_ok;
}
if (!u)
{
return 1;
}
return memcmp(u, &nil, sizeof(uuid_t)) == 0 ? 1 : 0;
}

View file

@ -0,0 +1,79 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_stream.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <endian.h>
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
void uuid_enc_le(void *buf, const uuid_t *uuid)
{
uuid_t *temp = buf;
memcpy(temp, uuid, sizeof(*uuid));
#if BYTE_ORDER == BIG_ENDIAN
temp->time_low = htole32(temp->time_low);
temp->time_mid = htole16(temp->time_mid);
temp->time_hi_and_version = htole16(temp->time_hi_and_version);
#endif
}
void uuid_dec_le(const void *buf, uuid_t *uuid)
{
const uuid_t *temp = buf;
memcpy(uuid, temp, sizeof(*uuid));
#if BYTE_ORDER == BIG_ENDIAN
uuid->time_low = le32toh(uuid->time_low);
uuid->time_mid = le16toh(uuid->time_mid);
uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version);
#endif
}
void uuid_enc_be(void *buf, const uuid_t *uuid)
{
uuid_t *temp = buf;
memcpy(temp, uuid, sizeof(*uuid));
#if BYTE_ORDER == LITTLE_ENDIAN
temp->time_low = htobe32(temp->time_low);
temp->time_mid = htobe16(temp->time_mid);
temp->time_hi_and_version = htobe16(temp->time_hi_and_version);
#endif
}
void uuid_dec_be(const void *buf, uuid_t *uuid)
{
const uuid_t *temp = buf;
memcpy(uuid, temp, sizeof(*uuid));
#if BYTE_ORDER == LITTLE_ENDIAN
uuid->time_low = be32toh(uuid->time_low);
uuid->time_mid = be16toh(uuid->time_mid);
uuid->time_hi_and_version = be16toh(uuid->time_hi_and_version);
#endif
}

View file

@ -0,0 +1,75 @@
/****************************************************************************
* libs/libc/uuid/lib_uuid_to_string.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <uuid.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* uuid_to_string
*
* Description:
* Convert a binary UUID into a string representation.
*
* See also:
* http://www.opengroup.org/onlinepubs/009629399/uuid_to_string.htm
*
****************************************************************************/
void uuid_to_string(const uuid_t *u, char **s, uint32_t *status)
{
static const uuid_t nil;
int c;
if (status != NULL)
{
*status = uuid_s_ok;
}
/* Why allow a NULL-pointer here? */
if (s == NULL)
{
return;
}
if (u == NULL)
{
u = &nil;
}
c = asprintf(s,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
u->time_low, u->time_mid, u->time_hi_and_version,
u->clock_seq_hi_and_reserved, u->clock_seq_low, u->node[0],
u->node[1], u->node[2], u->node[3], u->node[4], u->node[5]);
if (c == -1 && status != NULL)
{
*status = uuid_s_no_memory;
}
}