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

net.sandius.rembulan.ArrayByteString Maven / Gradle / Ivy

There is a newer version: 1.0.3
Show newest version
/*
 * Copyright 2016 Miroslav Janíček
 *
 * 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 net.sandius.rembulan;

import net.sandius.rembulan.util.ArrayByteIterator;
import net.sandius.rembulan.util.ByteIterator;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Objects;

/**
 * A byte string backed by a byte array.
 */
class ArrayByteString extends ByteString {

	static final ArrayByteString EMPTY_INSTANCE = new ArrayByteString(new byte[0]);

	private final byte[] bytes;
	private int hashCode;

	ArrayByteString(byte[] bytes) {
		this.bytes = Objects.requireNonNull(bytes);
	}

	@Override
	protected boolean equals(ByteString that) {
		if (this.length() != that.length()) return false;

		int len = this.length();
		for (int i = 0; i < len; i++) {
			if (this.byteAt(i) != that.byteAt(i)) return false;
		}

		return true;
	}

	@Override
	public int hashCode() {
		int hc = hashCode;
		if (hc == 0) {
			if (bytes.length > 0) {
				for (byte b : bytes) {
					hc = (hc * 31) + (b & 0xff);
				}
				hashCode = hc;
			}
		}

		return hc;
	}

	@Override
	int maybeHashCode() {
		return hashCode;
	}

	@Override
	public String toString() {
		return decode();
	}

	@Override
	public String toRawString() {
		char[] chars = new char[bytes.length];
		for (int i = 0; i < chars.length; i++) {
			chars[i] = (char) (bytes[i] & 0xff);
		}
		return String.valueOf(chars);
	}

	@Override
	public int length() {
		return bytes.length;
	}

	@Override
	int maybeLength() {
		return bytes.length;
	}

	@Override
	public boolean isEmpty() {
		return bytes.length == 0;
	}

	@Override
	public byte byteAt(int index) {
		return bytes[index];
	}

	@Override
	public ByteIterator byteIterator() {
		return new ArrayByteIterator(bytes);
	}

	@Override
	public InputStream asInputStream() {
		// no need to go via the iterator
		return new ByteArrayInputStream(bytes);
	}

	@Override
	public ByteString substring(int start, int end) {
		if (start > end || start < 0 || end < 0 || end > bytes.length) {
			throw new IndexOutOfBoundsException();
		}
		return new ArrayByteString(Arrays.copyOfRange(bytes, start, end));
	}

	@Override
	public byte[] getBytes() {
		return Arrays.copyOf(bytes, bytes.length);
	}

	@Override
	public void putTo(ByteBuffer buffer) {
		buffer.put(bytes);
	}

	@Override
	public void writeTo(OutputStream stream) throws IOException {
		// must make a defensive copy to avoid leaking the contents
		stream.write(getBytes());
	}

	@Override
	public boolean startsWith(byte b) {
		return bytes.length > 0 && bytes[0] == b;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy