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

jetbrains.exodus.FixedLengthByteIterable Maven / Gradle / Ivy

There is a newer version: 9.8.0.76914
Show newest version
/**
 * Copyright 2010 - 2022 JetBrains s.r.o.
 *
 * 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
 *
 * https://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 jetbrains.exodus;

import org.jetbrains.annotations.NotNull;

/**
 * Helps to create new {@code ByteIterable} as a part of another (source) {@code ByteIterable}.
 * Is used in basic implementation of {@link ByteIterable#subIterable(int, int)}.
 */
public class FixedLengthByteIterable extends ByteIterableBase {

    protected final ByteIterable source;
    protected final int offset;

    protected FixedLengthByteIterable(@NotNull final ByteIterable source, final int offset, final int length) {
        if (length < 0) {
            throw new ExodusException("ByteIterable length can't be less than zero");
        }
        this.source = source;
        this.offset = offset;
        this.length = length;
    }

    @Override
    public byte[] getBytesUnsafe() {
        if (bytes == null) {
            final int length = this.length;
            byte[] bytes = null;
            if (source instanceof ByteIterableBase) {
                final ByteIterableBase s = (ByteIterableBase) source;
                final byte[] sourceBytes = s.getBytesUnsafe();
                if (sourceBytes != null) {
                    bytes = new byte[length];
                    System.arraycopy(sourceBytes, offset, bytes, 0, length);
                }
            }
            if (bytes == null) {
                bytes = new byte[length];
                final ByteIterator it = source.iterator();
                it.skip(offset);
                for (int i = 0; it.hasNext() && i < length; ++i) {
                    bytes[i] = it.next();
                }
            }
            this.bytes = bytes;
        }
        return bytes;
    }

    public int getOffset() {
        return offset;
    }

    @Override
    public int getLength() {
        return length;
    }

    @NotNull
    @Override
    public ByteIterable subIterable(final int offset, final int length) {
        final int safeLength = Math.min(length, this.length - offset);
        return safeLength == 0 ? EMPTY : new FixedLengthByteIterable(source, this.offset + offset, safeLength);
    }

    public ByteIterable getSource() {
        return source;
    }

    @Override
    protected ByteIterator getIterator() {
        if (length == 0) {
            return ByteIterable.EMPTY_ITERATOR;
        }
        final ByteIterator bi = source.iterator();
        bi.skip(offset);
        return new ByteIterator() {
            private int i = length;

            @Override
            public boolean hasNext() {
                return i > 0 && bi.hasNext();
            }

            @Override
            public byte next() {
                i--;
                return bi.next();
            }

            @Override
            public long skip(long bytes) {
                long result = bi.skip(Math.min(bytes, i));
                i -= (int) result;
                return result;
            }
        };
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy