WIP. send a large constant string twice a second, in order to test out the transport with something indicative of our required load.

Dependencies:   FXOS8700CQ NTPClient azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Fork of FXOS8700CQ_To_Azure_IoT by Mark Radbourne

Committer:
julianhigginson
Date:
Thu Jan 05 23:40:24 2017 +0000
Revision:
7:0d1a0fe537dc
Parent:
3:c0556ff7b8e3
modified dummy message for minimal data transport

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 3:c0556ff7b8e3 1 // Copyright (c) Microsoft. All rights reserved.
markrad 3:c0556ff7b8e3 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
markrad 3:c0556ff7b8e3 3
markrad 3:c0556ff7b8e3 4 //
markrad 3:c0556ff7b8e3 5 // PUT NO INCLUDES BEFORE HERE
markrad 3:c0556ff7b8e3 6 //
markrad 3:c0556ff7b8e3 7 #include <stdlib.h>
markrad 3:c0556ff7b8e3 8 #ifdef _CRTDBG_MAP_ALLOC
markrad 3:c0556ff7b8e3 9 #include <crtdbg.h>
markrad 3:c0556ff7b8e3 10 #endif
markrad 3:c0556ff7b8e3 11 #include "azure_c_shared_utility/gballoc.h"
markrad 3:c0556ff7b8e3 12
markrad 3:c0556ff7b8e3 13 #include <stddef.h>
markrad 3:c0556ff7b8e3 14 #include <string.h>
markrad 3:c0556ff7b8e3 15 #include <stdarg.h>
markrad 3:c0556ff7b8e3 16 #include <stdio.h>
markrad 3:c0556ff7b8e3 17
markrad 3:c0556ff7b8e3 18 //
markrad 3:c0556ff7b8e3 19 // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE
markrad 3:c0556ff7b8e3 20 //
markrad 3:c0556ff7b8e3 21
markrad 3:c0556ff7b8e3 22 #include "azure_c_shared_utility/strings.h"
markrad 3:c0556ff7b8e3 23 #include "azure_c_shared_utility/xlogging.h"
markrad 3:c0556ff7b8e3 24
markrad 3:c0556ff7b8e3 25 static const char hexToASCII[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
markrad 3:c0556ff7b8e3 26
markrad 3:c0556ff7b8e3 27 typedef struct STRING_TAG
markrad 3:c0556ff7b8e3 28 {
markrad 3:c0556ff7b8e3 29 char* s;
markrad 3:c0556ff7b8e3 30 }STRING;
markrad 3:c0556ff7b8e3 31
markrad 3:c0556ff7b8e3 32 /*this function will allocate a new string with just '\0' in it*/
markrad 3:c0556ff7b8e3 33 /*return NULL if it fails*/
markrad 3:c0556ff7b8e3 34 /* Codes_SRS_STRING_07_001: [STRING_new shall allocate a new STRING_HANDLE pointing to an empty string.] */
markrad 3:c0556ff7b8e3 35 STRING_HANDLE STRING_new(void)
markrad 3:c0556ff7b8e3 36 {
markrad 3:c0556ff7b8e3 37 STRING* result;
markrad 3:c0556ff7b8e3 38 if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
markrad 3:c0556ff7b8e3 39 {
markrad 3:c0556ff7b8e3 40 if ((result->s = (char*)malloc(1)) != NULL)
markrad 3:c0556ff7b8e3 41 {
markrad 3:c0556ff7b8e3 42 result->s[0] = '\0';
markrad 3:c0556ff7b8e3 43 }
markrad 3:c0556ff7b8e3 44 else
markrad 3:c0556ff7b8e3 45 {
markrad 3:c0556ff7b8e3 46 /* Codes_SRS_STRING_07_002: [STRING_new shall return an NULL STRING_HANDLE on any error that is encountered.] */
markrad 3:c0556ff7b8e3 47 free(result);
markrad 3:c0556ff7b8e3 48 result = NULL;
markrad 3:c0556ff7b8e3 49 }
markrad 3:c0556ff7b8e3 50 }
markrad 3:c0556ff7b8e3 51 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 52 }
markrad 3:c0556ff7b8e3 53
markrad 3:c0556ff7b8e3 54 /*Codes_SRS_STRING_02_001: [STRING_clone shall produce a new string having the same content as the handle string.*/
markrad 3:c0556ff7b8e3 55 STRING_HANDLE STRING_clone(STRING_HANDLE handle)
markrad 3:c0556ff7b8e3 56 {
markrad 3:c0556ff7b8e3 57 STRING* result;
markrad 3:c0556ff7b8e3 58 /*Codes_SRS_STRING_02_002: [If parameter handle is NULL then STRING_clone shall return NULL.]*/
markrad 3:c0556ff7b8e3 59 if (handle == NULL)
markrad 3:c0556ff7b8e3 60 {
markrad 3:c0556ff7b8e3 61 result = NULL;
markrad 3:c0556ff7b8e3 62 }
markrad 3:c0556ff7b8e3 63 else
markrad 3:c0556ff7b8e3 64 {
markrad 3:c0556ff7b8e3 65 /*Codes_SRS_STRING_02_003: [If STRING_clone fails for any reason, it shall return NULL.] */
markrad 3:c0556ff7b8e3 66 if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
markrad 3:c0556ff7b8e3 67 {
markrad 3:c0556ff7b8e3 68 STRING* source = (STRING*)handle;
markrad 3:c0556ff7b8e3 69 /*Codes_SRS_STRING_02_003: [If STRING_clone fails for any reason, it shall return NULL.] */
markrad 3:c0556ff7b8e3 70 size_t sourceLen = strlen(source->s);
markrad 3:c0556ff7b8e3 71 if ((result->s = (char*)malloc(sourceLen + 1)) == NULL)
markrad 3:c0556ff7b8e3 72 {
markrad 3:c0556ff7b8e3 73 free(result);
markrad 3:c0556ff7b8e3 74 result = NULL;
markrad 3:c0556ff7b8e3 75 }
markrad 3:c0556ff7b8e3 76 else
markrad 3:c0556ff7b8e3 77 {
markrad 3:c0556ff7b8e3 78 memcpy(result->s, source->s, sourceLen + 1);
markrad 3:c0556ff7b8e3 79 }
markrad 3:c0556ff7b8e3 80 }
markrad 3:c0556ff7b8e3 81 else
markrad 3:c0556ff7b8e3 82 {
markrad 3:c0556ff7b8e3 83 /*not much to do, result is NULL from malloc*/
markrad 3:c0556ff7b8e3 84 }
markrad 3:c0556ff7b8e3 85 }
markrad 3:c0556ff7b8e3 86 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 87 }
markrad 3:c0556ff7b8e3 88
markrad 3:c0556ff7b8e3 89 /* Codes_SRS_STRING_07_003: [STRING_construct shall allocate a new string with the value of the specified const char*.] */
markrad 3:c0556ff7b8e3 90 STRING_HANDLE STRING_construct(const char* psz)
markrad 3:c0556ff7b8e3 91 {
markrad 3:c0556ff7b8e3 92 STRING_HANDLE result;
markrad 3:c0556ff7b8e3 93 if (psz == NULL)
markrad 3:c0556ff7b8e3 94 {
markrad 3:c0556ff7b8e3 95 /* Codes_SRS_STRING_07_005: [If the supplied const char* is NULL STRING_construct shall return a NULL value.] */
markrad 3:c0556ff7b8e3 96 result = NULL;
markrad 3:c0556ff7b8e3 97 }
markrad 3:c0556ff7b8e3 98 else
markrad 3:c0556ff7b8e3 99 {
markrad 3:c0556ff7b8e3 100 STRING* str;
markrad 3:c0556ff7b8e3 101 if ((str = (STRING*)malloc(sizeof(STRING))) != NULL)
markrad 3:c0556ff7b8e3 102 {
markrad 3:c0556ff7b8e3 103 size_t nLen = strlen(psz) + 1;
markrad 3:c0556ff7b8e3 104 if ((str->s = (char*)malloc(nLen)) != NULL)
markrad 3:c0556ff7b8e3 105 {
markrad 3:c0556ff7b8e3 106 memcpy(str->s, psz, nLen);
markrad 3:c0556ff7b8e3 107 result = (STRING_HANDLE)str;
markrad 3:c0556ff7b8e3 108 }
markrad 3:c0556ff7b8e3 109 /* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */
markrad 3:c0556ff7b8e3 110 else
markrad 3:c0556ff7b8e3 111 {
markrad 3:c0556ff7b8e3 112 free(str);
markrad 3:c0556ff7b8e3 113 result = NULL;
markrad 3:c0556ff7b8e3 114 }
markrad 3:c0556ff7b8e3 115 }
markrad 3:c0556ff7b8e3 116 else
markrad 3:c0556ff7b8e3 117 {
markrad 3:c0556ff7b8e3 118 /* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */
markrad 3:c0556ff7b8e3 119 result = NULL;
markrad 3:c0556ff7b8e3 120 }
markrad 3:c0556ff7b8e3 121 }
markrad 3:c0556ff7b8e3 122 return result;
markrad 3:c0556ff7b8e3 123 }
markrad 3:c0556ff7b8e3 124
markrad 3:c0556ff7b8e3 125 STRING_HANDLE STRING_construct_sprintf(const char* format, ...)
markrad 3:c0556ff7b8e3 126 {
markrad 3:c0556ff7b8e3 127 STRING* result;
markrad 3:c0556ff7b8e3 128 if (format != NULL)
markrad 3:c0556ff7b8e3 129 {
markrad 3:c0556ff7b8e3 130 va_list arg_list;
markrad 3:c0556ff7b8e3 131 int length;
markrad 3:c0556ff7b8e3 132 va_start(arg_list, format);
markrad 3:c0556ff7b8e3 133
markrad 3:c0556ff7b8e3 134 /* Codes_SRS_STRING_07_041: [STRING_construct_sprintf shall determine the size of the resulting string and allocate the necessary memory.] */
markrad 3:c0556ff7b8e3 135 length = vsnprintf(NULL, 0, format, arg_list);
markrad 3:c0556ff7b8e3 136 va_end(arg_list);
markrad 3:c0556ff7b8e3 137 if (length > 0)
markrad 3:c0556ff7b8e3 138 {
markrad 3:c0556ff7b8e3 139 result = (STRING*)malloc(sizeof(STRING));
markrad 3:c0556ff7b8e3 140 if (result != NULL)
markrad 3:c0556ff7b8e3 141 {
markrad 3:c0556ff7b8e3 142 result->s = (char*)malloc(length+1);
markrad 3:c0556ff7b8e3 143 if (result->s != NULL)
markrad 3:c0556ff7b8e3 144 {
markrad 3:c0556ff7b8e3 145 va_start(arg_list, format);
markrad 3:c0556ff7b8e3 146 if (vsnprintf(result->s, length+1, format, arg_list) < 0)
markrad 3:c0556ff7b8e3 147 {
markrad 3:c0556ff7b8e3 148 /* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */
markrad 3:c0556ff7b8e3 149 free(result->s);
markrad 3:c0556ff7b8e3 150 free(result);
markrad 3:c0556ff7b8e3 151 result = NULL;
markrad 3:c0556ff7b8e3 152 LogError("Failure: vsnprintf formatting failed.");
markrad 3:c0556ff7b8e3 153 }
markrad 3:c0556ff7b8e3 154 va_end(arg_list);
markrad 3:c0556ff7b8e3 155 }
markrad 3:c0556ff7b8e3 156 else
markrad 3:c0556ff7b8e3 157 {
markrad 3:c0556ff7b8e3 158 /* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */
markrad 3:c0556ff7b8e3 159 free(result);
markrad 3:c0556ff7b8e3 160 result = NULL;
markrad 3:c0556ff7b8e3 161 LogError("Failure: allocation failed.");
markrad 3:c0556ff7b8e3 162 }
markrad 3:c0556ff7b8e3 163 }
markrad 3:c0556ff7b8e3 164 else
markrad 3:c0556ff7b8e3 165 {
markrad 3:c0556ff7b8e3 166 LogError("Failure: allocation failed.");
markrad 3:c0556ff7b8e3 167 }
markrad 3:c0556ff7b8e3 168 }
markrad 3:c0556ff7b8e3 169 else if (length == 0)
markrad 3:c0556ff7b8e3 170 {
markrad 3:c0556ff7b8e3 171 result = (STRING*)STRING_new();
markrad 3:c0556ff7b8e3 172 }
markrad 3:c0556ff7b8e3 173 else
markrad 3:c0556ff7b8e3 174 {
markrad 3:c0556ff7b8e3 175 /* Codes_SRS_STRING_07_039: [If the parameter format is NULL then STRING_construct_sprintf shall return NULL.] */
markrad 3:c0556ff7b8e3 176 result = NULL;
markrad 3:c0556ff7b8e3 177 LogError("Failure: vsnprintf return 0 length");
markrad 3:c0556ff7b8e3 178 }
markrad 3:c0556ff7b8e3 179 }
markrad 3:c0556ff7b8e3 180 else
markrad 3:c0556ff7b8e3 181 {
markrad 3:c0556ff7b8e3 182 LogError("Failure: invalid argument.");
markrad 3:c0556ff7b8e3 183 result = NULL;
markrad 3:c0556ff7b8e3 184 }
markrad 3:c0556ff7b8e3 185 /* Codes_SRS_STRING_07_045: [STRING_construct_sprintf shall allocate a new string with the value of the specified printf formated const char. ] */
markrad 3:c0556ff7b8e3 186 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 187 }
markrad 3:c0556ff7b8e3 188
markrad 3:c0556ff7b8e3 189 /*this function will return a new STRING with the memory for the actual string passed in as a parameter.*/
markrad 3:c0556ff7b8e3 190 /*return NULL if it fails.*/
markrad 3:c0556ff7b8e3 191 /* The supplied memory must have been allocated with malloc! */
markrad 3:c0556ff7b8e3 192 /* Codes_SRS_STRING_07_006: [STRING_new_with_memory shall return a STRING_HANDLE by using the supplied char* memory.] */
markrad 3:c0556ff7b8e3 193 STRING_HANDLE STRING_new_with_memory(const char* memory)
markrad 3:c0556ff7b8e3 194 {
markrad 3:c0556ff7b8e3 195 STRING* result;
markrad 3:c0556ff7b8e3 196 if (memory == NULL)
markrad 3:c0556ff7b8e3 197 {
markrad 3:c0556ff7b8e3 198 /* Codes_SRS_STRING_07_007: [STRING_new_with_memory shall return a NULL STRING_HANDLE if the supplied char* is NULL.] */
markrad 3:c0556ff7b8e3 199 result = NULL;
markrad 3:c0556ff7b8e3 200 }
markrad 3:c0556ff7b8e3 201 else
markrad 3:c0556ff7b8e3 202 {
markrad 3:c0556ff7b8e3 203 if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
markrad 3:c0556ff7b8e3 204 {
markrad 3:c0556ff7b8e3 205 result->s = (char*)memory;
markrad 3:c0556ff7b8e3 206 }
markrad 3:c0556ff7b8e3 207 }
markrad 3:c0556ff7b8e3 208 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 209 }
markrad 3:c0556ff7b8e3 210
markrad 3:c0556ff7b8e3 211 /* Codes_SRS_STRING_07_008: [STRING_new_quoted shall return a valid STRING_HANDLE Copying the supplied const char* value surrounded by quotes.] */
markrad 3:c0556ff7b8e3 212 STRING_HANDLE STRING_new_quoted(const char* source)
markrad 3:c0556ff7b8e3 213 {
markrad 3:c0556ff7b8e3 214 STRING* result;
markrad 3:c0556ff7b8e3 215 if (source == NULL)
markrad 3:c0556ff7b8e3 216 {
markrad 3:c0556ff7b8e3 217 /* Codes_SRS_STRING_07_009: [STRING_new_quoted shall return a NULL STRING_HANDLE if the supplied const char* is NULL.] */
markrad 3:c0556ff7b8e3 218 result = NULL;
markrad 3:c0556ff7b8e3 219 }
markrad 3:c0556ff7b8e3 220 else if ((result = (STRING*)malloc(sizeof(STRING))) != NULL)
markrad 3:c0556ff7b8e3 221 {
markrad 3:c0556ff7b8e3 222 size_t sourceLength = strlen(source);
markrad 3:c0556ff7b8e3 223 if ((result->s = (char*)malloc(sourceLength + 3)) != NULL)
markrad 3:c0556ff7b8e3 224 {
markrad 3:c0556ff7b8e3 225 result->s[0] = '"';
markrad 3:c0556ff7b8e3 226 memcpy(result->s + 1, source, sourceLength);
markrad 3:c0556ff7b8e3 227 result->s[sourceLength + 1] = '"';
markrad 3:c0556ff7b8e3 228 result->s[sourceLength + 2] = '\0';
markrad 3:c0556ff7b8e3 229 }
markrad 3:c0556ff7b8e3 230 else
markrad 3:c0556ff7b8e3 231 {
markrad 3:c0556ff7b8e3 232 /* Codes_SRS_STRING_07_031: [STRING_new_quoted shall return a NULL STRING_HANDLE if any error is encountered.] */
markrad 3:c0556ff7b8e3 233 free(result);
markrad 3:c0556ff7b8e3 234 result = NULL;
markrad 3:c0556ff7b8e3 235 }
markrad 3:c0556ff7b8e3 236 }
markrad 3:c0556ff7b8e3 237 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 238 }
markrad 3:c0556ff7b8e3 239
markrad 3:c0556ff7b8e3 240 /*this function takes a regular const char* and turns in into "this is a\"JSON\" strings\u0008" (starting and ending quote included)*/
markrad 3:c0556ff7b8e3 241 /*the newly created handle needs to be disposed of with STRING_delete*/
markrad 3:c0556ff7b8e3 242 /*returns NULL if there are errors*/
markrad 3:c0556ff7b8e3 243 STRING_HANDLE STRING_new_JSON(const char* source)
markrad 3:c0556ff7b8e3 244 {
markrad 3:c0556ff7b8e3 245 STRING* result;
markrad 3:c0556ff7b8e3 246 if (source == NULL)
markrad 3:c0556ff7b8e3 247 {
markrad 3:c0556ff7b8e3 248 /*Codes_SRS_STRING_02_011: [If source is NULL then STRING_new_JSON shall return NULL.] */
markrad 3:c0556ff7b8e3 249 result = NULL;
markrad 3:c0556ff7b8e3 250 LogError("invalid arg (NULL)");
markrad 3:c0556ff7b8e3 251 }
markrad 3:c0556ff7b8e3 252 else
markrad 3:c0556ff7b8e3 253 {
markrad 3:c0556ff7b8e3 254 size_t i;
markrad 3:c0556ff7b8e3 255 size_t nControlCharacters = 0; /*counts how many characters are to be expanded from 1 character to \uxxxx (6 characters)*/
markrad 3:c0556ff7b8e3 256 size_t nEscapeCharacters = 0;
markrad 3:c0556ff7b8e3 257 size_t vlen = strlen(source);
markrad 3:c0556ff7b8e3 258
markrad 3:c0556ff7b8e3 259 for (i = 0; i < vlen; i++)
markrad 3:c0556ff7b8e3 260 {
markrad 3:c0556ff7b8e3 261 /*Codes_SRS_STRING_02_014: [If any character has the value outside [1...127] then STRING_new_JSON shall fail and return NULL.] */
markrad 3:c0556ff7b8e3 262 if ((unsigned char)source[i] >= 128) /*this be a UNICODE character begin*/
markrad 3:c0556ff7b8e3 263 {
markrad 3:c0556ff7b8e3 264 break;
markrad 3:c0556ff7b8e3 265 }
markrad 3:c0556ff7b8e3 266 else
markrad 3:c0556ff7b8e3 267 {
markrad 3:c0556ff7b8e3 268 if (source[i] <= 0x1F)
markrad 3:c0556ff7b8e3 269 {
markrad 3:c0556ff7b8e3 270 nControlCharacters++;
markrad 3:c0556ff7b8e3 271 }
markrad 3:c0556ff7b8e3 272 else if (
markrad 3:c0556ff7b8e3 273 (source[i] == '"') ||
markrad 3:c0556ff7b8e3 274 (source[i] == '\\') ||
markrad 3:c0556ff7b8e3 275 (source[i] == '/')
markrad 3:c0556ff7b8e3 276 )
markrad 3:c0556ff7b8e3 277 {
markrad 3:c0556ff7b8e3 278 nEscapeCharacters++;
markrad 3:c0556ff7b8e3 279 }
markrad 3:c0556ff7b8e3 280 }
markrad 3:c0556ff7b8e3 281 }
markrad 3:c0556ff7b8e3 282
markrad 3:c0556ff7b8e3 283 if (i < vlen)
markrad 3:c0556ff7b8e3 284 {
markrad 3:c0556ff7b8e3 285 result = NULL;
markrad 3:c0556ff7b8e3 286 LogError("invalid character in input string");
markrad 3:c0556ff7b8e3 287 }
markrad 3:c0556ff7b8e3 288 else
markrad 3:c0556ff7b8e3 289 {
markrad 3:c0556ff7b8e3 290 if ((result = (STRING*)malloc(sizeof(STRING))) == NULL)
markrad 3:c0556ff7b8e3 291 {
markrad 3:c0556ff7b8e3 292 /*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */
markrad 3:c0556ff7b8e3 293 LogError("malloc failure");
markrad 3:c0556ff7b8e3 294 }
markrad 3:c0556ff7b8e3 295 else if ((result->s = (char*)malloc(vlen + 5 * nControlCharacters + nEscapeCharacters + 3)) == NULL)
markrad 3:c0556ff7b8e3 296 {
markrad 3:c0556ff7b8e3 297 /*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */
markrad 3:c0556ff7b8e3 298 free(result);
markrad 3:c0556ff7b8e3 299 result = NULL;
markrad 3:c0556ff7b8e3 300 LogError("malloc failed");
markrad 3:c0556ff7b8e3 301 }
markrad 3:c0556ff7b8e3 302 else
markrad 3:c0556ff7b8e3 303 {
markrad 3:c0556ff7b8e3 304 size_t pos = 0;
markrad 3:c0556ff7b8e3 305 /*Codes_SRS_STRING_02_012: [The string shall begin with the quote character.] */
markrad 3:c0556ff7b8e3 306 result->s[pos++] = '"';
markrad 3:c0556ff7b8e3 307 for (i = 0; i < vlen; i++)
markrad 3:c0556ff7b8e3 308 {
markrad 3:c0556ff7b8e3 309 if (source[i] <= 0x1F)
markrad 3:c0556ff7b8e3 310 {
markrad 3:c0556ff7b8e3 311 /*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.]*/
markrad 3:c0556ff7b8e3 312 result->s[pos++] = '\\';
markrad 3:c0556ff7b8e3 313 result->s[pos++] = 'u';
markrad 3:c0556ff7b8e3 314 result->s[pos++] = '0';
markrad 3:c0556ff7b8e3 315 result->s[pos++] = '0';
markrad 3:c0556ff7b8e3 316 result->s[pos++] = hexToASCII[(source[i] & 0xF0) >> 4]; /*high nibble*/
markrad 3:c0556ff7b8e3 317 result->s[pos++] = hexToASCII[source[i] & 0x0F]; /*low nibble*/
markrad 3:c0556ff7b8e3 318 }
markrad 3:c0556ff7b8e3 319 else if (source[i] == '"')
markrad 3:c0556ff7b8e3 320 {
markrad 3:c0556ff7b8e3 321 /*Codes_SRS_STRING_02_016: [If the character is " (quote) then it shall be repsented as \".] */
markrad 3:c0556ff7b8e3 322 result->s[pos++] = '\\';
markrad 3:c0556ff7b8e3 323 result->s[pos++] = '"';
markrad 3:c0556ff7b8e3 324 }
markrad 3:c0556ff7b8e3 325 else if (source[i] == '\\')
markrad 3:c0556ff7b8e3 326 {
markrad 3:c0556ff7b8e3 327 /*Codes_SRS_STRING_02_017: [If the character is \ (backslash) then it shall represented as \\.] */
markrad 3:c0556ff7b8e3 328 result->s[pos++] = '\\';
markrad 3:c0556ff7b8e3 329 result->s[pos++] = '\\';
markrad 3:c0556ff7b8e3 330 }
markrad 3:c0556ff7b8e3 331 else if (source[i] == '/')
markrad 3:c0556ff7b8e3 332 {
markrad 3:c0556ff7b8e3 333 /*Codes_SRS_STRING_02_018: [If the character is / (slash) then it shall be represented as \/.] */
markrad 3:c0556ff7b8e3 334 result->s[pos++] = '\\';
markrad 3:c0556ff7b8e3 335 result->s[pos++] = '/';
markrad 3:c0556ff7b8e3 336 }
markrad 3:c0556ff7b8e3 337 else
markrad 3:c0556ff7b8e3 338 {
markrad 3:c0556ff7b8e3 339 /*Codes_SRS_STRING_02_013: [The string shall copy the characters of source "as they are" (until the '\0' character) with the following exceptions:] */
markrad 3:c0556ff7b8e3 340 result->s[pos++] = source[i];
markrad 3:c0556ff7b8e3 341 }
markrad 3:c0556ff7b8e3 342 }
markrad 3:c0556ff7b8e3 343 /*Codes_SRS_STRING_02_020: [The string shall end with " (quote).] */
markrad 3:c0556ff7b8e3 344 result->s[pos++] = '"';
markrad 3:c0556ff7b8e3 345 /*zero terminating it*/
markrad 3:c0556ff7b8e3 346 result->s[pos] = '\0';
markrad 3:c0556ff7b8e3 347 }
markrad 3:c0556ff7b8e3 348 }
markrad 3:c0556ff7b8e3 349
markrad 3:c0556ff7b8e3 350 }
markrad 3:c0556ff7b8e3 351 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 352 }
markrad 3:c0556ff7b8e3 353
markrad 3:c0556ff7b8e3 354 /*this function will concatenate to the string s1 the string s2, resulting in s1+s2*/
markrad 3:c0556ff7b8e3 355 /*returns 0 if success*/
markrad 3:c0556ff7b8e3 356 /*any other error code is failure*/
markrad 3:c0556ff7b8e3 357 /* 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.] */
markrad 3:c0556ff7b8e3 358 int STRING_concat(STRING_HANDLE handle, const char* s2)
markrad 3:c0556ff7b8e3 359 {
markrad 3:c0556ff7b8e3 360 int result;
markrad 3:c0556ff7b8e3 361 if ((handle == NULL) || (s2 == NULL))
markrad 3:c0556ff7b8e3 362 {
markrad 3:c0556ff7b8e3 363 /* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */
markrad 3:c0556ff7b8e3 364 result = __LINE__;
markrad 3:c0556ff7b8e3 365 }
markrad 3:c0556ff7b8e3 366 else
markrad 3:c0556ff7b8e3 367 {
markrad 3:c0556ff7b8e3 368 STRING* s1 = (STRING*)handle;
markrad 3:c0556ff7b8e3 369 size_t s1Length = strlen(s1->s);
markrad 3:c0556ff7b8e3 370 size_t s2Length = strlen(s2);
markrad 3:c0556ff7b8e3 371 char* temp = (char*)realloc(s1->s, s1Length + s2Length + 1);
markrad 3:c0556ff7b8e3 372 if (temp == NULL)
markrad 3:c0556ff7b8e3 373 {
markrad 3:c0556ff7b8e3 374 /* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */
markrad 3:c0556ff7b8e3 375 result = __LINE__;
markrad 3:c0556ff7b8e3 376 }
markrad 3:c0556ff7b8e3 377 else
markrad 3:c0556ff7b8e3 378 {
markrad 3:c0556ff7b8e3 379 s1->s = temp;
markrad 3:c0556ff7b8e3 380 memcpy(s1->s + s1Length, s2, s2Length + 1);
markrad 3:c0556ff7b8e3 381 result = 0;
markrad 3:c0556ff7b8e3 382 }
markrad 3:c0556ff7b8e3 383 }
markrad 3:c0556ff7b8e3 384 return result;
markrad 3:c0556ff7b8e3 385 }
markrad 3:c0556ff7b8e3 386
markrad 3:c0556ff7b8e3 387 /*this function will concatenate to the string s1 the string s2, resulting in s1+s2*/
markrad 3:c0556ff7b8e3 388 /*returns 0 if success*/
markrad 3:c0556ff7b8e3 389 /*any other error code is failure*/
markrad 3:c0556ff7b8e3 390 /* Codes_SRS_STRING_07_034: [String_Concat_with_STRING shall concatenate a given STRING_HANDLE variable with a source STRING_HANDLE.] */
markrad 3:c0556ff7b8e3 391 int STRING_concat_with_STRING(STRING_HANDLE s1, STRING_HANDLE s2)
markrad 3:c0556ff7b8e3 392 {
markrad 3:c0556ff7b8e3 393 int result;
markrad 3:c0556ff7b8e3 394 if ((s1 == NULL) || (s2 == NULL))
markrad 3:c0556ff7b8e3 395 {
markrad 3:c0556ff7b8e3 396 /* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */
markrad 3:c0556ff7b8e3 397 result = __LINE__;
markrad 3:c0556ff7b8e3 398 }
markrad 3:c0556ff7b8e3 399 else
markrad 3:c0556ff7b8e3 400 {
markrad 3:c0556ff7b8e3 401 STRING* dest = (STRING*)s1;
markrad 3:c0556ff7b8e3 402 STRING* src = (STRING*)s2;
markrad 3:c0556ff7b8e3 403
markrad 3:c0556ff7b8e3 404 size_t s1Length = strlen(dest->s);
markrad 3:c0556ff7b8e3 405 size_t s2Length = strlen(src->s);
markrad 3:c0556ff7b8e3 406 char* temp = (char*)realloc(dest->s, s1Length + s2Length + 1);
markrad 3:c0556ff7b8e3 407 if (temp == NULL)
markrad 3:c0556ff7b8e3 408 {
markrad 3:c0556ff7b8e3 409 /* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */
markrad 3:c0556ff7b8e3 410 result = __LINE__;
markrad 3:c0556ff7b8e3 411 }
markrad 3:c0556ff7b8e3 412 else
markrad 3:c0556ff7b8e3 413 {
markrad 3:c0556ff7b8e3 414 dest->s = temp;
markrad 3:c0556ff7b8e3 415 /* Codes_SRS_STRING_07_034: [String_Concat_with_STRING shall concatenate a given STRING_HANDLE variable with a source STRING_HANDLE.] */
markrad 3:c0556ff7b8e3 416 memcpy(dest->s + s1Length, src->s, s2Length + 1);
markrad 3:c0556ff7b8e3 417 result = 0;
markrad 3:c0556ff7b8e3 418 }
markrad 3:c0556ff7b8e3 419 }
markrad 3:c0556ff7b8e3 420 return result;
markrad 3:c0556ff7b8e3 421 }
markrad 3:c0556ff7b8e3 422
markrad 3:c0556ff7b8e3 423 /*this function will copy the string from s2 to s1*/
markrad 3:c0556ff7b8e3 424 /*returns 0 if success*/
markrad 3:c0556ff7b8e3 425 /*any other error code is failure*/
markrad 3:c0556ff7b8e3 426 /* Codes_SRS_STRING_07_016: [STRING_copy shall copy the const char* into the supplied STRING_HANDLE.] */
markrad 3:c0556ff7b8e3 427 int STRING_copy(STRING_HANDLE handle, const char* s2)
markrad 3:c0556ff7b8e3 428 {
markrad 3:c0556ff7b8e3 429 int result;
markrad 3:c0556ff7b8e3 430 if ((handle == NULL) || (s2 == NULL))
markrad 3:c0556ff7b8e3 431 {
markrad 3:c0556ff7b8e3 432 /* Codes_SRS_STRING_07_017: [STRING_copy shall return a nonzero value if any of the supplied parameters are NULL.] */
markrad 3:c0556ff7b8e3 433 result = __LINE__;
markrad 3:c0556ff7b8e3 434 }
markrad 3:c0556ff7b8e3 435 else
markrad 3:c0556ff7b8e3 436 {
markrad 3:c0556ff7b8e3 437 STRING* s1 = (STRING*)handle;
markrad 3:c0556ff7b8e3 438 /* 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.] */
markrad 3:c0556ff7b8e3 439 if (s1->s != s2)
markrad 3:c0556ff7b8e3 440 {
markrad 3:c0556ff7b8e3 441 size_t s2Length = strlen(s2);
markrad 3:c0556ff7b8e3 442 char* temp = (char*)realloc(s1->s, s2Length + 1);
markrad 3:c0556ff7b8e3 443 if (temp == NULL)
markrad 3:c0556ff7b8e3 444 {
markrad 3:c0556ff7b8e3 445 /* Codes_SRS_STRING_07_027: [STRING_copy shall return a nonzero value if any error is encountered.] */
markrad 3:c0556ff7b8e3 446 result = __LINE__;
markrad 3:c0556ff7b8e3 447 }
markrad 3:c0556ff7b8e3 448 else
markrad 3:c0556ff7b8e3 449 {
markrad 3:c0556ff7b8e3 450 s1->s = temp;
markrad 3:c0556ff7b8e3 451 memmove(s1->s, s2, s2Length + 1);
markrad 3:c0556ff7b8e3 452 result = 0;
markrad 3:c0556ff7b8e3 453 }
markrad 3:c0556ff7b8e3 454 }
markrad 3:c0556ff7b8e3 455 else
markrad 3:c0556ff7b8e3 456 {
markrad 3:c0556ff7b8e3 457 /* Codes_SRS_STRING_07_033: [If overlapping pointer address is given to STRING_copy the behavior is undefined.] */
markrad 3:c0556ff7b8e3 458 result = 0;
markrad 3:c0556ff7b8e3 459 }
markrad 3:c0556ff7b8e3 460 }
markrad 3:c0556ff7b8e3 461 return result;
markrad 3:c0556ff7b8e3 462 }
markrad 3:c0556ff7b8e3 463
markrad 3:c0556ff7b8e3 464 /*this function will copy n chars from s2 to the string s1, resulting in n chars only from s2 being stored in s1.*/
markrad 3:c0556ff7b8e3 465 /*returns 0 if success*/
markrad 3:c0556ff7b8e3 466 /*any other error code is failure*/
markrad 3:c0556ff7b8e3 467 /* Codes_SRS_STRING_07_018: [STRING_copy_n shall copy the number of characters in const char* or the size_t whichever is lesser.] */
markrad 3:c0556ff7b8e3 468 int STRING_copy_n(STRING_HANDLE handle, const char* s2, size_t n)
markrad 3:c0556ff7b8e3 469 {
markrad 3:c0556ff7b8e3 470 int result;
markrad 3:c0556ff7b8e3 471 if ((handle == NULL) || (s2 == NULL))
markrad 3:c0556ff7b8e3 472 {
markrad 3:c0556ff7b8e3 473 /* Codes_SRS_STRING_07_019: [STRING_copy_n shall return a nonzero value if STRING_HANDLE or const char* is NULL.] */
markrad 3:c0556ff7b8e3 474 result = __LINE__;
markrad 3:c0556ff7b8e3 475 }
markrad 3:c0556ff7b8e3 476 else
markrad 3:c0556ff7b8e3 477 {
markrad 3:c0556ff7b8e3 478 STRING* s1 = (STRING*)handle;
markrad 3:c0556ff7b8e3 479 size_t s2Length = strlen(s2);
markrad 3:c0556ff7b8e3 480 char* temp;
markrad 3:c0556ff7b8e3 481 if (s2Length > n)
markrad 3:c0556ff7b8e3 482 {
markrad 3:c0556ff7b8e3 483 s2Length = n;
markrad 3:c0556ff7b8e3 484 }
markrad 3:c0556ff7b8e3 485
markrad 3:c0556ff7b8e3 486 temp = (char*)realloc(s1->s, s2Length + 1);
markrad 3:c0556ff7b8e3 487 if (temp == NULL)
markrad 3:c0556ff7b8e3 488 {
markrad 3:c0556ff7b8e3 489 /* Codes_SRS_STRING_07_028: [STRING_copy_n shall return a nonzero value if any error is encountered.] */
markrad 3:c0556ff7b8e3 490 result = __LINE__;
markrad 3:c0556ff7b8e3 491 }
markrad 3:c0556ff7b8e3 492 else
markrad 3:c0556ff7b8e3 493 {
markrad 3:c0556ff7b8e3 494 s1->s = temp;
markrad 3:c0556ff7b8e3 495 memcpy(s1->s, s2, s2Length);
markrad 3:c0556ff7b8e3 496 s1->s[s2Length] = 0;
markrad 3:c0556ff7b8e3 497 result = 0;
markrad 3:c0556ff7b8e3 498 }
markrad 3:c0556ff7b8e3 499
markrad 3:c0556ff7b8e3 500 }
markrad 3:c0556ff7b8e3 501 return result;
markrad 3:c0556ff7b8e3 502 }
markrad 3:c0556ff7b8e3 503
markrad 3:c0556ff7b8e3 504 int STRING_sprintf(STRING_HANDLE handle, const char* format, ...)
markrad 3:c0556ff7b8e3 505 {
markrad 3:c0556ff7b8e3 506 int result;
markrad 3:c0556ff7b8e3 507 if (handle == NULL || format == NULL)
markrad 3:c0556ff7b8e3 508 {
markrad 3:c0556ff7b8e3 509 /* Codes_SRS_STRING_07_042: [if the parameters s1 or format are NULL then STRING_sprintf shall return non zero value.] */
markrad 3:c0556ff7b8e3 510 result = __LINE__;
markrad 3:c0556ff7b8e3 511 LogError("Invalid arg (NULL)");
markrad 3:c0556ff7b8e3 512 }
markrad 3:c0556ff7b8e3 513 else
markrad 3:c0556ff7b8e3 514 {
markrad 3:c0556ff7b8e3 515 va_list arg_list;
markrad 3:c0556ff7b8e3 516 int s2Length;
markrad 3:c0556ff7b8e3 517 va_start(arg_list, format);
markrad 3:c0556ff7b8e3 518
markrad 3:c0556ff7b8e3 519 s2Length = vsnprintf(NULL, 0, format, arg_list);
markrad 3:c0556ff7b8e3 520 va_end(arg_list);
markrad 3:c0556ff7b8e3 521 if (s2Length < 0)
markrad 3:c0556ff7b8e3 522 {
markrad 3:c0556ff7b8e3 523 /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */
markrad 3:c0556ff7b8e3 524 result = __LINE__;
markrad 3:c0556ff7b8e3 525 LogError("Failure vsnprintf return < 0");
markrad 3:c0556ff7b8e3 526 }
markrad 3:c0556ff7b8e3 527 else if (s2Length == 0)
markrad 3:c0556ff7b8e3 528 {
markrad 3:c0556ff7b8e3 529 // Don't need to reallocate and nothing should be added
markrad 3:c0556ff7b8e3 530 result = 0;
markrad 3:c0556ff7b8e3 531 }
markrad 3:c0556ff7b8e3 532 else
markrad 3:c0556ff7b8e3 533 {
markrad 3:c0556ff7b8e3 534 STRING* s1 = (STRING*)handle;
markrad 3:c0556ff7b8e3 535 char* temp;
markrad 3:c0556ff7b8e3 536 size_t s1Length = strlen(s1->s);
markrad 3:c0556ff7b8e3 537 temp = (char*)realloc(s1->s, s1Length + s2Length + 1);
markrad 3:c0556ff7b8e3 538 if (temp != NULL)
markrad 3:c0556ff7b8e3 539 {
markrad 3:c0556ff7b8e3 540 s1->s = temp;
markrad 3:c0556ff7b8e3 541 va_start(arg_list, format);
markrad 3:c0556ff7b8e3 542 if (vsnprintf(s1->s + s1Length, s1Length + s2Length + 1, format, arg_list) < 0)
markrad 3:c0556ff7b8e3 543 {
markrad 3:c0556ff7b8e3 544 /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */
markrad 3:c0556ff7b8e3 545 LogError("Failure vsnprintf formatting error");
markrad 3:c0556ff7b8e3 546 s1->s[s1Length] = '\0';
markrad 3:c0556ff7b8e3 547 result = __LINE__;
markrad 3:c0556ff7b8e3 548 }
markrad 3:c0556ff7b8e3 549 else
markrad 3:c0556ff7b8e3 550 {
markrad 3:c0556ff7b8e3 551 /* Codes_SRS_STRING_07_044: [On success STRING_sprintf shall return 0.]*/
markrad 3:c0556ff7b8e3 552 result = 0;
markrad 3:c0556ff7b8e3 553 }
markrad 3:c0556ff7b8e3 554 va_end(arg_list);
markrad 3:c0556ff7b8e3 555 }
markrad 3:c0556ff7b8e3 556 else
markrad 3:c0556ff7b8e3 557 {
markrad 3:c0556ff7b8e3 558 /* Codes_SRS_STRING_07_043: [If any error is encountered STRING_sprintf shall return a non zero value.] */
markrad 3:c0556ff7b8e3 559 LogError("Failure unable to reallocate memory");
markrad 3:c0556ff7b8e3 560 result = __LINE__;
markrad 3:c0556ff7b8e3 561 }
markrad 3:c0556ff7b8e3 562 }
markrad 3:c0556ff7b8e3 563 }
markrad 3:c0556ff7b8e3 564 return result;
markrad 3:c0556ff7b8e3 565 }
markrad 3:c0556ff7b8e3 566
markrad 3:c0556ff7b8e3 567 /*this function will quote the string passed as argument string =>"string"*/
markrad 3:c0556ff7b8e3 568 /*returns 0 if success*/ /*doesn't change the string otherwise*/
markrad 3:c0556ff7b8e3 569 /*any other error code is failure*/
markrad 3:c0556ff7b8e3 570 /* Codes_SRS_STRING_07_014: [STRING_quote shall "quote" the supplied STRING_HANDLE and return 0 on success.] */
markrad 3:c0556ff7b8e3 571 int STRING_quote(STRING_HANDLE handle)
markrad 3:c0556ff7b8e3 572 {
markrad 3:c0556ff7b8e3 573 int result;
markrad 3:c0556ff7b8e3 574 if (handle == NULL)
markrad 3:c0556ff7b8e3 575 {
markrad 3:c0556ff7b8e3 576 /* Codes_SRS_STRING_07_015: [STRING_quote shall return a nonzero value if any of the supplied parameters are NULL.] */
markrad 3:c0556ff7b8e3 577 result = __LINE__;
markrad 3:c0556ff7b8e3 578 }
markrad 3:c0556ff7b8e3 579 else
markrad 3:c0556ff7b8e3 580 {
markrad 3:c0556ff7b8e3 581 STRING* s1 = (STRING*)handle;
markrad 3:c0556ff7b8e3 582 size_t s1Length = strlen(s1->s);
markrad 3:c0556ff7b8e3 583 char* temp = (char*)realloc(s1->s, s1Length + 2 + 1);/*2 because 2 quotes, 1 because '\0'*/
markrad 3:c0556ff7b8e3 584 if (temp == NULL)
markrad 3:c0556ff7b8e3 585 {
markrad 3:c0556ff7b8e3 586 /* Codes_SRS_STRING_07_029: [STRING_quote shall return a nonzero value if any error is encountered.] */
markrad 3:c0556ff7b8e3 587 result = __LINE__;
markrad 3:c0556ff7b8e3 588 }
markrad 3:c0556ff7b8e3 589 else
markrad 3:c0556ff7b8e3 590 {
markrad 3:c0556ff7b8e3 591 s1->s = temp;
markrad 3:c0556ff7b8e3 592 memmove(s1->s + 1, s1->s, s1Length);
markrad 3:c0556ff7b8e3 593 s1->s[0] = '"';
markrad 3:c0556ff7b8e3 594 s1->s[s1Length + 1] = '"';
markrad 3:c0556ff7b8e3 595 s1->s[s1Length + 2] = '\0';
markrad 3:c0556ff7b8e3 596 result = 0;
markrad 3:c0556ff7b8e3 597 }
markrad 3:c0556ff7b8e3 598 }
markrad 3:c0556ff7b8e3 599 return result;
markrad 3:c0556ff7b8e3 600 }
markrad 3:c0556ff7b8e3 601 /*this function will revert a string to an empty state*/
markrad 3:c0556ff7b8e3 602 /*Returns 0 if the revert was succesful*/
markrad 3:c0556ff7b8e3 603 /* Codes_SRS_STRING_07_022: [STRING_empty shall revert the STRING_HANDLE to an empty state.] */
markrad 3:c0556ff7b8e3 604 int STRING_empty(STRING_HANDLE handle)
markrad 3:c0556ff7b8e3 605 {
markrad 3:c0556ff7b8e3 606 int result;
markrad 3:c0556ff7b8e3 607 if (handle == NULL)
markrad 3:c0556ff7b8e3 608 {
markrad 3:c0556ff7b8e3 609 /* Codes_SRS_STRING_07_023: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */
markrad 3:c0556ff7b8e3 610 result = __LINE__;
markrad 3:c0556ff7b8e3 611 }
markrad 3:c0556ff7b8e3 612 else
markrad 3:c0556ff7b8e3 613 {
markrad 3:c0556ff7b8e3 614 STRING* s1 = (STRING*)handle;
markrad 3:c0556ff7b8e3 615 char* temp = (char*)realloc(s1->s, 1);
markrad 3:c0556ff7b8e3 616 if (temp == NULL)
markrad 3:c0556ff7b8e3 617 {
markrad 3:c0556ff7b8e3 618 /* Codes_SRS_STRING_07_030: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */
markrad 3:c0556ff7b8e3 619 result = __LINE__;
markrad 3:c0556ff7b8e3 620 }
markrad 3:c0556ff7b8e3 621 else
markrad 3:c0556ff7b8e3 622 {
markrad 3:c0556ff7b8e3 623 s1->s = temp;
markrad 3:c0556ff7b8e3 624 s1->s[0] = '\0';
markrad 3:c0556ff7b8e3 625 result = 0;
markrad 3:c0556ff7b8e3 626 }
markrad 3:c0556ff7b8e3 627 }
markrad 3:c0556ff7b8e3 628 return result;
markrad 3:c0556ff7b8e3 629 }
markrad 3:c0556ff7b8e3 630
markrad 3:c0556ff7b8e3 631 /*this function will deallocate a string constructed by str_new*/
markrad 3:c0556ff7b8e3 632 /* Codes_SRS_STRING_07_010: [STRING_delete will free the memory allocated by the STRING_HANDLE.] */
markrad 3:c0556ff7b8e3 633 void STRING_delete(STRING_HANDLE handle)
markrad 3:c0556ff7b8e3 634 {
markrad 3:c0556ff7b8e3 635 /* Codes_SRS_STRING_07_011: [STRING_delete will not attempt to free anything with a NULL STRING_HANDLE.] */
markrad 3:c0556ff7b8e3 636 if (handle != NULL)
markrad 3:c0556ff7b8e3 637 {
markrad 3:c0556ff7b8e3 638 STRING* value = (STRING*)handle;
markrad 3:c0556ff7b8e3 639 free(value->s);
markrad 3:c0556ff7b8e3 640 value->s = NULL;
markrad 3:c0556ff7b8e3 641 free(value);
markrad 3:c0556ff7b8e3 642 }
markrad 3:c0556ff7b8e3 643 }
markrad 3:c0556ff7b8e3 644
markrad 3:c0556ff7b8e3 645 /* Codes_SRS_STRING_07_020: [STRING_c_str shall return the const char* associated with the given STRING_HANDLE.] */
markrad 3:c0556ff7b8e3 646 const char* STRING_c_str(STRING_HANDLE handle)
markrad 3:c0556ff7b8e3 647 {
markrad 3:c0556ff7b8e3 648 const char* result;
markrad 3:c0556ff7b8e3 649 if (handle != NULL)
markrad 3:c0556ff7b8e3 650 {
markrad 3:c0556ff7b8e3 651 result = ((STRING*)handle)->s;
markrad 3:c0556ff7b8e3 652 }
markrad 3:c0556ff7b8e3 653 else
markrad 3:c0556ff7b8e3 654 {
markrad 3:c0556ff7b8e3 655 /* Codes_SRS_STRING_07_021: [STRING_c_str shall return NULL if the STRING_HANDLE is NULL.] */
markrad 3:c0556ff7b8e3 656 result = NULL;
markrad 3:c0556ff7b8e3 657 }
markrad 3:c0556ff7b8e3 658 return result;
markrad 3:c0556ff7b8e3 659 }
markrad 3:c0556ff7b8e3 660
markrad 3:c0556ff7b8e3 661 /* Codes_SRS_STRING_07_024: [STRING_length shall return the length of the underlying char* for the given handle] */
markrad 3:c0556ff7b8e3 662 size_t STRING_length(STRING_HANDLE handle)
markrad 3:c0556ff7b8e3 663 {
markrad 3:c0556ff7b8e3 664 size_t result = 0;
markrad 3:c0556ff7b8e3 665 /* Codes_SRS_STRING_07_025: [STRING_length shall return zero if the given handle is NULL.] */
markrad 3:c0556ff7b8e3 666 if (handle != NULL)
markrad 3:c0556ff7b8e3 667 {
markrad 3:c0556ff7b8e3 668 STRING* value = (STRING*)handle;
markrad 3:c0556ff7b8e3 669 result = strlen(value->s);
markrad 3:c0556ff7b8e3 670 }
markrad 3:c0556ff7b8e3 671 return result;
markrad 3:c0556ff7b8e3 672 }
markrad 3:c0556ff7b8e3 673
markrad 3:c0556ff7b8e3 674 /*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.]*/
markrad 3:c0556ff7b8e3 675 STRING_HANDLE STRING_construct_n(const char* psz, size_t n)
markrad 3:c0556ff7b8e3 676 {
markrad 3:c0556ff7b8e3 677 STRING_HANDLE result;
markrad 3:c0556ff7b8e3 678 /*Codes_SRS_STRING_02_008: [If psz is NULL then STRING_construct_n shall return NULL.] */
markrad 3:c0556ff7b8e3 679 if (psz == NULL)
markrad 3:c0556ff7b8e3 680 {
markrad 3:c0556ff7b8e3 681 result = NULL;
markrad 3:c0556ff7b8e3 682 LogError("invalid arg (NULL)");
markrad 3:c0556ff7b8e3 683 }
markrad 3:c0556ff7b8e3 684 else
markrad 3:c0556ff7b8e3 685 {
markrad 3:c0556ff7b8e3 686 size_t len = strlen(psz);
markrad 3:c0556ff7b8e3 687 /*Codes_SRS_STRING_02_009: [If n is bigger than the size of the string psz, then STRING_construct_n shall return NULL.] */
markrad 3:c0556ff7b8e3 688 if (n > len)
markrad 3:c0556ff7b8e3 689 {
markrad 3:c0556ff7b8e3 690 result = NULL;
markrad 3:c0556ff7b8e3 691 LogError("invalig arg (n is bigger than the size of the string)");
markrad 3:c0556ff7b8e3 692 }
markrad 3:c0556ff7b8e3 693 else
markrad 3:c0556ff7b8e3 694 {
markrad 3:c0556ff7b8e3 695 STRING* str;
markrad 3:c0556ff7b8e3 696 if ((str = (STRING*)malloc(sizeof(STRING))) != NULL)
markrad 3:c0556ff7b8e3 697 {
markrad 3:c0556ff7b8e3 698 if ((str->s = (char*)malloc(len + 1)) != NULL)
markrad 3:c0556ff7b8e3 699 {
markrad 3:c0556ff7b8e3 700 memcpy(str->s, psz, n);
markrad 3:c0556ff7b8e3 701 str->s[n] = '\0';
markrad 3:c0556ff7b8e3 702 result = (STRING_HANDLE)str;
markrad 3:c0556ff7b8e3 703 }
markrad 3:c0556ff7b8e3 704 /* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.] */
markrad 3:c0556ff7b8e3 705 else
markrad 3:c0556ff7b8e3 706 {
markrad 3:c0556ff7b8e3 707 free(str);
markrad 3:c0556ff7b8e3 708 result = NULL;
markrad 3:c0556ff7b8e3 709 }
markrad 3:c0556ff7b8e3 710 }
markrad 3:c0556ff7b8e3 711 else
markrad 3:c0556ff7b8e3 712 {
markrad 3:c0556ff7b8e3 713 /* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.] */
markrad 3:c0556ff7b8e3 714 result = NULL;
markrad 3:c0556ff7b8e3 715 }
markrad 3:c0556ff7b8e3 716 }
markrad 3:c0556ff7b8e3 717 }
markrad 3:c0556ff7b8e3 718 return result;
markrad 3:c0556ff7b8e3 719 }
markrad 3:c0556ff7b8e3 720
markrad 3:c0556ff7b8e3 721 /* 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.] */
markrad 3:c0556ff7b8e3 722 int STRING_compare(STRING_HANDLE s1, STRING_HANDLE s2)
markrad 3:c0556ff7b8e3 723 {
markrad 3:c0556ff7b8e3 724 int result;
markrad 3:c0556ff7b8e3 725 if (s1 == NULL && s2 == NULL)
markrad 3:c0556ff7b8e3 726 {
markrad 3:c0556ff7b8e3 727 /* Codes_SRS_STRING_07_035: [If h1 and h2 are both NULL then STRING_compare shall return 0.]*/
markrad 3:c0556ff7b8e3 728 result = 0;
markrad 3:c0556ff7b8e3 729 }
markrad 3:c0556ff7b8e3 730 else if (s1 == NULL)
markrad 3:c0556ff7b8e3 731 {
markrad 3:c0556ff7b8e3 732 /* Codes_SRS_STRING_07_036: [If h1 is NULL and h2 is nonNULL then STRING_compare shall return 1.]*/
markrad 3:c0556ff7b8e3 733 result = 1;
markrad 3:c0556ff7b8e3 734 }
markrad 3:c0556ff7b8e3 735 else if (s2 == NULL)
markrad 3:c0556ff7b8e3 736 {
markrad 3:c0556ff7b8e3 737 /* Codes_SRS_STRING_07_037: [If h2 is NULL and h1 is nonNULL then STRING_compare shall return -1.] */
markrad 3:c0556ff7b8e3 738 result = -1;
markrad 3:c0556ff7b8e3 739 }
markrad 3:c0556ff7b8e3 740 else
markrad 3:c0556ff7b8e3 741 {
markrad 3:c0556ff7b8e3 742 /* Codes_SRS_STRING_07_038: [STRING_compare shall compare the char s variable using the strcmp function.] */
markrad 3:c0556ff7b8e3 743 STRING* value1 = (STRING*)s1;
markrad 3:c0556ff7b8e3 744 STRING* value2 = (STRING*)s2;
markrad 3:c0556ff7b8e3 745 result = strcmp(value1->s, value2->s);
markrad 3:c0556ff7b8e3 746 }
markrad 3:c0556ff7b8e3 747 return result;
markrad 3:c0556ff7b8e3 748 }
markrad 3:c0556ff7b8e3 749
markrad 3:c0556ff7b8e3 750 STRING_HANDLE STRING_from_byte_array(const unsigned char* source, size_t size)
markrad 3:c0556ff7b8e3 751 {
markrad 3:c0556ff7b8e3 752 STRING* result;
markrad 3:c0556ff7b8e3 753 /*Codes_SRS_STRING_02_022: [ If source is NULL and size > 0 then STRING_from_BUFFER shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 754 if ((source == NULL) && (size > 0))
markrad 3:c0556ff7b8e3 755 {
markrad 3:c0556ff7b8e3 756 LogError("invalid parameter (NULL)");
markrad 3:c0556ff7b8e3 757 result = NULL;
markrad 3:c0556ff7b8e3 758 }
markrad 3:c0556ff7b8e3 759 else
markrad 3:c0556ff7b8e3 760 {
markrad 3:c0556ff7b8e3 761 /*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. ]*/
markrad 3:c0556ff7b8e3 762 result = (STRING*)malloc(sizeof(STRING));
markrad 3:c0556ff7b8e3 763 if (result == NULL)
markrad 3:c0556ff7b8e3 764 {
markrad 3:c0556ff7b8e3 765 /*Codes_SRS_STRING_02_024: [ If building the string fails, then STRING_from_BUFFER shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 766 LogError("oom - unable to malloc");
markrad 3:c0556ff7b8e3 767 /*return as is*/
markrad 3:c0556ff7b8e3 768 }
markrad 3:c0556ff7b8e3 769 else
markrad 3:c0556ff7b8e3 770 {
markrad 3:c0556ff7b8e3 771 /*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. ]*/
markrad 3:c0556ff7b8e3 772 result->s = (char*)malloc(size + 1);
markrad 3:c0556ff7b8e3 773 if (result->s == NULL)
markrad 3:c0556ff7b8e3 774 {
markrad 3:c0556ff7b8e3 775 /*Codes_SRS_STRING_02_024: [ If building the string fails, then STRING_from_BUFFER shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 776 LogError("oom - unable to malloc");
markrad 3:c0556ff7b8e3 777 free(result);
markrad 3:c0556ff7b8e3 778 result = NULL;
markrad 3:c0556ff7b8e3 779 }
markrad 3:c0556ff7b8e3 780 else
markrad 3:c0556ff7b8e3 781 {
markrad 3:c0556ff7b8e3 782 memcpy(result->s, source, size);
markrad 3:c0556ff7b8e3 783 result->s[size] = '\0'; /*all is fine*/
markrad 3:c0556ff7b8e3 784 }
markrad 3:c0556ff7b8e3 785 }
markrad 3:c0556ff7b8e3 786 }
markrad 3:c0556ff7b8e3 787 return (STRING_HANDLE)result;
markrad 3:c0556ff7b8e3 788 }