mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Add BufferedInputStream and StringTokenizer
This commit is contained in:
parent
9902f583bd
commit
5c8b80aa32
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* 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.teavm.classlib.java.io;
|
||||||
|
|
||||||
|
import org.teavm.classlib.java.lang.TString;
|
||||||
|
|
||||||
|
public class TBufferedInputStream extends TFilterInputStream {
|
||||||
|
protected volatile byte[] buf;
|
||||||
|
protected int count;
|
||||||
|
protected int marklimit;
|
||||||
|
protected int markpos = -1;
|
||||||
|
protected int pos;
|
||||||
|
|
||||||
|
public TBufferedInputStream(TInputStream in) {
|
||||||
|
super(in);
|
||||||
|
buf = new byte[8192];
|
||||||
|
}
|
||||||
|
|
||||||
|
public TBufferedInputStream(TInputStream in, int size) {
|
||||||
|
super(in);
|
||||||
|
if (size <= 0) {
|
||||||
|
throw new IllegalArgumentException("Size " + size + " is negative");
|
||||||
|
}
|
||||||
|
buf = new byte[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized int available() throws TIOException {
|
||||||
|
TInputStream localIn = in;
|
||||||
|
if (buf == null || localIn == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
return count - pos + localIn.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws TIOException {
|
||||||
|
buf = null;
|
||||||
|
TInputStream localIn = in;
|
||||||
|
in = null;
|
||||||
|
if (localIn != null) {
|
||||||
|
localIn.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int fillbuf(TInputStream localIn, byte[] localBuf) throws TIOException {
|
||||||
|
if (markpos == -1 || (pos - markpos >= marklimit)) {
|
||||||
|
/* Mark position not set or exceeded readlimit */
|
||||||
|
int result = localIn.read(localBuf);
|
||||||
|
if (result > 0) {
|
||||||
|
markpos = -1;
|
||||||
|
pos = 0;
|
||||||
|
count = result == -1 ? 0 : result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (markpos == 0 && marklimit > localBuf.length) {
|
||||||
|
/* Increase buffer size to accommodate the readlimit */
|
||||||
|
int newLength = localBuf.length * 2;
|
||||||
|
if (newLength > marklimit) {
|
||||||
|
newLength = marklimit;
|
||||||
|
}
|
||||||
|
byte[] newbuf = new byte[newLength];
|
||||||
|
System.arraycopy(localBuf, 0, newbuf, 0, localBuf.length);
|
||||||
|
// Reassign buf, which will invalidate any local references
|
||||||
|
// FIXME: what if buf was null?
|
||||||
|
localBuf = buf = newbuf;
|
||||||
|
} else if (markpos > 0) {
|
||||||
|
System.arraycopy(localBuf, markpos, localBuf, 0, localBuf.length - markpos);
|
||||||
|
}
|
||||||
|
/* Set the new position and mark position */
|
||||||
|
pos -= markpos;
|
||||||
|
count = markpos = 0;
|
||||||
|
int bytesread = localIn.read(localBuf, pos, localBuf.length - pos);
|
||||||
|
count = bytesread <= 0 ? pos : pos + bytesread;
|
||||||
|
return bytesread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void mark(int readlimit) {
|
||||||
|
marklimit = readlimit;
|
||||||
|
markpos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized int read() throws TIOException {
|
||||||
|
// Use local refs since buf and in may be invalidated by an
|
||||||
|
// unsynchronized close()
|
||||||
|
byte[] localBuf = buf;
|
||||||
|
TInputStream localIn = in;
|
||||||
|
if (localBuf == null || localIn == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Are there buffered bytes available? */
|
||||||
|
if (pos >= count && fillbuf(localIn, localBuf) == -1) {
|
||||||
|
return -1; /* no, fill buffer */
|
||||||
|
}
|
||||||
|
// localBuf may have been invalidated by fillbuf
|
||||||
|
if (localBuf != buf) {
|
||||||
|
localBuf = buf;
|
||||||
|
if (localBuf == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did filling the buffer fail with -1 (EOF)? */
|
||||||
|
if (count - pos > 0) {
|
||||||
|
return localBuf[pos++] & 0xFF;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized int read(byte[] buffer, int offset, int length) throws TIOException {
|
||||||
|
byte[] localBuf = buf;
|
||||||
|
if (localBuf == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
// avoid int overflow
|
||||||
|
if (offset > buffer.length - length || offset < 0 || length < 0) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
TInputStream localIn = in;
|
||||||
|
if (localIn == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int required;
|
||||||
|
if (pos < count) {
|
||||||
|
/* There are bytes available in the buffer. */
|
||||||
|
int copylength = count - pos >= length ? length : count - pos;
|
||||||
|
System.arraycopy(localBuf, pos, buffer, offset, copylength);
|
||||||
|
pos += copylength;
|
||||||
|
if (copylength == length || localIn.available() == 0) {
|
||||||
|
return copylength;
|
||||||
|
}
|
||||||
|
offset += copylength;
|
||||||
|
required = length - copylength;
|
||||||
|
} else {
|
||||||
|
required = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int read;
|
||||||
|
/*
|
||||||
|
* If we're not marked and the required size is greater than the
|
||||||
|
* buffer, simply read the bytes directly bypassing the buffer.
|
||||||
|
*/
|
||||||
|
if (markpos == -1 && required >= localBuf.length) {
|
||||||
|
read = localIn.read(buffer, offset, required);
|
||||||
|
if (read == -1) {
|
||||||
|
return required == length ? -1 : length - required;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fillbuf(localIn, localBuf) == -1) {
|
||||||
|
return required == length ? -1 : length - required;
|
||||||
|
}
|
||||||
|
// localBuf may have been invalidated by fillbuf
|
||||||
|
if (localBuf != buf) {
|
||||||
|
localBuf = buf;
|
||||||
|
if (localBuf == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read = count - pos >= required ? required : count - pos;
|
||||||
|
System.arraycopy(localBuf, pos, buffer, offset, read);
|
||||||
|
pos += read;
|
||||||
|
}
|
||||||
|
required -= read;
|
||||||
|
if (required == 0) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
if (localIn.available() == 0) {
|
||||||
|
return length - required;
|
||||||
|
}
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void reset() throws TIOException {
|
||||||
|
if (buf == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
if (-1 == markpos) {
|
||||||
|
throw new TIOException(TString.wrap("Mark has been invalidated."));
|
||||||
|
}
|
||||||
|
pos = markpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized long skip(long amount) throws TIOException {
|
||||||
|
// Use local refs since buf and in may be invalidated by an
|
||||||
|
// unsynchronized close()
|
||||||
|
byte[] localBuf = buf;
|
||||||
|
TInputStream localIn = in;
|
||||||
|
if (localBuf == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
if (amount < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (localIn == null) {
|
||||||
|
throw new TIOException(TString.wrap("Stream is closed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count - pos >= amount) {
|
||||||
|
pos += amount;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
long read = count - pos;
|
||||||
|
pos = count;
|
||||||
|
|
||||||
|
if (markpos != -1) {
|
||||||
|
if (amount <= marklimit) {
|
||||||
|
if (fillbuf(localIn, localBuf) == -1) {
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
if (count - pos >= amount - read) {
|
||||||
|
pos += amount - read;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
// Couldn't get all the bytes, skip what we read
|
||||||
|
read += (count - pos);
|
||||||
|
pos = count;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return read + localIn.skip(amount - read);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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.teavm.classlib.java.io;
|
||||||
|
|
||||||
|
public class TFilterInputStream extends TInputStream {
|
||||||
|
protected volatile TInputStream in;
|
||||||
|
|
||||||
|
protected TFilterInputStream(TInputStream in) {
|
||||||
|
this.in = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() throws TIOException {
|
||||||
|
return in.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws TIOException {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void mark(int readlimit) {
|
||||||
|
in.mark(readlimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return in.markSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws TIOException {
|
||||||
|
return in.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buffer) throws TIOException {
|
||||||
|
return read(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buffer, int offset, int count) throws TIOException {
|
||||||
|
return in.read(buffer, offset, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void reset() throws TIOException {
|
||||||
|
in.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long skip(long count) throws TIOException {
|
||||||
|
return in.skip(count);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* 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.teavm.classlib.java.util;
|
||||||
|
|
||||||
|
public class TStringTokenizer implements TEnumeration<Object> {
|
||||||
|
private String string;
|
||||||
|
private String delimiters;
|
||||||
|
private boolean returnDelimiters;
|
||||||
|
private int position;
|
||||||
|
|
||||||
|
public TStringTokenizer(String string) {
|
||||||
|
this(string, " \t\n\r\f", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TStringTokenizer(String string, String delimiters) {
|
||||||
|
this(string, delimiters, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TStringTokenizer(String string, String delimiters, boolean returnDelimiters) {
|
||||||
|
if (string != null) {
|
||||||
|
this.string = string;
|
||||||
|
this.delimiters = delimiters;
|
||||||
|
this.returnDelimiters = returnDelimiters;
|
||||||
|
this.position = 0;
|
||||||
|
} else
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countTokens() {
|
||||||
|
int count = 0;
|
||||||
|
boolean inToken = false;
|
||||||
|
for (int i = position, length = string.length(); i < length; i++) {
|
||||||
|
if (delimiters.indexOf(string.charAt(i), 0) >= 0) {
|
||||||
|
if (returnDelimiters)
|
||||||
|
count++;
|
||||||
|
if (inToken) {
|
||||||
|
count++;
|
||||||
|
inToken = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inToken = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inToken)
|
||||||
|
count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasMoreElements() {
|
||||||
|
return hasMoreTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreTokens() {
|
||||||
|
if (delimiters == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
int length = string.length();
|
||||||
|
if (position < length) {
|
||||||
|
if (returnDelimiters)
|
||||||
|
return true; // there is at least one character and even if
|
||||||
|
// it is a delimiter it is a token
|
||||||
|
|
||||||
|
// otherwise find a character which is not a delimiter
|
||||||
|
for (int i = position; i < length; i++)
|
||||||
|
if (delimiters.indexOf(string.charAt(i), 0) == -1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object nextElement() {
|
||||||
|
return nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextToken() {
|
||||||
|
if (delimiters == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
int i = position;
|
||||||
|
int length = string.length();
|
||||||
|
|
||||||
|
if (i < length) {
|
||||||
|
if (returnDelimiters) {
|
||||||
|
if (delimiters.indexOf(string.charAt(position), 0) >= 0) {
|
||||||
|
return String.valueOf(string.charAt(position++));
|
||||||
|
}
|
||||||
|
for (position++; position < length; position++) {
|
||||||
|
if (delimiters.indexOf(string.charAt(position), 0) >= 0) {
|
||||||
|
return string.substring(i, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.substring(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < length && delimiters.indexOf(string.charAt(i), 0) >= 0) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
position = i;
|
||||||
|
if (i < length) {
|
||||||
|
for (position++; position < length; position++) {
|
||||||
|
if (delimiters.indexOf(string.charAt(position), 0) >= 0) {
|
||||||
|
return string.substring(i, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.substring(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new TNoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextToken(String delims) {
|
||||||
|
this.delimiters = delims;
|
||||||
|
return nextToken();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,338 @@
|
||||||
|
/*
|
||||||
|
* 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.teavm.classlib.java.io;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import java.io.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@SuppressWarnings("resource")
|
||||||
|
public class BufferedInputStreamTest {
|
||||||
|
byte[] ibuf = new byte[4096];
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_ConstructorLjava_io_InputStream() {
|
||||||
|
try {
|
||||||
|
BufferedInputStream str = new BufferedInputStream(null);
|
||||||
|
str.read();
|
||||||
|
fail("Expected an IOException");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MockBufferedInputStream extends BufferedInputStream {
|
||||||
|
static byte[] buf;
|
||||||
|
|
||||||
|
MockBufferedInputStream(InputStream is) {
|
||||||
|
super(is);
|
||||||
|
buf = super.buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
MockBufferedInputStream(InputStream is, int size) {
|
||||||
|
super(is, size);
|
||||||
|
buf = super.buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_available() throws IOException {
|
||||||
|
ByteArrayInputStream isFile = new ByteArrayInputStream(new byte[] { 2, 3, 5, 7, 11 });
|
||||||
|
BufferedInputStream is = new BufferedInputStream(isFile);
|
||||||
|
assertTrue("Returned incorrect number of available bytes", is.available() == 5);
|
||||||
|
|
||||||
|
// Test that a closed stream throws an IOE for available()
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 'h', 'e', 'l', 'l',
|
||||||
|
'o', ' ', 't', 'i', 'm' }));
|
||||||
|
int available = bis.available();
|
||||||
|
bis.close();
|
||||||
|
assertTrue(available != 0);
|
||||||
|
|
||||||
|
try {
|
||||||
|
bis.available();
|
||||||
|
fail("Expected test to throw IOE.");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_close() throws IOException {
|
||||||
|
new BufferedInputStream(new ByteArrayInputStream(new byte[100])).close();
|
||||||
|
|
||||||
|
// regression for HARMONY-667
|
||||||
|
BufferedInputStream buf = new BufferedInputStream(null, 5);
|
||||||
|
buf.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_markI() throws IOException {
|
||||||
|
ByteArrayInputStream isFile = new ByteArrayInputStream(new byte[10000]);
|
||||||
|
BufferedInputStream is = new BufferedInputStream(isFile, 5);
|
||||||
|
byte[] buf1 = new byte[100];
|
||||||
|
byte[] buf2 = new byte[100];
|
||||||
|
is.skip(3000);
|
||||||
|
is.mark(1000);
|
||||||
|
is.read(buf1, 0, buf1.length);
|
||||||
|
is.reset();
|
||||||
|
is.read(buf2, 0, buf2.length);
|
||||||
|
is.reset();
|
||||||
|
assertTrue("Failed to mark correct position",
|
||||||
|
new String(buf1, 0, buf1.length).equals(new String(buf2, 0, buf2.length)));
|
||||||
|
|
||||||
|
byte[] bytes = new byte[256];
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
bytes[i] = (byte)i;
|
||||||
|
}
|
||||||
|
InputStream in = new BufferedInputStream(new ByteArrayInputStream(bytes), 12);
|
||||||
|
in.skip(6);
|
||||||
|
in.mark(14);
|
||||||
|
in.read(new byte[14], 0, 14);
|
||||||
|
in.reset();
|
||||||
|
assertTrue("Wrong bytes", in.read() == 6 && in.read() == 7);
|
||||||
|
|
||||||
|
in = new BufferedInputStream(new ByteArrayInputStream(bytes), 12);
|
||||||
|
in.skip(6);
|
||||||
|
in.mark(8);
|
||||||
|
in.skip(7);
|
||||||
|
in.reset();
|
||||||
|
assertTrue("Wrong bytes 2", in.read() == 6 && in.read() == 7);
|
||||||
|
|
||||||
|
BufferedInputStream buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), 2);
|
||||||
|
buf.mark(3);
|
||||||
|
bytes = new byte[3];
|
||||||
|
int result = buf.read(bytes);
|
||||||
|
assertEquals(3, result);
|
||||||
|
assertEquals("Assert 0:", 0, bytes[0]);
|
||||||
|
assertEquals("Assert 1:", 1, bytes[1]);
|
||||||
|
assertEquals("Assert 2:", 2, bytes[2]);
|
||||||
|
assertEquals("Assert 3:", 3, buf.read());
|
||||||
|
|
||||||
|
buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), 2);
|
||||||
|
buf.mark(3);
|
||||||
|
bytes = new byte[4];
|
||||||
|
result = buf.read(bytes);
|
||||||
|
assertEquals(4, result);
|
||||||
|
assertEquals("Assert 4:", 0, bytes[0]);
|
||||||
|
assertEquals("Assert 5:", 1, bytes[1]);
|
||||||
|
assertEquals("Assert 6:", 2, bytes[2]);
|
||||||
|
assertEquals("Assert 7:", 3, bytes[3]);
|
||||||
|
assertEquals("Assert 8:", 4, buf.read());
|
||||||
|
assertEquals("Assert 9:", -1, buf.read());
|
||||||
|
|
||||||
|
buf = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 0, 1, 2, 3, 4 }), 2);
|
||||||
|
buf.mark(Integer.MAX_VALUE);
|
||||||
|
buf.read();
|
||||||
|
buf.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_read() throws IOException {
|
||||||
|
ByteArrayInputStream isFile = new ByteArrayInputStream(new byte[10000]);
|
||||||
|
BufferedInputStream is = new BufferedInputStream(isFile, 5);
|
||||||
|
InputStreamReader isr = new InputStreamReader(is);
|
||||||
|
int c = isr.read();
|
||||||
|
assertTrue("read returned incorrect char", c == 0);
|
||||||
|
|
||||||
|
byte[] bytes = new byte[256];
|
||||||
|
for (int i = 0; i < 256; i++) {
|
||||||
|
bytes[i] = (byte)i;
|
||||||
|
}
|
||||||
|
InputStream in = new BufferedInputStream(new ByteArrayInputStream(bytes), 12);
|
||||||
|
assertEquals("Wrong initial byte", 0, in.read()); // Fill the
|
||||||
|
// buffer
|
||||||
|
byte[] buf = new byte[14];
|
||||||
|
in.read(buf, 0, 14); // Read greater than the buffer
|
||||||
|
assertTrue("Wrong block read data", new String(buf, 0, 14).equals(new String(bytes, 1, 14)));
|
||||||
|
assertEquals("Wrong bytes", 15, in.read()); // Check next byte
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_read$BII_Exception() throws IOException {
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
bis.read(new byte[0], -1, -1);
|
||||||
|
fail("should throw IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
bis.read(new byte[0], 1, -1);
|
||||||
|
fail("should throw IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
bis.read(new byte[0], 1, 1);
|
||||||
|
fail("should throw IndexOutOfBoundsException");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
bis.close();
|
||||||
|
|
||||||
|
try {
|
||||||
|
bis.read(null, -1, -1);
|
||||||
|
fail("should throw IOException");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_read$BII() throws IOException {
|
||||||
|
ByteArrayInputStream isFile = new ByteArrayInputStream(new byte[10000]);
|
||||||
|
BufferedInputStream is = new BufferedInputStream(isFile);
|
||||||
|
byte[] buf1 = new byte[100];
|
||||||
|
is.skip(3000);
|
||||||
|
is.mark(1000);
|
||||||
|
is.read(buf1, 0, buf1.length);
|
||||||
|
|
||||||
|
BufferedInputStream bufin = new BufferedInputStream(new InputStream() {
|
||||||
|
int size = 2, pos = 0;
|
||||||
|
|
||||||
|
byte[] contents = new byte[size];
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (pos >= size) {
|
||||||
|
throw new IOException("Read past end of data");
|
||||||
|
}
|
||||||
|
return contents[pos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buf, int off, int len) throws IOException {
|
||||||
|
if (pos >= size) {
|
||||||
|
throw new IOException("Read past end of data");
|
||||||
|
}
|
||||||
|
int toRead = len;
|
||||||
|
if (toRead > available()) {
|
||||||
|
toRead = available();
|
||||||
|
}
|
||||||
|
System.arraycopy(contents, pos, buf, off, toRead);
|
||||||
|
pos += toRead;
|
||||||
|
return toRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return size - pos;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bufin.read();
|
||||||
|
int result = bufin.read(new byte[2], 0, 2);
|
||||||
|
assertTrue("Incorrect result: " + result, result == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_reset() throws IOException {
|
||||||
|
ByteArrayInputStream isFile = new ByteArrayInputStream(new byte[10000]);
|
||||||
|
BufferedInputStream is = new BufferedInputStream(isFile);
|
||||||
|
byte[] buf1 = new byte[10];
|
||||||
|
byte[] buf2 = new byte[10];
|
||||||
|
is.mark(2000);
|
||||||
|
is.read(buf1, 0, 10);
|
||||||
|
is.reset();
|
||||||
|
is.read(buf2, 0, 10);
|
||||||
|
is.reset();
|
||||||
|
assertTrue("Reset failed", new String(buf1, 0, buf1.length).equals(new String(buf2, 0, buf2.length)));
|
||||||
|
|
||||||
|
BufferedInputStream bIn = new BufferedInputStream(new ByteArrayInputStream("1234567890".getBytes()));
|
||||||
|
bIn.mark(10);
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
bIn.read();
|
||||||
|
}
|
||||||
|
bIn.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_reset_Exception() throws IOException {
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(null);
|
||||||
|
|
||||||
|
// throws IOException with message "Mark has been invalidated"
|
||||||
|
try {
|
||||||
|
bis.reset();
|
||||||
|
fail("should throw IOException");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
// does not throw IOException
|
||||||
|
bis.mark(1);
|
||||||
|
bis.reset();
|
||||||
|
|
||||||
|
bis.close();
|
||||||
|
|
||||||
|
// throws IOException with message "stream is closed"
|
||||||
|
try {
|
||||||
|
bis.reset();
|
||||||
|
fail("should throw IOException");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_reset_scenario1() throws IOException {
|
||||||
|
byte[] input = "12345678900".getBytes();
|
||||||
|
BufferedInputStream buffis = new BufferedInputStream(new ByteArrayInputStream(input));
|
||||||
|
buffis.read();
|
||||||
|
buffis.mark(5);
|
||||||
|
buffis.skip(5);
|
||||||
|
buffis.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_reset_scenario2() throws IOException {
|
||||||
|
byte[] input = "12345678900".getBytes();
|
||||||
|
BufferedInputStream buffis = new BufferedInputStream(new ByteArrayInputStream(input));
|
||||||
|
buffis.mark(5);
|
||||||
|
buffis.skip(6);
|
||||||
|
buffis.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_skipJ() throws IOException {
|
||||||
|
ByteArrayInputStream isFile = new ByteArrayInputStream(new byte[10000]);
|
||||||
|
BufferedInputStream is = new BufferedInputStream(isFile);
|
||||||
|
|
||||||
|
byte[] buf1 = new byte[10];
|
||||||
|
is.mark(2000);
|
||||||
|
is.skip(1000);
|
||||||
|
is.read(buf1, 0, buf1.length);
|
||||||
|
is.reset();
|
||||||
|
|
||||||
|
// regression for HARMONY-667
|
||||||
|
try {
|
||||||
|
BufferedInputStream buf = new BufferedInputStream(null, 5);
|
||||||
|
buf.skip(10);
|
||||||
|
fail("Should throw IOException");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_skip_NullInputStream() throws IOException {
|
||||||
|
BufferedInputStream buf = new BufferedInputStream(null, 5);
|
||||||
|
assertEquals(0, buf.skip(0));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* 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.teavm.classlib.java.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class StringTokenizerTest {
|
||||||
|
@Test
|
||||||
|
public void test_ConstructorLjava_lang_StringLjava_lang_String() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This:is:a:test:String", ":");
|
||||||
|
assertTrue("Created incorrect tokenizer", st.countTokens() == 5 && (st.nextElement().equals("This")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_ConstructorLjava_lang_StringLjava_lang_StringZ() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This:is:a:test:String", ":", true);
|
||||||
|
st.nextElement();
|
||||||
|
assertTrue("Created incorrect tokenizer", st.countTokens() == 8 && (st.nextElement().equals(":")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_countTokens() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This is a test String");
|
||||||
|
assertEquals("Incorrect token count returned", 5, st.countTokens());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_hasMoreElements() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This is a test String");
|
||||||
|
st.nextElement();
|
||||||
|
assertTrue("hasMoreElements returned incorrect value", st.hasMoreElements());
|
||||||
|
st.nextElement();
|
||||||
|
st.nextElement();
|
||||||
|
st.nextElement();
|
||||||
|
st.nextElement();
|
||||||
|
assertTrue("hasMoreElements returned incorrect value", !st.hasMoreElements());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_hasMoreTokens() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This is a test String");
|
||||||
|
for (int counter = 0; counter < 5; counter++) {
|
||||||
|
assertTrue("StringTokenizer incorrectly reports it has no more tokens", st.hasMoreTokens());
|
||||||
|
st.nextToken();
|
||||||
|
}
|
||||||
|
assertTrue("StringTokenizer incorrectly reports it has more tokens", !st.hasMoreTokens());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_nextElement() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This is a test String");
|
||||||
|
assertEquals("nextElement returned incorrect value", "This", st.nextElement());
|
||||||
|
assertEquals("nextElement returned incorrect value", "is", st.nextElement());
|
||||||
|
assertEquals("nextElement returned incorrect value", "a", st.nextElement());
|
||||||
|
assertEquals("nextElement returned incorrect value", "test", st.nextElement());
|
||||||
|
assertEquals("nextElement returned incorrect value", "String", st.nextElement());
|
||||||
|
try {
|
||||||
|
st.nextElement();
|
||||||
|
fail("nextElement failed to throw a NoSuchElementException when it should have been out of elements");
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_nextToken() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This is a test String");
|
||||||
|
assertEquals("nextToken returned incorrect value", "This", st.nextToken());
|
||||||
|
assertEquals("nextToken returned incorrect value", "is", st.nextToken());
|
||||||
|
assertEquals("nextToken returned incorrect value", "a", st.nextToken());
|
||||||
|
assertEquals("nextToken returned incorrect value", "test", st.nextToken());
|
||||||
|
assertEquals("nextToken returned incorrect value", "String", st.nextToken());
|
||||||
|
try {
|
||||||
|
st.nextToken();
|
||||||
|
fail("nextToken failed to throw a NoSuchElementException when it should have been out of elements");
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_nextTokenLjava_lang_String() {
|
||||||
|
StringTokenizer st = new StringTokenizer("This is a test String");
|
||||||
|
assertEquals("nextToken(String) returned incorrect value with normal token String", "This", st.nextToken(" "));
|
||||||
|
assertEquals("nextToken(String) returned incorrect value with custom token String", " is a ",
|
||||||
|
st.nextToken("tr"));
|
||||||
|
assertEquals("calling nextToken() did not use the new default delimiter list", "es", st.nextToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_hasMoreElements_NPE() {
|
||||||
|
StringTokenizer stringTokenizer = new StringTokenizer(new String(), (String)null, true);
|
||||||
|
try {
|
||||||
|
stringTokenizer.hasMoreElements();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
stringTokenizer = new StringTokenizer(new String(), (String)null);
|
||||||
|
try {
|
||||||
|
stringTokenizer.hasMoreElements();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_hasMoreTokens_NPE() {
|
||||||
|
StringTokenizer stringTokenizer = new StringTokenizer(new String(), (String)null, true);
|
||||||
|
try {
|
||||||
|
stringTokenizer.hasMoreTokens();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
stringTokenizer = new StringTokenizer(new String(), (String)null);
|
||||||
|
try {
|
||||||
|
stringTokenizer.hasMoreTokens();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_nextElement_NPE() {
|
||||||
|
StringTokenizer stringTokenizer = new StringTokenizer(new String(), (String)null, true);
|
||||||
|
try {
|
||||||
|
stringTokenizer.nextElement();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
stringTokenizer = new StringTokenizer(new String(), (String)null);
|
||||||
|
try {
|
||||||
|
stringTokenizer.nextElement();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_nextToken_NPE() {
|
||||||
|
StringTokenizer stringTokenizer = new StringTokenizer(new String(), (String)null, true);
|
||||||
|
try {
|
||||||
|
stringTokenizer.nextToken();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
stringTokenizer = new StringTokenizer(new String(), (String)null);
|
||||||
|
try {
|
||||||
|
stringTokenizer.nextToken();
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_nextTokenLjava_lang_String_NPE() {
|
||||||
|
StringTokenizer stringTokenizer = new StringTokenizer(new String());
|
||||||
|
try {
|
||||||
|
stringTokenizer.nextToken(null);
|
||||||
|
fail("should throw NullPointerException");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user