| 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 |  | 
| 40 | int 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 |  | 
| 46 | int 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 |  | 
| 79 | int 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 |  | 
| 107 | bool 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 |  |