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

com.dukescript.presenters.strings.Buffer Maven / Gradle / Ivy

The newest version!
package com.dukescript.presenters.strings;

/*
 * #%L
 * Strings Helpers - a library from the "DukeScript Presenters" project.
 * 
 * Dukehoff GmbH designates this particular file as subject to the "Classpath"
 * exception as provided in the README.md file that accompanies this code.
 * %%
 * Copyright (C) 2015 - 2019 Dukehoff GmbH
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * 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
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */


import java.util.List;
import java.util.ArrayList;
import java.util.Random;

final class Buffer {
    private final int segmentLen;
    private final int[] begins;
    final StringBuilder buf;

    Buffer(CharSequence sb, int segmentLen, long seed) {
        this.segmentLen = segmentLen;
        int add = sb.length() % segmentLen == 0 ? 0 : 1;
        this.begins = new int[sb.length() / segmentLen + add];
        Random r = new Random(seed);
        for (int i = 0; i < begins.length; i++) {
            begins[i] = i;
        }
        for (int i = begins.length - 1; i > 0; i--) {
            int mt = r.nextInt(i);
            int t = begins[i];
            begins[i] = begins[mt];
            begins[mt] = t;
        }
        int[] rev = new int[begins.length];
        for (int i = 0; i < begins.length; i++) {
            rev[begins[i]] = i;
        }

        this.buf = new StringBuilder();
        for (int i = 0; i < begins.length; i++) {
            begins[i] *= segmentLen;
            final int at = rev[i] * segmentLen;
            int end = Math.min(at + segmentLen, sb.length());
            buf.append(sb.subSequence(at, end));
            while (end < at + segmentLen) {
                buf.append(' ');
                end++;
            }
        }
    }

    char charAt(int pos) {
        int seg = pos / segmentLen;
        int off = pos % segmentLen;

        int index = begins[seg] + off;
        return buf.charAt(index);
    }

    List segments(int from, int end) {
        List arr = new ArrayList();
        BIG:
        while (from < end) {
            int i = from / segmentLen;
            int offset = from % segmentLen;
            int avail = segmentLen - offset;
            int needed = end - from;

            final int f = begins[i] + offset;
            assert f >= 0;
            arr.add(f);
            if (avail <= needed) {
                final int e = begins[i] + segmentLen;
                assert e >= f;
                arr.add(e);
                from += avail;
            } else {
                final int e = f + needed;
                assert e >= f;
                arr.add(e);
                from = end;
            }
        }
        return arr;
    }

    CharSequence subSequence(int from, int end) {
        StringBuilder sb = new StringBuilder();
        Integer frm = null;
        final List sgmnts = segments(from, end);
        for (Integer i1 : sgmnts) {
            if (frm == null) {
                frm = i1;
                continue;
            }
            sb.append(buf.subSequence(frm, i1));
            frm = null;
        }
        return sb;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy