Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
c-utility/src/uuid.c@0:f7f1f0d76dd6, 2018-08-23 (annotated)
- Committer:
- XinZhangMS
- Date:
- Thu Aug 23 06:52:14 2018 +0000
- Revision:
- 0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| XinZhangMS | 0:f7f1f0d76dd6 | 1 | // Copyright (c) Microsoft. All rights reserved. |
| XinZhangMS | 0:f7f1f0d76dd6 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
| XinZhangMS | 0:f7f1f0d76dd6 | 3 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 4 | #include <stdlib.h> |
| XinZhangMS | 0:f7f1f0d76dd6 | 5 | #include <stdio.h> |
| XinZhangMS | 0:f7f1f0d76dd6 | 6 | #include "azure_c_shared_utility/gballoc.h" |
| XinZhangMS | 0:f7f1f0d76dd6 | 7 | #include "azure_c_shared_utility/uuid.h" |
| XinZhangMS | 0:f7f1f0d76dd6 | 8 | #include "azure_c_shared_utility/uniqueid.h" |
| XinZhangMS | 0:f7f1f0d76dd6 | 9 | #include "azure_c_shared_utility/optimize_size.h" |
| XinZhangMS | 0:f7f1f0d76dd6 | 10 | #include "azure_c_shared_utility/xlogging.h" |
| XinZhangMS | 0:f7f1f0d76dd6 | 11 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 12 | #define UUID_STRING_LENGTH 36 |
| XinZhangMS | 0:f7f1f0d76dd6 | 13 | #define UUID_STRING_SIZE (UUID_STRING_LENGTH + 1) |
| XinZhangMS | 0:f7f1f0d76dd6 | 14 | #define __SUCCESS__ 0 |
| XinZhangMS | 0:f7f1f0d76dd6 | 15 | #define UUID_FORMAT_STRING "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" |
| XinZhangMS | 0:f7f1f0d76dd6 | 16 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 17 | int UUID_from_string(const char* uuid_string, UUID* uuid) |
| XinZhangMS | 0:f7f1f0d76dd6 | 18 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 19 | int result; |
| XinZhangMS | 0:f7f1f0d76dd6 | 20 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 21 | // Codes_SRS_UUID_09_007: [ If `uuid_string` or `uuid` are NULL, UUID_from_string shall return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 22 | if (uuid_string == NULL || uuid == NULL) |
| XinZhangMS | 0:f7f1f0d76dd6 | 23 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 24 | LogError("Invalid argument (uuid_string=%p, uuid=%p)", uuid_string, uuid); |
| XinZhangMS | 0:f7f1f0d76dd6 | 25 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 26 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 27 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 28 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 29 | size_t uuid_string_length = strlen(uuid_string); |
| XinZhangMS | 0:f7f1f0d76dd6 | 30 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 31 | if (uuid_string_length != UUID_STRING_LENGTH) |
| XinZhangMS | 0:f7f1f0d76dd6 | 32 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 33 | LogError("Unexpected size for an UUID string (%d)", uuid_string_length); |
| XinZhangMS | 0:f7f1f0d76dd6 | 34 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 35 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 36 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 37 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 38 | // Codes_SRS_UUID_09_008: [ Each pair of digits in `uuid_string`, excluding dashes, shall be read as a single HEX value and saved on the respective position in `uuid` ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 39 | size_t i, j; |
| XinZhangMS | 0:f7f1f0d76dd6 | 40 | unsigned char* uuid_bytes; |
| XinZhangMS | 0:f7f1f0d76dd6 | 41 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 42 | uuid_bytes = (unsigned char*)uuid; |
| XinZhangMS | 0:f7f1f0d76dd6 | 43 | // Codes_SRS_UUID_09_010: [ If no failures occur, UUID_from_string shall return zero ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 44 | result = __SUCCESS__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 45 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 46 | for (i = 0, j = 0; i < uuid_string_length; ) |
| XinZhangMS | 0:f7f1f0d76dd6 | 47 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 48 | if (uuid_string[i] == '-') |
| XinZhangMS | 0:f7f1f0d76dd6 | 49 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 50 | i++; |
| XinZhangMS | 0:f7f1f0d76dd6 | 51 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 52 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 53 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 54 | char double_hex_digit[3] = { 0, 0, 0 }; |
| XinZhangMS | 0:f7f1f0d76dd6 | 55 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 56 | (void)memcpy(double_hex_digit, uuid_string + i, 2); |
| XinZhangMS | 0:f7f1f0d76dd6 | 57 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 58 | if (sscanf(double_hex_digit, "%02hhx", uuid_bytes + j) != 1) |
| XinZhangMS | 0:f7f1f0d76dd6 | 59 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 60 | // Codes_SRS_UUID_09_009: [ If `uuid` fails to be generated, UUID_from_string shall return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 61 | LogError("Failed decoding UUID string (%d)", i); |
| XinZhangMS | 0:f7f1f0d76dd6 | 62 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 63 | break; |
| XinZhangMS | 0:f7f1f0d76dd6 | 64 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 65 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 66 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 67 | i += 2; |
| XinZhangMS | 0:f7f1f0d76dd6 | 68 | j++; |
| XinZhangMS | 0:f7f1f0d76dd6 | 69 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 70 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 71 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 72 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 73 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 74 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 75 | return result; |
| XinZhangMS | 0:f7f1f0d76dd6 | 76 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 77 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 78 | char* UUID_to_string(UUID* uuid) |
| XinZhangMS | 0:f7f1f0d76dd6 | 79 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 80 | char* result; |
| XinZhangMS | 0:f7f1f0d76dd6 | 81 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 82 | // Codes_SRS_UUID_09_011: [ If `uuid` is NULL, UUID_to_string shall return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 83 | if (uuid == NULL) |
| XinZhangMS | 0:f7f1f0d76dd6 | 84 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 85 | LogError("Invalid argument (uuid is NULL)"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 86 | result = NULL; |
| XinZhangMS | 0:f7f1f0d76dd6 | 87 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 88 | // Codes_SRS_UUID_09_012: [ UUID_to_string shall allocate a valid UUID string (`uuid_string`) as per RFC 4122 ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 89 | else if ((result = (char*)malloc(sizeof(char) * UUID_STRING_SIZE)) == NULL) |
| XinZhangMS | 0:f7f1f0d76dd6 | 90 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 91 | // Codes_SRS_UUID_09_013: [ If `uuid_string` fails to be allocated, UUID_to_string shall return NULL ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 92 | LogError("Failed allocating UUID string"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 93 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 94 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 95 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 96 | unsigned char* uuid_bytes; |
| XinZhangMS | 0:f7f1f0d76dd6 | 97 | int number_of_chars_written; |
| XinZhangMS | 0:f7f1f0d76dd6 | 98 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 99 | uuid_bytes = (unsigned char*)uuid; |
| XinZhangMS | 0:f7f1f0d76dd6 | 100 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 101 | // Codes_SRS_UUID_09_014: [ Each character in `uuid` shall be written in the respective positions of `uuid_string` as a 2-digit HEX value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 102 | number_of_chars_written = sprintf(result, UUID_FORMAT_STRING, |
| XinZhangMS | 0:f7f1f0d76dd6 | 103 | uuid_bytes[0], uuid_bytes[1], uuid_bytes[2], uuid_bytes[3], |
| XinZhangMS | 0:f7f1f0d76dd6 | 104 | uuid_bytes[4], uuid_bytes[5], |
| XinZhangMS | 0:f7f1f0d76dd6 | 105 | uuid_bytes[6], uuid_bytes[7], |
| XinZhangMS | 0:f7f1f0d76dd6 | 106 | uuid_bytes[8], uuid_bytes[9], |
| XinZhangMS | 0:f7f1f0d76dd6 | 107 | uuid_bytes[10], uuid_bytes[11], uuid_bytes[12], uuid_bytes[13], uuid_bytes[14], uuid_bytes[15]); |
| XinZhangMS | 0:f7f1f0d76dd6 | 108 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 109 | if (number_of_chars_written != UUID_STRING_LENGTH) |
| XinZhangMS | 0:f7f1f0d76dd6 | 110 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 111 | // Tests_SRS_UUID_09_015: [ If `uuid_string` fails to be set, UUID_to_string shall return NULL ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 112 | LogError("Failed encoding UUID string"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 113 | free(result); |
| XinZhangMS | 0:f7f1f0d76dd6 | 114 | result = NULL; |
| XinZhangMS | 0:f7f1f0d76dd6 | 115 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 116 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 117 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 118 | // Codes_SRS_UUID_09_016: [ If no failures occur, UUID_to_string shall return `uuid_string` ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 119 | return result; |
| XinZhangMS | 0:f7f1f0d76dd6 | 120 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 121 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 122 | int UUID_generate(UUID* uuid) |
| XinZhangMS | 0:f7f1f0d76dd6 | 123 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 124 | int result; |
| XinZhangMS | 0:f7f1f0d76dd6 | 125 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 126 | // Codes_SRS_UUID_09_001: [ If `uuid` is NULL, UUID_generate shall return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 127 | if (uuid == NULL) |
| XinZhangMS | 0:f7f1f0d76dd6 | 128 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 129 | LogError("Invalid argument (uuid is NULL)"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 130 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 131 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 132 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 133 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 134 | char* uuid_string; |
| XinZhangMS | 0:f7f1f0d76dd6 | 135 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 136 | if ((uuid_string = (char*)malloc(sizeof(char) * UUID_STRING_SIZE)) == NULL) |
| XinZhangMS | 0:f7f1f0d76dd6 | 137 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 138 | // Codes_SRS_UUID_09_003: [ If the UUID string fails to be obtained, UUID_generate shall fail and return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 139 | LogError("Failed allocating UUID string"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 140 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 141 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 142 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 143 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 144 | memset(uuid_string, 0, sizeof(char) * UUID_STRING_SIZE); |
| XinZhangMS | 0:f7f1f0d76dd6 | 145 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 146 | // Codes_SRS_UUID_09_002: [ UUID_generate shall obtain an UUID string from UniqueId_Generate ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 147 | if (UniqueId_Generate(uuid_string, UUID_STRING_SIZE) != UNIQUEID_OK) |
| XinZhangMS | 0:f7f1f0d76dd6 | 148 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 149 | // Codes_SRS_UUID_09_003: [ If the UUID string fails to be obtained, UUID_generate shall fail and return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 150 | LogError("Failed generating UUID"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 151 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 152 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 153 | // Codes_SRS_UUID_09_004: [ The UUID string shall be parsed into an UUID type (16 unsigned char array) and filled in `uuid` ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 154 | else if (UUID_from_string(uuid_string, uuid) != 0) |
| XinZhangMS | 0:f7f1f0d76dd6 | 155 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 156 | // Codes_SRS_UUID_09_005: [ If `uuid` fails to be set, UUID_generate shall fail and return a non-zero value ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 157 | LogError("Failed parsing UUID string"); |
| XinZhangMS | 0:f7f1f0d76dd6 | 158 | result = __FAILURE__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 159 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 160 | else |
| XinZhangMS | 0:f7f1f0d76dd6 | 161 | { |
| XinZhangMS | 0:f7f1f0d76dd6 | 162 | // Codes_SRS_UUID_09_006: [ If no failures occur, UUID_generate shall return zero ] |
| XinZhangMS | 0:f7f1f0d76dd6 | 163 | result = __SUCCESS__; |
| XinZhangMS | 0:f7f1f0d76dd6 | 164 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 165 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 166 | free(uuid_string); |
| XinZhangMS | 0:f7f1f0d76dd6 | 167 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 168 | } |
| XinZhangMS | 0:f7f1f0d76dd6 | 169 | |
| XinZhangMS | 0:f7f1f0d76dd6 | 170 | return result; |
| XinZhangMS | 0:f7f1f0d76dd6 | 171 | } |