Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.wildfly.common.bytes.ByteStringBuilder Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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 org.wildfly.common.bytes;
import static org.wildfly.common._private.CommonMessages.msg;
import java.security.DigestException;
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.Mac;
import org.wildfly.common.iteration.ByteIterator;
import org.wildfly.common.iteration.CodePointIterator;
/**
* A builder for byte arrays.
*/
public final class ByteStringBuilder {
private byte[] content;
private int length;
public ByteStringBuilder() {
this.content = new byte[16];
}
public ByteStringBuilder(final byte[] content) {
if (content != null && content.length != 0) {
this.content = content.clone();
this.length = this.content.length;
} else {
this.content = new byte[16];
}
}
public ByteStringBuilder append(boolean b) {
appendLatin1(Boolean.toString(b));
return this;
}
public ByteStringBuilder append(byte b) {
doAppend(b);
return this;
}
public ByteStringBuilder append(char c) {
return appendUtf8Raw((int) c);
}
public ByteStringBuilder appendUtf8Raw(int codePoint) {
if (codePoint < 0) {
throw new IllegalArgumentException();
} else if (codePoint < 0x80) {
doAppend((byte) codePoint);
} else if (codePoint < 0x800) {
doAppend((byte) (0xC0 | 0x1F & codePoint >>> 6));
doAppend((byte) (0x80 | 0x3F & codePoint));
} else if (codePoint < 0x10000) {
doAppend((byte) (0xE0 | 0x0F & codePoint >>> 12));
doAppend((byte) (0x80 | 0x3F & codePoint >>> 6));
doAppend((byte) (0x80 | 0x3F & codePoint));
} else if (codePoint < 0x110000) {
doAppend((byte) (0xF0 | 0x07 & codePoint >>> 18));
doAppend((byte) (0x80 | 0x3F & codePoint >>> 12));
doAppend((byte) (0x80 | 0x3F & codePoint >>> 6));
doAppend((byte) (0x80 | 0x3F & codePoint));
} else {
throw new IllegalArgumentException();
}
return this;
}
public ByteStringBuilder appendUtf8(CodePointIterator iterator) {
while (iterator.hasNext()) {
appendUtf8Raw(iterator.next());
}
return this;
}
public ByteStringBuilder appendLatin1(CodePointIterator iterator) {
int cp;
while (iterator.hasNext()) {
cp = iterator.next();
if (cp > 255) throw new IllegalArgumentException();
append((byte) cp);
}
return this;
}
public ByteStringBuilder appendAscii(CodePointIterator iterator) {
int cp;
while (iterator.hasNext()) {
cp = iterator.next();
if (cp > 127) throw new IllegalArgumentException();
append((byte) cp);
}
return this;
}
public ByteStringBuilder append(ByteIterator iterator) {
return iterator.appendTo(this);
}
public ByteStringBuilder append(byte[] bytes) {
int length = this.length;
int bl = bytes.length;
reserve(bl, false);
System.arraycopy(bytes, 0, content, length, bl);
this.length = length + bl;
return this;
}
public ByteStringBuilder append(byte[] bytes, int offs, int len) {
reserve(len, false);
int length = this.length;
System.arraycopy(bytes, offs, content, length, len);
this.length = length + len;
return this;
}
public ByteStringBuilder appendLatin1(CharSequence s) {
int len = s.length();
reserve(len, false);
char c;
for (int i = 0; i < len; i ++) {
c = s.charAt(i);
if (c > 255) throw new IllegalArgumentException();
doAppendNoCheck((byte) c);
}
return this;
}
public ByteStringBuilder appendLatin1(CharSequence s, int offs, int len) {
reserve(len, false);
char c;
for (int i = 0; i < len; i ++) {
c = s.charAt(i + offs);
if (c > 255) throw new IllegalArgumentException();
doAppendNoCheck((byte) c);
}
return this;
}
public ByteStringBuilder appendLatin1(String s) {
int len = s.length();
reserve(len, false);
char c;
for (int i = 0; i < len; i ++) {
c = s.charAt(i);
if (c > 255) throw new IllegalArgumentException();
doAppendNoCheck((byte) c);
}
return this;
}
public ByteStringBuilder appendLatin1(String s, int offs, int len) {
reserve(len, false);
char c;
for (int i = 0; i < len; i ++) {
c = s.charAt(i + offs);
if (c > 255) throw new IllegalArgumentException();
doAppendNoCheck((byte) c);
}
return this;
}
public ByteStringBuilder append(CharSequence s) {
return append(s, 0, s.length());
}
public ByteStringBuilder append(CharSequence s, int offs, int len) {
int c;
int i = 0;
while (i < len) {
c = s.charAt(offs + i++);
if (Character.isHighSurrogate((char) c)) {
if (i < len) {
char t = s.charAt(offs + i ++);
if (! Character.isLowSurrogate(t)) {
throw new IllegalArgumentException();
}
c = Character.toCodePoint((char) c, t);
} else {
throw new IllegalArgumentException();
}
}
appendUtf8Raw(c);
}
return this;
}
public ByteStringBuilder append(String s) {
return append(s, 0, s.length());
}
public ByteStringBuilder append(String s, int offs, int len) {
int c;
int i = 0;
while (i < len) {
c = s.charAt(offs + i++);
if (Character.isHighSurrogate((char) c)) {
if (i < len) {
char t = s.charAt(offs + i ++);
if (! Character.isLowSurrogate(t)) {
throw new IllegalArgumentException();
}
c = Character.toCodePoint((char) c, t);
} else {
throw new IllegalArgumentException();
}
}
appendUtf8Raw(c);
}
return this;
}
public ByteStringBuilder appendPackedUnsignedBE(int v) {
if (v > 0) {
final int bits = Integer.numberOfTrailingZeros(Integer.highestOneBit(v)) + 1;
final int size = (bits + 7) / 7;
for (int x = 0, b = (size - 1) * 7; x < size - 1; x ++, b -= 7) {
doAppend((byte) (0x80 | v >>> b));
}
}
doAppend((byte) (~0x80 & v));
return this;
}
public ByteStringBuilder appendPackedUnsignedBE(long v) {
if (v > 0) {
final int bits = Long.numberOfTrailingZeros(Long.highestOneBit(v)) + 1;
final int size = (bits + 7) / 7;
for (int x = 0, b = (size - 1) * 7; x < size - 1; x ++, b -= 7) {
doAppend((byte) (0x80L | v >>> b));
}
}
doAppend((byte) (~0x80L & v));
return this;
}
public ByteStringBuilder appendBE(short s) {
doAppend((byte) (s >>> 8));
doAppend((byte) s);
return this;
}
public ByteStringBuilder appendNumber(int i) {
appendLatin1(Integer.toString(i));
return this;
}
public ByteStringBuilder appendBE(int i) {
doAppend((byte) (i >>> 24));
doAppend((byte) (i >>> 16));
doAppend((byte) (i >>> 8));
doAppend((byte) i);
return this;
}
public ByteStringBuilder appendNumber(long l) {
appendLatin1(Long.toString(l));
return this;
}
public ByteStringBuilder appendBE(long l) {
doAppend((byte) (l >>> 56));
doAppend((byte) (l >>> 48));
doAppend((byte) (l >>> 40));
doAppend((byte) (l >>> 32));
doAppend((byte) (l >>> 24));
doAppend((byte) (l >>> 16));
doAppend((byte) (l >>> 8));
doAppend((byte) l);
return this;
}
public ByteStringBuilder appendObject(Object o) {
appendLatin1(String.valueOf(o));
return this;
}
public ByteStringBuilder append(ByteStringBuilder other) {
append(other.content, 0, other.length);
return this;
}
public ByteStringBuilder updateDigest(final MessageDigest messageDigest) {
messageDigest.update(content, 0, length);
return this;
}
public ByteStringBuilder appendDigestResult(final MessageDigest messageDigest) throws DigestException {
reserve(messageDigest.getDigestLength(), false);
final int length = this.length;
final byte[] content = this.content;
this.length = length + messageDigest.digest(content, length, content.length - length);
return this;
}
public ByteStringBuilder updateMac(final Mac mac) {
mac.update(content, 0, length);
return this;
}
public byte[] toArray() {
return Arrays.copyOf(content, length);
}
public byte byteAt(int index) {
if (index < 0 || index > length) throw new IndexOutOfBoundsException();
return content[index];
}
public int capacity() {
return content.length;
}
public int length() {
return length;
}
public void setLength(int newLength) {
if (newLength > length) {
// grow
reserve(newLength - length, true);
}
length = newLength;
}
public boolean contentEquals(final byte[] other) {
return contentEquals(other, 0, other.length);
}
public boolean contentEquals(final byte[] other, final int offs, final int length) {
if (length != this.length) return false;
for (int i = 0; i < length; i++) {
if (content[i] != other[offs + i]) {
return false;
}
}
return true;
}
private void reserve(final int count, final boolean clear) {
final int length = this.length;
final byte[] content = this.content;
int cl = content.length;
if (cl - length >= count) {
if (clear) Arrays.fill(content, length, length + count, (byte) 0);
return;
}
// clear remainder
if (clear) Arrays.fill(content, length, cl, (byte) 0);
do {
// not enough space... grow by 1.5x
cl = cl + (cl + 1 >> 1);
if (cl < 0) throw msg.tooLarge();
} while (cl - length < count);
this.content = Arrays.copyOf(content, cl);
}
private void doAppend(final byte b) {
byte[] content = this.content;
final int cl = content.length;
final int length = this.length;
if (length == cl) {
content = this.content = Arrays.copyOf(content, cl + (cl + 1 >> 1)); // content must not be blank
}
content[length] = b;
this.length = length + 1;
}
private void doAppendNoCheck(final byte b) {
content[length ++] = b;
}
public ByteIterator iterate() {
return ByteIterator.ofBytes(content, 0, length);
}
}