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

org.redkalex.convert.protobuf.ProtobufByteBufferWriter Maven / Gradle / Ivy

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.redkalex.convert.protobuf;

import java.nio.ByteBuffer;
import java.util.function.Supplier;
import org.redkale.util.Utility;

/**
 *
 * @author zhangjx
 */
public class ProtobufByteBufferWriter extends ProtobufWriter {

    private final Supplier supplier;

    private ByteBuffer[] buffers;

    private int index;

    public ProtobufByteBufferWriter(boolean enumtostring, Supplier supplier) {
        this(false, enumtostring, supplier);
    }

    protected ProtobufByteBufferWriter(boolean tiny, boolean enumtostring, Supplier supplier) {
        super((byte[]) null);
        this.tiny = tiny;
        this.enumtostring = enumtostring;
        this.supplier = supplier;
    }

    @Override
    public ByteBuffer[] toBuffers() {
        if (buffers == null) return new ByteBuffer[0];
        for (int i = index; i < this.buffers.length; i++) {
            ByteBuffer buf = this.buffers[i];
            if (buf.position() != 0) buf.flip();
        }
        return this.buffers;
    }

    @Override
    public byte[] toArray() {
        if (buffers == null) return new byte[0];
        int pos = 0;
        byte[] bytes = new byte[this.count];
        for (ByteBuffer buf : toBuffers()) {
            int r = buf.remaining();
            buf.get(bytes, pos, r);
            buf.flip();
            pos += r;
        }
        return bytes;
    }

    @Override
    public String toString() {
        return this.getClass().getSimpleName() + "[count=" + this.count + "]";
    }

    @Override
    public ProtobufByteBufferWriter tiny(boolean tiny) {
        this.tiny = tiny;
        return this;
    }

    @Override
    protected int expand(final int byteLength) {
        if (this.buffers == null) {
            this.index = 0;
            this.buffers = new ByteBuffer[]{supplier.get()};
        }
        ByteBuffer buffer = this.buffers[index];
        if (!buffer.hasRemaining()) {
            buffer.flip();
            buffer = supplier.get();
            this.buffers = Utility.append(this.buffers, buffer);
            this.index++;
        }
        int len = buffer.remaining();
        int size = 0;
        while (len < byteLength) {
            buffer = supplier.get();
            this.buffers = Utility.append(this.buffers, buffer);
            len += buffer.remaining();
            size++;
        }
        return size;
    }

    @Override
    public void writeTo(final byte[] chs, final int start, final int len) {
        if (expand(len) == 0) {
            this.buffers[index].put(chs, start, len);
        } else {
            ByteBuffer buffer = this.buffers[index];
            final int end = start + len;
            int remain = len;  //还剩多少没有写
            while (remain > 0) {
                final int br = buffer.remaining();
                if (remain > br) { //一个buffer写不完
                    buffer.put(chs, end - remain, br);
                    buffer = nextByteBuffer();
                    remain -= br;
                } else {
                    buffer.put(chs, end - remain, remain);
                    remain = 0;
                }
            }
        }
        this.count += len;
    }

    private ByteBuffer nextByteBuffer() {
        this.buffers[this.index].flip();
        return this.buffers[++this.index];
    }

    @Override
    public void writeTo(final byte ch) {
        expand(1);
        this.buffers[index].put(ch);
        count++;
    }

    @Override
    protected boolean recycle() {
        super.recycle();
        this.index = 0;
        this.specify = null;
        this.buffers = null;
        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy