org.freedesktop.dbus.MessageReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dbus-java Show documentation
Show all versions of dbus-java Show documentation
Improved version of the DBus-Java library provided by freedesktop.org (https://dbus.freedesktop.org/doc/dbus-java/).
/*
D-Bus Java Implementation
Copyright (c) 2005-2006 Matthew Johnson
This program is free software; you can redistribute it and/or modify it
under the terms of either the GNU Lesser General Public License Version 2 or the
Academic Free Licence Version 2.1.
Full licence texts are included in the COPYING file with this program.
*/
package org.freedesktop.dbus;
import static org.freedesktop.dbus.Gettext.t;
import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.text.MessageFormat;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.exceptions.MessageProtocolVersionException;
import org.freedesktop.dbus.exceptions.MessageTypeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cx.ath.matthew.utils.Hexdump;
public class MessageReader {
private final Logger logger = LoggerFactory.getLogger(getClass());
private InputStream in;
private byte[] buf = null;
private byte[] tbuf = null;
private byte[] header = null;
private byte[] body = null;
private int[] len = new int[4];
public MessageReader(InputStream _in) {
this.in = new BufferedInputStream(_in);
}
public Message readMessage() throws IOException, DBusException {
int rv;
/* Read the 12 byte fixed header, retrying as neccessary */
if (null == buf) {
buf = new byte[12];
len[0] = 0;
}
if (len[0] < 12) {
try {
rv = in.read(buf, len[0], 12 - len[0]);
} catch (SocketTimeoutException exSt) {
return null;
}
if (-1 == rv) {
throw new EOFException(t("Underlying transport returned EOF"));
}
len[0] += rv;
}
if (len[0] == 0) {
return null;
}
if (len[0] < 12) {
logger.debug("Only got " + len[0] + " of 12 bytes of header");
return null;
}
/* Parse the details from the header */
byte endian = buf[0];
byte type = buf[1];
byte protover = buf[3];
if (protover > Message.PROTOCOL) {
buf = null;
throw new MessageProtocolVersionException(MessageFormat.format(t("Protocol version {0} is unsupported"), new Object[] {
protover
}));
}
/* Read the length of the variable header */
if (null == tbuf) {
tbuf = new byte[4];
len[1] = 0;
}
if (len[1] < 4) {
try {
rv = in.read(tbuf, len[1], 4 - len[1]);
} catch (SocketTimeoutException exSt) {
return null;
}
if (-1 == rv) {
throw new EOFException(t("Underlying transport returned EOF"));
}
len[1] += rv;
}
if (len[1] < 4) {
logger.debug("Only got " + len[1] + " of 4 bytes of header");
return null;
}
/* Parse the variable header length */
int headerlen = 0;
if (null == header) {
headerlen = (int) Message.demarshallint(tbuf, 0, endian, 4);
if (0 != headerlen % 8) {
headerlen += 8 - (headerlen % 8);
}
} else {
headerlen = header.length - 8;
}
/* Read the variable header */
if (null == header) {
header = new byte[headerlen + 8];
System.arraycopy(tbuf, 0, header, 0, 4);
len[2] = 0;
}
if (len[2] < headerlen) {
try {
rv = in.read(header, 8 + len[2], headerlen - len[2]);
} catch (SocketTimeoutException exSt) {
return null;
}
if (-1 == rv) {
throw new EOFException(t("Underlying transport returned EOF"));
}
len[2] += rv;
}
if (len[2] < headerlen) {
logger.debug("Only got " + len[2] + " of " + headerlen + " bytes of header");
return null;
}
/* Read the body */
int bodylen = 0;
if (null == body) {
bodylen = (int) Message.demarshallint(buf, 4, endian, 4);
}
if (null == body) {
body = new byte[bodylen];
len[3] = 0;
}
if (len[3] < body.length) {
try {
rv = in.read(body, len[3], body.length - len[3]);
} catch (SocketTimeoutException exSt) {
return null;
}
if (-1 == rv) {
throw new EOFException(t("Underlying transport returned EOF"));
}
len[3] += rv;
}
if (len[3] < body.length) {
logger.debug("Only got " + len[3] + " of " + body.length + " bytes of body");
return null;
}
Message m;
switch (type) {
case Message.MessageType.METHOD_CALL:
m = new MethodCall();
break;
case Message.MessageType.METHOD_RETURN:
m = new MethodReturn();
break;
case Message.MessageType.SIGNAL:
m = new DBusSignal();
break;
case Message.MessageType.ERROR:
m = new Error();
break;
default:
throw new MessageTypeException(MessageFormat.format(t("Message type {0} unsupported"), new Object[] {
type
}));
}
if (logger.isTraceEnabled()) {
logger.trace(Hexdump.format(buf));
logger.trace(Hexdump.format(tbuf));
logger.trace(Hexdump.format(header));
logger.trace(Hexdump.format(body));
}
try {
m.populate(buf, header, body);
} catch (DBusException dbe) {
if (AbstractConnection.EXCEPTION_DEBUG) {
logger.error("", dbe);
}
buf = null;
tbuf = null;
body = null;
header = null;
throw dbe;
} catch (RuntimeException exRe) {
if (AbstractConnection.EXCEPTION_DEBUG) {
logger.error("", exRe);
}
buf = null;
tbuf = null;
body = null;
header = null;
throw exRe;
}
logger.debug("=> " + m);
buf = null;
tbuf = null;
body = null;
header = null;
return m;
}
public void close() throws IOException {
logger.info("Closing Message Reader");
in.close();
}
}