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

org.hcjf.io.net.messages.MessageBuffer Maven / Gradle / Ivy

package org.hcjf.io.net.messages;

import org.hcjf.bson.BsonDecoder;
import org.hcjf.bson.BsonEncoder;
import org.hcjf.utils.bson.BsonParcelable;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author javaito.
 */
public final class MessageBuffer {

    private List messages;
    private ByteBuffer buffer;
    private MessageBuffer leftover;

    public MessageBuffer() {
        this.messages = new ArrayList<>();
    }

    /**
     * Appends a message into the buffer.
     * @param message Message to append.
     */
    public synchronized void append(Message message) {
        this.messages.add(message);
        buffer = ByteBuffer.wrap(BsonEncoder.encode(message.toBson()));
    }

    /**
     * Appends data into the buffer.
     * @param data Data to append.
     */
    public synchronized void append(byte[] data) {
        if(messages.isEmpty()) {
            if (buffer == null) {
                buffer = ByteBuffer.wrap(data);
                buffer.rewind();
            } else {
                ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity() + data.length);
                buffer.rewind();
                newBuffer.put(buffer);
                newBuffer.put(data);
                buffer = newBuffer;
                buffer.rewind();
            }

            if(buffer.capacity() > 4) {
                int bsonObjectSize = buffer.getInt();
                if (bsonObjectSize == buffer.capacity()) {
                    buffer.rewind();
                    messages.add(BsonParcelable.Builder.create(BsonDecoder.decode(buffer.array())));
                } else if (bsonObjectSize < buffer.capacity()) {
                    byte[] bsonObjectBody = new byte[bsonObjectSize];
                    byte[] leftOverBody = new byte[buffer.capacity() - bsonObjectSize];
                    buffer.rewind();
                    buffer.get(bsonObjectBody);
                    messages.add(BsonParcelable.Builder.create(BsonDecoder.decode(buffer.array())));
                    buffer.get(leftOverBody);
                    MessageBuffer leftover = new MessageBuffer();
                    leftover.append(leftOverBody);
                    if(leftover.isComplete()) {
                        messages.addAll(leftover.getMessages());
                        this.leftover = leftover.getLeftover();
                    } else {
                        this.leftover = leftover;
                    }
                }
            }
        } else {
            if(leftover == null) {
                leftover = new MessageBuffer();
            }
            leftover.append(data);
        }
    }

    /**
     * This method indicate when buffer contains some massage decoded.
     * @return Returns true if the buffer contains messages decoded or false in the otherwise.
     */
    public synchronized boolean isComplete() {
        return !messages.isEmpty();
    }

    /**
     * Returns the messages decoded contained into the buffer.
     * @return List of decoded messages.
     */
    public List getMessages() {
        List result = new ArrayList<>();
        result.addAll(messages);
        messages.clear();
        return result;
    }

    /**
     * Returns the left over data that is a incomplete message.
     * @return Left over data.
     */
    public MessageBuffer getLeftover() {
        return leftover;
    }

    /**
     * Returns the byte array that represent the message.
     * @return Internal byte array.
     */
    public synchronized byte[] getBytes() {
        buffer.rewind();
        return buffer.array();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy