Host library for controlling a WiConnect enabled Wi-Fi module.

Dependents:   wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more

Committer:
dan_ackme
Date:
Tue Aug 26 16:53:06 2014 -0700
Revision:
22:2d7ef60a9f2a
Parent:
21:17bb3eddcbae
Child:
24:e27e23297f02
Child:
26:8067e3d463d3
fixed build error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dan_ackme 21:17bb3eddcbae 1 /**
dan_ackme 21:17bb3eddcbae 2 * ACKme WiConnect Host Library is licensed under the BSD licence:
dan_ackme 21:17bb3eddcbae 3 *
dan_ackme 21:17bb3eddcbae 4 * Copyright (c)2014 ACKme Networks.
dan_ackme 21:17bb3eddcbae 5 * All rights reserved.
dan_ackme 21:17bb3eddcbae 6 *
dan_ackme 21:17bb3eddcbae 7 * Redistribution and use in source and binary forms, with or without modification,
dan_ackme 21:17bb3eddcbae 8 * are permitted provided that the following conditions are met:
dan_ackme 21:17bb3eddcbae 9 *
dan_ackme 21:17bb3eddcbae 10 * 1. Redistributions of source code must retain the above copyright notice,
dan_ackme 21:17bb3eddcbae 11 * this list of conditions and the following disclaimer.
dan_ackme 21:17bb3eddcbae 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
dan_ackme 21:17bb3eddcbae 13 * this list of conditions and the following disclaimer in the documentation
dan_ackme 21:17bb3eddcbae 14 * and/or other materials provided with the distribution.
dan_ackme 21:17bb3eddcbae 15 * 3. The name of the author may not be used to endorse or promote products
dan_ackme 21:17bb3eddcbae 16 * derived from this software without specific prior written permission.
dan_ackme 21:17bb3eddcbae 17 *
dan_ackme 21:17bb3eddcbae 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
dan_ackme 21:17bb3eddcbae 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
dan_ackme 21:17bb3eddcbae 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
dan_ackme 21:17bb3eddcbae 21 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
dan_ackme 21:17bb3eddcbae 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
dan_ackme 21:17bb3eddcbae 23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dan_ackme 21:17bb3eddcbae 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dan_ackme 21:17bb3eddcbae 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
dan_ackme 21:17bb3eddcbae 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
dan_ackme 21:17bb3eddcbae 27 * OF SUCH DAMAGE.
dan_ackme 0:ea85c4bb5e1f 28 */
dan_ackme 0:ea85c4bb5e1f 29 #pragma once
dan_ackme 0:ea85c4bb5e1f 30
dan_ackme 0:ea85c4bb5e1f 31
dan_ackme 0:ea85c4bb5e1f 32 #include <string.h>
dan_ackme 0:ea85c4bb5e1f 33 #include <ctype.h>
dan_ackme 0:ea85c4bb5e1f 34 #include <stdint.h>
dan_ackme 0:ea85c4bb5e1f 35 #include <limits.h>
dan_ackme 0:ea85c4bb5e1f 36
dan_ackme 0:ea85c4bb5e1f 37
dan_ackme 0:ea85c4bb5e1f 38 #ifdef WICONNECT_USE_STRTOLL
dan_ackme 0:ea85c4bb5e1f 39 // Necessary to get strtoll in C99 mode.
dan_ackme 0:ea85c4bb5e1f 40 // http://sourceware.org/ml/newlib/2012/msg00425.html
dan_ackme 0:ea85c4bb5e1f 41 extern long long strtoll(const char *__n, char **__end_PTR, int __base);
dan_ackme 0:ea85c4bb5e1f 42 #endif
dan_ackme 0:ea85c4bb5e1f 43
dan_ackme 0:ea85c4bb5e1f 44
dan_ackme 0:ea85c4bb5e1f 45 class StringUtil
dan_ackme 0:ea85c4bb5e1f 46 {
dan_ackme 0:ea85c4bb5e1f 47
dan_ackme 0:ea85c4bb5e1f 48 public:
dan_ackme 0:ea85c4bb5e1f 49 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 50 // Helper to find an occurrence of a delimiter string,
dan_ackme 0:ea85c4bb5e1f 51 // insert '\0' in its place and return string after
dan_ackme 0:ea85c4bb5e1f 52 // the delimiter e.g.
dan_ackme 0:ea85c4bb5e1f 53 // if char s[] = "foo://bar";
dan_ackme 0:ea85c4bb5e1f 54 // - strchop(s, "://") returns "bar"
dan_ackme 0:ea85c4bb5e1f 55 // - s becomes "foo"
dan_ackme 0:ea85c4bb5e1f 56 static char *chop(char *haystack, const char *needle)
dan_ackme 0:ea85c4bb5e1f 57 {
dan_ackme 0:ea85c4bb5e1f 58 if (!haystack)
dan_ackme 0:ea85c4bb5e1f 59 {
dan_ackme 0:ea85c4bb5e1f 60 return NULL;
dan_ackme 0:ea85c4bb5e1f 61 }
dan_ackme 0:ea85c4bb5e1f 62 char *end = strstr(haystack, needle);
dan_ackme 0:ea85c4bb5e1f 63 if (end)
dan_ackme 0:ea85c4bb5e1f 64 {
dan_ackme 0:ea85c4bb5e1f 65 *end = '\0';
dan_ackme 0:ea85c4bb5e1f 66 return end + strlen(needle);
dan_ackme 0:ea85c4bb5e1f 67 }
dan_ackme 0:ea85c4bb5e1f 68 return NULL;
dan_ackme 0:ea85c4bb5e1f 69 }
dan_ackme 0:ea85c4bb5e1f 70
dan_ackme 0:ea85c4bb5e1f 71 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 72 // Check if string is non-null and non-empty.
dan_ackme 0:ea85c4bb5e1f 73 static bool empty(const char *s)
dan_ackme 0:ea85c4bb5e1f 74 {
dan_ackme 0:ea85c4bb5e1f 75 return !(s && *s);
dan_ackme 0:ea85c4bb5e1f 76 }
dan_ackme 0:ea85c4bb5e1f 77
dan_ackme 0:ea85c4bb5e1f 78 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 79 static bool isSpace(const char *s)
dan_ackme 0:ea85c4bb5e1f 80 {
dan_ackme 0:ea85c4bb5e1f 81 while(*s != 0)
dan_ackme 0:ea85c4bb5e1f 82 {
dan_ackme 0:ea85c4bb5e1f 83 if(!isspace((uint8_t)*s++))
dan_ackme 0:ea85c4bb5e1f 84 return false;
dan_ackme 0:ea85c4bb5e1f 85 }
dan_ackme 0:ea85c4bb5e1f 86 return true;
dan_ackme 0:ea85c4bb5e1f 87 }
dan_ackme 0:ea85c4bb5e1f 88
dan_ackme 0:ea85c4bb5e1f 89 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 90 // Convert null-terminated string to lower case.
dan_ackme 0:ea85c4bb5e1f 91 // ASCII charset only.
dan_ackme 0:ea85c4bb5e1f 92 static void toLower(char *s)
dan_ackme 0:ea85c4bb5e1f 93 {
dan_ackme 0:ea85c4bb5e1f 94 for (; *s; ++s)
dan_ackme 0:ea85c4bb5e1f 95 {
dan_ackme 0:ea85c4bb5e1f 96 *s = tolower((int) * s);
dan_ackme 0:ea85c4bb5e1f 97 }
dan_ackme 0:ea85c4bb5e1f 98 }
dan_ackme 0:ea85c4bb5e1f 99
dan_ackme 0:ea85c4bb5e1f 100 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 101 // Combination of strip left + right.
dan_ackme 0:ea85c4bb5e1f 102 static char *strip(char *s, const char *chars)
dan_ackme 0:ea85c4bb5e1f 103 {
dan_ackme 0:ea85c4bb5e1f 104 return rightStrip(leftStrip(s, chars), chars);
dan_ackme 0:ea85c4bb5e1f 105 }
dan_ackme 0:ea85c4bb5e1f 106
dan_ackme 0:ea85c4bb5e1f 107 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 108 // Strip string from the left.
dan_ackme 0:ea85c4bb5e1f 109 // Returns pointer into the input string.
dan_ackme 0:ea85c4bb5e1f 110 static char *leftStrip(char *s, const char *chars)
dan_ackme 0:ea85c4bb5e1f 111 {
dan_ackme 0:ea85c4bb5e1f 112 return s + strspn(s, chars);
dan_ackme 0:ea85c4bb5e1f 113 }
dan_ackme 0:ea85c4bb5e1f 114
dan_ackme 0:ea85c4bb5e1f 115 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 116 // Strip string from the right.
dan_ackme 0:ea85c4bb5e1f 117 // Modified in place.
dan_ackme 0:ea85c4bb5e1f 118 static char *rightStrip(char *s, const char *chars)
dan_ackme 0:ea85c4bb5e1f 119 {
dan_ackme 0:ea85c4bb5e1f 120 char *end = s + strlen(s) - 1;
dan_ackme 0:ea85c4bb5e1f 121 while (end > s && strstr(chars, end))
dan_ackme 0:ea85c4bb5e1f 122 {
dan_ackme 0:ea85c4bb5e1f 123 *end-- = '\0';
dan_ackme 0:ea85c4bb5e1f 124 }
dan_ackme 0:ea85c4bb5e1f 125 return s;
dan_ackme 0:ea85c4bb5e1f 126 }
dan_ackme 0:ea85c4bb5e1f 127
dan_ackme 0:ea85c4bb5e1f 128 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 129 // Parse decimal integer and check if it's in bounds [min, max].
dan_ackme 0:ea85c4bb5e1f 130 static bool parseInt(const char *s, intmax_t *result, intmax_t min, intmax_t max)
dan_ackme 0:ea85c4bb5e1f 131 {
dan_ackme 0:ea85c4bb5e1f 132 return parseBase(s, result, min, max, 10);
dan_ackme 0:ea85c4bb5e1f 133 }
dan_ackme 0:ea85c4bb5e1f 134
dan_ackme 0:ea85c4bb5e1f 135 // Parse hexadecimal integer and check if it's in bounds [min, max].
dan_ackme 0:ea85c4bb5e1f 136 static bool parseHex(const char *s, intmax_t *result, intmax_t min, intmax_t max)
dan_ackme 0:ea85c4bb5e1f 137 {
dan_ackme 0:ea85c4bb5e1f 138 return parseBase(s, result, min, max, 16);
dan_ackme 0:ea85c4bb5e1f 139 }
dan_ackme 0:ea85c4bb5e1f 140
dan_ackme 0:ea85c4bb5e1f 141 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 142 static bool parseBase(const char *s, intmax_t *result, intmax_t min, intmax_t max, int base)
dan_ackme 0:ea85c4bb5e1f 143 {
dan_ackme 0:ea85c4bb5e1f 144 if (!s)
dan_ackme 0:ea85c4bb5e1f 145 {
dan_ackme 0:ea85c4bb5e1f 146 return false;
dan_ackme 0:ea85c4bb5e1f 147 }
dan_ackme 0:ea85c4bb5e1f 148 char *end;
dan_ackme 0:ea85c4bb5e1f 149 #ifdef WICONNECT_USE_STRTOLL
dan_ackme 0:ea85c4bb5e1f 150 intmax_t value = strtoll(s, &end, base);
dan_ackme 0:ea85c4bb5e1f 151 #else
dan_ackme 0:ea85c4bb5e1f 152 intmax_t value = strtol(s, &end, base);
dan_ackme 0:ea85c4bb5e1f 153 #endif
dan_ackme 0:ea85c4bb5e1f 154 if (*end || value < min || value > max)
dan_ackme 0:ea85c4bb5e1f 155 {
dan_ackme 0:ea85c4bb5e1f 156 return false;
dan_ackme 0:ea85c4bb5e1f 157 }
dan_ackme 0:ea85c4bb5e1f 158 *result = value;
dan_ackme 0:ea85c4bb5e1f 159 return true;
dan_ackme 0:ea85c4bb5e1f 160 }
dan_ackme 0:ea85c4bb5e1f 161
dan_ackme 0:ea85c4bb5e1f 162 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 163 // Parse an long long integer.
dan_ackme 0:ea85c4bb5e1f 164 static bool parseBool(const char *onoff, bool *var)
dan_ackme 0:ea85c4bb5e1f 165 {
dan_ackme 0:ea85c4bb5e1f 166 const char* const on_vals[] =
dan_ackme 0:ea85c4bb5e1f 167 {
dan_ackme 0:ea85c4bb5e1f 168 "1",
dan_ackme 0:ea85c4bb5e1f 169 "on",
dan_ackme 0:ea85c4bb5e1f 170 "true",
dan_ackme 0:ea85c4bb5e1f 171 "yes",
dan_ackme 0:ea85c4bb5e1f 172 };
dan_ackme 0:ea85c4bb5e1f 173
dan_ackme 0:ea85c4bb5e1f 174 for(uint8_t i = 0; i < ARRAY_COUNT(on_vals); ++i)
dan_ackme 0:ea85c4bb5e1f 175 {
dan_ackme 0:ea85c4bb5e1f 176 if(strcasecmp(on_vals[i], onoff) == 0)
dan_ackme 0:ea85c4bb5e1f 177 {
dan_ackme 0:ea85c4bb5e1f 178 *var = true;
dan_ackme 0:ea85c4bb5e1f 179 return true;
dan_ackme 0:ea85c4bb5e1f 180 }
dan_ackme 0:ea85c4bb5e1f 181 }
dan_ackme 0:ea85c4bb5e1f 182
dan_ackme 0:ea85c4bb5e1f 183 const char* const off_vals[] =
dan_ackme 0:ea85c4bb5e1f 184 {
dan_ackme 0:ea85c4bb5e1f 185 "0",
dan_ackme 0:ea85c4bb5e1f 186 "false",
dan_ackme 0:ea85c4bb5e1f 187 "no",
dan_ackme 0:ea85c4bb5e1f 188 "off",
dan_ackme 0:ea85c4bb5e1f 189 NULL
dan_ackme 0:ea85c4bb5e1f 190 };
dan_ackme 0:ea85c4bb5e1f 191 for(uint8_t i = 0; i < ARRAY_COUNT(off_vals); ++i)
dan_ackme 0:ea85c4bb5e1f 192 {
dan_ackme 0:ea85c4bb5e1f 193 if(strcasecmp(off_vals[i], onoff) == 0)
dan_ackme 0:ea85c4bb5e1f 194 {
dan_ackme 0:ea85c4bb5e1f 195 *var = false;
dan_ackme 0:ea85c4bb5e1f 196 return true;
dan_ackme 0:ea85c4bb5e1f 197 }
dan_ackme 0:ea85c4bb5e1f 198 }
dan_ackme 0:ea85c4bb5e1f 199
dan_ackme 0:ea85c4bb5e1f 200 return false;
dan_ackme 0:ea85c4bb5e1f 201 }
dan_ackme 0:ea85c4bb5e1f 202
dan_ackme 0:ea85c4bb5e1f 203 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 204 // convert binary data to hex string
dan_ackme 0:ea85c4bb5e1f 205 static void binToHex(char *dst, int max_dst, const void *data, int data_len)
dan_ackme 0:ea85c4bb5e1f 206 {
dan_ackme 0:ea85c4bb5e1f 207 char *end = dst + max_dst - 1;
dan_ackme 0:ea85c4bb5e1f 208 for (int i = 0; i < data_len; ++i)
dan_ackme 0:ea85c4bb5e1f 209 {
dan_ackme 0:ea85c4bb5e1f 210 if (dst < end)
dan_ackme 0:ea85c4bb5e1f 211 {
dan_ackme 0:ea85c4bb5e1f 212 dst += sprintf(dst, "%2.2x", ((uint8_t *)data)[i]);
dan_ackme 0:ea85c4bb5e1f 213 }
dan_ackme 0:ea85c4bb5e1f 214 }
dan_ackme 0:ea85c4bb5e1f 215 }
dan_ackme 0:ea85c4bb5e1f 216
dan_ackme 0:ea85c4bb5e1f 217
dan_ackme 0:ea85c4bb5e1f 218 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 219 // Parse binary data into hex string
dan_ackme 0:ea85c4bb5e1f 220 // the input buffer MUST be len*2 long
dan_ackme 0:ea85c4bb5e1f 221 // as the parsing is destructive and done in-place
dan_ackme 0:ea85c4bb5e1f 222 static void binToHex(void *h, int len)
dan_ackme 0:ea85c4bb5e1f 223 {
dan_ackme 0:ea85c4bb5e1f 224 char *dst = (char*)h;
dan_ackme 0:ea85c4bb5e1f 225 char *src= (char*)h+len;
dan_ackme 0:ea85c4bb5e1f 226
dan_ackme 0:ea85c4bb5e1f 227 memmove(src, dst, len);
dan_ackme 0:ea85c4bb5e1f 228
dan_ackme 0:ea85c4bb5e1f 229 while(len--)
dan_ackme 0:ea85c4bb5e1f 230 {
dan_ackme 0:ea85c4bb5e1f 231 sprintf(dst, "%2.2X", (unsigned int)(*src & 0xff));
dan_ackme 0:ea85c4bb5e1f 232 dst += 2;
dan_ackme 0:ea85c4bb5e1f 233 ++src;
dan_ackme 0:ea85c4bb5e1f 234 }
dan_ackme 0:ea85c4bb5e1f 235 }
dan_ackme 0:ea85c4bb5e1f 236
dan_ackme 0:ea85c4bb5e1f 237
dan_ackme 0:ea85c4bb5e1f 238 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 239 // Parses hex representation of binary data destructively.
dan_ackme 0:ea85c4bb5e1f 240 // Returns number of bytes parsed or -1 on error.
dan_ackme 0:ea85c4bb5e1f 241 static int hexToBin(char *s)
dan_ackme 0:ea85c4bb5e1f 242 {
dan_ackme 0:ea85c4bb5e1f 243 int len, i, j;
dan_ackme 0:ea85c4bb5e1f 244 len = strlen(s);
dan_ackme 0:ea85c4bb5e1f 245 if (len % 2)
dan_ackme 0:ea85c4bb5e1f 246 {
dan_ackme 0:ea85c4bb5e1f 247 return -1;
dan_ackme 0:ea85c4bb5e1f 248 }
dan_ackme 0:ea85c4bb5e1f 249 for (i = j = 0; i < len; i += 2, j++)
dan_ackme 0:ea85c4bb5e1f 250 {
dan_ackme 0:ea85c4bb5e1f 251 const int num = hexToInt(&s[i]);
dan_ackme 0:ea85c4bb5e1f 252 if(num == -1)
dan_ackme 0:ea85c4bb5e1f 253 return -1;
dan_ackme 0:ea85c4bb5e1f 254 s[j] = (char)num;
dan_ackme 0:ea85c4bb5e1f 255 }
dan_ackme 0:ea85c4bb5e1f 256 return j;
dan_ackme 0:ea85c4bb5e1f 257 }
dan_ackme 0:ea85c4bb5e1f 258
dan_ackme 0:ea85c4bb5e1f 259 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 260 // hex string to integer, returns -1 on error
dan_ackme 0:ea85c4bb5e1f 261 static int hexToInt(const char *hex_str)
dan_ackme 0:ea85c4bb5e1f 262 {
dan_ackme 0:ea85c4bb5e1f 263 int hi = hexToNibble(*hex_str);
dan_ackme 0:ea85c4bb5e1f 264 int lo = hexToNibble(*(hex_str+1));
dan_ackme 0:ea85c4bb5e1f 265 if (hi == -1 || lo == -1)
dan_ackme 0:ea85c4bb5e1f 266 {
dan_ackme 0:ea85c4bb5e1f 267 return -1;
dan_ackme 0:ea85c4bb5e1f 268 }
dan_ackme 0:ea85c4bb5e1f 269 return (hi << 4) | lo;
dan_ackme 0:ea85c4bb5e1f 270 }
dan_ackme 0:ea85c4bb5e1f 271
dan_ackme 0:ea85c4bb5e1f 272 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 273 static int hexToNibble(char c)
dan_ackme 0:ea85c4bb5e1f 274 {
dan_ackme 0:ea85c4bb5e1f 275 if (c >= '0' && c <= '9')
dan_ackme 0:ea85c4bb5e1f 276 {
dan_ackme 0:ea85c4bb5e1f 277 return c - '0';
dan_ackme 0:ea85c4bb5e1f 278 }
dan_ackme 0:ea85c4bb5e1f 279 if (c >= 'a' && c <= 'f')
dan_ackme 0:ea85c4bb5e1f 280 {
dan_ackme 0:ea85c4bb5e1f 281 return 10 + (c - 'a');
dan_ackme 0:ea85c4bb5e1f 282 }
dan_ackme 0:ea85c4bb5e1f 283 if (c >= 'A' && c <= 'F')
dan_ackme 0:ea85c4bb5e1f 284 {
dan_ackme 0:ea85c4bb5e1f 285 return 10 + (c - 'A');
dan_ackme 0:ea85c4bb5e1f 286 }
dan_ackme 0:ea85c4bb5e1f 287 return -1;
dan_ackme 0:ea85c4bb5e1f 288 }
dan_ackme 0:ea85c4bb5e1f 289
dan_ackme 0:ea85c4bb5e1f 290 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 291 static const char* uint32ToStr(char* intStrBuffer, int integer)
dan_ackme 0:ea85c4bb5e1f 292 {
dan_ackme 0:ea85c4bb5e1f 293 sprintf(intStrBuffer, "%u", integer);
dan_ackme 0:ea85c4bb5e1f 294 return intStrBuffer;
dan_ackme 0:ea85c4bb5e1f 295 }
dan_ackme 0:ea85c4bb5e1f 296
dan_ackme 0:ea85c4bb5e1f 297 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 298 static bool strToUint32(const char *str, uint32_t *uint32Ptr)
dan_ackme 0:ea85c4bb5e1f 299 {
dan_ackme 0:ea85c4bb5e1f 300 intmax_t r;
dan_ackme 22:2d7ef60a9f2a 301 bool result = StringUtil::parseInt(str, &r, 0, UINT_MAX);
dan_ackme 0:ea85c4bb5e1f 302 *uint32Ptr = (uint32_t)r;
dan_ackme 0:ea85c4bb5e1f 303 return result;
dan_ackme 0:ea85c4bb5e1f 304 }
dan_ackme 0:ea85c4bb5e1f 305
dan_ackme 0:ea85c4bb5e1f 306 /*************************************************************************************************/
dan_ackme 21:17bb3eddcbae 307 static bool strToUint16(const char *str, uint16_t *uint16Ptr)
dan_ackme 21:17bb3eddcbae 308 {
dan_ackme 21:17bb3eddcbae 309 intmax_t r;
dan_ackme 22:2d7ef60a9f2a 310 bool result = StringUtil::parseInt(str, &r, 0, USHRT_MAX);
dan_ackme 21:17bb3eddcbae 311 *uint16Ptr = (uint16_t)r;
dan_ackme 21:17bb3eddcbae 312 return result;
dan_ackme 21:17bb3eddcbae 313 }
dan_ackme 21:17bb3eddcbae 314
dan_ackme 21:17bb3eddcbae 315 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 316 static bool strToInt32(const char *str, int32_t *int32Ptr)
dan_ackme 0:ea85c4bb5e1f 317 {
dan_ackme 0:ea85c4bb5e1f 318 intmax_t r;
dan_ackme 22:2d7ef60a9f2a 319 bool result = StringUtil::parseInt(str, &r, INT_MIN, INT_MAX);
dan_ackme 0:ea85c4bb5e1f 320 *int32Ptr = (int32_t)r;
dan_ackme 0:ea85c4bb5e1f 321 return result;
dan_ackme 0:ea85c4bb5e1f 322 }
dan_ackme 0:ea85c4bb5e1f 323
dan_ackme 0:ea85c4bb5e1f 324 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 325 // uint32 hex string to uint32
dan_ackme 0:ea85c4bb5e1f 326 static bool strHexToUint32(const char *strHex, uint32_t *uint32Ptr)
dan_ackme 0:ea85c4bb5e1f 327 {
dan_ackme 0:ea85c4bb5e1f 328 intmax_t r;
dan_ackme 22:2d7ef60a9f2a 329 bool result = StringUtil::parseHex(strHex, &r, 0, UINT_MAX);
dan_ackme 0:ea85c4bb5e1f 330 *uint32Ptr = (uint32_t)r;
dan_ackme 0:ea85c4bb5e1f 331 return result;
dan_ackme 0:ea85c4bb5e1f 332 }
dan_ackme 0:ea85c4bb5e1f 333
dan_ackme 0:ea85c4bb5e1f 334 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 335 static char *strtok_r(char *str, const char *delim, char **nextp)
dan_ackme 0:ea85c4bb5e1f 336 {
dan_ackme 0:ea85c4bb5e1f 337 char *ret;
dan_ackme 0:ea85c4bb5e1f 338
dan_ackme 0:ea85c4bb5e1f 339 if (str == NULL)
dan_ackme 0:ea85c4bb5e1f 340 {
dan_ackme 0:ea85c4bb5e1f 341 str = *nextp;
dan_ackme 0:ea85c4bb5e1f 342 }
dan_ackme 0:ea85c4bb5e1f 343
dan_ackme 0:ea85c4bb5e1f 344 str += strspn(str, delim);
dan_ackme 0:ea85c4bb5e1f 345
dan_ackme 0:ea85c4bb5e1f 346 if (*str == '\0')
dan_ackme 0:ea85c4bb5e1f 347 {
dan_ackme 0:ea85c4bb5e1f 348 return NULL;
dan_ackme 0:ea85c4bb5e1f 349 }
dan_ackme 0:ea85c4bb5e1f 350
dan_ackme 0:ea85c4bb5e1f 351 ret = str;
dan_ackme 0:ea85c4bb5e1f 352
dan_ackme 0:ea85c4bb5e1f 353 str += strcspn(str, delim);
dan_ackme 0:ea85c4bb5e1f 354
dan_ackme 0:ea85c4bb5e1f 355 if (*str)
dan_ackme 0:ea85c4bb5e1f 356 {
dan_ackme 0:ea85c4bb5e1f 357 *str++ = '\0';
dan_ackme 0:ea85c4bb5e1f 358 }
dan_ackme 0:ea85c4bb5e1f 359
dan_ackme 0:ea85c4bb5e1f 360 *nextp = str;
dan_ackme 0:ea85c4bb5e1f 361
dan_ackme 0:ea85c4bb5e1f 362 return ret;
dan_ackme 0:ea85c4bb5e1f 363 }
dan_ackme 0:ea85c4bb5e1f 364
dan_ackme 0:ea85c4bb5e1f 365 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 366 static int strncasecmp(const char *s1, const char *s2, int n)
dan_ackme 0:ea85c4bb5e1f 367 {
dan_ackme 0:ea85c4bb5e1f 368 if (n == 0)
dan_ackme 0:ea85c4bb5e1f 369 return 0;
dan_ackme 0:ea85c4bb5e1f 370
dan_ackme 0:ea85c4bb5e1f 371 while (n-- != 0 && tolower(*s1) == tolower(*s2))
dan_ackme 0:ea85c4bb5e1f 372 {
dan_ackme 0:ea85c4bb5e1f 373 if (n == 0 || *s1 == '\0' || *s2 == '\0')
dan_ackme 0:ea85c4bb5e1f 374 break;
dan_ackme 0:ea85c4bb5e1f 375 s1++;
dan_ackme 0:ea85c4bb5e1f 376 s2++;
dan_ackme 0:ea85c4bb5e1f 377 }
dan_ackme 0:ea85c4bb5e1f 378
dan_ackme 0:ea85c4bb5e1f 379 return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2);
dan_ackme 0:ea85c4bb5e1f 380 }
dan_ackme 0:ea85c4bb5e1f 381
dan_ackme 0:ea85c4bb5e1f 382 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 383 static int strcasecmp(const char *s1, const char *s2)
dan_ackme 0:ea85c4bb5e1f 384 {
dan_ackme 0:ea85c4bb5e1f 385 register const unsigned char *p1 = (const unsigned char *) s1;
dan_ackme 0:ea85c4bb5e1f 386 register const unsigned char *p2 = (const unsigned char *) s2;
dan_ackme 0:ea85c4bb5e1f 387 unsigned char c1, c2;
dan_ackme 0:ea85c4bb5e1f 388
dan_ackme 0:ea85c4bb5e1f 389 if (p1 == p2)
dan_ackme 0:ea85c4bb5e1f 390 return 0;
dan_ackme 0:ea85c4bb5e1f 391
dan_ackme 0:ea85c4bb5e1f 392 do
dan_ackme 0:ea85c4bb5e1f 393 {
dan_ackme 0:ea85c4bb5e1f 394 c1 = tolower (*p1);
dan_ackme 0:ea85c4bb5e1f 395 c2 = tolower (*p2);
dan_ackme 0:ea85c4bb5e1f 396
dan_ackme 0:ea85c4bb5e1f 397 if (c1 == '\0')
dan_ackme 0:ea85c4bb5e1f 398 break;
dan_ackme 0:ea85c4bb5e1f 399
dan_ackme 0:ea85c4bb5e1f 400 ++p1;
dan_ackme 0:ea85c4bb5e1f 401 ++p2;
dan_ackme 0:ea85c4bb5e1f 402 }
dan_ackme 0:ea85c4bb5e1f 403 while (c1 == c2);
dan_ackme 0:ea85c4bb5e1f 404
dan_ackme 0:ea85c4bb5e1f 405 if (UCHAR_MAX <= INT_MAX)
dan_ackme 0:ea85c4bb5e1f 406 return c1 - c2;
dan_ackme 0:ea85c4bb5e1f 407 else
dan_ackme 0:ea85c4bb5e1f 408 /* On machines where 'char' and 'int' are types of the same size, the
dan_ackme 0:ea85c4bb5e1f 409 difference of two 'unsigned char' values - including the sign bit -
dan_ackme 0:ea85c4bb5e1f 410 doesn't fit in an 'int'. */
dan_ackme 0:ea85c4bb5e1f 411 return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
dan_ackme 0:ea85c4bb5e1f 412 }
dan_ackme 0:ea85c4bb5e1f 413 };