/*
* @(#)$Id: IOUtils.java 3619 2008-03-26 07:23:03Z yui $
*
* Copyright 2006-2008 Makoto YUI
*
* 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.
*
* Contributors:
* Makoto YUI - ported from jakarta commons io
*/
/*
* Copyright 2001-2004 The Apache Software Foundation
*
* 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 xbird.util.io;
import java.io.*;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import xbird.util.lang.CancelAwareTimer;
/**
* IO related utilities.
* <DIV lang="en">
* This code is ported from Jakarta's <a href="http://jakarta.apache.org/commons/io/">Commons-IO</a>.
* </DIV>
* <DIV lang="ja"></DIV>
*
* @author Makoto YUI (yuin405+xbird@gmail.com)
* @link http://jakarta.apache.org/commons/io/
*/
public final class IOUtils {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
private IOUtils() {}
public static void writeInt(final int v, final OutputStream out) throws IOException {
out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
}
/**
* @return may be negative value when EOF is detected.
*/
public static int readInt(final InputStream in) throws IOException {
final int ch1 = in.read();
final int ch2 = in.read();
final int ch3 = in.read();
final int ch4 = in.read();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
public static int readUnsignedIntOrEOF(final InputStream in) throws IOException {
final int ch1 = in.read();
if(ch1 == -1) {
return -1;
}
final int ch2 = in.read();
final int ch3 = in.read();
final int ch4 = in.read();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
public static void writeChar(final char v, final OutputStream out) throws IOException {
out.write(0xff & (v >> 8));
out.write(0xff & v);
}
public static void writeChar(final char v, final FastByteArrayOutputStream out) {
out.write(0xff & (v >> 8));
out.write(0xff & v);
}
public static char readChar(final InputStream in) throws IOException {
final int a = in.read();
final int b = in.read();
return (char) ((a << 8) | (b & 0xff));
}
public static void readFully(final InputStream in, final byte[] b, int offset, int len)
throws IOException {
do {
final int bytesRead = in.read(b, offset, len);
if(bytesRead < 0) {
throw new EOFException();
}
len -= bytesRead;
offset += bytesRead;
} while(len != 0);
}
public static void readFully(final InputStream in, final byte[] b) throws IOException {
readFully(in, b, 0, b.length);
}
public static int readLoop(final InputStream in, final byte[] b, final int off, final int len)
throws IOException {
int total = 0;
for(;;) {
final int got = in.read(b, off + total, len - total);
if(got < 0) {
return (total == 0) ? -1 : total;
} else {
total += got;
if(total == len) {
return total;
}
}
}
}
/**
* InputStream -> OutputStream
*/
public static int copy(InputStream input, OutputStream output) throws IOException {
final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int count = 0;
int n = 0;
while(-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
/**
* Reader -> Writer.
*/
public static int copy(Reader input, Writer output) throws IOException {
final char[] buffer = new char[DEFAULT_BUFFER_SIZE];
int count = 0;
int n = 0;
while(-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
/**
* String -> OutputStream.
*/
public static void copy(String input, OutputStream output) throws IOException {
final StringReader in = new StringReader(input);
final OutputStreamWriter out = new OutputStreamWriter(output);
copy(in, out);
// Unless anyone is planning on rewriting OutputStreamWriter, we have to flush here.
out.flush();
}
/**
* Serialize given InputStream as String.
*/
public static String toString(InputStream input) throws IOException {
final FastMultiByteArrayOutputStream output = new FastMultiByteArrayOutputStream();
copy(input, output);
return output.toString();
}
public static String toString(InputStream input, String cs) throws IOException {
final FastMultiByteArrayOutputStream output = new FastMultiByteArrayOutputStream();
copy(input, output);
return output.toString(cs);
}
public static String toString(Reader input) throws IOException {
final StringWriter sw = new StringWriter();
copy(input, sw);
return sw.toString();
}
@Deprecated
public static void getBytes(final List<byte[]> srcLst, final byte[] dest) {
int pos = 0;
for(byte[] bytes : srcLst) {
final int len = bytes.length;
System.arraycopy(bytes, 0, dest, pos, len);
pos += len;
}
}
public static byte[] getBytes(final InputStream in) throws IOException {
FastByteArrayOutputStream out = new FastByteArrayOutputStream(4096);
copy(in, out);
return out.toByteArray();
}
public static void closeQuietly(final Closeable channel) {
if(channel != null) {
try {
channel.close();
} catch (IOException e) {
;
}
}
}
public static void closeQuietly(final Closeable... channels) {
for(Closeable c : channels) {
if(c != null) {
try {
c.close();
} catch (IOException e) {
;
}
}
}
}
public static void closeAndRethrow(final Exception e, final Closeable... channels)
throws IllegalStateException {
closeQuietly(channels);
throw new IllegalStateException(e);
}
/**
* @param delay delay in milliseconds before task is to be executed.
*/
public static void schduleCloseQuietly(final Timer timer, final long delay, final Closeable... channels) {
if(delay == 0) {
closeQuietly(channels);
return;
}
final TimerTask cancel = new TimerTask() {
@Override
public void run() {
closeQuietly(channels);
}
};
timer.schedule(cancel, delay);
}
/**
* @param delay delay in milliseconds before task is to be executed.
*/
public static boolean schduleCloseQuietly(final CancelAwareTimer timer, final long delay, final AtomicInteger activeCount, final int limitSched, final Closeable... channels) {
if(delay == 0) {
closeQuietly(channels);
return true;
}
if(timer.getNumberOfScheduled() >= limitSched) {
return false;
}
final TimerTask cancel = new TimerTask() {
public void run() {
if(activeCount.get() < 1) {
closeQuietly(channels);
}
}
};
timer.schedule(cancel, delay);
return true;
}
public static void schduleCloseQuietly(final ScheduledExecutorService sched, final int delay, final AtomicInteger activeCount, final Closeable... channels) {
if(delay == 0) {
closeQuietly(channels);
return;
}
final Runnable cancel = new Runnable() {
public void run() {
if(activeCount.get() < 1) {
closeQuietly(channels);
}
}
};
sched.schedule(cancel, delay, TimeUnit.MILLISECONDS);
}
public static void writeBytes(@Nullable final byte[] b, final DataOutput out)
throws IOException {
if(b == null) {
out.writeInt(-1);
return;
}
final int len = b.length;
out.writeInt(len);
out.write(b, 0, len);
}
public static void writeBytes(@Nullable final byte[] b, final FastBufferedOutputStream out)
throws IOException {
if(b == null) {
writeInt(-1, out);
return;
}
final int len = b.length;
writeInt(len, out);
out.write(b, 0, len);
}
@Nullable
public static byte[] readBytes(final DataInput in) throws IOException {
final int len = in.readInt();
if(len == -1) {
return null;
}
final byte[] b = new byte[len];
in.readFully(b, 0, len);
return b;
}
@Nullable
public static byte[] readBytes(final FastBufferedInputStream in) throws IOException {
final int len = readInt(in);
if(len == -1) {
return null;
}
final byte[] b = new byte[len];
in.read(b, 0, len);
return b;
}
public static void writeString(@Nullable final String s, final ObjectOutputStream out)
throws IOException {
writeString(s, (DataOutput) out);
}
public static void writeString(@Nullable final String s, final DataOutputStream out)
throws IOException {
writeString(s, (DataOutput) out);
}
public static void writeString(@Nullable final String s, final DataOutput out)
throws IOException {
if(s == null) {
out.writeInt(-1);
return;
}
final int len = s.length();
out.writeInt(len);
for(int i = 0; i < len; i++) {
int v = s.charAt(i);
out.writeChar(v);
}
}
public static void writeString(@Nullable final String s, final OutputStream out)
throws IOException {
if(s == null) {
writeInt(-1, out);
return;
}
final int len = s.length();
writeInt(len, out);
for(int i = 0; i < len; i++) {
char c = s.charAt(i);
writeChar(c, out);
}
}
@Nullable
public static String readString(@Nonnull final ObjectInputStream in) throws IOException {
return readString((DataInput) in);
}
@Nullable
public static String readString(@Nonnull final DataInputStream in) throws IOException {
return readString((DataInput) in);
}
@Nullable
public static String readString(@Nonnull final DataInput in) throws IOException {
final int len = in.readInt();
if(len == -1) {
return null;
}
final char[] ch = new char[len];
for(int i = 0; i < len; i++) {
ch[i] = in.readChar();
}
return new String(ch);
}
@Nullable
public static String readString(@Nonnull final InputStream in) throws IOException {
final int len = readInt(in);
if(len == -1) {
return null;
}
final char[] ch = new char[len];
for(int i = 0; i < len; i++) {
ch[i] = readChar(in);
}
return new String(ch);
}
}