001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.imagery.vectortile.mapbox;
003
004import java.util.Arrays;
005import java.util.stream.Stream;
006
007/**
008 * An indicator for a command to be executed
009 * @author Taylor Smock
010 * @since 17862
011 */
012public class CommandInteger {
013    private final Command type;
014    private final short[] parameters;
015    private int added;
016
017    /**
018     * Create a new command
019     * @param command the command (treated as an unsigned int)
020     */
021    public CommandInteger(final int command) {
022        // Technically, the int is unsigned, but it is easier to work with the long
023        final long unsigned = Integer.toUnsignedLong(command);
024        this.type = Stream.of(Command.values()).filter(e -> e.getId() == (unsigned & 0x7)).findAny()
025                .orElseThrow(InvalidMapboxVectorTileException::new);
026        // This is safe, since we are shifting right 3 when we converted an int to a long (for unsigned).
027        // So we <i>cannot</i> lose anything.
028        final int operationsInt = (int) (unsigned >> 3);
029        this.parameters = new short[operationsInt * this.type.getParameterNumber()];
030    }
031
032    /**
033     * Add a parameter
034     * @param parameterInteger The parameter to add (converted to {@code short}).
035     */
036    public void addParameter(Number parameterInteger) {
037        this.parameters[added++] = parameterInteger.shortValue();
038    }
039
040    /**
041     * Get the operations for the command
042     * @return The operations
043     */
044    public short[] getOperations() {
045        return this.parameters;
046    }
047
048    /**
049     * Get the command type
050     * @return the command type
051     */
052    public Command getType() {
053        return this.type;
054    }
055
056    /**
057     * Get the expected parameter length
058     * @return The expected parameter size
059     */
060    public boolean hasAllExpectedParameters() {
061        return this.added >= this.parameters.length;
062    }
063
064    @Override
065    public String toString() {
066        return "CommandInteger [type=" + type + ", parameters=" + Arrays.toString(parameters) + ']';
067    }
068}