/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.process.protocol;
import org.jboss.as.process.logging.ProcessLogger;
import org.jboss.marshalling.Marshaller;
import org.jboss.marshalling.Unmarshaller;
import javax.xml.stream.XMLStreamWriter;
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
public final class StreamUtils {
private StreamUtils() {
}
public static int readChar(final InputStream input) throws IOException {
final int a = input.read();
//System.err.println((char)a + "(" + a + ")");
if (a < 0) {
return -1;
} else if (a == 0) {
return -1;
} else if (a < 0x80) {
return (char)a;
} else if (a < 0xc0) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
} else if (a < 0xe0) {
final int b = input.read();
if (b == -1) {
throw new EOFException();
} else if ((b & 0xc0) != 0x80) {
throw ProcessLogger.ROOT_LOGGER.invalidByte((char)a, a);
}
return (a & 0x1f) << 6 | b & 0x3f;
} else if (a < 0xf0) {
final int b = input.read();
if (b == -1) {
throw new EOFException();
} else if ((b & 0xc0) != 0x80) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
final int c = input.read();
if (c == -1) {
throw new EOFException();
} else if ((c & 0xc0) != 0x80) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
return (a & 0x0f) << 12 | (b & 0x3f) << 6 | c & 0x3f;
} else {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
}
public static void readToEol(final InputStream input) throws IOException {
for (;;) {
switch (input.read()) {
case -1: return;
case '\n': return;
}
}
}
public static byte[] readBytesWithLength(final InputStream in) throws IOException {
int expectedLength = readInt(in);
byte[] bytes = new byte[expectedLength];
readFully(in, bytes, 0, expectedLength);
return bytes;
}
public static boolean readBoolean(final InputStream input) throws IOException {
return readUnsignedByte(input) != 0;
}
public static int readUnsignedShort(final InputStream input) throws IOException {
int ch1 = input.read();
int ch2 = input.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return ((ch1 << 8) + (ch2));
}
public static int readInt(final InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
public static void readFully(final InputStream in, byte[] b) throws IOException {
readFully(in, b, 0, b.length);
}
public static void readFully(final InputStream in, byte[] b, int off, int len) throws IOException {
if (len < 0)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = in.read(b, off + n, len - n);
if (count < 0)
throw ProcessLogger.ROOT_LOGGER.readBytes(n);
n += count;
}
}
public static long readLong(final InputStream in) throws IOException {
byte[] bytes = new byte[8];
readFully(in, bytes, 0, 8);
return (((long)bytes[0] << 56) +
((long)(bytes[1] & 255) << 48) +
((long)(bytes[2] & 255) << 40) +
((long)(bytes[3] & 255) << 32) +
((long)(bytes[4] & 255) << 24) +
((bytes[5] & 255) << 16) +
((bytes[6] & 255) << 8) +
((bytes[7] & 255) << 0));
}
public static void writeString(final OutputStream output, final Object o) throws IOException {
writeString(output, o.toString());
}
public static void writeString(final OutputStream output, final String s) throws IOException {
final int length = s.length();
int strIdx = 0;
while (strIdx < length) {
writeChar(output, s.charAt(strIdx ++));
}
}
public static void writeChar(final OutputStream output, final char c) throws IOException {
if (c >= 0x20 && c <= 0x7f) {
output.write((byte)c);
} else if (c <= 0x07ff) {
output.write((byte)(0xc0 | 0x1f & c >> 6));
output.write((byte)(0x80 | 0x3f & c));
} else {
output.write((byte)(0xe0 | 0x0f & c >> 12));
output.write((byte)(0x80 | 0x3f & c >> 6));
output.write((byte)(0x80 | 0x3f & c));
}
}
public static void writeShort(final OutputStream out, final int value) throws IOException {
out.write(value >>> 8);
out.write(value);
}
public static void writeInt(final OutputStream out, final int v) throws IOException {
out.write((v >>> 24) & 0xFF);
out.write((v >>> 16) & 0xFF);
out.write((v >>> 8) & 0xFF);
out.write((v >>> 0) & 0xFF);
}
public static void writeLong(final OutputStream out, final long v) throws IOException {
out.write((byte) (v >>> 56) & 0xFF);
out.write((byte) (v >>> 48) & 0xFF);
out.write((byte) (v >>> 40) & 0xFF);
out.write((byte) (v >>> 32) & 0xFF);
out.write((byte) (v >>> 24) & 0xFF);
out.write((byte) (v >>> 16) & 0xFF);
out.write((byte) (v >>> 8) & 0xFF);
out.write((byte) (v >>> 0) & 0xFF);
}
public static void writeBoolean(final OutputStream os, final boolean b) throws IOException {
os.write(b ? 1 : 0);
}
public static byte readByte(final InputStream stream) throws IOException {
int b = stream.read();
if (b == -1) {
throw new EOFException();
}
return (byte) b;
}
public static int readUnsignedByte(final InputStream stream) throws IOException {
int b = stream.read();
if (b == -1) {
throw new EOFException();
}
return b;
}
public static void copyStream(final InputStream in, final OutputStream out) throws IOException {
final byte[] bytes = new byte[8192];
int cnt;
while ((cnt = in.read(bytes)) != -1) {
out.write(bytes, 0, cnt);
}
}
public static String readUTFZBytes(final InputStream input) throws IOException {
final StringBuilder builder = new StringBuilder();
for (;;) {
final int c = readUTFChar(input);
if (c == -1) {
return builder.toString();
}
builder.append((char) c);
}
}
private static int readUTFChar(final InputStream input) throws IOException {
final int a = input.read();
if (a < 0) {
throw new EOFException();
} else if (a == 0) {
return -1;
} else if (a < 0x80) {
return (char)a;
} else if (a < 0xc0) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
} else if (a < 0xe0) {
final int b = input.read();
if (b == -1) {
throw new EOFException();
} else if ((b & 0xc0) != 0x80) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
return (a & 0x1f) << 6 | b & 0x3f;
} else if (a < 0xf0) {
final int b = input.read();
if (b == -1) {
throw new EOFException();
} else if ((b & 0xc0) != 0x80) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
final int c = input.read();
if (c == -1) {
throw new EOFException();
} else if ((c & 0xc0) != 0x80) {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
return (a & 0x0f) << 12 | (b & 0x3f) << 6 | c & 0x3f;
} else {
throw ProcessLogger.ROOT_LOGGER.invalidByte();
}
}
public static void writeUTFZBytes(final OutputStream outputStream, String string) throws IOException {
final int len = string.length();
for (int i = 0; i < len; i ++) {
writeChar(outputStream, string.charAt(i));
}
outputStream.write(0);
}
public static void safeClose(final Closeable closeable) {
if (closeable != null) try {
closeable.close();
} catch (Throwable t) {
ProcessLogger.PROTOCOL_LOGGER.failedToCloseResource(t, closeable);
}
}
public static void safeClose(final Socket socket) {
if (socket != null) try {
socket.close();
} catch (Throwable t) {
ProcessLogger.PROTOCOL_LOGGER.failedToCloseResource(t, socket);
}
}
public static void safeClose(final ServerSocket serverSocket) {
if (serverSocket != null) try {
serverSocket.close();
} catch (IOException e) {
ProcessLogger.PROTOCOL_LOGGER.failedToCloseServerSocket(e, serverSocket);
}
}
public static void safeFinish(final Marshaller marshaller) {
if (marshaller != null) try {
marshaller.finish();
} catch (IOException e) {
ProcessLogger.PROTOCOL_LOGGER.failedToFinishMarshaller(e, marshaller);
}
}
public static void safeFinish(final Unmarshaller unmarshaller) {
if (unmarshaller != null) try {
unmarshaller.finish();
} catch (IOException e) {
ProcessLogger.PROTOCOL_LOGGER.failedToFinishUnmarshaller(e, unmarshaller);
}
}
public static void safeClose(final XMLStreamWriter writer) {
if (writer != null) try {
writer.close();
} catch (Throwable t) {
ProcessLogger.PROTOCOL_LOGGER.failedToCloseResource(t, writer);
}
}
}