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

com.fluxtion.ext.text.api.ascii.ByteBufferDelimiter Maven / Gradle / Ivy

There is a newer version: 2.10.50
Show newest version
/* 
 * Copyright (C) 2018 V12 Technology Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Server Side Public License, version 1,
 * as published by MongoDB, Inc.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Server Side Public License for more details.
 *
 * You should have received a copy of the Server Side Public License
 * along with this program.  If not, see 
 * .
 */
package com.fluxtion.ext.text.api.ascii;


/**
 *
 * @author Greg Higgins
 */
import com.fluxtion.api.annotations.ConfigVariable;
import com.fluxtion.api.annotations.EventHandler;
import com.fluxtion.api.annotations.Initialise;
import com.fluxtion.api.annotations.Inject;
import com.fluxtion.api.annotations.OnEvent;
import com.fluxtion.api.annotations.OnEventComplete;
import com.fluxtion.api.annotations.OnParentUpdate;
import com.fluxtion.ext.streaming.api.numeric.BufferValue;
import com.fluxtion.ext.text.api.event.CharEvent;
import com.fluxtion.ext.text.api.filter.AnyCharMatchFilter;
import java.nio.ByteBuffer;
import java.util.HashMap;

/**
 * Extract a "word" from a CharEvent stream. Words are broken on delimiters. A
 * set of ignore characters can be optionally provided
 * @author Greg Higgins
 */
public class ByteBufferDelimiter implements BufferValue {

    private static final int DEFAULT_ARRAY_SIZE = 16;

    private transient boolean parseComplete;
    private transient ByteBuffer buffer;
    private transient HashMap stringCache;
    private String cachedString = "";
    private final String delimiterChars;
    private final String ignoreChars;
    private char[] ignoreCharArr;

    public ByteBufferDelimiter(String delimiterChars, String ignoreChars) {
        this.delimiterChars = delimiterChars;
        this.ignoreChars = ignoreChars;
        ignoreCharArr = (delimiterChars + ignoreChars).toCharArray();
    }

    public ByteBufferDelimiter() {
        this(" \n", ",.;-_:[]{}()?|&*'\\\"\r");
    }

    @Inject
    @ConfigVariable(field = "delimiterChars", key = AnyCharMatchFilter.KEY_FILTER_ARRAY)
    public AnyCharMatchFilter delimiterNotifier;

    @OnParentUpdate("delimiterNotifier")
    public boolean onDelimiter(AnyCharMatchFilter terminatorNotifier) {
        parseComplete = buffer.position() > 0;
        cachedString = null;
        return parseComplete;
    }

    @OnEvent
    public boolean onEvent() {
        return parseComplete;
    }

    @OnEventComplete
    public void onEventComplete() {
        buffer.clear();
        parseComplete = false;
    }

    @EventHandler()
    public boolean appendToBuffer(CharEvent e) {
        char c = e.getCharacter();
        if (ignoreChar(c)) {
            //do nothing
        } else if (buffer.hasRemaining()) {
            buffer.put((byte) c);
        } else {
            buffer.flip();
            buffer = ByteBuffer.allocateDirect(buffer.limit() * 2).put(buffer);
            buffer.put((byte) c);
        }
        return false;
    }

    private boolean ignoreChar(char c) {
        for (int i = 0; i < ignoreCharArr.length; i++) {
            if (c == ignoreCharArr[i]) {
                return true;
            }
        }
        return false;
    }

    @Initialise
    public void init() {
        parseComplete = false;
        buffer = ByteBuffer.allocateDirect(DEFAULT_ARRAY_SIZE);
        stringCache = new HashMap<>();
        cachedString = "uninitialised";
    }

    @Override
    public ByteBuffer getBuffer() {
        return buffer;
    }

    @Override
    public ByteBuffer clone() {
        final int limit = buffer.limit();
        ByteBuffer newBuf = ByteBuffer.allocateDirect(buffer.capacity());
        buffer.flip();
        newBuf.put(buffer);
        buffer.limit(limit);
        return newBuf;
    }

    @Override
    public String toString() {
        return cachedString;//asString();
    }

    @Override
    public String asString() {
        if (cachedString == null) {
            return cacheString();
        } else {
            return cachedString;
        }
    }

    public String cacheString() {
        int lim = buffer.limit();
        int pos = buffer.position();
        buffer.flip();
        cachedString = stringCache.get(buffer);
        buffer.limit(lim);
        buffer.position(pos);
        if (cachedString == null) {
            ByteBuffer wrappingBuffer = clone();
            wrappingBuffer.flip();
            byte[] arr = new byte[wrappingBuffer.limit()];
            wrappingBuffer.get(arr);
            wrappingBuffer.flip();
            cachedString = new String(arr);
            stringCache.put(wrappingBuffer, cachedString);
        }
        return cachedString;
    }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy