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

Revision:
0:ea85c4bb5e1f
Child:
1:6ec9998427ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/StringUtil.h	Mon Aug 11 09:58:24 2014 +0000
@@ -0,0 +1,387 @@
+/*
+ * Copyright 2014, ACKme Networks
+ * All Rights Reserved.
+ *
+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks;
+ * the contents of this file may not be disclosed to third parties, copied
+ * or duplicated in any form, in whole or in part, without the prior
+ * written permission of ACKme Networks.
+ */
+
+#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 = StringUtil::parseInt(str, &r, 0, UINT_MAX);
+        *uint32Ptr = (uint32_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);
+    }
+};
+