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.
Fork of azure_c_shared_utility by
connection_string_parser.c
00001 // Copyright (c) Microsoft. All rights reserved. 00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 00003 00004 #include "azure_c_shared_utility/connection_string_parser.h" 00005 #include "azure_c_shared_utility/map.h" 00006 #include "azure_c_shared_utility/strings.h" 00007 #include "azure_c_shared_utility/string_tokenizer.h" 00008 #include <stdbool.h> 00009 #include "azure_c_shared_utility/optimize_size.h" 00010 #include "azure_c_shared_utility/xlogging.h" 00011 00012 00013 MAP_HANDLE connectionstringparser_parse_from_char(const char* connection_string) 00014 { 00015 MAP_HANDLE result; 00016 STRING_HANDLE connString = NULL; 00017 00018 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_020: [connectionstringparser_parse_from_char shall create a STRING_HANDLE from the connection_string passed in as argument and parse it using the connectionstringparser_parse.]*/ 00019 if ((connString = STRING_construct(connection_string)) == NULL) 00020 { 00021 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_021: [If connectionstringparser_parse_from_char get error creating a STRING_HANDLE, it shall return NULL.]*/ 00022 LogError("Error constructing connection String"); 00023 result = NULL; 00024 } 00025 else 00026 { 00027 result = connectionstringparser_parse(connString); 00028 STRING_delete(connString); 00029 } 00030 00031 return result; 00032 } 00033 00034 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_001: [connectionstringparser_parse shall parse all key value pairs from the connection_string passed in as argument and return a new map that holds the key/value pairs.] */ 00035 MAP_HANDLE connectionstringparser_parse(STRING_HANDLE connection_string) 00036 { 00037 MAP_HANDLE result; 00038 00039 if (connection_string == NULL) 00040 { 00041 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_002: [If connection_string is NULL then connectionstringparser_parse shall fail and return NULL.] */ 00042 result = NULL; 00043 LogError("NULL connection string passed to tokenizer."); 00044 } 00045 else 00046 { 00047 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_003: [connectionstringparser_parse shall create a STRING tokenizer to be used for parsing the connection string, by calling STRING_TOKENIZER_create.] */ 00048 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_004: [connectionstringparser_parse shall start scanning at the beginning of the connection string.] */ 00049 STRING_TOKENIZER_HANDLE tokenizer = STRING_TOKENIZER_create(connection_string); 00050 if (tokenizer == NULL) 00051 { 00052 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_015: [If STRING_TOKENIZER_create fails, connectionstringparser_parse shall fail and return NULL.] */ 00053 result = NULL; 00054 LogError("Error creating STRING tokenizer."); 00055 } 00056 else 00057 { 00058 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_016: [2 STRINGs shall be allocated in order to hold the to be parsed key and value tokens.] */ 00059 STRING_HANDLE token_key_string = STRING_new(); 00060 if (token_key_string == NULL) 00061 { 00062 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_017: [If allocating the STRINGs fails connectionstringparser_parse shall fail and return NULL.] */ 00063 result = NULL; 00064 LogError("Error creating key token STRING."); 00065 } 00066 else 00067 { 00068 STRING_HANDLE token_value_string = STRING_new(); 00069 if (token_value_string == NULL) 00070 { 00071 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_017: [If allocating the STRINGs fails connectionstringparser_parse shall fail and return NULL.] */ 00072 result = NULL; 00073 LogError("Error creating value token STRING."); 00074 } 00075 else 00076 { 00077 result = Map_Create(NULL); 00078 if (result == NULL) 00079 { 00080 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_018: [If creating the result map fails, then connectionstringparser_parse shall return NULL.] */ 00081 LogError("Error creating Map."); 00082 } 00083 else 00084 { 00085 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_005: [The following actions shall be repeated until parsing is complete:] */ 00086 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_006: [connectionstringparser_parse shall find a token (the key of the key/value pair) delimited by the `=` character, by calling STRING_TOKENIZER_get_next_token.] */ 00087 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_007: [If STRING_TOKENIZER_get_next_token fails, parsing shall be considered complete.] */ 00088 while (STRING_TOKENIZER_get_next_token(tokenizer, token_key_string, "=") == 0) 00089 { 00090 bool is_error = false; 00091 00092 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_008: [connectionstringparser_parse shall find a token (the value of the key/value pair) delimited by the `;` character, by calling STRING_TOKENIZER_get_next_token.] */ 00093 if (STRING_TOKENIZER_get_next_token(tokenizer, token_value_string, ";") != 0) 00094 { 00095 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_009: [If STRING_TOKENIZER_get_next_token fails, connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ 00096 is_error = true; 00097 LogError("Error reading value token from the connection string."); 00098 } 00099 else 00100 { 00101 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_011: [The C strings for the key and value shall be extracted from the previously parsed STRINGs by using STRING_c_str.] */ 00102 const char* token = STRING_c_str(token_key_string); 00103 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_013: [If STRING_c_str fails then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ 00104 if ((token == NULL) || 00105 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_019: [If the key length is zero then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ 00106 (strlen(token) == 0)) 00107 { 00108 is_error = true; 00109 LogError("The key token is NULL or empty."); 00110 } 00111 else 00112 { 00113 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_011: [The C strings for the key and value shall be extracted from the previously parsed STRINGs by using STRING_c_str.] */ 00114 const char* value = STRING_c_str(token_value_string); 00115 if (value == NULL) 00116 { 00117 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_013: [If STRING_c_str fails then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ 00118 is_error = true; 00119 LogError("Could not get C string for value token."); 00120 } 00121 else 00122 { 00123 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_010: [The key and value shall be added to the result map by using Map_Add.] */ 00124 if (Map_Add(result, token, value) != 0) 00125 { 00126 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_012: [If Map_Add fails connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ 00127 is_error = true; 00128 LogError("Could not add the key/value pair to the result map."); 00129 } 00130 } 00131 } 00132 } 00133 00134 if (is_error) 00135 { 00136 LogError("Error parsing connection string."); 00137 Map_Destroy(result); 00138 result = NULL; 00139 break; 00140 } 00141 } 00142 } 00143 00144 STRING_delete(token_value_string); 00145 } 00146 00147 STRING_delete(token_key_string); 00148 } 00149 00150 /* Codes_SRS_CONNECTIONSTRINGPARSER_01_014: [After the parsing is complete the previously allocated STRINGs and STRING tokenizer shall be freed by calling STRING_TOKENIZER_destroy.] */ 00151 STRING_TOKENIZER_destroy(tokenizer); 00152 } 00153 } 00154 00155 return result; 00156 } 00157 00158 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_022: [connectionstringparser_splitHostName_from_char shall split the provided hostName in name and suffix.]*/ 00159 int connectionstringparser_splitHostName_from_char(const char* hostName, STRING_HANDLE nameString, STRING_HANDLE suffixString) 00160 { 00161 int result; 00162 const char* runHostName = hostName; 00163 00164 if ((hostName == NULL) || ((*hostName) == '\0') || ((*hostName) == '.') || (nameString == NULL) || (suffixString == NULL)) 00165 { 00166 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_026: [If the hostName is NULL, connectionstringparser_splitHostName_from_char shall return __FAILURE__.]*/ 00167 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_027: [If the hostName is an empty string, connectionstringparser_splitHostName_from_char shall return __FAILURE__.]*/ 00168 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_028: [If the nameString is NULL, connectionstringparser_splitHostName_from_char shall return __FAILURE__.]*/ 00169 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_029: [If the suffixString is NULL, connectionstringparser_splitHostName_from_char shall return __FAILURE__.]*/ 00170 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_030: [If the hostName is not a valid host name, connectionstringparser_splitHostName_from_char shall return __FAILURE__.]*/ 00171 result = __FAILURE__; 00172 } 00173 else 00174 { 00175 while ((*runHostName) != '\0') 00176 { 00177 if ((*runHostName) == '.') 00178 { 00179 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_023: [connectionstringparser_splitHostName_from_char shall copy all characters, from the beginning of the hostName to the first `.` to the nameString.]*/ 00180 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_024: [connectionstringparser_splitHostName_from_char shall copy all characters, from the first `.` to the end of the hostName, to the suffixString.]*/ 00181 runHostName++; 00182 break; 00183 } 00184 runHostName++; 00185 } 00186 00187 if ((*runHostName) == '\0') 00188 { 00189 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_030: [If the hostName is not a valid host name, connectionstringparser_splitHostName_from_char shall return __FAILURE__.]*/ 00190 result = __FAILURE__; 00191 } 00192 else 00193 { 00194 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_023: [connectionstringparser_splitHostName_from_char shall copy all characters, from the beginning of the hostName to the first `.` to the nameString.]*/ 00195 if (STRING_copy_n(nameString, hostName, runHostName - hostName - 1) != 0) 00196 { 00197 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_031: [If connectionstringparser_splitHostName_from_char get error copying the name to the nameString, it shall return __FAILURE__.]*/ 00198 result = __FAILURE__; 00199 } 00200 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_024: [connectionstringparser_splitHostName_from_char shall copy all characters, from the first `.` to the end of the hostName, to the suffixString.]*/ 00201 else if (STRING_copy(suffixString, runHostName) != 0) 00202 { 00203 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_032: [If connectionstringparser_splitHostName_from_char get error copying the suffix to the suffixString, it shall return __FAILURE__.]*/ 00204 result = __FAILURE__; 00205 } 00206 else 00207 { 00208 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_025: [If connectionstringparser_splitHostName_from_char get success splitting the hostName, it shall return 0.]*/ 00209 result = 0; 00210 } 00211 } 00212 } 00213 00214 return result; 00215 } 00216 00217 00218 int connectionstringparser_splitHostName(STRING_HANDLE hostNameString, STRING_HANDLE nameString, STRING_HANDLE suffixString) 00219 { 00220 int result; 00221 00222 if (hostNameString == NULL) 00223 { 00224 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_034: [If the hostNameString is NULL, connectionstringparser_splitHostName shall return __FAILURE__.]*/ 00225 result = __FAILURE__; 00226 } 00227 else 00228 { 00229 /* Codes_SRS_CONNECTIONSTRINGPARSER_21_033: [connectionstringparser_splitHostName shall convert the hostNameString to a connection_string passed in as argument, and call connectionstringparser_splitHostName_from_char.]*/ 00230 result = connectionstringparser_splitHostName_from_char(STRING_c_str(hostNameString), nameString, suffixString); 00231 } 00232 00233 return result; 00234 }
Generated on Tue Jul 12 2022 19:14:38 by
