BuiltInOperators.java

package zserio.runtime;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

/**
 * The implementation of all Zserio built-in operators called from code generated by Zserio.
 */
public final class BuiltInOperators
{
    /**
     * Checks whether the requiredMask is set within the bitmaskValue.
     * <p>
     * This method implements Zserio built-in operator <code>isset</code> for Zserio bitmask types.</p>
     * <p>
     * Example:</p>
     * <code>issset(bitmaskField, Bitmask.READ)</code>
     *
     * @param bitmaskValue Bitmask value to check.
     * @param requiredMask Mast to use.
     *
     * @return True when the required mask is set within the bitmaskValue, false otherwise.
     */
    public static boolean isSet(ZserioBitmask bitmaskValue, ZserioBitmask requiredMask)
    {
        final Number bitmaskValueGeneric = bitmaskValue.getGenericValue();
        final BigInteger bigBitmaskValue = bitmaskValueGeneric instanceof BigInteger
                ? (BigInteger)bitmaskValueGeneric
                : BigInteger.valueOf(bitmaskValueGeneric.longValue());
        final Number requiredMaskGeneric = requiredMask.getGenericValue();
        final BigInteger bigRequiredMask = requiredMaskGeneric instanceof BigInteger
                ? (BigInteger)requiredMaskGeneric
                : BigInteger.valueOf(requiredMaskGeneric.longValue());

        return bigBitmaskValue.and(bigRequiredMask).equals(bigRequiredMask);
    }

    /**
     * Gets the minimum number of bits required to encode <code>numValues</code> different values.
     * <p>
     * This method implements Zserio built-in operator <code>numbits</code> for Zserio uint8, uint16
     * and uint32 types.</p>
     * <p>
     * <b>Note:</b> Please note that this method returns 0 if value is zero or negative value.</p>
     * <p>
     * Examples:</p>
     * <code>numbits(0) = 0</code><br>
     * <code>numbits(1) = 1</code><br>
     * <code>numbits(2) = 1</code><br>
     * <code>numbits(3) = 2</code><br>
     * <code>numbits(4) = 2</code><br>
     * <code>numbits(8) = 3</code><br>
     * <code>numbits(16) = 4</code>
     *
     * @param numValues The number of different values from which to calculate number of bits.
     *
     * @return Number of bis required to encode <code>numValues</code> different values.
     */
    public static short numBits(long numValues)
    {
        if (numValues <= 0)
            return 0;

        short result = 1;
        long current = (numValues - 1) >> 1;
        while (current > 0)
        {
            result++;
            current >>= 1;
        }

        return result;
    }

    /**
     * Gets the minimum number of bits required to encode <code>numValues</code> different values.
     * <p>
     * This method implements Zserio built-in operator <code>numbits</code> for Zserio uint64 type
     * which is mapped to Java BigInteger type.</p>
     * <p>
     * Examples:</p>
     * <code>numbits(0) = 0</code><br>
     * <code>numbits(1) = 1</code><br>
     * <code>numbits(2) = 1</code><br>
     * <code>numbits(3) = 2</code><br>
     * <code>numbits(4) = 2</code><br>
     * <code>numbits(8) = 3</code><br>
     * <code>numbits(16) = 4</code>
     *
     * @param numValues The number of different values from which to calculate number of bits.
     *
     * @return Number of bis required to encode <code>numValues</code> different values.
     */
    public static short numBits(BigInteger numValues)
    {
        if (numValues.doubleValue() <= 0.0)
            return 0;
        if (numValues.doubleValue() == 1.0)
            return 1;

        final BigInteger calcValue = numValues.subtract(BigInteger.ONE);

        return (short)calcValue.bitLength();
    }

    /**
     * Gets length of the given string in UTF-8 bytes.
     *
     * @param stringValue String value.
     * @return Number of bytes needed to encode given string in UTF-8.
     */
    public static int lengthOf(String stringValue)
    {
        return stringValue.getBytes(StandardCharsets.UTF_8).length;
    }
}