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.
Dependencies: EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed
Fork of iothub_client_sample_amqp by
strings.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 // 00005 // PUT NO INCLUDES BEFORE HERE 00006 // 00007 #include <stdlib.h> 00008 #ifdef _CRTDBG_MAP_ALLOC 00009 #include <crtdbg.h> 00010 #endif 00011 #include "azure_c_shared_utility/gballoc.h" 00012 00013 #include <stddef.h> 00014 #include <string.h> 00015 #include <stdarg.h> 00016 #include <stdio.h> 00017 00018 // 00019 // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE 00020 // 00021 00022 #include "azure_c_shared_utility/strings.h" 00023 #include "azure_c_shared_utility/xlogging.h" 00024 00025 static const char hexToASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 00026 00027 typedef struct STRING_TAG 00028 { 00029 char* s; 00030 }STRING; 00031 00032 /*this function will allocate a new string with just '\0' in it*/ 00033 /*return NULL if it fails*/ 00034 /* Codes_SRS_STRING_07_001: [STRING_new shall allocate a new STRING_HANDLE pointing to an empty string.] */ 00035 STRING_HANDLE STRING_new(void) 00036 { 00037 STRING* result; 00038 if ((result = (STRING*)malloc(sizeof(STRING))) != NULL) 00039 { 00040 if ((result->s = (char*)malloc(1)) != NULL) 00041 { 00042 result->s[0] = '\0'; 00043 } 00044 else 00045 { 00046 /* Codes_SRS_STRING_07_002: [STRING_new shall return an NULL STRING_HANDLE on any error that is encountered.] */ 00047 free(result); 00048 result = NULL; 00049 } 00050 } 00051 return (STRING_HANDLE)result; 00052 } 00053 00054 /*Codes_SRS_STRING_02_001: [STRING_clone shall produce a new string having the same content as the handle string.*/ 00055 STRING_HANDLE STRING_clone(STRING_HANDLE handle) 00056 { 00057 STRING* result; 00058 /*Codes_SRS_STRING_02_002: [If parameter handle is NULL then STRING_clone shall return NULL.]*/ 00059 if (handle == NULL) 00060 { 00061 result = NULL; 00062 } 00063 else 00064 { 00065 /*Codes_SRS_STRING_02_003: [If STRING_clone fails for any reason, it shall return NULL.] */ 00066 if ((result = (STRING*)malloc(sizeof(STRING))) != NULL) 00067 { 00068 STRING* source = (STRING*)handle; 00069 /*Codes_SRS_STRING_02_003: [If STRING_clone fails for any reason, it shall return NULL.] */ 00070 size_t sourceLen = strlen(source->s); 00071 if ((result->s = (char*)malloc(sourceLen + 1)) == NULL) 00072 { 00073 free(result); 00074 result = NULL; 00075 } 00076 else 00077 { 00078 memcpy(result->s, source->s, sourceLen + 1); 00079 } 00080 } 00081 else 00082 { 00083 /*not much to do, result is NULL from malloc*/ 00084 } 00085 } 00086 return (STRING_HANDLE)result; 00087 } 00088 00089 /* Codes_SRS_STRING_07_003: [STRING_construct shall allocate a new string with the value of the specified const char*.] */ 00090 STRING_HANDLE STRING_construct(const char* psz) 00091 { 00092 STRING_HANDLE result; 00093 if (psz == NULL) 00094 { 00095 /* Codes_SRS_STRING_07_005: [If the supplied const char* is NULL STRING_construct shall return a NULL value.] */ 00096 result = NULL; 00097 } 00098 else 00099 { 00100 STRING* str; 00101 if ((str = (STRING*)malloc(sizeof(STRING))) != NULL) 00102 { 00103 size_t nLen = strlen(psz) + 1; 00104 if ((str->s = (char*)malloc(nLen)) != NULL) 00105 { 00106 memcpy(str->s, psz, nLen); 00107 result = (STRING_HANDLE)str; 00108 } 00109 /* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */ 00110 else 00111 { 00112 free(str); 00113 result = NULL; 00114 } 00115 } 00116 else 00117 { 00118 /* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */ 00119 result = NULL; 00120 } 00121 } 00122 return result; 00123 } 00124 00125 STRING_HANDLE STRING_construct_sprintf(const char* format, ...) 00126 { 00127 STRING* result; 00128 00129 #ifdef ARDUINO_ARCH_ESP8266 00130 size_t maxBufSize = 512; 00131 char buf[512]; 00132 #else 00133 size_t maxBufSize = 0; 00134 char* buf = NULL; 00135 #endif 00136 00137 if (format != NULL) 00138 { 00139 va_list arg_list; 00140 int length; 00141 va_start(arg_list, format); 00142 00143 /* Codes_SRS_STRING_07_041: [STRING_construct_sprintf shall determine the size of the resulting string and allocate the necessary memory.] */ 00144 length = vsnprintf(buf, maxBufSize, format, arg_list); 00145 va_end(arg_list); 00146 if (length > 0) 00147 { 00148 result = (STRING*)malloc(sizeof(STRING)); 00149 if (result != NULL) 00150 { 00151 result->s = (char*)malloc(length+1); 00152 if (result->s != NULL) 00153 { 00154 va_start(arg_list, format); 00155 if (vsnprintf(result->s, length+1, format, arg_list) < 0) 00156 { 00157 /* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */ 00158 free(result->s); 00159 free(result); 00160 result = NULL; 00161 LogError("Failure: vsnprintf formatting failed."); 00162 } 00163 va_end(arg_list); 00164 } 00165 else 00166 { 00167 /* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */ 00168 free(result); 00169 result = NULL; 00170 LogError("Failure: allocation failed."); 00171 } 00172 } 00173 else 00174 { 00175 LogError("Failure: allocation failed."); 00176 } 00177 } 00178 else if (length == 0) 00179 { 00180 result = (STRING*)STRING_new(); 00181 } 00182 else 00183 { 00184 /* Codes_SRS_STRING_07_039: [If the parameter format is NULL then STRING_construct_sprintf shall return NULL.] */ 00185 result = NULL; 00186 LogError("Failure: vsnprintf return 0 length"); 00187 } 00188 } 00189 else 00190 { 00191 LogError("Failure: invalid argument."); 00192 result = NULL; 00193 } 00194 /* Codes_SRS_STRING_07_045: [STRING_construct_sprintf shall allocate a new string with the value of the specified printf formated const char. ] */ 00195 return (STRING_HANDLE)result; 00196 } 00197 00198 /*this function will return a new STRING with the memory for the actual string passed in as a parameter.*/ 00199 /*return NULL if it fails.*/ 00200 /* The supplied memory must have been allocated with malloc! */ 00201 /* Codes_SRS_STRING_07_006: [STRING_new_with_memory shall return a STRING_HANDLE by using the supplied char* memory.] */ 00202 STRING_HANDLE STRING_new_with_memory(const char* memory) 00203 { 00204 STRING* result; 00205 if (memory == NULL) 00206 { 00207 /* Codes_SRS_STRING_07_007: [STRING_new_with_memory shall return a NULL STRING_HANDLE if the supplied char* is NULL.] */ 00208 result = NULL; 00209 } 00210 else 00211 { 00212 if ((result = (STRING*)malloc(sizeof(STRING))) != NULL) 00213 { 00214 result->s = (char*)memory; 00215 } 00216 } 00217 return (STRING_HANDLE)result; 00218 } 00219 00220 /* Codes_SRS_STRING_07_008: [STRING_new_quoted shall return a valid STRING_HANDLE Copying the supplied const char* value surrounded by quotes.] */ 00221 STRING_HANDLE STRING_new_quoted(const char* source) 00222 { 00223 STRING* result; 00224 if (source == NULL) 00225 { 00226 /* Codes_SRS_STRING_07_009: [STRING_new_quoted shall return a NULL STRING_HANDLE if the supplied const char* is NULL.] */ 00227 result = NULL; 00228 } 00229 else if ((result = (STRING*)malloc(sizeof(STRING))) != NULL) 00230 { 00231 size_t sourceLength = strlen(source); 00232 if ((result->s = (char*)malloc(sourceLength + 3)) != NULL) 00233 { 00234 result->s[0] = '"'; 00235 memcpy(result->s + 1, source, sourceLength); 00236 result->s[sourceLength + 1] = '"'; 00237 result->s[sourceLength + 2] = '\0'; 00238 } 00239 else 00240 { 00241 /* Codes_SRS_STRING_07_031: [STRING_new_quoted shall return a NULL STRING_HANDLE if any error is encountered.] */ 00242 free(result); 00243 result = NULL; 00244 } 00245 } 00246 return (STRING_HANDLE)result; 00247 } 00248 00249 /*this function takes a regular const char* and turns in into "this is a\"JSON\" strings\u0008" (starting and ending quote included)*/ 00250 /*the newly created handle needs to be disposed of with STRING_delete*/ 00251 /*returns NULL if there are errors*/ 00252 STRING_HANDLE STRING_new_JSON(const char* source) 00253 { 00254 STRING* result; 00255 if (source == NULL) 00256 { 00257 /*Codes_SRS_STRING_02_011: [If source is NULL then STRING_new_JSON shall return NULL.] */ 00258 result = NULL; 00259 LogError("invalid arg (NULL)"); 00260 } 00261 else 00262 { 00263 size_t i; 00264 size_t nControlCharacters = 0; /*counts how many characters are to be expanded from 1 character to \uxxxx (6 characters)*/ 00265 size_t nEscapeCharacters = 0; 00266 size_t vlen = strlen(source); 00267 00268 for (i = 0; i < vlen; i++) 00269 { 00270 /*Codes_SRS_STRING_02_014: [If any character has the value outside [1...127] then STRING_new_JSON shall fail and return NULL.] */ 00271 if ((unsigned char)source[i] >= 128) /*this be a UNICODE character begin*/ 00272 { 00273 break; 00274 } 00275 else 00276 { 00277 if (source[i] <= 0x1F) 00278 { 00279 nControlCharacters++; 00280 } 00281 else if ( 00282 (source[i] == '"') || 00283 (source[i] == '\\') || 00284 (source[i] == '/') 00285 ) 00286 { 00287 nEscapeCharacters++; 00288 } 00289 } 00290 } 00291 00292 if (i < vlen) 00293 { 00294 result = NULL; 00295 LogError("invalid character in input string"); 00296 } 00297 else 00298 { 00299 if ((result = (STRING*)malloc(sizeof(STRING))) == NULL) 00300 { 00301 /*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */ 00302 LogError("malloc failure"); 00303 } 00304 else if ((result->s = (char*)malloc(vlen + 5 * nControlCharacters + nEscapeCharacters + 3)) == NULL) 00305 { 00306 /*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */ 00307 free(result); 00308 result = NULL; 00309 LogError("malloc failed"); 00310 } 00311 else 00312 { 00313 size_t pos = 0; 00314 /*Codes_SRS_STRING_02_012: [The string shall begin with the quote character.] */ 00315 result->s[pos++] = '"'; 00316 for (i = 0; i < vlen; i++) 00317 { 00318 if (source[i] <= 0x1F) 00319 { 00320 /*Codes_SRS_STRING_02_019: [If the character code is less than 0x20 then it shall be represented as \u00xx, where xx is the hex representation of the character code.]*/ 00321 result->s[pos++] = '\\'; 00322 result->s[pos++] = 'u'; 00323 result->s[pos++] = '0'; 00324 result->s[pos++] = '0'; 00325 result->s[pos++] = hexToASCII[(source[i] & 0xF0) >> 4]; /*high nibble*/ 00326 result->s[pos++] = hexToASCII[source[i] & 0x0F]; /*low nibble*/ 00327 } 00328 else if (source[i] == '"') 00329 { 00330 /*Codes_SRS_STRING_02_016: [If the character is " (quote) then it shall be repsented as \".] */ 00331 result->s[pos++] = '\\'; 00332 result->s[pos++] = '"'; 00333 } 00334 else if (source[i] == '\\') 00335 { 00336 /*Codes_SRS_STRING_02_017: [If the character is \ (backslash) then it shall represented as \\.] */ 00337 result->s[pos++] = '\\'; 00338 result->s[pos++] = '\\'; 00339 } 00340 else if (source[i] == '/') 00341 { 00342 /*Codes_SRS_STRING_02_018: [If the character is / (slash) then it shall be represented as \/.] */ 00343 result->s[pos++] = '\\'; 00344 result->s[pos++] = '/'; 00345 } 00346 else 00347 { 00348 /*Codes_SRS_STRING_02_013: [The string shall copy the characters of source "as they are" (until the '\0' character) with the following exceptions:] */ 00349 result->s[pos++] = source[i]; 00350 } 00351 } 00352 /*Codes_SRS_STRING_02_020: [The string shall end with " (quote).] */ 00353 result->s[pos++] = '"'; 00354 /*zero terminating it*/ 00355 result->s[pos] = '\0'; 00356 } 00357 } 00358 00359 } 00360 return (STRING_HANDLE)result; 00361 } 00362 00363 /*this function will concatenate to the string s1 the string s2, resulting in s1+s2*/ 00364 /*returns 0 if success*/ 00365 /*any other error code is failure*/ 00366 /* Codes_SRS_STRING_07_012: [STRING_concat shall concatenate the given STRING_HANDLE and the const char* value and place the value in the handle.] */ 00367 int STRING_concat(STRING_HANDLE handle, const char* s2) 00368 { 00369 int result; 00370 if ((handle == NULL) || (s2 == NULL)) 00371 { 00372 /* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */ 00373 result = __LINE__; 00374 } 00375 else 00376 { 00377 STRING* s1 = (STRING*)handle; 00378 size_t s1Length = strlen(s1->s); 00379 size_t s2Length = strlen(s2); 00380 char* temp = (char*)realloc(s1->s, s1Length + s2Length + 1); 00381 if (temp == NULL) 00382 { 00383 /* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */ 00384 result = __LINE__; 00385 } 00386 else 00387 { 00388 s1->s = temp; 00389 memcpy(s1->s + s1Length, s2, s2Length + 1); 00390 result = 0; 00391 } 00392 } 00393 return result; 00394 } 00395 00396 /*this function will concatenate to the string s1 the string s2, resulting in s1+s2*/ 00397 /*returns 0 if success*/ 00398 /*any other error code is failure*/ 00399 /* Codes_SRS_STRING_07_034: [String_Concat_with_STRING shall concatenate a given STRING_HANDLE variable with a source STRING_HANDLE.] */ 00400 int STRING_concat_with_STRING(STRING_HANDLE s1, STRING_HANDLE s2) 00401 { 00402 int result; 00403 if ((s1 == NULL) || (s2 == NULL)) 00404 { 00405 /* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */ 00406 result = __LINE__; 00407 } 00408 else 00409 { 00410 STRING* dest = (STRING*)s1; 00411 STRING* src = (STRING*)s2; 00412 00413 size_t s1Length = strlen(dest->s); 00414 size_t s2Length = strlen(src->s); 00415 char* temp = (char*)realloc(dest->s, s1Length + s2Length + 1); 00416 if (temp == NULL) 00417 { 00418 /* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */ 00419 result = __LINE__; 00420 } 00421 else 00422 { 00423 dest->s = temp; 00424 /* Codes_SRS_STRING_07_034: [String_Concat_with_STRING shall concatenate a given STRING_HANDLE variable with a source STRING_HANDLE.] */ 00425 memcpy(dest->s + s1Length, src->s, s2Length + 1); 00426 result = 0; 00427 } 00428 } 00429 return result; 00430 } 00431 00432 /*this function will copy the string from s2 to s1*/ 00433 /*returns 0 if success*/ 00434 /*any other error code is failure*/ 00435 /* Codes_SRS_STRING_07_016: [STRING_copy shall copy the const char* into the supplied STRING_HANDLE.] */ 00436 int STRING_copy(STRING_HANDLE handle, const char* s2) 00437 { 00438 int result; 00439 if ((handle == NULL) || (s2 == NULL)) 00440 { 00441 /* Codes_SRS_STRING_07_017: [STRING_copy shall return a nonzero value if any of the supplied parameters are NULL.] */ 00442 result = __LINE__; 00443 } 00444 else 00445 { 00446 STRING* s1 = (STRING*)handle; 00447 /* Codes_SRS_STRING_07_026: [If the underlying char* refered to by s1 handle is equal to char* s2 than STRING_copy shall be a noop and return 0.] */ 00448 if (s1->s != s2) 00449 { 00450 size_t s2Length = strlen(s2); 00451 char* temp = (char*)realloc(s1->s, s2Length + 1); 00452 if (temp == NULL) 00453 { 00454 /* Codes_SRS_STRING_07_027: [STRING_copy shall return a nonzero value if any error is encountered.] */ 00455 result = __LINE__; 00456 } 00457 else 00458 { 00459 s1->s = temp; 00460 memmove(s1->s, s2, s2Length + 1); 00461 result = 0; 00462 } 00463 } 00464 else 00465 { 00466 /* Codes_SRS_STRING_07_033: [If overlapping pointer address is given to STRING_copy the behavior is undefined.] */ 00467 result = 0; 00468 } 00469 } 00470 return result; 00471 } 00472 00473 /*this function will copy n chars from s2 to the string s1, resulting in n chars only from s2 being stored in s1.*/ 00474 /*returns 0 if success*/ 00475 /*any other error code is failure*/ 00476 /* Codes_SRS_STRING_07_018: [STRING_copy_n shall copy the number of characters in const char* or the size_t whichever is lesser.] */ 00477 int STRING_copy_n(STRING_HANDLE handle, const char* s2, size_t n) 00478 { 00479 int result; 00480 if ((handle == NULL) || (s2 == NULL)) 00481 { 00482 /* Codes_SRS_STRING_07_019: [STRING_copy_n shall return a nonzero value if STRING_HANDLE or const char* is NULL.] */ 00483 result = __LINE__; 00484 } 00485 else 00486 { 00487 STRING* s1 = (STRING*)handle; 00488 size_t s2Length = strlen(s2); 00489 char* temp; 00490 if (s2Length > n) 00491 { 00492 s2Length = n; 00493 } 00494 00495 temp = (char*)realloc(s1->s, s2Length + 1); 00496 if (temp == NULL) 00497 { 00498 /* Codes_SRS_STRING_07_028: [STRING_copy_n shall return a nonzero value if any error is encountered.] */ 00499 result = __LINE__; 00500 } 00501 else 00502 { 00503 s1->s = temp; 00504 memcpy(s1->s, s2, s2Length); 00505 s1->s[s2Length] = 0; 00506 result = 0; 00507 } 00508 00509 } 00510 return result; 00511 } 00512 00513 int STRING_sprintf(STRING_HANDLE handle, const char* format, ...) 00514 { 00515 int result; 00516 00517 #ifdef ARDUINO_ARCH_ESP8266 00518 size_t maxBufSize = 512; 00519 char buf[512]; 00520 #else 00521 size_t maxBufSize = 0; 00522 char* buf = NULL; 00523 #endif 00524 00525 if (handle == NULL || format == NULL) 00526 { 00527 /* Codes_SRS_STRING_07_042: [if the parameters s1 or format are NULL then STRING_sprintf shall return non zero value.] */ 00528 result = __LINE__; 00529 LogError("Invalid arg (NULL)"); 00530 } 00531 else 00532 { 00533 va_list arg_list; 00534 int s2Length; 00535 va_start(arg_list, format); 00536 00537 s2Length = vsnprintf(buf, maxBufSize, format, arg_list); 00538 va_end(arg_list); 00539 if (s2Length < 0) 00540 { 00541 /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */ 00542 result = __LINE__; 00543 LogError("Failure vsnprintf return < 0"); 00544 } 00545 else if (s2Length == 0) 00546 { 00547 // Don't need to reallocate and nothing should be added 00548 result = 0; 00549 } 00550 else 00551 { 00552 STRING* s1 = (STRING*)handle; 00553 char* temp; 00554 size_t s1Length = strlen(s1->s); 00555 temp = (char*)realloc(s1->s, s1Length + s2Length + 1); 00556 if (temp != NULL) 00557 { 00558 s1->s = temp; 00559 va_start(arg_list, format); 00560 if (vsnprintf(s1->s + s1Length, s1Length + s2Length + 1, format, arg_list) < 0) 00561 { 00562 /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */ 00563 LogError("Failure vsnprintf formatting error"); 00564 s1->s[s1Length] = '\0'; 00565 result = __LINE__; 00566 } 00567 else 00568 { 00569 /* Codes_SRS_STRING_07_044: [On success STRING_sprintf shall return 0.]*/ 00570 result = 0; 00571 } 00572 va_end(arg_list); 00573 } 00574 else 00575 { 00576 /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */ 00577 LogError("Failure unable to reallocate memory"); 00578 result = __LINE__; 00579 } 00580 } 00581 } 00582 return result; 00583 } 00584 00585 /*this function will quote the string passed as argument string =>"string"*/ 00586 /*returns 0 if success*/ /*doesn't change the string otherwise*/ 00587 /*any other error code is failure*/ 00588 /* Codes_SRS_STRING_07_014: [STRING_quote shall "quote" the supplied STRING_HANDLE and return 0 on success.] */ 00589 int STRING_quote(STRING_HANDLE handle) 00590 { 00591 int result; 00592 if (handle == NULL) 00593 { 00594 /* Codes_SRS_STRING_07_015: [STRING_quote shall return a nonzero value if any of the supplied parameters are NULL.] */ 00595 result = __LINE__; 00596 } 00597 else 00598 { 00599 STRING* s1 = (STRING*)handle; 00600 size_t s1Length = strlen(s1->s); 00601 char* temp = (char*)realloc(s1->s, s1Length + 2 + 1);/*2 because 2 quotes, 1 because '\0'*/ 00602 if (temp == NULL) 00603 { 00604 /* Codes_SRS_STRING_07_029: [STRING_quote shall return a nonzero value if any error is encountered.] */ 00605 result = __LINE__; 00606 } 00607 else 00608 { 00609 s1->s = temp; 00610 memmove(s1->s + 1, s1->s, s1Length); 00611 s1->s[0] = '"'; 00612 s1->s[s1Length + 1] = '"'; 00613 s1->s[s1Length + 2] = '\0'; 00614 result = 0; 00615 } 00616 } 00617 return result; 00618 } 00619 /*this function will revert a string to an empty state*/ 00620 /*Returns 0 if the revert was succesful*/ 00621 /* Codes_SRS_STRING_07_022: [STRING_empty shall revert the STRING_HANDLE to an empty state.] */ 00622 int STRING_empty(STRING_HANDLE handle) 00623 { 00624 int result; 00625 if (handle == NULL) 00626 { 00627 /* Codes_SRS_STRING_07_023: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */ 00628 result = __LINE__; 00629 } 00630 else 00631 { 00632 STRING* s1 = (STRING*)handle; 00633 char* temp = (char*)realloc(s1->s, 1); 00634 if (temp == NULL) 00635 { 00636 /* Codes_SRS_STRING_07_030: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */ 00637 result = __LINE__; 00638 } 00639 else 00640 { 00641 s1->s = temp; 00642 s1->s[0] = '\0'; 00643 result = 0; 00644 } 00645 } 00646 return result; 00647 } 00648 00649 /*this function will deallocate a string constructed by str_new*/ 00650 /* Codes_SRS_STRING_07_010: [STRING_delete will free the memory allocated by the STRING_HANDLE.] */ 00651 void STRING_delete(STRING_HANDLE handle) 00652 { 00653 /* Codes_SRS_STRING_07_011: [STRING_delete will not attempt to free anything with a NULL STRING_HANDLE.] */ 00654 if (handle != NULL) 00655 { 00656 STRING* value = (STRING*)handle; 00657 free(value->s); 00658 value->s = NULL; 00659 free(value); 00660 } 00661 } 00662 00663 /* Codes_SRS_STRING_07_020: [STRING_c_str shall return the const char* associated with the given STRING_HANDLE.] */ 00664 const char* STRING_c_str(STRING_HANDLE handle) 00665 { 00666 const char* result; 00667 if (handle != NULL) 00668 { 00669 result = ((STRING*)handle)->s; 00670 } 00671 else 00672 { 00673 /* Codes_SRS_STRING_07_021: [STRING_c_str shall return NULL if the STRING_HANDLE is NULL.] */ 00674 result = NULL; 00675 } 00676 return result; 00677 } 00678 00679 /* Codes_SRS_STRING_07_024: [STRING_length shall return the length of the underlying char* for the given handle] */ 00680 size_t STRING_length(STRING_HANDLE handle) 00681 { 00682 size_t result = 0; 00683 /* Codes_SRS_STRING_07_025: [STRING_length shall return zero if the given handle is NULL.] */ 00684 if (handle != NULL) 00685 { 00686 STRING* value = (STRING*)handle; 00687 result = strlen(value->s); 00688 } 00689 return result; 00690 } 00691 00692 /*Codes_SRS_STRING_02_007: [STRING_construct_n shall construct a STRING_HANDLE from first "n" characters of the string pointed to by psz parameter.]*/ 00693 STRING_HANDLE STRING_construct_n(const char* psz, size_t n) 00694 { 00695 STRING_HANDLE result; 00696 /*Codes_SRS_STRING_02_008: [If psz is NULL then STRING_construct_n shall return NULL.] */ 00697 if (psz == NULL) 00698 { 00699 result = NULL; 00700 LogError("invalid arg (NULL)"); 00701 } 00702 else 00703 { 00704 size_t len = strlen(psz); 00705 /*Codes_SRS_STRING_02_009: [If n is bigger than the size of the string psz, then STRING_construct_n shall return NULL.] */ 00706 if (n > len) 00707 { 00708 result = NULL; 00709 LogError("invalig arg (n is bigger than the size of the string)"); 00710 } 00711 else 00712 { 00713 STRING* str; 00714 if ((str = (STRING*)malloc(sizeof(STRING))) != NULL) 00715 { 00716 if ((str->s = (char*)malloc(len + 1)) != NULL) 00717 { 00718 memcpy(str->s, psz, n); 00719 str->s[n] = '\0'; 00720 result = (STRING_HANDLE)str; 00721 } 00722 /* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.] */ 00723 else 00724 { 00725 free(str); 00726 result = NULL; 00727 } 00728 } 00729 else 00730 { 00731 /* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.] */ 00732 result = NULL; 00733 } 00734 } 00735 } 00736 return result; 00737 } 00738 00739 /* Codes_SRS_STRING_07_034: [STRING_compare returns an integer greater than, equal to, or less than zero, accordingly as the string pointed to by s1 is greater than, equal to, or less than the string s2.] */ 00740 int STRING_compare(STRING_HANDLE s1, STRING_HANDLE s2) 00741 { 00742 int result; 00743 if (s1 == NULL && s2 == NULL) 00744 { 00745 /* Codes_SRS_STRING_07_035: [If h1 and h2 are both NULL then STRING_compare shall return 0.]*/ 00746 result = 0; 00747 } 00748 else if (s1 == NULL) 00749 { 00750 /* Codes_SRS_STRING_07_036: [If h1 is NULL and h2 is nonNULL then STRING_compare shall return 1.]*/ 00751 result = 1; 00752 } 00753 else if (s2 == NULL) 00754 { 00755 /* Codes_SRS_STRING_07_037: [If h2 is NULL and h1 is nonNULL then STRING_compare shall return -1.] */ 00756 result = -1; 00757 } 00758 else 00759 { 00760 /* Codes_SRS_STRING_07_038: [STRING_compare shall compare the char s variable using the strcmp function.] */ 00761 STRING* value1 = (STRING*)s1; 00762 STRING* value2 = (STRING*)s2; 00763 result = strcmp(value1->s, value2->s); 00764 } 00765 return result; 00766 } 00767 00768 STRING_HANDLE STRING_from_byte_array(const unsigned char* source, size_t size) 00769 { 00770 STRING* result; 00771 /*Codes_SRS_STRING_02_022: [ If source is NULL and size > 0 then STRING_from_BUFFER shall fail and return NULL. ]*/ 00772 if ((source == NULL) && (size > 0)) 00773 { 00774 LogError("invalid parameter (NULL)"); 00775 result = NULL; 00776 } 00777 else 00778 { 00779 /*Codes_SRS_STRING_02_023: [ Otherwise, STRING_from_BUFFER shall build a string that has the same content (byte-by-byte) as source and return a non-NULL handle. ]*/ 00780 result = (STRING*)malloc(sizeof(STRING)); 00781 if (result == NULL) 00782 { 00783 /*Codes_SRS_STRING_02_024: [ If building the string fails, then STRING_from_BUFFER shall fail and return NULL. ]*/ 00784 LogError("oom - unable to malloc"); 00785 /*return as is*/ 00786 } 00787 else 00788 { 00789 /*Codes_SRS_STRING_02_023: [ Otherwise, STRING_from_BUFFER shall build a string that has the same content (byte-by-byte) as source and return a non-NULL handle. ]*/ 00790 result->s = (char*)malloc(size + 1); 00791 if (result->s == NULL) 00792 { 00793 /*Codes_SRS_STRING_02_024: [ If building the string fails, then STRING_from_BUFFER shall fail and return NULL. ]*/ 00794 LogError("oom - unable to malloc"); 00795 free(result); 00796 result = NULL; 00797 } 00798 else 00799 { 00800 memcpy(result->s, source, size); 00801 result->s[size] = '\0'; /*all is fine*/ 00802 } 00803 } 00804 } 00805 return (STRING_HANDLE)result; 00806 }
Generated on Tue Jul 12 2022 12:43:24 by
