changeset 23893:75eff5b667b3

new mxSetProperty function for MEX API * mex.cc, mexproto.h (mxSetProperty): New function. * mex.cc (mxArray_octave_value::get_property): Forward to octave_classdef::get_property to do the real work. * mxarray.in.h, mex.cc (mxArray_octave_value::set_property): New function. * mxarray.in.h (mxArray::set_property): New virtual function. * mxarray.in.h (mxArray::as_octave_value): Now public. * ov-classdef.h (cdef_object::set_property, cdef_object::set_property, cdef_object_array::set_property, cdef_object_array::set_property, cdef_object_scalar::set_property, cdef_object_scalar::set_property): New functions. (cdef_object_rep::set_property, cdef_object_rep::set_property): New virtual functions.
author John W. Eaton <jwe@octave.org>
date Fri, 11 Aug 2017 17:26:38 -0400
parents 142a9c7e403a
children 61cd842e158a
files libinterp/corefcn/mex.cc libinterp/corefcn/mexproto.h libinterp/corefcn/mxarray.in.h libinterp/octave-value/ov-classdef.h
diffstat 4 files changed, 112 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/mex.cc	Fri Aug 11 11:39:40 2017 -0700
+++ b/libinterp/corefcn/mex.cc	Fri Aug 11 17:26:38 2017 -0400
@@ -377,7 +377,7 @@
   // Not allowed.
   void set_class_name (const char * /*name_arg*/) { request_mutation (); }
 
-  mxArray * get_property (mwIndex idx, const char *name) const
+  mxArray * get_property (mwIndex idx, const char *pname) const
   {
     mxArray *retval = nullptr;
 
@@ -387,21 +387,29 @@
 
         if (ov_cdef)
           {
-            cdef_object& cdef = ov_cdef->get_object_ref ();
-
-            if (cdef.is_array ())
-              cdef = cdef.array_value ().elem (idx);
-
-            octave_value prop_val = cdef.get (name);
-
-            if (prop_val.is_defined())
-              retval = new mxArray (prop_val);
+            octave_value pval = ov_cdef->get_property (idx, pname);
+
+            if (val.is_defined())
+              retval = new mxArray (pval);
           }
       }
 
     return retval;
   }
 
+  void set_property (mwIndex idx, const char *pname, const mxArray *pval)
+  {
+    if (val.is_classdef_object ())
+      {
+        octave_classdef *ov_cdef = val.classdef_object_value ();
+
+        if (ov_cdef)
+          ov_cdef->set_property (idx, pname, pval->as_octave_value ());
+      }
+    else
+      err_invalid_type ();
+  }
+
   mxArray * get_cell (mwIndex /*idx*/) const
   {
     request_mutation ();
@@ -2975,6 +2983,13 @@
   ptr->set_class_name (name);
 }
 
+void
+mxSetProperty (mxArray *ptr, mwIndex idx, const char *property_name,
+               const mxArray *property_value)
+{
+  ptr->set_property (idx, property_name, property_value);
+}
+
 mxArray *
 mxGetProperty (const mxArray *ptr, mwIndex idx, const char *property_name)
 {
--- a/libinterp/corefcn/mexproto.h	Fri Aug 11 11:39:40 2017 -0700
+++ b/libinterp/corefcn/mexproto.h	Fri Aug 11 17:26:38 2017 -0400
@@ -245,6 +245,9 @@
 extern OCTINTERP_API void mxSetClassName (mxArray *ptr, const char *name);
 extern OCTINTERP_API mxArray * mxGetProperty (const mxArray *ptr, mwIndex idx,
                                               const char *property_name);
+extern OCTINTERP_API void mxSetProperty (mxArray *ptr, mwIndex idx,
+                                         const char *property_name,
+                                         const mxArray *property_value);
 
 /* Cell support.  */
 extern OCTINTERP_API mxArray * mxGetCell (const mxArray *ptr, mwIndex idx);
--- a/libinterp/corefcn/mxarray.in.h	Fri Aug 11 11:39:40 2017 -0700
+++ b/libinterp/corefcn/mxarray.in.h	Fri Aug 11 17:26:38 2017 -0400
@@ -224,13 +224,23 @@
 
   virtual void set_class_name (const char *name_arg) = 0;
 
-  virtual mxArray * get_property (mwIndex /*idx*/, const char * /*name*/) const
+  // The following functions aren't pure virtual becuase they are only
+  // valid for one type.  Making them pure virtual would mean tha they
+  // have to be implemented for all derived types, and all of those
+  // would need to throw errors instead of just doing it once here.
+
+  virtual mxArray *
+  get_property (mwIndex /*idx*/, const char * /*pname*/) const
   {
     return nullptr;
   }
 
-  // FIXME: Why not just have this '= 0' as the others?
-  // Could then eliminate err_invalid_type function and #include "error.h".
+  virtual void set_property (mwIndex /*idx*/, const char * /*pname*/,
+                             const mxArray * /*pval*/)
+  {
+    err_invalid_type ();
+  }
+
   virtual mxArray * get_cell (mwIndex /*idx*/) const
   {
     err_invalid_type ();
@@ -445,9 +455,12 @@
   mxClassID get_class_id (void) const { return rep->get_class_id (); }
 
   const char * get_class_name (void) const { return rep->get_class_name (); }
-  
-  mxArray * get_property (mwIndex idx, const char * propNm) const
-  { return rep->get_property (idx, propNm); }
+
+  mxArray * get_property (mwIndex idx, const char *pname) const
+  { return rep->get_property (idx, pname); }
+
+  void set_property (mwIndex idx, const char *pname, const mxArray *pval)
+  { rep->set_property (idx, pname, pval); }
 
   void set_class_name (const char *name_arg)
   { DO_VOID_MUTABLE_METHOD (set_class_name (name_arg)); }
@@ -534,8 +547,6 @@
 
   static octave_value as_octave_value (const mxArray *ptr);
 
-protected:
-
   octave_value as_octave_value (void) const;
 
 private:
--- a/libinterp/octave-value/ov-classdef.h	Fri Aug 11 11:39:40 2017 -0700
+++ b/libinterp/octave-value/ov-classdef.h	Fri Aug 11 17:26:38 2017 -0400
@@ -110,6 +110,17 @@
     err_invalid_object ("get");
   }
 
+  virtual void set_property (octave_idx_type, const std::string&,
+                             const octave_value&)
+  {
+    err_invalid_object ("set_property");
+  }
+
+  virtual octave_value get_property (octave_idx_type, const std::string&) const
+  {
+    err_invalid_object ("get_property");
+  }
+
   virtual octave_value_list
   subsref (const std::string&, const std::list<octave_value_list>&,
            int, size_t&, const cdef_class&, bool)
@@ -258,6 +269,14 @@
   octave_value get (const std::string& pname) const
   { return rep->get (pname); }
 
+  void set_property (octave_idx_type idx, const std::string& pname,
+                     const octave_value& pval)
+  { return rep->set_property (idx, pname, pval); }
+
+  octave_value
+  get_property (octave_idx_type idx, const std::string& pname) const
+  { return rep->get_property (idx, pname); }
+
   octave_value_list
   subsref (const std::string& type, const std::list<octave_value_list>& idx,
            int nargout, size_t& skip, const cdef_class& context,
@@ -381,6 +400,22 @@
   subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
             const octave_value& rhs);
 
+  void set_property (octave_idx_type idx, const std::string& pname,
+                     const octave_value& pval)
+  {
+    cdef_object& tmp = array.elem (idx);
+
+    return tmp.put (pname, pval);
+  }
+
+  octave_value
+  get_property (octave_idx_type idx, const std::string& pname) const
+  {
+    cdef_object tmp = array.elem (idx);
+
+    return tmp.get (pname);
+  }
+
 private:
   Array<cdef_object> array;
 
@@ -419,6 +454,24 @@
     return val(0, 0);
   }
 
+  void set_property (octave_idx_type idx, const std::string& pname,
+                     const octave_value& pval)
+  {
+    if (idx != 0)
+      error ("invalid index");  // FIXME
+
+    put (pname, pval);
+  }
+
+  octave_value
+  get_property (octave_idx_type idx, const std::string& pname) const
+  {
+    if (idx != 0)
+      error ("invalid index");  // FIXME
+
+    return get (pname);
+  }
+
   octave_value_list
   subsref (const std::string& type, const std::list<octave_value_list>& idx,
            int nargout, size_t& skip, const cdef_class& context,
@@ -1453,6 +1506,18 @@
 
   dim_vector dims (void) const { return object.dims (); }
 
+  void set_property (octave_idx_type idx, const std::string& name,
+                     const octave_value& pval)
+  {
+    object.set_property (idx, name, pval);
+  }
+
+  octave_value
+  get_property (octave_idx_type idx, const std::string& name) const
+  {
+    return object.get_property (idx, name);
+  }
+
 public:
   int type_id (void) const { return t_id; }
   std::string type_name (void) const { return t_name; }