com.addthis.basis.chars.ByteArrayReadOnlyUtfBuf.java Source code

Java tutorial

Introduction

Here is the source code for com.addthis.basis.chars.ByteArrayReadOnlyUtfBuf.java

Source

/*
 * 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 com.addthis.basis.chars;

import java.util.Arrays;

import java.nio.charset.StandardCharsets;

import com.google.common.annotations.Beta;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;

/**
 * Originally intended for those cases where you just really can't avoid using byte[]s.
 * For instance, interacting with third parties that require, or already provide byte[]s
 * from their interface. However, it turns out to be far easier to maximize performance
 * and minimize memory footprint with byte[]s rather than ByteBufs -- to the extent that
 * it may be worth it in more circumstances.
 *
 * Now you _could_ just wrap the byte[] in a ByteBuf, but at high speeds that might
 * be annoyingly expensive. This class will at least let us test that.
 */
@Beta
public class ByteArrayReadOnlyUtfBuf extends AbstractReadOnlyUtfBuf {

    protected final byte[] data;

    public ByteArrayReadOnlyUtfBuf(byte[] data) {
        if (data == null) {
            throw new NullPointerException("data");
        }
        this.data = data;
    }

    // ideally only used for low-performance requirement code; like testing
    public ByteArrayReadOnlyUtfBuf(String javaString) {
        if (javaString == null) {
            throw new NullPointerException("java string");
        }
        this.data = javaString.getBytes(StandardCharsets.UTF_8);
    }

    @Override
    public byte getByte(int index) {
        return data[index];
    }

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

    @Override
    public ReadableCharBuf getSubSequenceForByteBounds(int start, int end) {
        // TODO: reconsider support byte[] slices; was ignored previously under the expectation
        // that slices are already handled by ByteBufs, but ByteBufs are less immediately performant
        // than we might have hoped.
        int length = end - start;
        byte[] wastefulClone = new byte[length];
        System.arraycopy(data, start, wastefulClone, 0, length);
        return new ByteArrayReadOnlyUtfBuf(wastefulClone);
    }

    @Override
    public ByteBuf toByteBuf() {
        return Unpooled.wrappedBuffer(data);
    }

    @Override
    public String toString() {
        if (knownAsciiOnly(packedIndexCache)) {
            return new String(data, 0);
        } else {
            return new String(data, StandardCharsets.UTF_8);
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof ByteArrayReadOnlyUtfBuf) {
            return Arrays.equals(data, ((ByteArrayReadOnlyUtfBuf) obj).data);
        } else if (obj instanceof ReadableCharBuf) {
            return ByteBufUtil.equals(((ReadableCharBuf) obj).toByteBuf(), toByteBuf());
        }
        return false;
    }
}