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