handle the variant types for exposure time (string / integer) master
authorPat Thoyts <pat.thoyts@gmail.com>
Tue, 4 Jul 2023 14:53:54 +0000 (15:53 +0100)
committerPat Thoyts <pat.thoyts@gmail.com>
Tue, 4 Jul 2023 14:53:54 +0000 (15:53 +0100)
CMakeLists.txt
server.c
wdf_props.cpp

index 362f49e8fe41194c90785de94fbee9cfe39bc749..2e93a4e1c2211af7019bca25a5dfaeec14094509 100644 (file)
@@ -58,4 +58,6 @@ if (MSVC)
     target_compile_definitions(${TARGET} PUBLIC
         STRICT WIN32_LEAN_AND_MEAN
         _CRT_DECLARE_NONSTDC_NAMES _CRT_NONSTDC_NO_WARNINGS _CRT_SECURE_NO_WARNINGS)
+    # disable warning C5105: macro expansion producing 'defined' has undefined behavior
+    target_compile_options(${TARGET} PRIVATE -wd5105)
 endif()
index d1ac9eef4cb8c1e36d47d2ec342d44f97228542b..132821b5aa0b4639e2c494a6c2114433656a731b 100644 (file)
--- a/server.c
+++ b/server.c
@@ -58,7 +58,7 @@ static void getSpectrumCallback(UA_Server *server, void *clientData)
         { "Time",  "renishaw.spd.spectrum.time" },
         { "Flags", "renishaw.spd.spectrum.flags" },
         { "XList", "renishaw.spd.spectrum.xlist" },
-        { "YList", "renishaw.spd.spectrum.ilist" }
+        { "IList", "renishaw.spd.spectrum.ilist" }
     };
 
     App *app = (App *)clientData;
index 008cde569e0e40a0ca0439864d5e3145547ca7c6..26e3c7ac1dff7bf27430e06a8a923a190c254d11 100644 (file)
@@ -7,6 +7,40 @@
 
 constexpr int WDF_BLOCK_HDR_SIZE = 16;
 
+static UA_StatusCode get_property(Pset &pset, const char* keyname, UA_Variant* valuePtr)
+{
+    UA_StatusCode status = UA_STATUSCODE_BAD;
+    if (pset.exists(keyname))
+    {
+        status = UA_STATUSCODE_GOOD;
+        const auto item = pset.get_item(keyname);
+        switch (item->hdr.type)
+        {
+        case PSET_TYPE_INT:
+            UA_Variant_setScalar(valuePtr, const_cast<int32_t*>(&item->val.lVal), &UA_TYPES[UA_TYPES_INT32]);
+            break;
+        case PSET_TYPE_FLOAT:
+            UA_Variant_setScalar(valuePtr, const_cast<float*>(&item->val.fltVal), &UA_TYPES[UA_TYPES_FLOAT]);
+            break;
+        case PSET_TYPE_DOUBLE:
+            UA_Variant_setScalar(valuePtr, const_cast<double*>(&item->val.dblVal), &UA_TYPES[UA_TYPES_DOUBLE]);
+            break;
+        case PSET_TYPE_STRING:
+        {
+            UA_String str = { 0 };
+            str.length = item->length;
+            str.data = (UA_Byte*)UA_malloc(item->length);
+            memcpy(str.data, item->val.strVal, item->length);
+            UA_Variant_setScalarCopy(valuePtr, &str, &UA_TYPES[UA_TYPES_STRING]);
+            break;
+        }
+        default:
+            status = UA_STATUSCODE_BAD;
+        }
+    }
+    return status;
+}
+
 // works for WXDA properties - get by name.
 UA_StatusCode wdf_get_property(const char *filename, uint64_t pos, const char *keyname, UA_Variant *valuePtr)
 {
@@ -18,38 +52,37 @@ UA_StatusCode wdf_get_property(const char *filename, uint64_t pos, const char *k
     {
         const auto itemlist = Pset::ParseStream(file, len);
         Pset pset(itemlist, nullptr);
-        if (pset.exists(keyname))
-        {
-            status = UA_STATUSCODE_GOOD;
-            const auto item = pset.get_item(keyname);
-            switch (item->hdr.type)
-            {
-            case PSET_TYPE_INT:
-                UA_Variant_setScalar(valuePtr, const_cast<int32_t*>(&item->val.lVal), &UA_TYPES[UA_TYPES_INT32]);
-                break;
-            case PSET_TYPE_FLOAT:
-                UA_Variant_setScalar(valuePtr, const_cast<float*>(&item->val.fltVal), &UA_TYPES[UA_TYPES_FLOAT]);
-                break;
-            case PSET_TYPE_DOUBLE:
-                UA_Variant_setScalar(valuePtr, const_cast<double*>(&item->val.dblVal), &UA_TYPES[UA_TYPES_DOUBLE]);
-                break;
-            case PSET_TYPE_STRING:
-            {
-                UA_String str = { 0 };
-                str.length = item->length;
-                str.data = (UA_Byte*)UA_malloc(item->length);
-                memcpy(str.data, item->val.strVal, item->length);
-                UA_Variant_setScalarCopy(valuePtr, &str, &UA_TYPES[UA_TYPES_STRING]);
-                break;
-            }
-            default:
-                status = UA_STATUSCODE_BAD;
-            }
-        }
+        status = get_property(pset, keyname, valuePtr);
     }
     return status;
 }
 
+uint32_t strntol(const char* str, size_t len, char** end, int base)
+{
+    char buf[24];
+    uint32_t r = 0;
+    const char* beg = str;
+
+    // skip leading spaces
+    for (; beg && len && *beg == ' '; beg++, len--)
+        ;
+
+    if (!len || len >= sizeof(buf)) {
+        if (end)
+            *end = (char*)str;
+        return 0;
+    }
+
+    memcpy(buf, beg, len);
+    buf[len] = '\0';
+    r = strtol(buf, end, base);
+    if (r == LONG_MIN || r == LONG_MAX)
+        return r;
+    if (end)
+        *end = (char*)beg + (*end - buf);
+    return r;
+}
+
 uint32_t wdf_get_scan_exposuretime(const char* filename, uint64_t pos)
 {
     uint32_t value = 0;
@@ -65,7 +98,18 @@ uint32_t wdf_get_scan_exposuretime(const char* filename, uint64_t pos)
         const auto& scanitem = nameditems.get_item("Scan");
         Pset scan(scanitem->val.childVal, &nameditems);
         const auto extime = scan.get_item("Exposure Time");
-        value = extime->val.ulVal;
+        switch (extime->hdr.type)
+        {
+        case PSET_TYPE_SHORT:
+            value = static_cast<uint32_t>(extime->val.hVal);
+            break;
+        case PSET_TYPE_INT:
+            value = static_cast<uint32_t>(extime->val.lVal);
+            break;
+        case PSET_TYPE_STRING:
+            value = strntol(extime->val.strVal, extime->length, nullptr, 0);
+            break;
+        }
     }
     return value;
 }