1/*
2 * Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15#include <aws/common/uuid.h>
16
17#include <aws/common/byte_buf.h>
18#include <aws/common/device_random.h>
19
20#include <inttypes.h>
21#include <stdio.h>
22
23#define HEX_CHAR_FMT "%02" SCNx8
24
25#define UUID_FORMAT \
26 HEX_CHAR_FMT HEX_CHAR_FMT HEX_CHAR_FMT HEX_CHAR_FMT \
27 "-" HEX_CHAR_FMT HEX_CHAR_FMT "-" HEX_CHAR_FMT HEX_CHAR_FMT "-" HEX_CHAR_FMT HEX_CHAR_FMT \
28 "-" HEX_CHAR_FMT HEX_CHAR_FMT HEX_CHAR_FMT HEX_CHAR_FMT HEX_CHAR_FMT HEX_CHAR_FMT
29
30#include <stdio.h>
31
32#ifdef _MSC_VER
33/* disables warning non const declared initializers for Microsoft compilers */
34# pragma warning(disable : 4204)
35# pragma warning(disable : 4706)
36/* sprintf warning (we already check the bounds in this case). */
37# pragma warning(disable : 4996)
38#endif
39
40int aws_uuid_init(struct aws_uuid *uuid) {
41 struct aws_byte_buf buf = aws_byte_buf_from_empty_array(uuid->uuid_data, sizeof(uuid->uuid_data));
42
43 return aws_device_random_buffer(&buf);
44}
45
46int aws_uuid_init_from_str(struct aws_uuid *uuid, const struct aws_byte_cursor *uuid_str) {
47 AWS_ERROR_PRECONDITION(uuid_str->len >= AWS_UUID_STR_LEN - 1, AWS_ERROR_INVALID_BUFFER_SIZE);
48
49 char cpy[AWS_UUID_STR_LEN] = {0};
50 memcpy(cpy, uuid_str->ptr, AWS_UUID_STR_LEN - 1);
51
52 AWS_ZERO_STRUCT(*uuid);
53
54 if (16 != sscanf(
55 cpy,
56 UUID_FORMAT,
57 &uuid->uuid_data[0],
58 &uuid->uuid_data[1],
59 &uuid->uuid_data[2],
60 &uuid->uuid_data[3],
61 &uuid->uuid_data[4],
62 &uuid->uuid_data[5],
63 &uuid->uuid_data[6],
64 &uuid->uuid_data[7],
65 &uuid->uuid_data[8],
66 &uuid->uuid_data[9],
67 &uuid->uuid_data[10],
68 &uuid->uuid_data[11],
69 &uuid->uuid_data[12],
70 &uuid->uuid_data[13],
71 &uuid->uuid_data[14],
72 &uuid->uuid_data[15])) {
73 return aws_raise_error(AWS_ERROR_MALFORMED_INPUT_STRING);
74 }
75
76 return AWS_OP_SUCCESS;
77}
78
79int aws_uuid_to_str(const struct aws_uuid *uuid, struct aws_byte_buf *output) {
80 AWS_ERROR_PRECONDITION(output->capacity - output->len >= AWS_UUID_STR_LEN, AWS_ERROR_SHORT_BUFFER);
81
82 sprintf(
83 (char *)(output->buffer + output->len),
84 UUID_FORMAT,
85 uuid->uuid_data[0],
86 uuid->uuid_data[1],
87 uuid->uuid_data[2],
88 uuid->uuid_data[3],
89 uuid->uuid_data[4],
90 uuid->uuid_data[5],
91 uuid->uuid_data[6],
92 uuid->uuid_data[7],
93 uuid->uuid_data[8],
94 uuid->uuid_data[9],
95 uuid->uuid_data[10],
96 uuid->uuid_data[11],
97 uuid->uuid_data[12],
98 uuid->uuid_data[13],
99 uuid->uuid_data[14],
100 uuid->uuid_data[15]);
101
102 output->len += AWS_UUID_STR_LEN - 1;
103
104 return AWS_OP_SUCCESS;
105}
106
107bool aws_uuid_equals(const struct aws_uuid *a, const struct aws_uuid *b) {
108 return 0 == memcmp(a->uuid_data, b->uuid_data, sizeof(a->uuid_data));
109}
110