Add wrapping of ByteBuffer into CharBuffer

This commit is contained in:
konsoletyper 2014-10-29 21:44:38 +03:00
parent 5c8b80aa32
commit 8dd5661dfa
6 changed files with 242 additions and 54 deletions

View File

@ -198,4 +198,6 @@ public abstract class TByteBuffer extends TBuffer implements TComparable<TByteBu
order = bo;
return this;
}
public abstract TCharBuffer asCharBuffer();
}

View File

@ -102,4 +102,10 @@ class TByteBufferImpl extends TByteBuffer {
public boolean isReadOnly() {
return readOnly;
}
@Override
public TCharBuffer asCharBuffer() {
int sz = remaining() / 2;
return new TCharBufferOverByteBuffer(start + position, sz, this, 0, sz, isReadOnly());
}
}

View File

@ -24,26 +24,25 @@ import org.teavm.classlib.java.lang.TReadable;
*/
public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuffer>, Appendable,
CharSequence, TReadable {
int start;
char[] array;
TCharBuffer(int start, int capacity, char[] array, int position, int limit) {
TCharBuffer(int capacity, int position, int limit) {
super(capacity);
this.start = start;
this.array = array;
this.position = position;
this.limit = limit;
}
abstract char getChar(int index);
abstract void putChar(int index, char value);
public static TCharBuffer allocate(int capacity) {
if (capacity < 0) {
throw new IllegalArgumentException("Capacity is negative: " + capacity);
}
return new TCharBufferImpl(capacity);
return new TCharBufferOverArray(capacity);
}
public static TCharBuffer wrap(char[] array, int offset, int length) {
return new TCharBufferImpl(0, array.length, array, offset, offset + length, false);
return new TCharBufferOverArray(0, array.length, array, offset, offset + length, false);
}
public static TCharBuffer wrap(char[] array) {
@ -62,7 +61,12 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
return -1;
}
int sz = Math.min(remaining(), target.remaining());
target.put(array, start + position, sz);
int srcPos = position;
int dstPos = target.position;
for (int i = 0; i < sz; ++i) {
target.putChar(dstPos++, getChar(srcPos++));
}
target.position += sz;
return sz;
}
@ -102,9 +106,9 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
if (length < 0) {
throw new IndexOutOfBoundsException("Length " + length + " must be non-negative");
}
int pos = position + start;
int pos = position;
for (int i = 0; i < length; ++i) {
dst[offset++] = array[pos++];
dst[offset++] = getChar(pos++);
}
position += length;
return this;
@ -115,7 +119,20 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
}
public TCharBuffer put(TCharBuffer src) {
return put(src.array, src.start + src.position, src.remaining());
if (isReadOnly()) {
throw new TReadOnlyBufferException();
}
if (remaining() < src.remaining()) {
throw new TBufferOverflowException();
}
int length = src.remaining();
int pos = position;
int offset = src.position;
for (int i = 0; i < length; ++i) {
putChar(pos++, src.getChar(offset++));
}
position += length;
return this;
}
public TCharBuffer put(char[] src, int offset, int length) {
@ -135,9 +152,9 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
if (length < 0) {
throw new IndexOutOfBoundsException("Length " + length + " must be non-negative");
}
int pos = position + start;
int pos = position;
for (int i = 0; i < length; ++i) {
array[pos++] = src[offset++];
putChar(pos++, src[offset++]);
}
position += length;
return this;
@ -165,9 +182,9 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
if (start > end) {
throw new IndexOutOfBoundsException("Start " + start + " must be before end " + end);
}
int pos = position + this.start;
int pos = position;
while (start < end) {
array[pos++] = src.charAt(start++);
putChar(pos++, src.charAt(start++));
}
position += sz;
return this;
@ -179,19 +196,25 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
@Override
public final boolean hasArray() {
return true;
return isArrayPresent();
}
@Override
public final char[] array() {
return array;
return getArray();
}
@Override
public final int arrayOffset() {
return start;
return getArrayOffset();
}
abstract boolean isArrayPresent();
abstract char[] getArray();
abstract int getArrayOffset();
public abstract TCharBuffer compact();
@Override
@ -200,9 +223,9 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
@Override
public int hashCode() {
int hashCode = 0;
int pos = position + start;
int pos = position;
for (int i = position; i < limit; ++i) {
hashCode = 31 * hashCode + array[pos++];
hashCode = 31 * hashCode + getChar(pos++);
}
return hashCode;
}
@ -220,10 +243,10 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
if (sz != other.remaining()) {
return false;
}
int a = position + start;
int b = other.position + other.start;
int a = position;
int b = other.position;
for (int i = 0; i < sz; ++i) {
if (array[a++] != other.array[b++]) {
if (getChar(a++) != other.getChar(b++)) {
return false;
}
}
@ -236,10 +259,10 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
return 0;
}
int sz = Math.min(remaining(), other.remaining());
int a = position + start;
int b = other.position + other.start;
int a = position;
int b = other.position;
for (int i = 0; i < sz; ++i) {
int r = Character.compare(array[a++], other.array[b++]);
int r = Character.compare(getChar(a++), other.getChar(b++));
if (r != 0) {
return r;
}
@ -249,7 +272,12 @@ public abstract class TCharBuffer extends TBuffer implements Comparable<TCharBuf
@Override
public String toString() {
return new String(array, start + position, limit - position);
char[] chars = new char[limit - position];
int pos = position;
for (int i = 0; i < chars.length; ++i) {
chars[i] = getChar(pos++);
}
return new String(chars);
}
@Override

View File

@ -19,51 +19,45 @@ package org.teavm.classlib.java.nio;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
class TCharBufferImpl extends TCharBuffer {
private boolean readOnly;
public TCharBufferImpl(int capacity) {
this(0, capacity, new char[capacity], 0, capacity, false);
}
public TCharBufferImpl(int start, int capacity, char[] array, int position, int limit,
boolean readOnly) {
super(start, capacity, array, position, limit);
this.readOnly = readOnly;
abstract class TCharBufferImpl extends TCharBuffer {
public TCharBufferImpl(int capacity, int position, int limit) {
super(capacity, position, limit);
}
@Override
public TCharBuffer slice() {
return new TCharBufferImpl(position, limit - position, array, 0, limit - position, readOnly);
return duplicate(position, limit - position, 0, limit - position, isReadOnly());
}
@Override
public TCharBuffer duplicate() {
return new TCharBufferImpl(start, capacity, array, position, limit, readOnly);
return duplicate(0, capacity, position, limit, isReadOnly());
}
@Override
public TCharBuffer asReadOnlyBuffer() {
return new TCharBufferImpl(start, capacity, array, position, limit, true);
return duplicate(0, capacity, position, limit, true);
}
abstract TCharBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly);
@Override
public char get() {
if (position >= limit) {
throw new TBufferUnderflowException();
}
return array[start + position++];
return getChar(position++);
}
@Override
public TCharBuffer put(char c) {
if (readOnly) {
if (isReadOnly()) {
throw new TReadOnlyBufferException();
}
if (position >= limit) {
throw new TBufferOverflowException();
}
array[start + position++] = c;
putChar(position++, c);
return this;
}
@ -72,32 +66,31 @@ class TCharBufferImpl extends TCharBuffer {
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")");
}
return array[start + index];
return getChar(index);
}
@Override
public TCharBuffer put(int index, char b) {
if (readOnly) {
if (isReadOnly()) {
throw new TReadOnlyBufferException();
}
if (index < 0 || index >= limit) {
throw new IndexOutOfBoundsException("Index " + index + " is outside of range [0;" + limit + ")");
}
array[start + index] = b;
putChar(index, b);
return this;
}
@Override
public TCharBuffer compact() {
if (readOnly) {
if (isReadOnly()) {
throw new TReadOnlyBufferException();
}
if (position > 0) {
int sz = remaining();
int dst = start;
int src = start + position;
int src = position;
for (int i = 0; i < sz; ++i) {
array[dst++] = array[src++];
putChar(i, getChar(src++));
}
position = sz;
}
@ -113,11 +106,13 @@ class TCharBufferImpl extends TCharBuffer {
@Override
public boolean isReadOnly() {
return readOnly;
return readOnly();
}
abstract boolean readOnly();
@Override
public TCharBuffer subSequence(int start, int end) {
return wrap(array, arrayOffset() + start, end - start);
return duplicate(0, capacity, position + start, position + end, isReadOnly());
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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.teavm.classlib.java.nio;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
class TCharBufferOverArray extends TCharBufferImpl {
boolean readOnly;
int start;
char[] array;
public TCharBufferOverArray(int capacity) {
this(0, capacity, new char[capacity], 0, capacity, false);
}
public TCharBufferOverArray(int start, int capacity, char[] array, int position, int limit, boolean readOnly) {
super(capacity, position, limit);
this.start = start;
this.readOnly = readOnly;
this.array = array;
}
@Override
TCharBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly) {
return new TCharBufferOverArray(this.start + start, capacity, array, position, limit, readOnly);
}
@Override
char getChar(int index) {
return array[index + start];
}
@Override
void putChar(int index, char value) {
array[index + start] = value;
}
@Override
boolean isArrayPresent() {
return true;
}
@Override
char[] getArray() {
return array;
}
@Override
int getArrayOffset() {
return start;
}
@Override
boolean readOnly() {
return readOnly;
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright 2014 Alexey Andreev.
*
* 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.teavm.classlib.java.nio;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
class TCharBufferOverByteBuffer extends TCharBufferImpl {
private TByteBufferImpl byteByffer;
private TByteOrder byteOrder = TByteOrder.BIG_ENDIAN;
boolean readOnly;
private int start;
public TCharBufferOverByteBuffer(int start, int capacity, TByteBufferImpl byteBuffer, int position, int limit,
boolean readOnly) {
super(capacity, position, limit);
this.start = start;
this.byteByffer = byteBuffer;
this.readOnly = readOnly;
}
@Override
TCharBuffer duplicate(int start, int capacity, int position, int limit, boolean readOnly) {
TCharBufferOverByteBuffer result = new TCharBufferOverByteBuffer(this.start + start * 2, capacity, byteByffer,
position, limit, readOnly);
result.byteOrder = byteOrder;
return result;
}
@Override
char getChar(int index) {
int value;
if (byteOrder == TByteOrder.BIG_ENDIAN) {
value = (byteByffer.array[start + index * 2] << 8) | (byteByffer.array[start + index * 2 + 1]);
} else {
value = (byteByffer.array[start + index * 2 + 1] << 8) | (byteByffer.array[start + index * 2]);
}
return (char)value;
}
@Override
void putChar(int index, char value) {
if (byteOrder == TByteOrder.BIG_ENDIAN) {
byteByffer.array[start + index * 2] = (byte)(value >> 8);
byteByffer.array[start + index * 2 + 1] = (byte)value;
} else {
byteByffer.array[start + index * 2] = (byte)value;
byteByffer.array[start + index * 2 + 1] = (byte)(value >> 8);
}
}
@Override
boolean isArrayPresent() {
return false;
}
@Override
char[] getArray() {
throw new UnsupportedOperationException();
}
@Override
int getArrayOffset() {
throw new UnsupportedOperationException();
}
@Override
boolean readOnly() {
return readOnly;
}
}