Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Revision:
7:1af47e3a19b6
Parent:
6:c55b013dfc2a
Child:
11:77df6d7e65ae
diff -r c55b013dfc2a -r 1af47e3a19b6 httpapi_compact.c
--- a/httpapi_compact.c	Fri Jul 01 10:43:23 2016 -0700
+++ b/httpapi_compact.c	Fri Jul 29 16:01:07 2016 -0700
@@ -18,6 +18,7 @@
 #include "azure_c_shared_utility/tlsio.h"
 #include "azure_c_shared_utility/threadapi.h"
 #include <string.h>
+#include <limits.h>
 
 #define MAX_HOSTNAME     64
 #define TEMP_BUFFER_SIZE 4096
@@ -46,6 +47,68 @@
     unsigned int    is_connected : 1;
 } HTTP_HANDLE_DATA;
 
+/*the following function does the same as sscanf(pos2, "%d", &sec)*/
+/*this function only exists because some of platforms do not have sscanf. */
+static int ParseStringToDecimal(const char *src, int* dst)
+{
+    char* next;
+    (*dst) = strtol(src, &next, 0);
+    if ((src == next) || ((((*dst) == LONG_MAX) || ((*dst) == LONG_MIN)) && (errno != 0)))
+    {
+        return EOF;
+    }
+    return 1;
+}
+
+/*the following function does the same as sscanf(pos2, "%x", &sec)*/
+/*this function only exists because some of platforms do not have sscanf. This is not a full implementation; it only works with well-defined x numbers. */
+#define HEXA_DIGIT_VAL(c)         (((c>='0') && (c<='9')) ? (c-'0') : ((c>='a') && (c<='f')) ? (c-'a'+10) : ((c>='A') && (c<='F')) ? (c-'A'+10) : -1)
+static int ParseStringToHexadecimal(const char *src, int* dst)
+{
+    if (src == NULL)
+        return EOF;
+    if (HEXA_DIGIT_VAL(*src) == -1)
+        return EOF;
+
+    int digitVal;
+    (*dst) = 0;
+    while ((digitVal = HEXA_DIGIT_VAL(*src)) != -1)
+    {
+        (*dst) *= 0x10;
+        (*dst) += digitVal;
+        src++;
+    }
+    return 1;
+}
+
+/*the following function does the same as sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &ret) */
+/*this function only exists because some of platforms do not have sscanf. This is not a full implementation; it only works with well-defined HTTP response. */
+static int ParseHttpResponse(const char* src, int* dst)
+{
+    const char* prefix = "HTTP/";
+    while ((*prefix) != '\0')
+    {
+        if ((*prefix) != (*src))
+            return EOF;
+        prefix++;
+        src++;
+    }
+
+    while ((*src) != '.')
+    {
+        if ((*src) == '\0')
+            return EOF;
+    }
+
+    while ((*src) != ' ')
+    {
+        if ((*src) == '\0')
+            return EOF;
+    }
+
+    return ParseStringToDecimal(src, dst);
+}
+
 HTTPAPI_RESULT HTTPAPI_Init(void)
 {
     return HTTPAPI_OK;
@@ -529,7 +592,7 @@
     }
 
     //Parse HTTP response
-    if (sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &ret) != 1)
+    if (ParseHttpResponse(buf, &ret) != 1)
     {
         //Cannot match string, error
         LogInfo("HTTPAPI_ExecuteRequest::Not a correct HTTP answer=%s", buf);
@@ -555,7 +618,7 @@
 
         if (my_strnicmp(buf, ContentLength, CHAR_COUNT(ContentLength)) == 0)
         {
-            if (sscanf(buf + CHAR_COUNT(ContentLength), " %d", &bodyLength) != 1)
+            if (ParseStringToDecimal(buf + CHAR_COUNT(ContentLength), &bodyLength) != 1)
             {
                 result = HTTPAPI_READ_DATA_FAILED;
                 LogError("(result = %s)", ENUM_TO_STRING(HTTPAPI_RESULT, result));
@@ -640,7 +703,7 @@
                 LogError("(result = %s)", ENUM_TO_STRING(HTTPAPI_RESULT, result));
                 goto exit;
             }
-            if (sscanf(buf, "%x", &chunkSize) != 1)     // chunkSize is length of next line (/r/n is not counted)
+            if (ParseStringToHexadecimal(buf, &chunkSize) != 1)     // chunkSize is length of next line (/r/n is not counted)
             {
                 //Cannot match string, error
                 result = HTTPAPI_RECEIVE_RESPONSE_FAILED;