From eeefff2cdecff940b229eb31853440e5574722ab Mon Sep 17 00:00:00 2001
From: Christian Zimmermann <christian.zimmermann@ur.de>
Date: Mon, 5 Feb 2024 00:38:08 +0100
Subject: [PATCH] WIP: range wrapper + WIP: array IO

---
 cnorxz/core/include/array_wrapper.h |  4 ++
 cnorxz/core/include/range_wrapper.h | 41 +++++++++++++++++
 cnorxz/core/lib/range_wrapper.cpp   | 68 +++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 cnorxz/core/include/range_wrapper.h
 create mode 100644 cnorxz/core/lib/range_wrapper.cpp

diff --git a/cnorxz/core/include/array_wrapper.h b/cnorxz/core/include/array_wrapper.h
index fd0f621..fb553fc 100644
--- a/cnorxz/core/include/array_wrapper.h
+++ b/cnorxz/core/include/array_wrapper.h
@@ -17,6 +17,10 @@ namespace CNORXZ
 	virtual RangePtr range() const = 0;
 	virtual SizeT size() const = 0;
 	// virtual PyObject* get() const = 0; // operator[]!!
+#ifdef HAVE_CEREAL
+	virtual void writeFile(Format f, const String& fname);
+	virtual void readFile(Format f, const String& fname);
+#endif
     };
 
     template <typename T>
diff --git a/cnorxz/core/include/range_wrapper.h b/cnorxz/core/include/range_wrapper.h
new file mode 100644
index 0000000..82fdda7
--- /dev/null
+++ b/cnorxz/core/include/range_wrapper.h
@@ -0,0 +1,41 @@
+
+#ifndef __python_cnorxz_range_wrapper_h__
+#define __python_cnorxz_range_wrapper_h__
+
+#include <Python.h>
+#include "cnorxz.h"
+
+namespace CNORXZ
+{
+    class CRangeWrapper
+    {
+    public:
+	DEFAULT_MEMBERS(CRangeWrapper);
+
+	inline bool _init() const { return mR != nullptr; }
+	inline SizeT size() const { return mR->size(); }
+	inline SizeT dim() const { return mR->dim(); }
+	inline String stringMeta(SizeT pos) const { mR->stringMeta(pos); }
+	
+    private:
+	RangePtr mR;
+    };
+}
+
+struct PyCRange
+{
+    PyObject_HEAD
+    CNORXZ::CRangeWrapper* ptrObj;
+};
+
+int PyCRange_init(PyCRange* self, PyObject* args, PyObject* kwds);
+void PyCRange_dealloc(PyCRange* self);
+PyObject* PyCRange_size(PyCRange* self);
+PyObject* PyCRange_dim(PyCRange* self);
+PyObject* PyCRange_stringMeta(PyCRange* self, PyObject* args, PyObject* kwds);
+PyTypeObject* PyCRange_init();
+
+extern PyMethodDef PyCRange_methods[];
+extern PyTypeObject PyCRangeType;
+
+#endif
diff --git a/cnorxz/core/lib/range_wrapper.cpp b/cnorxz/core/lib/range_wrapper.cpp
new file mode 100644
index 0000000..184a886
--- /dev/null
+++ b/cnorxz/core/lib/range_wrapper.cpp
@@ -0,0 +1,68 @@
+
+#include "range_wrapper.h"
+
+using namespace CNORXZ;
+
+int PyCRange_init(PyCRange* self, PyObject* args, PyObject* kwds)
+{
+    //!!!
+}
+
+void PyCRange_dealloc(PyCRange* self)
+{
+    delete self->ptrObj;
+    Py_TYPE(self)->tp_free(self);
+}
+
+PyObject* PyCRange_size(PyCRange* self)
+{
+    if(not self->ptrObj->_init()){
+	const SizeT retval = 0;
+	return Py_BuildValue("k", retval);
+    }
+    const SizeT retval = self->ptrObj->size();
+    return Py_BuildValue("k", retval);
+}
+
+PyObject* PyCRange_dim(PyCRange* self)
+{
+    if(not self->ptrObj->_init()){
+	const SizeT retval = 0;
+	return Py_BuildValue("k", retval);
+    }
+    const SizeT retval = self->ptrObj->dim();
+    return Py_BuildValue("k", retval);
+}
+
+PyObject* PyCRange_stringMeta(PyCRange* self, PyObject* args, PyObject* kwds)
+{
+    //!!!
+}
+
+PyMethodDef PyCRange_methods[] = {
+    { "size", (PyCFunction) PyCRange_size, METH_VARARGS, "return range size" },
+    { "dim", (PyCFunction) PyCRange_dim, METH_VARARGS, "return range dimension" },
+    { "stringMeta", (PyCFunction) PyCRange_stringMeta, METH_VARARGS,
+      "return string meta data for given range position" },
+    { NULL }
+};
+
+PyTypeObject PyCRangeType = { PyVarObject_HEAD_INIT(NULL,0) "cnorxz.CRange" };
+
+PyTypeObject* PyCRangeType_init()
+{
+    PyCRangeType.tp_new = PyType_GenericNew;
+    PyCRangeType.tp_basicsize = sizeof(PyCRange);
+    PyCRangeType.tp_dealloc = (destructor) PyCRange_dealloc;
+    PyCRangeType.to_flags = Py_TPFLAGS_DEFAULT;
+    PyCRangeType.tp_doc = "cnorxz CRange wrapper";
+    PyCRangeType.tp_methods = PyCRange_methods;
+    PyCRangeType.tp_init = (initproc) PyCRange_init;
+
+    if(PyType_Ready(&PyCRangeType) < 0){
+	return NULL;
+    }
+    else {
+	return &PyCRangeType;
+    }
+}