ArduinoSignalFactor.java

/*******************************************************************************
 * jArduino: Arduino C++ Code Generation From Java
 * Copyright 2020 Tony Washer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package net.sourceforge.jarduino.message;

import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;

/**
 * Arduino Signal Factor.
 */
public final class ArduinoSignalFactor {
    /**
     * The start character.
     */
    private static final char START = '(';

    /**
     * The end character.
     */
    private static final char END = ')';

    /**
     * the factor of the signal.
     */
    private final Number theFactor;

    /**
     * the offset of the signal.
     */
    private final Number theOffset;

    /**
     * the numberf of decimals.
     */
    private final int theNumDecimals;

    /**
     * Constructor.
     * @param pFactor the factor
     * @param pOffset the offset
     * @param pNumDecimals the number of decimals
     */
    private ArduinoSignalFactor(final Number pFactor,
                                final Number pOffset,
                                final int pNumDecimals) {
        /* Store values */
        theFactor = pFactor;
        theOffset = pOffset;
        theNumDecimals = pNumDecimals;
    }

    /**
     * Obtain the factor.
     * @return the factor
     */
    public Number getFactor() {
        return theFactor;
    }

    /**
     * Obtain the offset.
     * @return the offset
     */
    public Number getOffset() {
        return theOffset;
    }

    /**
     * Obtain the number of decimals.
     * @return the number of decimals
     */
    public int getNumDecimals() {
        return theNumDecimals;
    }

    /**
     * Does this factor use floats?
     * @return true/false
     */
    public boolean isFloat() {
        return theFactor instanceof Double;
    }

    /**
     * Parse factors.
     * @param pFactorDef the factor representation
     * @return the factors
     * @throws ArduinoParserException on error
     */
    static ArduinoSignalFactor parseFactors(final String pFactorDef) throws ArduinoParserException {
        /* Remove surrounding parentheses */
        if (pFactorDef.charAt(0) != START
                || pFactorDef.charAt(pFactorDef.length() - 1) != END) {
            throw new ArduinoParserException("Missing surrounding ()s", pFactorDef);
        }
        final String myFactors = pFactorDef.substring(1, pFactorDef.length() - 1);

        /* Split out factors */
        final int myIndex = myFactors.indexOf(ArduinoChar.COMMA);
        if (myIndex == -1) {
            throw new ArduinoParserException("Missing " + ArduinoChar.COMMA + " separator", pFactorDef);
        }
        final String myFact = myFactors.substring(0, myIndex);
        Number myFactor = ArduinoParser.parseNumber(myFact);
        final String myOff = myFactors.substring(myIndex + 1);
        Number myOffset = ArduinoParser.parseNumber(myOff);

        /* Check number of decimals */
        final int myNumDecimals = ArduinoParser.determineNumDecimals(myFact);

        /* Make sure that if either value is double, both are */
        if (myFactor.getClass() != myOffset.getClass()) {
            /* Convert longs to doubles */
            if (myFactor instanceof Long) {
                myFactor = myFactor.doubleValue();
            }
            if (myOffset instanceof Long) {
                myOffset = myOffset.doubleValue();
            }
        }

        /* return the parsed Factor */
        return new ArduinoSignalFactor(myFactor, myOffset, myNumDecimals);
    }

    @Override
    public String toString() {
        return "" + START + theFactor + ArduinoChar.COMMA + theOffset + END;
    }
}