blob: 391debbcdec2bf2d5244cd257f40103ba0ed88fd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.jackrabbit.oak.commons;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.util.zip.CRC32;
/**
* This is a wrapper around {@link ByteBuffer}. It maintains the same semantics
* and mechanisms of the {@link ByteBuffer}.
* <p>
* Java 9 introduced API changes to some methods in {@link ByteBuffer}. Instead
* of returning instances of {@link java.nio.Buffer Buffer}, those methods were
* rewritten to return instances of {@link ByteBuffer} instead. While this is
* perfectly fine at compile time, running "modern" code on Java 8 and earlier
* throws {@link NoSuchMethodError}. In order to prevent occurrences of this
* exceptions in the future, {@link Buffer} is used consistently in place of
* {@link ByteBuffer}. Since it is not possible to directly convert a {@link
* Buffer} into a {@link ByteBuffer} and the other way around, {@link Buffer}
* makes it less likely to develop dangerous code in the future.
*/
final public class Buffer {
private final ByteBuffer buffer;
private Buffer(ByteBuffer buffer) {
this.buffer = buffer;
}
public static Buffer map(FileChannel channel, MapMode mode, long position, long size) throws IOException {
return new Buffer(channel.map(mode, position, size));
}
public static Buffer wrap(byte[] buffer) {
return new Buffer(ByteBuffer.wrap(buffer));
}
public static Buffer wrap(byte[] buffer, int pos, int len) {
return new Buffer(ByteBuffer.wrap(buffer, pos, len));
}
public static Buffer allocate(int cap) {
return new Buffer(ByteBuffer.allocate(cap));
}
public static Buffer allocateDirect(int cap) {
return new Buffer(ByteBuffer.allocateDirect(cap));
}
public int remaining() {
return buffer.remaining();
}
public Buffer asReadOnlyBuffer() {
return new Buffer(buffer.asReadOnlyBuffer());
}
public Buffer position(int pos) {
((java.nio.Buffer) buffer).position(pos);
return this;
}
public int position() {
return buffer.position();
}
public Buffer limit(int lim) {
((java.nio.Buffer) buffer).limit(lim);
return this;
}
public int limit() {
return buffer.limit();
}
public Buffer slice() {
return new Buffer(buffer.slice());
}
public int readFully(FileChannel channel, int position) throws IOException {
int result = 0;
while (buffer.remaining() > 0) {
int count = channel.read(buffer, position);
if (count < 0) {
break;
}
result += count;
position += count;
}
return result;
}
public Buffer flip() {
((java.nio.Buffer) buffer).flip();
return this;
}
public int getInt() {
return buffer.getInt();
}
public int getInt(int pos) {
return buffer.getInt(pos);
}
public Buffer mark() {
((java.nio.Buffer) buffer).mark();
return this;
}
public Buffer get(byte[] b) {
buffer.get(b);
return this;
}
public Buffer get(byte[] b, int pos, int len) {
buffer.get(b, pos, len);
return this;
}
public byte get(int pos) {
return buffer.get(pos);
}
public byte get() {
return buffer.get();
}
public Buffer reset() {
((java.nio.Buffer) buffer).reset();
return this;
}
public void update(CRC32 checksum) {
checksum.update(buffer);
}
public byte[] array() {
return buffer.array();
}
public int capacity() {
return buffer.capacity();
}
public boolean isDirect() {
return buffer.isDirect();
}
public Buffer put(byte[] b) {
buffer.put(b);
return this;
}
public Buffer put(byte[] buf, int pos, int len) {
buffer.put(buf, pos, len);
return this;
}
public Buffer put(byte b) {
buffer.put(b);
return this;
}
public Buffer put(Buffer b) {
buffer.put(b.buffer);
return this;
}
public Buffer rewind() {
((java.nio.Buffer) buffer).rewind();
return this;
}
public long getLong(int pos) {
return buffer.getLong(pos);
}
public long getLong() {
return buffer.getLong();
}
public short getShort(int pos) {
return buffer.getShort(pos);
}
public Buffer duplicate() {
return new Buffer(buffer.duplicate());
}
public CharBuffer decode(Charset charset) {
return charset.decode(buffer);
}
public boolean hasRemaining() {
return buffer.hasRemaining();
}
public int write(WritableByteChannel channel) throws IOException {
return channel.write(buffer);
}
public Buffer putInt(int i) {
buffer.putInt(i);
return this;
}
public Buffer putLong(long l) {
buffer.putLong(l);
return this;
}
@Override
public int hashCode() {
return buffer.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj instanceof Buffer) {
return buffer.equals(((Buffer) obj).buffer);
}
return false;
}
}