package io.vertx.core.buffer.impl;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.impl.Arguments;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
public class BufferImpl implements Buffer {
public static Buffer buffer(int initialSizeHint) {
return new BufferImpl(initialSizeHint);
}
public static Buffer buffer() {
return new BufferImpl();
}
public static Buffer buffer(String str) {
return new BufferImpl(str);
}
public static Buffer buffer(String str, String enc) {
return new BufferImpl(str, enc);
}
public static Buffer buffer(byte[] bytes) {
return new BufferImpl(bytes);
}
public static Buffer buffer(ByteBuf byteBuffer) {
return new BufferImpl(byteBuffer);
}
private ByteBuf buffer;
public BufferImpl() {
this(0);
}
BufferImpl(int initialSizeHint) {
buffer = VertxByteBufAllocator.DEFAULT.heapBuffer(initialSizeHint, Integer.MAX_VALUE);
}
BufferImpl(byte[] bytes) {
buffer = VertxByteBufAllocator.DEFAULT.heapBuffer(bytes.length, Integer.MAX_VALUE).writeBytes(bytes);
}
BufferImpl(String str, String enc) {
this(str.getBytes(Charset.forName(Objects.requireNonNull(enc))));
}
BufferImpl(String str, Charset cs) {
this(str.getBytes(cs));
}
BufferImpl(String str) {
this(str, StandardCharsets.UTF_8);
}
BufferImpl(ByteBuf buffer) {
this.buffer = buffer;
}
public String toString() {
return buffer.toString(StandardCharsets.UTF_8);
}
public String toString(String enc) {
return buffer.toString(Charset.forName(enc));
}
public String toString(Charset enc) {
return buffer.toString(enc);
}
@Override
public JsonObject toJsonObject() {
return new JsonObject(this);
}
@Override
public JsonArray toJsonArray() {
return new JsonArray(this);
}
public byte getByte(int pos) {
return buffer.getByte(pos);
}
public short getUnsignedByte(int pos) {
return buffer.getUnsignedByte(pos);
}
public int getInt(int pos) {
return buffer.getInt(pos);
}
public int getIntLE(int pos) {
return buffer.getIntLE(pos);
}
public long getUnsignedInt(int pos) {
return buffer.getUnsignedInt(pos);
}
public long getUnsignedIntLE(int pos) {
return buffer.getUnsignedIntLE(pos);
}
public long getLong(int pos) {
return buffer.getLong(pos);
}
public long getLongLE(int pos) {
return buffer.getLongLE(pos);
}
public double getDouble(int pos) {
return buffer.getDouble(pos);
}
public float getFloat(int pos) {
return buffer.getFloat(pos);
}
public short getShort(int pos) {
return buffer.getShort(pos);
}
public short getShortLE(int pos) {
return buffer.getShortLE(pos);
}
public int getUnsignedShort(int pos) {
return buffer.getUnsignedShort(pos);
}
public int getUnsignedShortLE(int pos) {
return buffer.getUnsignedShortLE(pos);
}
public int getMedium(int pos) {
return buffer.getMedium(pos);
}
public int getMediumLE(int pos) {
return buffer.getMediumLE(pos);
}
public int getUnsignedMedium(int pos) {
return buffer.getUnsignedMedium(pos);
}
public int getUnsignedMediumLE(int pos) {
return buffer.getUnsignedMediumLE(pos);
}
public byte[] getBytes() {
byte[] arr = new byte[buffer.writerIndex()];
buffer.getBytes(0, arr);
return arr;
}
public byte[] getBytes(int start, int end) {
Arguments.require(end >= start, "end must be greater or equal than start");
byte[] arr = new byte[end - start];
buffer.getBytes(start, arr, 0, end - start);
return arr;
}
@Override
public Buffer getBytes(byte[] dst) {
return getBytes(dst, 0);
}
@Override
public Buffer getBytes(byte[] dst, int dstIndex) {
return getBytes(0, buffer.writerIndex(), dst, dstIndex);
}
@Override
public Buffer getBytes(int start, int end, byte[] dst) {
return getBytes(start, end, dst, 0);
}
@Override
public Buffer getBytes(int start, int end, byte[] dst, int dstIndex) {
Arguments.require(end >= start, "end must be greater or equal than start");
buffer.getBytes(start, dst, dstIndex, end - start);
return this;
}
public Buffer getBuffer(int start, int end) {
return new BufferImpl(getBytes(start, end));
}
public String getString(int start, int end, String enc) {
byte[] bytes = getBytes(start, end);
Charset cs = Charset.forName(enc);
return new String(bytes, cs);
}
public String getString(int start, int end) {
byte[] bytes = getBytes(start, end);
return new String(bytes, StandardCharsets.UTF_8);
}
public Buffer appendBuffer(Buffer buff) {
BufferImpl impl = (BufferImpl) buff;
ByteBuf byteBuf = impl.buffer;
buffer.writeBytes(impl.buffer, byteBuf.readerIndex(), impl.buffer.readableBytes());
return this;
}
public Buffer appendBuffer(Buffer buff, int offset, int len) {
BufferImpl impl = (BufferImpl) buff;
ByteBuf byteBuf = impl.buffer;
int from = byteBuf.readerIndex() + offset;
buffer.writeBytes(byteBuf, from, len);
return this;
}
public Buffer appendBytes(byte[] bytes) {
buffer.writeBytes(bytes);
return this;
}
public Buffer appendBytes(byte[] bytes, int offset, int len) {
buffer.writeBytes(bytes, offset, len);
return this;
}
public Buffer appendByte(byte b) {
buffer.writeByte(b);
return this;
}
public Buffer appendUnsignedByte(short b) {
buffer.writeByte(b);
return this;
}
public Buffer appendInt(int i) {
buffer.writeInt(i);
return this;
}
public Buffer appendIntLE(int i) {
buffer.writeIntLE(i);
return this;
}
public Buffer appendUnsignedInt(long i) {
buffer.writeInt((int) i);
return this;
}
public Buffer appendUnsignedIntLE(long i) {
buffer.writeIntLE((int) i);
return this;
}
public Buffer appendMedium(int i) {
buffer.writeMedium(i);
return this;
}
public Buffer appendMediumLE(int i) {
buffer.writeMediumLE(i);
return this;
}
public Buffer appendLong(long l) {
buffer.writeLong(l);
return this;
}
public Buffer appendLongLE(long l) {
buffer.writeLongLE(l);
return this;
}
public Buffer appendShort(short s) {
buffer.writeShort(s);
return this;
}
public Buffer appendShortLE(short s) {
buffer.writeShortLE(s);
return this;
}
public Buffer appendUnsignedShort(int s) {
buffer.writeShort(s);
return this;
}
public Buffer appendUnsignedShortLE(int s) {
buffer.writeShortLE(s);
return this;
}
public Buffer appendFloat(float f) {
buffer.writeFloat(f);
return this;
}
public Buffer appendDouble(double d) {
buffer.writeDouble(d);
return this;
}
public Buffer appendString(String str, String enc) {
return append(str, Charset.forName(Objects.requireNonNull(enc)));
}
public Buffer appendString(String str) {
return append(str, CharsetUtil.UTF_8);
}
public Buffer setByte(int pos, byte b) {
ensureLength(pos + 1);
buffer.setByte(pos, b);
return this;
}
public Buffer setUnsignedByte(int pos, short b) {
ensureLength(pos + 1);
buffer.setByte(pos, b);
return this;
}
public Buffer setInt(int pos, int i) {
ensureLength(pos + 4);
buffer.setInt(pos, i);
return this;
}
public Buffer setIntLE(int pos, int i) {
ensureLength(pos + 4);
buffer.setIntLE(pos, i);
return this;
}
public Buffer setUnsignedInt(int pos, long i) {
ensureLength(pos + 4);
buffer.setInt(pos, (int) i);
return this;
}
public Buffer setUnsignedIntLE(int pos, long i) {
ensureLength(pos + 4);
buffer.setIntLE(pos, (int) i);
return this;
}
public Buffer setMedium(int pos, int i) {
ensureLength(pos + 3);
buffer.setMedium(pos, i);
return this;
}
public Buffer setMediumLE(int pos, int i) {
ensureLength(pos + 3);
buffer.setMediumLE(pos, i);
return this;
}
public Buffer setLong(int pos, long l) {
ensureLength(pos + 8);
buffer.setLong(pos, l);
return this;
}
public Buffer setLongLE(int pos, long l) {
ensureLength(pos + 8);
buffer.setLongLE(pos, l);
return this;
}
public Buffer setDouble(int pos, double d) {
ensureLength(pos + 8);
buffer.setDouble(pos, d);
return this;
}
public Buffer setFloat(int pos, float f) {
ensureLength(pos + 4);
buffer.setFloat(pos, f);
return this;
}
public Buffer setShort(int pos, short s) {
ensureLength(pos + 2);
buffer.setShort(pos, s);
return this;
}
public Buffer setShortLE(int pos, short s) {
ensureLength(pos + 2);
buffer.setShortLE(pos, s);
return this;
}
public Buffer setUnsignedShort(int pos, int s) {
ensureLength(pos + 2);
buffer.setShort(pos, s);
return this;
}
public Buffer setUnsignedShortLE(int pos, int s) {
ensureLength(pos + 2);
buffer.setShortLE(pos, s);
return this;
}
public Buffer setBuffer(int pos, Buffer buff) {
ensureLength(pos + buff.length());
BufferImpl impl = (BufferImpl) buff;
ByteBuf byteBuf = impl.buffer;
buffer.setBytes(pos, byteBuf, byteBuf.readerIndex(), byteBuf.readableBytes());
return this;
}
public Buffer setBuffer(int pos, Buffer buffer, int offset, int len) {
ensureLength(pos + len);
BufferImpl impl = (BufferImpl) buffer;
ByteBuf byteBuf = impl.buffer;
this.buffer.setBytes(pos, byteBuf, byteBuf.readerIndex() + offset, len);
return this;
}
public BufferImpl setBytes(int pos, ByteBuffer b) {
ensureLength(pos + b.limit());
buffer.setBytes(pos, b);
return this;
}
public Buffer setBytes(int pos, byte[] b) {
ensureLength(pos + b.length);
buffer.setBytes(pos, b);
return this;
}
public Buffer setBytes(int pos, byte[] b, int offset, int len) {
ensureLength(pos + len);
buffer.setBytes(pos, b, offset, len);
return this;
}
public Buffer setString(int pos, String str) {
return setBytes(pos, str, CharsetUtil.UTF_8);
}
public Buffer setString(int pos, String str, String enc) {
return setBytes(pos, str, Charset.forName(enc));
}
public int length() {
return buffer.writerIndex();
}
public Buffer copy() {
return new BufferImpl(buffer.copy());
}
public Buffer slice() {
return new BufferImpl(buffer.slice());
}
public Buffer slice(int start, int end) {
return new BufferImpl(buffer.slice(start, end - start));
}
public ByteBuf byteBuf() {
return buffer;
}
public ByteBuf getByteBuf() {
ByteBuf duplicate = buffer.duplicate();
if (buffer.getClass() != VertxHeapByteBuf.class && buffer.getClass() != VertxUnsafeHeapByteBuf.class) {
duplicate = Unpooled.unreleasableBuffer(duplicate);
}
return duplicate;
}
private Buffer append(String str, Charset charset) {
byte[] bytes = str.getBytes(charset);
ensureExpandableBy(bytes.length);
buffer.writeBytes(bytes);
return this;
}
private Buffer setBytes(int pos, String str, Charset charset) {
byte[] bytes = str.getBytes(charset);
ensureLength(pos + bytes.length);
buffer.setBytes(pos, bytes);
return this;
}
private void ensureLength(int newLength) {
int capacity = buffer.capacity();
int over = newLength - capacity;
int writerIndex = buffer.writerIndex();
if (over > 0) {
int maxCapacity = buffer.maxCapacity();
if (capacity + over > maxCapacity) {
setFullMaxCapacity(capacity + over);
}
buffer.ensureWritable(newLength - writerIndex);
}
if (newLength > writerIndex) {
buffer.writerIndex(newLength);
}
}
private void ensureExpandableBy(int amount) {
int minMaxCapa = buffer.writerIndex() + amount;
if (minMaxCapa > buffer.maxCapacity()) {
setFullMaxCapacity(minMaxCapa);
}
}
private void setFullMaxCapacity(int capacity) {
ByteBuf tmp = buffer.alloc().heapBuffer(capacity, Integer.MAX_VALUE);
tmp.writeBytes(buffer);
buffer = tmp;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BufferImpl buffer1 = (BufferImpl) o;
return Objects.equals(buffer, buffer1.buffer);
}
@Override
public int hashCode() {
return buffer != null ? buffer.hashCode() : 0;
}
@Override
public void writeToBuffer(Buffer buff) {
buff.appendInt(this.length());
buff.appendBuffer(this);
}
@Override
public int readFromBuffer(int pos, Buffer buffer) {
int len = buffer.getInt(pos);
BufferImpl impl = (BufferImpl)buffer.getBuffer(pos + 4, pos + 4 + len);
this.buffer = impl.getByteBuf();
return pos + 4 + len;
}
}