package com.sun.slp;
import java.util.*;
import java.net.*;
import java.io.*;
abstract class SrvLocHeader extends Object implements SrvLocMsg, Cloneable {
private static final Hashtable classTable = new Hashtable();
static final int XID_OFFSET = 10;
static int VERSION_FUNCTION_BYTES = 2;
static final int SrvReq = 1;
static final int SrvRply = 2;
static final int SrvReg = 3;
static final int SrvDereg = 4;
static final int SrvAck = 5;
static final int AttrRqst = 6;
static final int AttrRply = 7;
static final int DAAdvert = 8;
static final int SrvTypeRqst = 9;
static final int SrvTypeRply = 10;
static final int SAAdvert = 11;
static final String[] functionCodeAbbr = {
"0",
"SrvReq",
"SrvRply",
"SrvReg",
"SrvDereg",
"SrvAck",
"AttrRqst",
"AttrRply",
"DAAdvert",
"SrvTypeRqst",
"SrvTypeRply",
"SAAdvert",
};
protected static final int BYTE_SIZE = 1;
protected static final int SHORT_SIZE = 2;
protected static final int INT24_SIZE = 3;
int version = 0;
int functionCode = 0;
int length = 0;
short xid = 0;
short errCode =
ServiceLocationException.OK;
Locale locale = Defaults.locale;
Vector previousResponders = null;
Vector scopes = null;
boolean overflow = false;
boolean fresh = false;
boolean mcast = false;
byte[] payload = new byte[0];
int nbytes = 0;
int packetLength = 0;
int iNumReplies = 0;
protected static short uniqueXID = 0;
private String msgType;
private String msgDescription;
SrvLocHeader() {
packetLength = SLPConfig.getSLPConfig().getMTU();
}
public SrvLocHeader getHeader() {
return this;
}
public short getErrorCode() {
return errCode;
}
public int getNumReplies() {
return iNumReplies;
}
static void addHeaderClass(String className, int version) {
try {
Class headerClass = Class.forName(className);
classTable.put(Integer.valueOf(version), headerClass);
} catch (ClassNotFoundException ex) {
Assert.slpassert(false,
"no_class",
new Object[] {className});
}
}
static SrvLocHeader newInstance(int version) {
try {
Class hdrClass = (Class)classTable.get(Integer.valueOf(version));
if (hdrClass == null) {
return null;
}
SrvLocHeader hdr = (SrvLocHeader)hdrClass.newInstance();
return hdr;
} catch (Exception ex) {
SLPConfig.getSLPConfig().writeLog("slh_creation_exception",
new Object[] {
Integer.valueOf(version),
ex,
ex.getMessage()});
return null;
}
}
abstract void parseHeader(int functionCode, DataInputStream dis)
throws ServiceLocationException, IOException, IllegalArgumentException;
abstract SrvLocMsg parseMsg(DataInputStream dis)
throws ServiceLocationException, IOException, IllegalArgumentException;
abstract void
externalize(ByteArrayOutputStream baos,
boolean multicast,
boolean isTCP)
throws ServiceLocationException;
abstract SDAAdvert
getDAAdvert(short xid,
long timestamp,
ServiceURL url,
Vector scopes,
Vector attrs)
throws ServiceLocationException;
void parseOptions(DataInputStream dis)
throws ServiceLocationException,
IOException,
IllegalArgumentException {
}
SrvLocMsg makeErrorReply(Exception ex) {
return null;
}
void setPacketLength(int newLength) {
if (newLength > 0) {
packetLength = newLength;
}
}
void addPreviousResponder(InetAddress addr) {
String hostAddr = addr.getHostAddress();
Assert.slpassert((previousResponders != null),
"prev_resp_reply",
new Object[0]);
if (!previousResponders.contains(hostAddr)) {
previousResponders.addElement(hostAddr);
}
}
synchronized static short getUniqueXID() {
if (uniqueXID == 0) {
Random r = new Random();
uniqueXID = (short)(r.nextInt() &0xFFFF);
}
uniqueXID++;
return (short)(uniqueXID & 0xFFFF);
}
int getInt(DataInputStream dis)
throws ServiceLocationException, IOException {
int ret = getInteger(dis);
nbytes += SHORT_SIZE;
return ret;
}
static int getInteger(DataInputStream dis)
throws ServiceLocationException, IOException {
byte[] b = new byte[2];
dis.readFully(b, 0, 2);
int x = (int)((char)b[0] & 0xFF);
int y = (int)((char)b[1] & 0xFF);
int z = x << 8;
z += y;
return z;
}
void putInt(int z, ByteArrayOutputStream baos) {
putInteger(z, baos);
nbytes += SHORT_SIZE;
}
static void putInteger(int z, ByteArrayOutputStream baos) {
baos.write((byte) ((0xFF00 & z)>>8));
baos.write((byte) (0xFF & z));
}
protected int getInt24(DataInputStream dis)
throws ServiceLocationException, IOException {
byte[] b = new byte[3];
dis.readFully(b, 0, 3);
int w = (int)((char)b[0] & 0xFF);
int x = (int)((char)b[1] & 0xFF);
int y = (int)((char)b[2] & 0xFF);
int z = w << 16;
z += x << 8;
z += y;
nbytes += 3;
return z;
}
protected void putInt24(int z, ByteArrayOutputStream baos) {
baos.write((byte) ((0xFF0000 & z) >> 16));
baos.write((byte) ((0xFF00 & z)>>8));
baos.write((byte) (0xFF & z));
nbytes += 3;
}
byte[] getString(StringBuffer buf, DataInputStream dis)
throws ServiceLocationException, IOException {
byte[] ret = getStringField(buf, dis, Defaults.UTF8);
nbytes += ret.length + SHORT_SIZE;
return ret;
}
static byte[]
getStringField(StringBuffer buf, DataInputStream dis, String encoding)
throws ServiceLocationException, IOException {
buf.setLength(0);
int i, n = 0;
n = getInteger(dis);
byte[] bytes = new byte[n];
dis.readFully(bytes, 0, n);
buf.append(getBytesString(bytes, encoding));
return bytes;
}
byte[] putString(String string, ByteArrayOutputStream baos) {
byte[] bytes = putStringField(string, baos, Defaults.UTF8);
nbytes += bytes.length + SHORT_SIZE;
return bytes;
}
static byte[]
putStringField(String string,
ByteArrayOutputStream baos,
String encoding) {
byte[] bytes = getStringBytes(string, encoding);
putInteger(bytes.length, baos);
baos.write(bytes, 0, bytes.length);
return bytes;
}
static byte[] getStringBytes(String string, String encoding) {
try {
return string.getBytes(encoding);
} catch (UnsupportedEncodingException ex) {
return new byte[0];
}
}
static String getBytesString(byte[] bytes, String encoding) {
try {
return new String(bytes, encoding);
} catch (UnsupportedEncodingException ex) {
return "";
}
}
protected byte[]
parseCommaSeparatedListOut(Vector v,
ByteArrayOutputStream baos) {
return putString(vectorToCommaSeparatedList(v), baos);
}
static String
vectorToCommaSeparatedList(Vector v) {
int i, n = v.size();
StringBuffer buf = new StringBuffer();
for (i = 0; i < n; i++) {
String string = (String)v.elementAt(i);
if (i != 0) {
buf.append(',');
}
buf.append(string);
}
return buf.toString();
}
static Vector parseCommaSeparatedListIn(String s, boolean ignoreParens)
throws ServiceLocationException {
if (s == null)
return new Vector();
if (s.length() == 0)
return new Vector();
StringTokenizer st = new StringTokenizer(s, ",()", true);
try {
int level = 0;
String el = "";
Vector v = new Vector();
while (st.hasMoreElements()) {
String tok = st.nextToken();
if (tok.equals("(")) {
if (!ignoreParens) {
level++;
}
el += tok;
} else if (tok.equals(")")) {
if (!ignoreParens) {
level--;
}
el += tok;
} else if (tok.equals(",")) {
if (level != 0) {
el += tok;
} else {
if (el.length() <= 0) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"csl_syntax_error",
new Object[] {s});
}
v.addElement(el);
el = "";
}
} else {
el += tok;
}
}
if (el.length() <= 0) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"csl_syntax_error",
new Object[] {s});
}
v.addElement(el);
if (level != 0) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"csl_syntax_error",
new Object[] {s});
}
return v;
} catch (NoSuchElementException nsee) {
throw
new ServiceLocationException(
ServiceLocationException.PARSE_ERROR,
"csl_syntax_error",
new Object[] {s});
}
}
public Object clone()
throws CloneNotSupportedException {
SrvLocHeader hdr = (SrvLocHeader)super.clone();
hdr.length = 0;
hdr.payload = new byte[0];
hdr.iNumReplies = 0;
return hdr;
}
protected void constructDescription(String msgType,
String msgDescription) {
this.msgType = msgType;
this.msgDescription = msgDescription;
}
public String getMsgType() {
if (msgType == null) {
if (functionCode > 0 && functionCode < functionCodeAbbr.length) {
return functionCodeAbbr[functionCode];
} else {
return String.valueOf(functionCode);
}
} else {
return msgType;
}
}
public String getMsgDescription() {
return (msgDescription == null) ? "" : msgDescription;
}
}