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

juzu.impl.common.CharBuffer Maven / Gradle / Ivy

/*
 * Copyright 2013 eXo Platform SAS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package juzu.impl.common;

import java.io.IOException;

/**
 * A growing char buffer that can be read and written.
 *
 * @author Julien Viet
 */
public class CharBuffer implements Appendable {

  /** The initial size. */
  private static final int INITIAL_SIZE = 16;

  /** . */
  private char[] chars;

  /** . */
  private int from;

  /** . */
  private int to;

  public CharBuffer() {
    this(INITIAL_SIZE);
  }

  public CharBuffer(int length) {
    if (length < 1) {
      throw new IllegalArgumentException();
    }
    this.chars = new char[length];
    this.from = 0;
    this.to = 0;
  }

  public int getLength() {
    return to - from;
  }

  public int getSize() {
    return chars.length;
  }

  /**
   * Read from a char array.
   *
   * @param src the char array source
   * @param at the first index of the chars to read
   * @param len the amount of chars to read
   * @throws NullPointerException if the source is null
   * @throws IllegalArgumentException if the len argument is negative
   * @throws IndexOutOfBoundsException if the source is adressed out of its bounds
   */
  public void readFrom(char[] src, int at, int len) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException {
    if (src == null) {
      throw new NullPointerException("Buffer cannot be null");
    }
    if (at < 0) {
      throw new IndexOutOfBoundsException("Begin pointer cannot be negative: " + at);
    }
    if (len < 0) {
      throw new IllegalArgumentException("Length cannot be negative: " + len);
    }
    if (at + len > src.length) {
      throw new IndexOutOfBoundsException("End pointer cannot be greater than buffer: " + (at + len));
    }

    // Check if we have enough remaining space
    ensure(len);

    // Copy data
    System.arraycopy(src, at, this.chars, to, len);
    to += len;
  }

  /**
   * Write to a char array.
   *
   * @param dst the char array destination
   * @param at the first index of the chars to write
   * @param len the amount of chars to write
   * @return the amount of chars written
   * @throws NullPointerException if the destintation is null
   * @throws IllegalArgumentException if the len argument is null
   * @throws IndexOutOfBoundsException if the destination is addressed out of its bounds
   */
  public int writeTo(char[] dst, int at, int len) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException  {
    if (dst == null) {
      throw new NullPointerException("Destination cannot be null");
    }
    if (at < 0) {
      throw new IndexOutOfBoundsException("Begin pointer cannot be negative: " + at);
    }
    if (len < 0) {
      throw new IllegalArgumentException("Length cannot be negative: " + len);
    }
    if (at + len > dst.length) {
      throw new IndexOutOfBoundsException("End pointer cannot be greater than buffer: " + (at + len));
    }

    // Determine how much we copy
    int l = Math.min(to - from, len);
    System.arraycopy(this.chars, from, dst, at, l);
    from += l;
    return l;
  }

  /**
   * Write to an appendable.
   *
   * @param dst the appendable destination
   * @return the amount of chars written
   * @throws NullPointerException if the destination is null
   * @throws IOException any IOException thrown by the dst argument
   */
  public int writeTo(Appendable dst) throws NullPointerException, IOException {
    if (dst == null) {
      throw new NullPointerException("Destination cannot be null");
    }

    //
    int from = this.from;
    int to = this.to;
    char[] chars = this.chars;

    //
    final int delta = to - from;
    if (delta > 0) {
      while (from < to) {
        dst.append(chars[from++]);
      }
      this.from = from;
      this.to = to;
      this.chars = chars;
    }

    //
    return delta;
  }

  private void ensure(int amount) {
    int remaining = chars.length - to;
    if (remaining < amount) {
      char[] tmp = new char[chars.length * 2];
      System.arraycopy(chars, from, tmp, from, to - from);
      this.chars = tmp;
    }
  }

  // Appendable implementation *****************************************************************************************

  public Appendable append(CharSequence csq) throws IOException {
    return append(csq, 0, csq.length());
  }

  public Appendable append(CharSequence csq, int start, int end) throws IOException {
    if (start < 0) {
      throw new IndexOutOfBoundsException("Start " + start + " cannot be negative");
    }
    if (start > end) {
      throw new IndexOutOfBoundsException("Start " + start + " cannot be greater then end " + end);
    }
    if (end > csq.length()) {
      throw new IndexOutOfBoundsException("End " + end + " cannot be greater then char sequence " + csq.length());
    }
    int len = end - start;
    ensure(len);
    while (start < end) {
      chars[to++] = csq.charAt(start++);
    }
    return this;
  }

  public Appendable append(char c) throws IOException {
    ensure(1);
    chars[to++] = c;
    return this;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy