Skip to content

Commit c28ddac

Browse files
committed
Attempt to create classdef object before calling loadobj method (bug #67414).
* libinterp/octave-value/ov-classdef.cc (octave_classdef::loadobj): If a classdef implements a loadobj method, try to create an object from the stored properties before calling the loadobj method. Pass the stored properties as structure if creating an object would loose information from the property map. * test/classdef-load-save/classdef-load-save-text.tst, test/classdef-load-save/classdef-load-save-v6.tst, test/classdef-load-save/classdef-load-save-v7.tst: Mark tests as fixed.
1 parent a0805c8 commit c28ddac

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

libinterp/octave-value/ov-classdef.cc

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ octave_classdef::loadobj (std::vector<std::tuple<octave_map, uint32_t, bool>>& m
154154
if (! in_obj_cache || prop_map.nfields () > 0)
155155
{
156156
// Default behaviour of loading is triggered if loadobj is not static
157-
if (meth.ok () && meth.is_static ())
157+
if (meth.ok () && meth.is_static () && prop_map.nfields () > 0)
158158
{
159159
octave_value ov;
160160
if (std::get<bool> (m[n]))
@@ -163,7 +163,49 @@ octave_classdef::loadobj (std::vector<std::tuple<octave_map, uint32_t, bool>>& m
163163
ov = (meth.execute (octave_value_list (any), 1))(0);
164164
}
165165
else
166-
ov = (meth.execute (octave_value_list (prop_map), 1))(0);
166+
{
167+
// create object from saved properties
168+
octave::cdef_object new_object;
169+
if (in_obj_cache)
170+
new_object = ovc.classdef_object_value ()->m_object;
171+
else
172+
new_object = scalar_obj.copy ();
173+
174+
bool props_changed = false;
175+
string_vector fnames = prop_map.fieldnames ();
176+
string_vector sv = map_keys ();
177+
for (octave_idx_type i = 0; i < prop_map.nfields (); i++)
178+
{
179+
octave_idx_type j;
180+
for (j = 0; j < sv.numel (); j++)
181+
{
182+
if (sv[j] == fnames(i))
183+
{
184+
new_object.set_property (0, sv[j], prop_map.contents (fnames(i)).xelem (0));
185+
break;
186+
}
187+
}
188+
if (j == sv.numel ())
189+
{
190+
// properties have been renamed or deleted
191+
props_changed = true;
192+
break;
193+
}
194+
}
195+
196+
if (props_changed)
197+
// attempting to create the object failed
198+
// call loadobj with struct
199+
ov = (meth.execute (octave_value_list (prop_map), 1))(0);
200+
else
201+
{
202+
if (! in_obj_cache)
203+
ovc = octave::to_ov (new_object);
204+
205+
// pass object to loadobj
206+
ov = (meth.execute (octave_value_list (ovc), 1))(0);
207+
}
208+
}
167209

168210
if (! ov.is_defined ())
169211
{

test/classdef-load-save/classdef-load-save-text.tst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173

174174
## No constructor, ConstructOnLoad = false, loadobj is defined, no saveobj
175175
## Class definition changes between saving and loading the object
176-
%!test <67414>
176+
%!test <*67414>
177177
%! clear classes;
178178
%! obj = loadobj_changed_class ();
179179
%! obj.a = 0;

test/classdef-load-save/classdef-load-save-v6.tst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173

174174
## No constructor, ConstructOnLoad = false, loadobj is defined, no saveobj
175175
## Class definition changes between saving and loading the object
176-
%!test <67414>
176+
%!test <*67414>
177177
%! clear classes;
178178
%! obj = loadobj_changed_class ();
179179
%! obj.a = 0;

test/classdef-load-save/classdef-load-save-v7.tst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173

174174
## No constructor, ConstructOnLoad = false, loadobj is defined, no saveobj
175175
## Class definition changes between saving and loading the object
176-
%!testif HAVE_ZLIB <67414>
176+
%!testif HAVE_ZLIB <*67414>
177177
%! clear classes;
178178
%! obj = loadobj_changed_class ();
179179
%! obj.a = 0;

0 commit comments

Comments
 (0)