Parse integers and single-precision floats in incoming CBOR streams
authorThiago Macieira <thiago.macieira@intel.com>
Thu, 24 Mar 2016 00:04:08 +0000 (17:04 -0700)
committerHabib Virji <habib.virji@samsung.com>
Thu, 24 Mar 2016 23:27:22 +0000 (23:27 +0000)
Incoming single-precision data is automatically converted to
double-precision upon parsing. Integers are kept as is, but if the user
requests the data as floating point, we convert on the fly. That is
inefficient if the call is performed more than once, but the appication
shouldn't do that anyway to avoid memory allocations.

Fixes IOT-981.

Change-Id: I11a23ec8442c40bf9f7affff143e9edd0d17eec7
Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/6239
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Habib Virji <habib.virji@samsung.com>
resource/csdk/stack/src/ocpayload.c
resource/csdk/stack/src/ocpayloadparse.c

index c09c1e6..3e45446 100644 (file)
@@ -536,13 +536,21 @@ bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, do
 {
     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
 
-    if (!val || val->type != OCREP_PROP_DOUBLE)
+    if (val)
     {
-        return false;
+        if (val->type == OCREP_PROP_DOUBLE)
+        {
+            *value = val->d;
+            return true;
+        }
+        else if (val->type == OCREP_PROP_INT)
+        {
+            *value = val->i;
+            return true;
+        }
     }
 
-    *value = val->d;
-    return true;
+    return false;
 }
 
 bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
@@ -930,7 +938,8 @@ bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
 {
     OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
 
-    if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE
+    if (!val || val->type != OCREP_PROP_ARRAY ||
+        (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
             || !val->arr.dArray)
     {
         return false;
@@ -947,7 +956,19 @@ bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name,
         return false;
     }
 
-    memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+    if (val->arr.type != OCREP_PROP_DOUBLE)
+    {
+        memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+    }
+    else
+    {
+        /* need to convert from integer */
+        size_t n = 0;
+        for ( ; n < dimTotal; ++n)
+        {
+            (*array)[n] = val->arr.iArray[n];
+        }
+    }
     memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
     return true;
 }
index dfd8c0c..f2bbd53 100644 (file)
@@ -509,6 +509,7 @@ static OCRepPayloadPropType DecodeCborType(CborType type)
         case CborIntegerType:
             return OCREP_PROP_INT;
         case CborDoubleType:
+        case CborFloatType:
             return OCREP_PROP_DOUBLE;
         case CborBooleanType:
             return OCREP_PROP_BOOL;
@@ -655,7 +656,19 @@ static CborError OCParseArrayFillArray(const CborValue *parent,
                 case OCREP_PROP_DOUBLE:
                     if (dimensions[1] == 0)
                     {
-                        err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i]));
+                        double *d = &(((double*)targetArray)[i]);
+                        if (cbor_value_get_type(&insideArray) == CborDoubleType)
+                        {
+                            err = cbor_value_get_double(&insideArray, d);
+                        }
+                        else
+                        {
+                            /* must be float */
+                            float f;
+                            err = cbor_value_get_float(&insideArray, &f);
+                            if (!err)
+                                *d = f;
+                        }
                     }
                     else
                     {