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
Diff: StringUtil.h
- Revision:
- 28:3c52f578708a
- Parent:
- 27:b63f5a9cdefa
- Child:
- 29:b6af04b77a56
--- a/StringUtil.h Thu Oct 23 15:21:50 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,413 +0,0 @@ -/** - * ACKme WiConnect Host Library is licensed under the BSD licence: - * - * Copyright (c)2014 ACKme Networks. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ -#pragma once - - -#include <string.h> -#include <ctype.h> -#include <stdint.h> -#include <limits.h> - - -#ifdef WICONNECT_USE_STRTOLL -// Necessary to get strtoll in C99 mode. -// http://sourceware.org/ml/newlib/2012/msg00425.html -extern long long strtoll(const char *__n, char **__end_PTR, int __base); -#endif - - -class StringUtil -{ - -public: - /*************************************************************************************************/ - // Helper to find an occurrence of a delimiter string, - // insert '\0' in its place and return string after - // the delimiter e.g. - // if char s[] = "foo://bar"; - // - strchop(s, "://") returns "bar" - // - s becomes "foo" - static char *chop(char *haystack, const char *needle) - { - if (!haystack) - { - return NULL; - } - char *end = strstr(haystack, needle); - if (end) - { - *end = '\0'; - return end + strlen(needle); - } - return NULL; - } - - /*************************************************************************************************/ - // Check if string is non-null and non-empty. - static bool empty(const char *s) - { - return !(s && *s); - } - - /*************************************************************************************************/ - static bool isSpace(const char *s) - { - while(*s != 0) - { - if(!isspace((uint8_t)*s++)) - return false; - } - return true; - } - - /*************************************************************************************************/ - // Convert null-terminated string to lower case. - // ASCII charset only. - static void toLower(char *s) - { - for (; *s; ++s) - { - *s = tolower((int) * s); - } - } - - /*************************************************************************************************/ - // Combination of strip left + right. - static char *strip(char *s, const char *chars) - { - return rightStrip(leftStrip(s, chars), chars); - } - - /*************************************************************************************************/ - // Strip string from the left. - // Returns pointer into the input string. - static char *leftStrip(char *s, const char *chars) - { - return s + strspn(s, chars); - } - - /*************************************************************************************************/ - // Strip string from the right. - // Modified in place. - static char *rightStrip(char *s, const char *chars) - { - char *end = s + strlen(s) - 1; - while (end > s && strstr(chars, end)) - { - *end-- = '\0'; - } - return s; - } - - /*************************************************************************************************/ - // Parse decimal integer and check if it's in bounds [min, max]. - static bool parseInt(const char *s, intmax_t *result, intmax_t min, intmax_t max) - { - return parseBase(s, result, min, max, 10); - } - - // Parse hexadecimal integer and check if it's in bounds [min, max]. - static bool parseHex(const char *s, intmax_t *result, intmax_t min, intmax_t max) - { - return parseBase(s, result, min, max, 16); - } - - /*************************************************************************************************/ - static bool parseBase(const char *s, intmax_t *result, intmax_t min, intmax_t max, int base) - { - if (!s) - { - return false; - } - char *end; -#ifdef WICONNECT_USE_STRTOLL - intmax_t value = strtoll(s, &end, base); -#else - intmax_t value = strtol(s, &end, base); -#endif - if (*end || value < min || value > max) - { - return false; - } - *result = value; - return true; - } - - /*************************************************************************************************/ - // Parse an long long integer. - static bool parseBool(const char *onoff, bool *var) - { - const char* const on_vals[] = - { - "1", - "on", - "true", - "yes", - }; - - for(uint8_t i = 0; i < ARRAY_COUNT(on_vals); ++i) - { - if(strcasecmp(on_vals[i], onoff) == 0) - { - *var = true; - return true; - } - } - - const char* const off_vals[] = - { - "0", - "false", - "no", - "off", - NULL - }; - for(uint8_t i = 0; i < ARRAY_COUNT(off_vals); ++i) - { - if(strcasecmp(off_vals[i], onoff) == 0) - { - *var = false; - return true; - } - } - - return false; - } - - /*************************************************************************************************/ - // convert binary data to hex string - static void binToHex(char *dst, int max_dst, const void *data, int data_len) - { - char *end = dst + max_dst - 1; - for (int i = 0; i < data_len; ++i) - { - if (dst < end) - { - dst += sprintf(dst, "%2.2x", ((uint8_t *)data)[i]); - } - } - } - - - /*************************************************************************************************/ - // Parse binary data into hex string - // the input buffer MUST be len*2 long - // as the parsing is destructive and done in-place - static void binToHex(void *h, int len) - { - char *dst = (char*)h; - char *src= (char*)h+len; - - memmove(src, dst, len); - - while(len--) - { - sprintf(dst, "%2.2X", (unsigned int)(*src & 0xff)); - dst += 2; - ++src; - } - } - - - /*************************************************************************************************/ - // Parses hex representation of binary data destructively. - // Returns number of bytes parsed or -1 on error. - static int hexToBin(char *s) - { - int len, i, j; - len = strlen(s); - if (len % 2) - { - return -1; - } - for (i = j = 0; i < len; i += 2, j++) - { - const int num = hexToInt(&s[i]); - if(num == -1) - return -1; - s[j] = (char)num; - } - return j; - } - - /*************************************************************************************************/ - // hex string to integer, returns -1 on error - static int hexToInt(const char *hex_str) - { - int hi = hexToNibble(*hex_str); - int lo = hexToNibble(*(hex_str+1)); - if (hi == -1 || lo == -1) - { - return -1; - } - return (hi << 4) | lo; - } - - /*************************************************************************************************/ - static int hexToNibble(char c) - { - if (c >= '0' && c <= '9') - { - return c - '0'; - } - if (c >= 'a' && c <= 'f') - { - return 10 + (c - 'a'); - } - if (c >= 'A' && c <= 'F') - { - return 10 + (c - 'A'); - } - return -1; - } - - /*************************************************************************************************/ - static const char* uint32ToStr(char* intStrBuffer, int integer) - { - sprintf(intStrBuffer, "%u", integer); - return intStrBuffer; - } - - /*************************************************************************************************/ - static bool strToUint32(const char *str, uint32_t *uint32Ptr) - { - intmax_t r; - bool result = (str[0] == '0' && str[1] == 'x') ? StringUtil::parseHex(&str[2], &r, 0, UINT_MAX): StringUtil::parseInt(str, &r, 0, UINT_MAX); - *uint32Ptr = (uint32_t)r; - return result; - } - - /*************************************************************************************************/ - static bool strToUint16(const char *str, uint16_t *uint16Ptr) - { - intmax_t r; - bool result = StringUtil::parseInt(str, &r, 0, USHRT_MAX); - *uint16Ptr = (uint16_t)r; - return result; - } - - /*************************************************************************************************/ - static bool strToInt32(const char *str, int32_t *int32Ptr) - { - intmax_t r; - bool result = StringUtil::parseInt(str, &r, INT_MIN, INT_MAX); - *int32Ptr = (int32_t)r; - return result; - } - - /*************************************************************************************************/ - // uint32 hex string to uint32 - static bool strHexToUint32(const char *strHex, uint32_t *uint32Ptr) - { - intmax_t r; - bool result = StringUtil::parseHex(strHex, &r, 0, UINT_MAX); - *uint32Ptr = (uint32_t)r; - return result; - } - - /*************************************************************************************************/ - static char *strtok_r(char *str, const char *delim, char **nextp) - { - char *ret; - - if (str == NULL) - { - str = *nextp; - } - - str += strspn(str, delim); - - if (*str == '\0') - { - return NULL; - } - - ret = str; - - str += strcspn(str, delim); - - if (*str) - { - *str++ = '\0'; - } - - *nextp = str; - - return ret; - } - - /*************************************************************************************************/ - static int strncasecmp(const char *s1, const char *s2, int n) - { - if (n == 0) - return 0; - - while (n-- != 0 && tolower(*s1) == tolower(*s2)) - { - if (n == 0 || *s1 == '\0' || *s2 == '\0') - break; - s1++; - s2++; - } - - return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); - } - - /*************************************************************************************************/ - static int strcasecmp(const char *s1, const char *s2) - { - register const unsigned char *p1 = (const unsigned char *) s1; - register const unsigned char *p2 = (const unsigned char *) s2; - unsigned char c1, c2; - - if (p1 == p2) - return 0; - - do - { - c1 = tolower (*p1); - c2 = tolower (*p2); - - if (c1 == '\0') - break; - - ++p1; - ++p2; - } - while (c1 == c2); - - if (UCHAR_MAX <= INT_MAX) - return c1 - c2; - else - /* On machines where 'char' and 'int' are types of the same size, the - difference of two 'unsigned char' values - including the sign bit - - doesn't fit in an 'int'. */ - return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); - } -};