changeset 278:02077e32cd70

manual wrapping of functions for queues
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 12 Aug 2025 16:17:57 +0200
parents 919836e3fafd
children 66768d476400
files CodeAnalysis/CustomFunctions.json CodeAnalysis/GenerateOrthancSDK.py Sources/Plugin.cpp
diffstat 3 files changed, 147 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/CodeAnalysis/CustomFunctions.json	Tue Aug 12 15:55:49 2025 +0200
+++ b/CodeAnalysis/CustomFunctions.json	Tue Aug 12 16:17:57 2025 +0200
@@ -382,7 +382,7 @@
     "documentation" : {
       "description" : [ "Get the value associated with a key in the Orthanc key-value store." ],
       "args" : {
-        "storeId" : "The key-value store.",
+        "storeId" : "The identifier of the key-value store.",
         "key" : "The key."
       },
       "return" : "The value, or None."
@@ -403,12 +403,60 @@
 
   {
     "comment" : "New in release 6.0",
+    "short_name" : "DequeueValue",
+    "implementation" : "DequeueValue",
+    "documentation" : {
+      "description" : [ "Dequeue a value from a queue." ],
+      "args" : {
+        "queueId" : "The identifier of the queue.",
+        "origin" : "The position from where the value is dequeued (back for LIFO, front for FIFO)."
+      },
+      "return" : "The value, or None if no more value is available."
+    },
+    "args" : [
+      {
+        "sdk_name" : "queueId",
+        "sdk_type" : "const char *"
+      },
+      {
+        "sdk_name" : "origin",
+        "sdk_type" : "enumeration",
+        "sdk_enumeration" : "OrthancPluginQueueOrigin"
+      }
+    ],
+    "return_sdk_type" : "OrthancPluginMemoryBuffer *",
+    "since_sdk" : [ 1, 12, 8 ]
+  },
+
+  {
+    "comment" : "New in release 6.0",
+    "short_name" : "GetQueueSize",
+    "implementation" : "GetQueueSize",
+    "documentation" : {
+      "description" : [ "Get the number of elements in a queue." ],
+      "args" : {
+        "queueId" : "The identifier of the queue."
+      },
+      "return" : "The value, or None."
+    },
+    "args" : [
+      {
+        "sdk_name" : "queueId",
+        "sdk_type" : "const char *"
+      }
+    ],
+    "return_sdk_type" : "uint64_t",
+    "since_sdk" : [ 1, 12, 8 ]
+  },
+
+  {
+    "comment" : "New in release 6.0",
     "short_name" : "SetStableStatus",
     "implementation" : "SetStableStatus",
     "documentation" : {
       "description" : [ "Change the Stable status of a resource" ],
       "args" : {
-        "resourceId" : "The id of the resource.",
+        "resourceId" : "The identifier of the resource.",
         "stableStatus" : "The new stable status: 0 for Stable, 1 for Unstable."
       },
       "return" : "A tuple with (The error code, An integer indicating wheter the status has changed (1) or not (0) during the execution of this command)."
--- a/CodeAnalysis/GenerateOrthancSDK.py	Tue Aug 12 15:55:49 2025 +0200
+++ b/CodeAnalysis/GenerateOrthancSDK.py	Tue Aug 12 16:17:57 2025 +0200
@@ -254,7 +254,7 @@
             arg_type = GetShortName(a['sdk_enumeration'])
         elif a['sdk_type'] == 'const_object':
             arg_type = GetShortName(a['sdk_class'])
-        elif a['sdk_type'] in [ 'int32_t', 'int64_t', 'uint32_t', 'uint8_t', 'uint16_t', 'uint64_t' ]:
+        elif a['sdk_type'] in [ 'int32_t', 'int64_t', 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t' ]:
             arg_type = 'int'
         elif a['sdk_type'] == 'Callable':
             # This is only used to generate the documentation file "orthanc.pyi"
@@ -288,7 +288,7 @@
         documentation['return_type'] = 'bytes'
     elif f['return_sdk_type'] in [ 'char *', 'const char *' ]:
         documentation['return_type'] = 'str'
-    elif f['return_sdk_type'] in [ 'int32_t', 'uint32_t', 'uint16_t', 'int64_t' ]:
+    elif f['return_sdk_type'] in [ 'int32_t', 'int64_t', 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t' ]:
         documentation['return_type'] = 'int'
     elif f['return_sdk_type'] == 'Dictionary':
         # This is only used to generate the documentation file "orthanc.pyi"
@@ -386,7 +386,7 @@
 
     if f['return_sdk_type'] == 'void':
         answer['return_void'] = True
-    elif f['return_sdk_type'] in [ 'int32_t', 'uint32_t', 'int64_t' ]:
+    elif f['return_sdk_type'] in [ 'int32_t', 'int64_t', 'uint32_t', 'uint64_t' ]:
         answer['return_long'] = True
     elif f['return_sdk_type'] == 'OrthancPluginMemoryBuffer *':
         answer['return_bytes'] = True
--- a/Sources/Plugin.cpp	Tue Aug 12 15:55:49 2025 +0200
+++ b/Sources/Plugin.cpp	Tue Aug 12 16:17:57 2025 +0200
@@ -304,7 +304,12 @@
   {
     uint8_t found = 0;
     OrthancPlugins::MemoryBuffer buffer;
-    OrthancPluginErrorCode code = OrthancPluginGetKeyValue(OrthancPlugins::GetGlobalContext(), &found, *buffer, storeId, key);
+    OrthancPluginErrorCode code;
+
+    {
+      PythonThreadsAllower allower;
+      code = OrthancPluginGetKeyValue(OrthancPlugins::GetGlobalContext(), &found, *buffer, storeId, key);
+    }
 
     if (code == OrthancPluginErrorCode_Success)
     {
@@ -328,6 +333,88 @@
 
 
 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8)
+PyObject* DequeueValue(PyObject* module, PyObject* args)
+{
+  // The GIL is locked at this point (no need to create "PythonLock")
+
+  const char* queueId = NULL;
+  unsigned long origin = 0;
+
+  if (!PyArg_ParseTuple(args, "sl", &queueId, &origin))
+  {
+    PyErr_SetString(PyExc_TypeError, "Bad arguments");
+    return NULL;
+  }
+  else
+  {
+    uint8_t found = 0;
+    OrthancPlugins::MemoryBuffer buffer;
+    OrthancPluginErrorCode code;
+
+    {
+      PythonThreadsAllower allower;
+      code = OrthancPluginDequeueValue(OrthancPlugins::GetGlobalContext(), &found, *buffer, queueId,
+                                       static_cast<OrthancPluginQueueOrigin>(origin));
+    }
+
+    if (code == OrthancPluginErrorCode_Success)
+    {
+      if (found)
+      {
+        return PyBytes_FromStringAndSize(reinterpret_cast<const char*>(buffer.GetData()), buffer.GetSize());
+      }
+      else
+      {
+        return Py_None;
+      }
+    }
+    else
+    {
+      PyErr_SetString(PyExc_TypeError, OrthancPluginGetErrorDescription(OrthancPlugins::GetGlobalContext(), code));
+      return NULL;
+    }
+  }
+}
+#endif
+
+
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8)
+PyObject* GetQueueSize(PyObject* module, PyObject* args)
+{
+  // The GIL is locked at this point (no need to create "PythonLock")
+
+  const char* queueId = NULL;
+
+  if (!PyArg_ParseTuple(args, "s", &queueId))
+  {
+    PyErr_SetString(PyExc_TypeError, "Bad arguments");
+    return NULL;
+  }
+  else
+  {
+    uint64_t size = 0;
+    OrthancPluginErrorCode code;
+
+    {
+      PythonThreadsAllower allower;
+      code = OrthancPluginGetQueueSize(OrthancPlugins::GetGlobalContext(), queueId, &size);
+    }
+
+    if (code == OrthancPluginErrorCode_Success)
+    {
+      return PyLong_FromLong(size);
+    }
+    else
+    {
+      PyErr_SetString(PyExc_TypeError, OrthancPluginGetErrorDescription(OrthancPlugins::GetGlobalContext(), code));
+      return NULL;
+    }
+  }
+}
+#endif
+
+
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8)
 PyObject* KeysValuesIteratorNext(sdk_OrthancPluginKeysValuesIterator_Object* self, PyObject *args)
 {
   // The GIL is locked at this point (no need to create "PythonLock")
@@ -340,7 +427,12 @@
   else
   {
     uint8_t done;
-    OrthancPluginErrorCode code = OrthancPluginKeysValuesIteratorNext(OrthancPlugins::GetGlobalContext(), &done, self->object_);
+    OrthancPluginErrorCode code;
+
+    {
+      PythonThreadsAllower allower;
+      code = OrthancPluginKeysValuesIteratorNext(OrthancPlugins::GetGlobalContext(), &done, self->object_);
+    }
 
     if (code == OrthancPluginErrorCode_Success)
     {