Commit f7e67fdc authored by Matthew Dawson's avatar Matthew Dawson
Browse files

Change MLObject to use a Map<String,MLArray> to store properties.

With the change to have MLObject properly store arrays of objects, and due
to the fact MLObject needs to handle the handle class, using MLStructure as
the data storage and array handler is about to get very messy.  Thus change
to the obvious data structure to manage everything.  The instance of a Map<>
is a specific instance of an MCOS.  That way handles are properly represented.
parent c2f1720f
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -560,7 +560,8 @@ public class MatFileReader
                    int[][] data = ((MLUInt32) property).getArray();
                    if (data[0][0] == 0xdd000000 && data[1][0] == 0x02 && data[2][0] == 0x01 && data[3][0] == 0x01) {
                        MatMCOSObjectInformation objectInformation = objectInfoList.get(data[4][0] - 1);
                        property = new MLObject(propertyName, classNamesList.get(objectInformation.classId - 1), objectInformation.structure);
                        property = new MLObject(propertyName, classNamesList.get(objectInformation.classId - 1), new int[]{1, 1}, 0)
                                .setFields(0, objectInformation.structure);
                    }
                }
                properties.put(propertyName, property);
@@ -577,10 +578,10 @@ public class MatFileReader

        // Now merge in the properties from segment 4 into object.
        for (MatMCOSObjectInformation it : objectInfoList.values()) {
            MLStructure objAttributes = it.structure;
            Map<String, MLArray> objAttributes = it.structure;
            if (it.segment4PropertiesIndex > 0) {
                for (Map.Entry<String, MLArray> attribute : segment4Properties.get(it.segment4PropertiesIndex - 1).entrySet()) {
                    objAttributes.setField(attribute.getKey(), attribute.getValue());
                    objAttributes.put(attribute.getKey(), attribute.getValue());
                }
            } else {
                throw new IllegalStateException("Properties are not found!  Not sure where to look ...");
@@ -592,10 +593,10 @@ public class MatFileReader
        for (MatMCOSObjectInformation it : objectInfoList.values()) {
            MLStructure attributes = (MLStructure) attribBag.get(it.classId);
            Collection<String> attributeNames = attributes.getFieldNames();
            MLStructure objAttributes = it.structure;
            Map<String, MLArray> objAttributes = it.structure;
            for (String attributeName : attributeNames) {
                if (objAttributes.getField(attributeName) == null) {
                    objAttributes.setField(attributeName, attributes.getField(attributeName));
                if (objAttributes.get(attributeName) == null) {
                    objAttributes.put(attributeName, attributes.getField(attributeName));
                }
            }
        }
@@ -605,7 +606,7 @@ public class MatFileReader
            if ( it.getValue() instanceof MLObjectPlaceholder ) {
                MLObjectPlaceholder obj = (MLObjectPlaceholder) it.getValue();
                MatMCOSObjectInformation objectInformation = objectInfoList.get(obj.objectId - 1);
                it.setValue(new MLObject(obj.name, classNamesList.get(objectInformation.classId - 1), objectInformation.structure));
                it.setValue(new MLObject(obj.name, classNamesList.get(objectInformation.classId - 1), new int[]{1, 1}, 0).setFields(0, objectInformation.structure));
            }
        }
    }
@@ -1223,7 +1224,7 @@ public class MatFileReader
                
                // TODO: currently copy pasted from structure

                struct = new MLStructure(name, dims, type, attributes);
                mlArray = new MLObject( name, className, dims, attributes );
                
                //field name lenght - this subelement always uses the compressed data element format
                tag = new ISMatTag(buf);
@@ -1246,6 +1247,7 @@ public class MatFileReader
                //read fields
                for ( int index = 0; index < 1; index++ )
                {
                    Map<String, MLArray> fields = new HashMap<String, MLArray>();
                    for ( int i = 0; i < numOfFields; i++ )
                    {
                        //read matrix recursively
@@ -1254,16 +1256,15 @@ public class MatFileReader
                        if ( tag.size > 0 )
                        {
                            MLArray fieldValue = readMatrix( buf, false);
                            struct.setField( fieldNames[i], fieldValue, index );
                            fields.put(fieldNames[i], fieldValue);
                        }
                        else
                        {
                            struct.setField(fieldNames[i], new MLEmptyArray(), index);
                            fields.put(fieldNames[i], new MLEmptyArray());
                        }
                    }
                    ((MLObject) mlArray).setFields(index, fields);
                }
                
                mlArray = new MLObject( name, className, struct );
                break;
            default:
                throw new MatlabIOException("Incorrect matlab array class: " + MLArray.typeToString(type) );
+5 −1
Original line number Diff line number Diff line
@@ -3,8 +3,12 @@
 */
package ca.mjdsystems.jmatio.io;

import ca.mjdsystems.jmatio.types.MLArray;
import ca.mjdsystems.jmatio.types.MLStructure;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Matthew Dawson <matthew@mjdsystems.ca>
@@ -26,5 +30,5 @@ class MatMCOSObjectInformation {
    final int classId;
    final int segment2PropertiesIndex;
    final int segment4PropertiesIndex;
    final MLStructure structure = new MLStructure("", new int[]{1,1});
    final Map<String, MLArray> structure = new HashMap<String, MLArray>();
}
+21 −6
Original line number Diff line number Diff line
package ca.mjdsystems.jmatio.types;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MLObject extends MLArray
{
    private final MLStructure o;
    private final List<Map<String, MLArray>> objects = new ArrayList<Map<String, MLArray>>();
    private final String className;
    
    public MLObject( String name, String className, MLStructure o )
    public MLObject(String name, String className, int[] dimensions, int attributes)
    {
        super( name, new int[] {1, 1}, MLArray.mxOBJECT_CLASS, 0 );
        this.o = o;
        super( name, dimensions, MLArray.mxOBJECT_CLASS, 0 );
        for (int i = 0; i < getSize(); ++i) {
            objects.add(null);
        }
        this.className = className;
    }

@@ -17,8 +23,17 @@ public class MLObject extends MLArray
        return className;
    }
    
    public MLStructure getObject()
    public Map<String, MLArray> getFields(int index)
    {
        return objects.get(index);
    }

    public MLObject setFields(int index, Map<String, MLArray> fields)
    {
        return o;
        if (index >= getSize()) {
            throw new IndexOutOfBoundsException("Index: " + index + " Size: " + getSize());
        }
        objects.set(index, fields);
        return this;
    }
}
+23 −41
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ public class MatlabMCOSTest {

        assertThat(obj.getName(), is("obj"));
        assertThat(obj.getClassName(), is("SimpleEmpty"));
        assertThat(obj.getObject().getAllFields().size(), is(0));
        assertThat(obj.getFields(0).size(), is(0));
    }

    @Test
@@ -64,7 +64,7 @@ public class MatlabMCOSTest {

        assertThat(obj.getName(), is("obj1"));
        assertThat(obj.getClassName(), is("SimpleEmpty"));
        assertThat(obj.getObject().getAllFields().size(), is(0));
        assertThat(obj.getFields(0).size(), is(0));


        obj = (MLObject) content.get("obj2");
@@ -72,7 +72,7 @@ public class MatlabMCOSTest {

        assertThat(obj.getName(), is("obj2"));
        assertThat(obj.getClassName(), is("SimpleEmpty"));
        assertThat(obj.getObject().getAllFields().size(), is(0));
        assertThat(obj.getFields(0).size(), is(0));
    }

    @Test
@@ -89,13 +89,11 @@ public class MatlabMCOSTest {

        assertThat(obj.getName(), is("obj"));
        assertThat(obj.getClassName(), is("SimpleSingleText"));
        Collection<MLArray> fields = obj.getObject().getAllFields();
        Map<String, MLArray> fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        MLChar field = (MLChar) fields.toArray()[0];
        MLChar field = (MLChar) fields.get("test_text");
        assertThat(field.getString(0), is("Default text"));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("test_text"));
    }

    @Test
@@ -112,41 +110,35 @@ public class MatlabMCOSTest {

        assertThat(obj.getName(), is("obj1"));
        assertThat(obj.getClassName(), is("SimpleSingleText"));
        Collection<MLArray> fields = obj.getObject().getAllFields();
        Map<String, MLArray> fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        MLChar field = (MLChar) fields.toArray()[0];
        MLChar field = (MLChar) fields.get("test_text");
        assertThat(field.getString(0), is("other text 1"));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("test_text"));


        obj = (MLObject) content.get("obj2");
        assertThat(obj, is(notNullValue()));

        assertThat(obj.getName(), is("obj2"));
        assertThat(obj.getClassName(), is("SimpleSingleText"));
        fields = obj.getObject().getAllFields();
        fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        field = (MLChar) fields.toArray()[0];
        field = (MLChar) fields.get("test_text");
        assertThat(field.getString(0), is("Default text"));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("test_text"));


        obj = (MLObject) content.get("obj3");
        assertThat(obj, is(notNullValue()));

        assertThat(obj.getName(), is("obj3"));
        assertThat(obj.getClassName(), is("SimpleSingleText"));
        fields = obj.getObject().getAllFields();
        fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        field = (MLChar) fields.toArray()[0];
        field = (MLChar) fields.get("test_text");
        assertThat(field.getString(0), is("other text 3"));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("test_text"));
    }

    @Test
@@ -163,63 +155,53 @@ public class MatlabMCOSTest {

        assertThat(obj.getName(), is("obj1"));
        assertThat(obj.getClassName(), is("HandleSingle"));
        assertThat(((MLObject) content.get("obj3")).getObject(), is(sameInstance(obj.getObject())));
        Collection<MLArray> fields = obj.getObject().getAllFields();
        assertThat(((MLObject) content.get("obj3")).getFields(0), is(sameInstance(obj.getFields(0))));
        Map<String, MLArray> fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        MLInt8 intField = (MLInt8) fields.toArray()[0];
        MLInt8 intField = (MLInt8) fields.get("myelement");
        assertThat(intField.getSize(), is(1));
        assertThat(intField.get(0).byteValue(), is((byte)25));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("myelement"));


        obj = (MLObject) content.get("obj3");
        assertThat(obj, is(notNullValue()));

        assertThat(obj.getName(), is("obj3"));
        assertThat(obj.getClassName(), is("HandleSingle"));
        assertThat(((MLObject) content.get("obj1")).getObject(), is(sameInstance(obj.getObject())));
        fields = obj.getObject().getAllFields();
        assertThat(((MLObject) content.get("obj1")).getFields(0), is(sameInstance(obj.getFields(0))));
        fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        intField = (MLInt8) fields.toArray()[0];
        intField = (MLInt8) fields.get("myelement");
        assertThat(intField.getSize(), is(1));
        assertThat(intField.get(0).byteValue(), is((byte)25));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("myelement"));




        obj = (MLObject) content.get("obj2");
        assertThat(obj, is(notNullValue()));

        assertThat(obj.getName(), is("obj2"));
        assertThat(obj.getClassName(), is("HandleSingle"));
        assertThat(((MLObject) content.get("obj4")).getObject(), is(sameInstance(obj.getObject())));
        fields = obj.getObject().getAllFields();
        assertThat(((MLObject) content.get("obj4")).getFields(0), is(sameInstance(obj.getFields(0))));
        fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        MLChar charField = (MLChar) fields.toArray()[0];
        MLChar charField = (MLChar) fields.get("myelement");
        assertThat(charField.getString(0), is("testing"));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("myelement"));


        obj = (MLObject) content.get("obj4");
        assertThat(obj, is(notNullValue()));

        assertThat(obj.getName(), is("obj4"));
        assertThat(obj.getClassName(), is("HandleSingle"));
        assertThat(((MLObject) content.get("obj2")).getObject(), is(sameInstance(obj.getObject())));
        fields = obj.getObject().getAllFields();
        assertThat(((MLObject) content.get("obj2")).getFields(0), is(sameInstance(obj.getFields(0))));
        fields = obj.getFields(0);
        assertThat(fields.size(), is(1));

        charField = (MLChar) fields.toArray()[0];
        charField = (MLChar) fields.get("myelement");
        assertThat(charField.getString(0), is("testing"));

        assertThat(obj.getObject().getFieldNames().iterator().next(), is("myelement"));
    }

    private File fileFromStream(String location) throws IOException
+14 −16
Original line number Diff line number Diff line
@@ -7,10 +7,7 @@ import ca.mjdsystems.jmatio.io.MatFileFilter;
import ca.mjdsystems.jmatio.io.MatFileReader;
import ca.mjdsystems.jmatio.io.MatFileType;
import ca.mjdsystems.jmatio.io.SimulinkDecoder;
import ca.mjdsystems.jmatio.types.MLChar;
import ca.mjdsystems.jmatio.types.MLDouble;
import ca.mjdsystems.jmatio.types.MLObject;
import ca.mjdsystems.jmatio.types.MLStructure;
import ca.mjdsystems.jmatio.types.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -18,6 +15,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.*;
import java.util.Map;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
@@ -43,17 +41,17 @@ public class SimulinkMatTest
        // First check that the root element is correct.
        assertThat(data, is(notNullValue()));
        assertThat(data.getClassName(), is("Data"));
        MLStructure dataO = data.getObject();
        assertThat(dataO.getAllFields().size(), is(10));
        assertThat(((MLChar) dataO.getField("function_name")).getString(0), is("quad_fcn_subtype"));
        assertThat(((MLChar) dataO.getField("function_inputs")).getString(0), is("c,a,b:{x:real|(a=0 => x /= 0) AND (a /= 0 => (x^2) - 4*a*c >= 0)}"));
        assertThat(((MLDouble) dataO.getField("open")).get(0), is(1.0));
        assertThat(((MLDouble) dataO.getField("fig")).get(0), is(notNullValue())); // This can be anything, just not null!
        assertThat(((MLDouble) dataO.getField("multi_mode")).get(0), is(1.0));
        assertThat(((MLDouble) dataO.getField("checked")).get(0), is(0.0));
        Map<String, MLArray> dataO = data.getFields(0);
        assertThat(dataO.size(), is(10));
        assertThat(((MLChar) dataO.get("function_name")).getString(0), is("quad_fcn_subtype"));
        assertThat(((MLChar) dataO.get("function_inputs")).getString(0), is("c,a,b:{x:real|(a=0 => x /= 0) AND (a /= 0 => (x^2) - 4*a*c >= 0)}"));
        assertThat(((MLDouble) dataO.get("open")).get(0), is(1.0));
        assertThat(((MLDouble) dataO.get("fig")).get(0), is(notNullValue())); // This can be anything, just not null!
        assertThat(((MLDouble) dataO.get("multi_mode")).get(0), is(1.0));
        assertThat(((MLDouble) dataO.get("checked")).get(0), is(0.0));

        // Next, make sure the settings structure came out right.  Not super important, but a good test.
        MLStructure settings = (MLStructure) dataO.getField("settings");
        MLStructure settings = (MLStructure) dataO.get("settings");
        assertThat(settings.getAllFields().size(), is(5));
        assertThat(((MLDouble) settings.getField("set")).get(0), is(1.0));
        assertThat(((MLDouble) settings.getField("inputs")), is(notNullValue()));
@@ -62,11 +60,11 @@ public class SimulinkMatTest
        assertThat(((MLDouble) settings.getField("except")).get(0), is(0.0));

        // Next, verify Grid2, as it is easiest.
        MLObject Grid2 = (MLObject) dataO.getField("Grid2");
        MLObject Grid2 = (MLObject) dataO.get("Grid2");
        assertThat(Grid2.getClassName(), is("Grid"));

        System.out.println(Grid2.getObject().getField("cells").contentToString());
        System.out.println(Grid2.getObject().contentToString());
        System.out.println(Grid2.getFields(0).get("cells").contentToString());
        System.out.println(Grid2.getFields(0));


    }