Commit 7fea2491 authored by Matthew Dawson's avatar Matthew Dawson
Browse files

Get a first run of attributes working.

Any class that has default attributes only is now fulled loaded and parsed.
Other attributes are currently skipped.  Also commit in a test for this
behaviour that uses a char array as a single parameter.
parent 79497dd2
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
classdef SimpleSingleText
    %SIMPLESINGLETEXT Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
        test_text = 'Default text'
    end
    
    methods
    end
    
end
+48 −5
Original line number Diff line number Diff line
@@ -14,10 +14,7 @@ import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.zip.InflaterInputStream;

import ca.mjdsystems.jmatio.common.MatDataTypes;
@@ -499,10 +496,56 @@ public class MatFileReader
            throw new IllegalStateException("Data from the class section was not all read!");
        }

        // @todo: Second segment, Object properties containing other properties.  Not used yet, thus ignored.
        mcosDataBuf.position(segmentIndexes[2]);

        // Third segment.  Contains all the useful per-object information.
        Map<Integer, MatMCOSObjectInformation> objectInfoList = new HashMap<Integer, MatMCOSObjectInformation>();
        // There are 16 unknown bytes.  Ensure they are 0.
        if (mcosDataBuf.getLong() != 0 || mcosDataBuf.getLong() != 0 || mcosDataBuf.getLong() != 0) {
            throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields!  Aborting!");
        }
        while (mcosDataBuf.position() < segmentIndexes[3]) {
            // First fetch the data.
            int classIndex = mcosDataBuf.getInt();
            if (mcosDataBuf.getLong() != 0) {
                throw new IllegalStateException("MAT file's MCOS data has different byte values for unknown fields!  Aborting!");
            }
            int segment2Index = mcosDataBuf.getInt();
            int segment4Index = mcosDataBuf.getInt();
            int objectId = mcosDataBuf.getInt();
            // Then parse it into the form needed for the object.

            MatMCOSObjectInformation objHolder = objectInfoList.get(objectId - 1);
            if (objHolder == null) {
                objHolder = new MatMCOSObjectInformation(classNamesList.get(classIndex - 1), classIndex, objectId);
                objectInfoList.put(objectId - 1, objHolder);
            }

        }

        // Sanity check, position in the buffer should equal the start of the fourth segment!
        if (mcosDataBuf.position() != segmentIndexes[3]) {
            throw new IllegalStateException("Data from the object section was not all read!  At: " + mcosDataBuf.position() + ", wanted: " + segmentIndexes[3]);
        }

        // Finally, merge in attributes from the global grab bag.
        MLCell attribBag = (MLCell) mcosInfo.get(mcosInfo.getSize() -1); // Get the grab bag.
        for (MatMCOSObjectInformation it : objectInfoList.values()) {
            Collection<MLArray> attributes = ((MLStructure) attribBag.get(it.classId)).getAllFields();
            MLStructure objAttributes = it.structure;
            for (MLArray attribute : attributes) {
                if (objAttributes.getField(attribute.getName()) == null) {
                    objAttributes.setField(attribute.getName(), attribute);
                }
            }
        }


        for (Map.Entry<String, MLArray> it : data.entrySet()) {
            if ( it.getValue() instanceof MLObjectPlaceholder ) {
                MLObjectPlaceholder obj = (MLObjectPlaceholder) it.getValue();
                it.setValue(new MLObject(obj.name, classNamesList.get(obj.classId - 1), new MLStructure("", new int[]{1, 1})));
                it.setValue(new MLObject(obj.name, classNamesList.get(obj.classId - 1), objectInfoList.get(obj.objectId - 1).structure));
            }
        }
    }
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright 2014 Matthew Dawson <matthew@mjdsystems.ca>
 */
package ca.mjdsystems.jmatio.io;

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

/**
 *
 * @author Matthew Dawson <matthew@mjdsystems.ca>
 */
class MatMCOSObjectInformation {
    MatMCOSObjectInformation(String className, int classId, int objectId)
    {
        this.className = className;

        this.objectId = objectId;
        this.classId = classId;
    }

    final String className;
    final int objectId;
    final int classId;
    final MLStructure structure = new MLStructure("", new int[]{1,1});
}
+23 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ package ca.mjdsystems.jmatio.test;

import ca.mjdsystems.jmatio.io.MatFileReader;
import ca.mjdsystems.jmatio.types.MLArray;
import ca.mjdsystems.jmatio.types.MLChar;
import ca.mjdsystems.jmatio.types.MLObject;
import org.junit.Rule;
import org.junit.Test;
@@ -13,6 +14,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

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

import static org.hamcrest.CoreMatchers.is;
@@ -71,6 +73,27 @@ public class MatlabMCOSTest {
        assertThat(obj.getObject().getAllFields().size(), is(0));
    }

    @Test
    public void testParsingSimpleSingleTextUnmodifiedMCOS() throws IOException
    {
        File file = fileFromStream("/mcos/simplesingletext_unmodified.mat");
        MatFileReader reader = new MatFileReader(file);
        Map<String, MLArray> content = reader.getContent();

        assertThat(content.size(), is(1));

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

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

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

    private File fileFromStream(String location) throws IOException
    {
        String outname = location.replace("/", "_");
+1.16 KiB

File added.

No diff preview for this file type.