package com.jpexs.proxy;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
import java.io.*;
public abstract class Message {
/**
* Hashtable used to store message headers.
*/
private Hashtable headers = new Hashtable(33);
/**
*
*/
String statusLine = null;
public String readLine(InputStream in) throws IOException {
char[] buf = new char[128];
int offset = 0;
int ch;
for (;;) {
ch = in.read();
if (ch == -1 || ch == '\n') {
break;
} else if (ch == '\r') {
int tmpch = in.read();
if (tmpch != '\n') {
if (!(in instanceof PushbackInputStream)) {
in = new PushbackInputStream(in);
}
((PushbackInputStream) in).unread(tmpch);
}
break;
} else {
if (offset == buf.length) {
char[] tmpbuf = buf;
buf = new char[tmpbuf.length * 2];
System.arraycopy(tmpbuf, 0, buf, 0, offset);
}
buf[offset++] = (char) ch;
}
}
return String.copyValueOf(buf, 0, offset);
}
/**
* Read headers and store them in the hashtable.
*/
void readHeaders(InputStream in) throws IOException {
int i;
Key key = null;
for (;;) {
String s = readLine(in);
if (s == null) {
break;
}
i = s.indexOf(':');
if (i == -1) {
/* end of header */
if (s.length() == 0) {
break;
} /* multi-line headers */ else if (key != null
&& (s.startsWith(" ") || s.startsWith("\t"))) {
int index = getHeaderValueCount(key.toString());
index--;
Vector v = (Vector) headers.get(key);
v.setElementAt(v.elementAt(index) + "\n" + s, index);
}
} else {
key = new Key(s.substring(0, i));
Vector v;
if (headers.containsKey(key)) {
v = (Vector) headers.get(key);
} else {
v = new Vector();
}
v.addElement(s.substring(i + 1).trim());
headers.put(key, v);
}
}
}
public int headerCount() {
return headers.size();
}
/**
* Set the Status line.
*/
public void setStatusLine(String l) {
statusLine = l;
}
public int getHeaderValueCount(String name) {
Vector v = (Vector) headers.get(new Key(name));
return v.size();
}
public String getHeaderField(String name) {
return getHeaderField(name, 0);
}
public String getHeaderField(String name, int index) {
Vector v = (Vector) headers.get(new Key(name));
if (v == null) {
return null;
}
return (String) v.elementAt(index);
}
public void setHeaderField(String name, String value) {
setHeaderField(name, value, 0);
}
public void setHeaderField(String name, String value, int index) {
Vector v;
Key key = new Key(name);
if (headers.containsKey(key)) {
v = (Vector) headers.get(key);
} else {
v = new Vector();
if (index == 0) {
v.addElement("");
}
headers.put(key, v);
}
v.setElementAt(value, index);
}
public void setHeaderField(String name, int value) {
setHeaderField(name, value, 0);
}
public void setHeaderField(String name, int value, int index) {
setHeaderField(name, new Integer(value).toString(), index);
}
/**
* Set all header fields with the give name to the specified value.
*/
public void setHeaderFields(String name, String value) {
Vector v;
Key key = new Key(name);
v = (Vector) headers.get(key);
if (v != null) {
for (int i = 0; i < v.size(); i++) {
v.setElementAt(value, i);
}
}
}
public void appendHeaderField(String name, String value) {
appendHeaderField(name, value, 0);
}
public void appendHeaderField(String name, String value, int index) {
setHeaderField(name, getHeaderField(name, index) + value, index);
}
public void removeHeaderField(String name) {
headers.remove(new Key(name));
}
/**
* Return whether or not a header exists.
*
* @param name header name
*/
public boolean containsHeaderField(String name) {
return headers.containsKey(new Key(name));
}
/**
* @return an Enumeration of Strings
*/
public Enumeration getHeaders() {
Vector v = new Vector();
for (Enumeration e = headers.keys(); e.hasMoreElements();) {
v.addElement(e.nextElement().toString());
}
return v.elements();
}
private final static byte[] COLON_SPACE = ": ".getBytes();
private final static byte[] CRLF = "\r\n".getBytes();
private ByteArray toByteArray(byte[] sep) {
ByteArray buf = new ByteArray();
Key key;
String value;
Vector v;
int i = 0;
buf.append(statusLine);
buf.append(sep);
for (Enumeration e = headers.keys(); e.hasMoreElements();) {
key = (Key) e.nextElement();
v = (Vector) headers.get(key);
for (i = 0; i < v.size(); i++) {
buf.append(key.toString());
buf.append(COLON_SPACE);
buf.append(v.elementAt(i).toString());
buf.append(sep);
}
}
buf.append(sep);
return buf;
}
private ByteArray toByteArray() {
return toByteArray(CRLF);
}
private ByteArray toByteArray(String sep) {
return toByteArray(sep.getBytes());
}
public String toString() {
return toByteArray().toString();
}
public String toString(String sep) {
return toByteArray(sep).toString();
}
public void write(OutputStream out)
throws IOException {
toByteArray().writeTo(out);
out.flush();
}
}