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

org.jgroups.util.ByteArrayDataOutputStream Maven / Gradle / Ivy

package org.jgroups.util;

import java.io.DataOutput;
import java.util.Arrays;

/**
 * Implements {@link java.io.DataOutput} over a byte[] buffer. The byte[] buffer expands when needed; however, it
 * doesn't double but only expands minimally, to accommodate the additional data.
 * It is therefore recommended to always size the buffer to the actual number of bytes needed.
 * This class is not thread safe.
 * @author Bela Ban
 * @since  3.5
 */
public class ByteArrayDataOutputStream implements DataOutput {
    protected byte[] buf;
    protected int    pos;

    public ByteArrayDataOutputStream() {
        this(32);
    }

    public ByteArrayDataOutputStream(int capacity) {
        this.buf=new byte[capacity];
    }

    public ByteArrayDataOutputStream position(int pos) {
        this.pos=checkBounds(pos); return this;
    }

    public int    position()  {return pos;}
    public byte[] buffer()    {return buf;}
    public Buffer getBuffer() {return new Buffer(buf, 0, pos);}


    public void write(int b) {
        ensureCapacity(1);
        buf[pos++]=(byte)b;
    }

    public void write(byte[] b) {
        write(b, 0, b.length);
    }

    public void write(byte[] b, int off, int len) {
        if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) - b.length > 0))
            throw new IndexOutOfBoundsException();
        ensureCapacity(len);

        System.arraycopy(b, off, buf, pos, len);
        pos+=len;
    }

    public void writeBoolean(boolean v) {
        write(v ? 1 : 0);
    }

    public void writeByte(int v) {
        write(v);
    }

    public void writeShort(int v) {
        write((v >>> 8) & 0xFF);
        write((v >>> 0) & 0xFF);
    }

    public void writeChar(int v) {
        write((v >>> 8) & 0xFF);
        write((v >>> 0) & 0xFF);
    }

    public void writeInt(int v) {
        write((v >>> 24) & 0xFF);
        write((v >>> 16) & 0xFF);
        write((v >>>  8) & 0xFF);
        write((v >>>  0) & 0xFF);
    }

    public void writeLong(long v) {
        write((byte)(v >>> 56));
        write((byte)(v >>> 48));
        write((byte)(v >>> 40));
        write((byte)(v >>> 32));
        write((byte)(v >>> 24));
        write((byte)(v >>> 16));
        write((byte)(v >>>  8));
        write((byte)(v >>>  0));
    }

    public void writeFloat(float v) {
        writeInt(Float.floatToIntBits(v));
    }

    public void writeDouble(double v) {
        writeLong(Double.doubleToLongBits(v));
    }

    public void writeBytes(String s) {
        int len=s != null? s.length() : 0;
        if(len > 0)
            ensureCapacity(len);
        for(int i = 0 ; i < len ; i++)
            write((byte)s.charAt(i));
    }

    public void writeChars(String s) {
        int len=s != null? s.length() : 0;
        if(len > 0)
            ensureCapacity(len *2); // 2 bytes per char

        for(int i = 0 ; i < len ; i++) {
            int v = s.charAt(i);
            writeChar(v);
        }
    }

    public void writeUTF(String str) {
        int strlen=str != null? str.length() : 0;
        if(strlen > 0)
            ensureCapacity(strlen *2 + 2);

        int utflen = 0;
        int c, count = 0;

        if(str == null) {
            writeShort(-1);
            return;
        }

        /* use charAt instead of copying String to char array */
        for (int i = 0; i < strlen; i++) {
            c = str.charAt(i);
            if ((c >= 0x0001) && (c <= 0x007F))
                utflen++;
            else if (c > 0x07FF)
                utflen += 3;
            else
                utflen += 2;
        }

        if (utflen > 65535)
            throw new IllegalArgumentException("encoded string too long: " + utflen + " bytes");

        byte[] bytearr=new byte[utflen+2];

        bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
        bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);

        int i=0;
        for (i=0; i= 0x0001) && (c <= 0x007F))) break;
            bytearr[count++] = (byte) c;
        }

        for (;i < strlen; i++){
            c = str.charAt(i);
            if ((c >= 0x0001) && (c <= 0x007F)) {
                bytearr[count++] = (byte) c;

            } else if (c > 0x07FF) {
                bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
                bytearr[count++] = (byte) (0x80 | ((c >>  6) & 0x3F));
                bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
            } else {
                bytearr[count++] = (byte) (0xC0 | ((c >>  6) & 0x1F));
                bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
            }
        }
        write(bytearr, 0, utflen+2);
    }

    public String toString() {
        return "pos=" + pos + " lim=" + buf.length;
    }

    protected int checkBounds(int pos) {
        if(pos < 0 || pos > buf.length)
            throw new IndexOutOfBoundsException("pos=" + pos + ", length=" + buf.length);
        return pos;
    }

    protected void ensureCapacity(int bytes) {
        if(pos + bytes > buf.length) {
            int new_size=buf.length + bytes + 32;
            buf=Arrays.copyOf(buf, new_size);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy