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

org.yamcs.parameterarchive.LongValueSegment Maven / Gradle / Ivy

There is a newer version: 5.10.9
Show newest version
package org.yamcs.parameterarchive;

import java.nio.ByteBuffer;

import org.yamcs.parameter.Value;
import org.yamcs.parameter.ValueArray;
import org.yamcs.protobuf.Yamcs.Value.Type;
import org.yamcs.utils.DecodingException;
import org.yamcs.utils.LongArray;
import org.yamcs.utils.ValueUtility;
import org.yamcs.utils.VarIntUtil;

public class LongValueSegment extends BaseSegment implements ValueSegment {

    final static int SUBFORMAT_ID_RAW = 0;
    LongArray values;

    // all possible types that can be stored by this segment
    static final Type[] types = new Type[] { Type.UINT64, Type.SINT64, Type.TIMESTAMP };
    int numericType;// index in the array above

    LongValueSegment(Type type) {
        super(FORMAT_ID_LongValueSegment);
        values = new LongArray();
        this.numericType = getNumericType(type);
    }

    private LongValueSegment() {
        super(FORMAT_ID_LongValueSegment);
    }

    @Override
    public void insert(int pos, Value value) {
        Type type = value.getType();
        if (type == Type.UINT64) {
            values.add(pos, value.getUint64Value());
        } else if (type == Type.SINT64) {
            values.add(pos, value.getSint64Value());
        } else {
            values.add(pos, value.getTimestampValue());
        }
    }

    @Override
    public void add(Value value) {
        Type type = value.getType();
        if (type == Type.UINT64) {
            values.add(value.getUint64Value());
        } else if (type == Type.SINT64) {
            values.add(value.getSint64Value());
        } else {
            values.add(value.getTimestampValue());
        }
    }

    private int getNumericType(Type type) {
        for (int i = 0; i < types.length; i++) {
            if (types[i] == type) {
                return i;
            }
        }
        throw new IllegalStateException();
    }

    @Override
    public void writeTo(ByteBuffer bb) {
        writeHeader(SUBFORMAT_ID_RAW, bb);
        int n = values.size();
        VarIntUtil.writeVarInt32(bb, n);
        for (int i = 0; i < n; i++) {
            bb.putLong(values.get(i));
        }
    }

    // write header:
    // 1st byte: spare type subformatid
    // 2 bits 2 bits 4 bits
    private void writeHeader(int subFormatId, ByteBuffer bb) {
        int x = (numericType << 4) | subFormatId;
        bb.put((byte) x);
    }

    private void parse(ByteBuffer bb) throws DecodingException {
        byte x = bb.get();
        int subFormatId = x & 0xF;
        if (subFormatId != SUBFORMAT_ID_RAW)
            throw new DecodingException("Unknown subformatId " + subFormatId + " for LongValueSegment");

        numericType = (x >> 4) & 3;

        int n = VarIntUtil.readVarInt32(bb);

        if (bb.limit() - bb.position() < 8 * n) {
            throw new DecodingException("Cannot decode long segment: expected " + (8 * n) + " bytes and only "
                    + (bb.limit() - bb.position()) + " available");
        }
        values = new LongArray(n);
        for (int i = 0; i < n; i++) {
            values.add(bb.getLong());
        }
    }

    public static LongValueSegment parseFrom(ByteBuffer bb) throws DecodingException {
        LongValueSegment r = new LongValueSegment();
        r.parse(bb);
        return r;
    }

    @Override
    public int getMaxSerializedSize() {
        return 4 + 8 * values.size(); // 4 for the size plus 8 for each element
    }

    @Override
    public ValueArray getRange(int posStart, int posStop, boolean ascending) {
        long[] r = new long[posStop - posStart];
        if (ascending) {
            for (int i = posStart; i < posStop; i++) {
                r[i - posStart] = values.get(i);
            }
        } else {
            for (int i = posStop; i > posStart; i--) {
                r[posStop - i] = values.get(i);
            }
        }
        return new ValueArray(types[numericType], r);
    }

    @Override
    public Value getValue(int index) {
        if (numericType == 0) {
            return ValueUtility.getUint64Value(values.get(index));
        } else if (numericType == 1) {
            return ValueUtility.getSint64Value(values.get(index));
        } else {
            return ValueUtility.getTimestampValue(values.get(index));
        }
    }

    @Override
    public int size() {
        return values.size();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy