All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jmatio.common.util.MLArrayQuery Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
/*
 * Code licensed under new-style BSD (see LICENSE).
 * All code up to tags/original: Copyright (c) 2006, Wojciech Gradkowski
 * All code after tags/original: Copyright (c) 2015, DiffPlug
 */
package com.jmatio.common.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.jmatio.types.MLArray;
import com.jmatio.types.MLCell;
import com.jmatio.types.MLChar;
import com.jmatio.types.MLNumericArray;
import com.jmatio.types.MLObject;
import com.jmatio.types.MLStructure;

/**
 * The JMatIO query parser. Allows to use Matlab-like syntax to access {@link MLArray} objects. 
 * 

* * @author wgradkowski * */ public class MLArrayQuery { private String queryString; private static final String regexp = "([a-zA-Z0-9]+)(\\(([0-9]+|:)(,([0-9:]+|:))?\\))?\\.?"; private static final Pattern pat = Pattern.compile(regexp); public MLArrayQuery(String queryString) { if (!Pattern.matches("^(" + regexp + ")+$", queryString)) { throw new IllegalArgumentException(); } this.queryString = queryString; } /** * * * @param array * @param query * @return */ public static Object q(MLArray array, String query) { MLArrayQuery q = new MLArrayQuery(query); return q.query(array); } /** * Parses the query string and returns the object it refers to. * * @param array * source {@link MLArray} * @return query result */ public Object query(MLArray array) { Matcher mat = pat.matcher(queryString); MLArray current = null; int prevM = 0; int prevN = 0; while (mat.find()) { String name = mat.group(1); String rangeM = mat.group(3); String rangeN = mat.group(5); int m = rangeM != null ? Integer.parseInt(rangeM) - 1 : -1; int n = rangeN != null ? Integer.parseInt(rangeN) - 1 : -1; if (current == null) { current = array; if (!current.getName().equals(name) && !current.getName().equals("@")) { throw new RuntimeException("No such array or field <" + name + "> in <" + current.getName() + ">"); } prevM = m; prevN = n; continue; } int type = current.getType(); switch (type) { case MLArray.mxOBJECT_CLASS: { MLObject object = cast(current, MLObject.class); MLArray field = object.getObject().getField(name, prevM, prevN); if (field == null) { throw new RuntimeException("no such field: " + name); } current = field; } break; case MLArray.mxSTRUCT_CLASS: { MLStructure struct = cast(current, MLStructure.class); MLArray field = struct.getField(name, prevM > 0 ? prevM : 0, prevN > 0 ? prevN : 0); if (field == null) { throw new RuntimeException("no such field: " + name); } current = field; } break; case MLArray.mxCELL_CLASS: { MLCell mlcell = cast(current, MLCell.class); if (m > -1 && n > -1) { current = mlcell.get(m, n); } else if (m > -1) { current = mlcell.get(m); } else { throw new RuntimeException(); } } break; default: } prevM = m; prevN = n; } return getContent(current, prevM, prevN); } /** * Returns the content of the field/cell/object. * * @param array * the parent structure/cell * @param m * column or -1 * @param n * row or -1 * @return if both m and n are -1, returns {@link MLArray}, if n is -1, returns * content under index m, if both m and n are not-negative, returns * content of (m,n) */ public Object getContent(MLArray array, int m, int n) { int type = array.getType(); Object result = null; switch (type) { case MLArray.mxINT8_CLASS: case MLArray.mxINT16_CLASS: case MLArray.mxINT32_CLASS: case MLArray.mxINT64_CLASS: case MLArray.mxUINT8_CLASS: case MLArray.mxUINT16_CLASS: case MLArray.mxUINT32_CLASS: case MLArray.mxUINT64_CLASS: case MLArray.mxSINGLE_CLASS: case MLArray.mxDOUBLE_CLASS: MLNumericArray numeric = cast(array, MLNumericArray.class); if (m > -1 && n > -1) { result = numeric.get(m, n); } else if (m > -1) { result = numeric.get(m); } else { result = array; } break; case MLArray.mxCHAR_CLASS: MLChar mlchar = cast(array, MLChar.class); if (m > -1 && n > -1) { result = mlchar.getChar(m, n); } else if (m > -1) { result = mlchar.getString(m); } else { result = mlchar; } break; case MLArray.mxCELL_CLASS: MLCell mlcell = cast(array, MLCell.class); if (m > -1 && n > -1) { result = getContent(mlcell.get(m, n), 0, -1); } else if (m > -1) { result = getContent(mlcell.get(m), 0, -1); } else { result = getContent(mlcell.get(0), -1, -1); } break; default: result = array; } return result; } /** Performs a checked cast to keep FindBugs happy. */ @SuppressWarnings("unchecked") private static T cast(Object o, Class clazz) { if (o.getClass().isAssignableFrom(clazz)) { return (T) o; } else { throw new ClassCastException(o.getClass().toString()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy