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

org.bouncycastle.oer.BitBuilder Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for ASN.1 extension and utility APIs used to support bcpkix and bctls. This jar contains APIs for JDK 1.5 and up.

The newest version!
package org.bouncycastle.oer;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;

import org.bouncycastle.util.Arrays;

public class BitBuilder
{
    private static final byte[] bits = new byte[]{(byte)128, 64, 32, 16, 8, 4, 2, 1};


    byte[] buf = new byte[1];
    int pos = 0;

    /**
     * write a bit
     *
     * @param bit where 0 = 0 bit and not zero is 1 bit.
     * @return
     */
    public BitBuilder writeBit(int bit)
    {

        if (pos / 8 >= buf.length)
        {
            byte[] newBytes = new byte[buf.length + 4];
            System.arraycopy(buf, 0, newBytes, 0, pos / 8);
            Arrays.clear(buf);
            buf = newBytes;
        }

        if (bit == 0)
        {
            buf[pos / 8] &= ~bits[pos % 8];
        }
        else
        {
            buf[pos / 8] |= bits[pos % 8];
        }
        pos++;

        return this;
    }

    public BitBuilder writeBits(long value, int start)
    {

        for (int p = start - 1; p >= 0; p--)
        {
            int set = (value & (1L << p)) > 0 ? 1 : 0;
            writeBit(set);
        }

        return this;
    }

    public BitBuilder writeBits(long value, int start, int len)
    {

        for (int p = start - 1; p >= start - len; p--)
        {
            int set = (value & (1L << p)) != 0 ? 1 : 0;
            writeBit(set);
        }

        return this;
    }


    public int write(OutputStream outputStream)
        throws IOException
    {

        int l = (pos + (pos % 8)) / 8;
        outputStream.write(buf, 0, l);
        outputStream.flush();
        return l;
    }

    public int writeAndClear(OutputStream outputStream)
        throws IOException
    {

        int l = (pos + (pos % 8)) / 8;
        outputStream.write(buf, 0, l);
        outputStream.flush();
        zero();
        return l;
    }


    public void pad()
    {
        pos = pos + pos % 8;
    }


    public void write7BitBytes(int value)
    {

        // Skip leading zero bytes.
        boolean writing = false;
        for (int t = 4; t >= 0; t--)
        {
            if (!writing && (value & 0xFE000000) != 0)
            {
                writing = true;
            }
            if (writing)
            {
                writeBit(t).writeBits(value, 32, 7);
            }
            value <<= 7;
        }
    }

    public void write7BitBytes(BigInteger value)
    {
        int size = ((value.bitLength() + value.bitLength() % 8) / 8);
        BigInteger mask = BigInteger.valueOf(0xFE).shiftLeft(size * 8);


        // Skip leading zero bytes.
        boolean writing = false;
        for (int t = size; t >= 0; t--)
        {
            if (!writing && (value.and(mask)).compareTo(BigInteger.ZERO) != 0)
            {
                writing = true;
            }
            if (writing)
            {
                BigInteger b = value.and(mask).shiftRight(8 * size - 8);
                writeBit(t).writeBits(b.intValue(), 8, 7);
            }
            value = value.shiftLeft(7);
        }
    }
    
    protected void finalize()
        throws Throwable
    {
        zero();
        super.finalize();
    }

    public void zero()
    {
        Arrays.clear(buf);
        pos = 0;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy