com.javanut.pronghorn.util.AppendableBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pronghorn-pipes Show documentation
Show all versions of pronghorn-pipes Show documentation
Ring buffer based queuing utility for applications that require high performance and/or a small
footprint. Well suited for embedded and stream based processing.
package com.javanut.pronghorn.util;
import java.io.IOException;
import java.io.OutputStream;
import com.javanut.pronghorn.pipe.ChannelReader;
import com.javanut.pronghorn.pipe.ChannelWriter;
import com.javanut.pronghorn.pipe.DataOutputBlobWriter;
import com.javanut.pronghorn.pipe.Pipe;
public class AppendableBuilder implements AppendableByteWriter {
private int maximumAllocation;
private static final int defaultSize = 1<<15;
private byte[] buffer;
private int byteCount;
public AppendableBuilder() {
this(Integer.MAX_VALUE);
}
//This class is allowed to grow but only up to the maximumAllocation
public AppendableBuilder(int maximumAllocation) {
this.maximumAllocation = maximumAllocation;
this.buffer = new byte[maximumAllocation=0);
try {
target.write(buffer, pos, len);
pos += len;
} catch (IOException e) {
throw new RuntimeException(e);
}
return len;
}
public void copyTo(Appendable target) {
if (target instanceof DataOutputBlobWriter) {
((DataOutputBlobWriter)target).write(buffer, 0, byteCount, Integer.MAX_VALUE);
} else {
Appendables.appendUTF8(target, buffer, 0, byteCount, Integer.MAX_VALUE);
}
}
public static void appendLongAsText(AppendableBuilder ab, long value, boolean useNegPara) {
if (ab.byteCount+(18) <= ab.buffer.length) {
ab.byteCount = Appendables.longToChars(value, useNegPara, ab.buffer,
Integer.MAX_VALUE, ab.byteCount);
} else {
growNow(ab, ab.byteCount+(18));
ab.byteCount = Appendables.longToChars(value, useNegPara, ab.buffer,
Integer.MAX_VALUE, ab.byteCount);
}
}
@Override
public AppendableBuilder append(CharSequence csq) {
int len = csq.length();
if (byteCount+(len<<3) <= buffer.length) {
int bytesConsumed = Pipe.copyUTF8ToByte(csq, 0, buffer, Integer.MAX_VALUE, byteCount, len);
byteCount+=bytesConsumed;
} else {
growNow(this,byteCount+(len<<3));
int bytesConsumed = Pipe.copyUTF8ToByte(csq, 0, buffer, Integer.MAX_VALUE, byteCount, len);
byteCount+=bytesConsumed;
}
return this;
}
private static void growNow(AppendableBuilder that, int req) {
if (req > that.maximumAllocation) {
throw new UnsupportedOperationException("Max allocation was limited to "+that.maximumAllocation+" but more space needed");
}
byte[] temp = new byte[req];
System.arraycopy(that.buffer, 0, temp, 0, that.buffer.length);
that.buffer = temp;
}
@Override
public AppendableBuilder append(CharSequence csq, int start, int end) {
int len = end-start;
if (byteCount+(len<<3) <= buffer.length) {
int bytesConsumed = Pipe.copyUTF8ToByte(csq, start, buffer, Integer.MAX_VALUE, byteCount, len);
byteCount+=bytesConsumed;
} else {
growNow(this,byteCount+(len<<3));
int bytesConsumed = Pipe.copyUTF8ToByte(csq, start, buffer, Integer.MAX_VALUE, byteCount, len);
byteCount+=bytesConsumed;
}
return this;
}
@Override
public AppendableBuilder append(char c) {
if (byteCount+(1<<3) <= buffer.length) {
byteCount = Pipe.encodeSingleChar(c, buffer, Integer.MAX_VALUE, byteCount);
} else {
growNow(this,byteCount+(1<<3));
byteCount = Pipe.encodeSingleChar(c, buffer, Integer.MAX_VALUE, byteCount);
}
return this;
}
@Override
public void write(byte[] encodedBlock, int pos, int len) {
if (byteCount+len <= buffer.length) {
Pipe.copyBytesFromArrayToRing(encodedBlock, pos,
buffer, byteCount, Integer.MAX_VALUE,
len);
} else {
growNow(this,byteCount+len);
Pipe.copyBytesFromArrayToRing(encodedBlock, pos,
buffer, byteCount, Integer.MAX_VALUE,
len);
}
this.byteCount+=len;
}
@Override
public void write(byte[] encodedBlock) {
if (byteCount+encodedBlock.length <= buffer.length) {
Pipe.copyBytesFromArrayToRing(encodedBlock, 0,
buffer, byteCount, Integer.MAX_VALUE,
encodedBlock.length);
this.byteCount+=encodedBlock.length;
} else {
growNow(this,byteCount+encodedBlock.length);
Pipe.copyBytesFromArrayToRing(encodedBlock, 0,
buffer, byteCount, Integer.MAX_VALUE,
encodedBlock.length);
this.byteCount+=encodedBlock.length;
}
}
@Override
public void writeByte(int asciiChar) {
if (byteCount+1 <= buffer.length) {
buffer[byteCount++] = (byte)asciiChar;
} else {
growNow(this,byteCount+1);
buffer[byteCount++] = (byte)asciiChar;
}
}
public int absolutePosition() {
return byteCount;
}
public void absolutePosition(int absolutePosition) {
byteCount = absolutePosition;
}
public boolean isEqual(ChannelReader target) {
return target.equalBytes(buffer, 0, byteCount);
}
public int base64Decode(byte[] target, int targetIdx, int targetMask) {
return Appendables.decodeBase64(buffer, 0, byteCount, Integer.MAX_VALUE,
target, targetIdx, targetMask);
}
public byte[] toBytes() {
byte[] result = new byte[byteCount];
System.arraycopy(this.buffer, 0, result, 0, result.length);
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy