001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.jk.core;
019:
020: import java.io.IOException;
021:
022: import org.apache.tomcat.util.buf.ByteChunk;
023: import org.apache.tomcat.util.buf.MessageBytes;
024:
025: /**
026: * A single packet for communication between the web server and the
027: * container.
028: *
029: * In a more generic sense, it's the event that drives the processing chain.
030: * XXX Use Event, make Msg a particular case.
031: *
032: * @author Henri Gomez [hgomez@apache.org]
033: * @author Dan Milstein [danmil@shore.net]
034: * @author Keith Wannamaker [Keith@Wannamaker.org]
035: * @author Kevin Seguin
036: * @author Costin Manolache
037: */
038: public abstract class Msg {
039:
040: /**
041: * Prepare this packet for accumulating a message from the container to
042: * the web server. Set the write position to just after the header
043: * (but leave the length unwritten, because it is as yet unknown).
044: */
045: public abstract void reset();
046:
047: /**
048: * For a packet to be sent to the web server, finish the process of
049: * accumulating data and write the length of the data payload into
050: * the header.
051: */
052: public abstract void end();
053:
054: public abstract void appendInt(int val);
055:
056: public abstract void appendByte(int val);
057:
058: public abstract void appendLongInt(int val);
059:
060: /**
061: */
062: public abstract void appendBytes(MessageBytes mb)
063: throws IOException;
064:
065: public abstract void appendByteChunk(ByteChunk bc)
066: throws IOException;
067:
068: /**
069: * Copy a chunk of bytes into the packet, starting at the current
070: * write position. The chunk of bytes is encoded with the length
071: * in two bytes first, then the data itself, and finally a
072: * terminating \0 (which is <B>not</B> included in the encoded
073: * length).
074: *
075: * @param b The array from which to copy bytes.
076: * @param off The offset into the array at which to start copying
077: * @param numBytes The number of bytes to copy.
078: */
079: public abstract void appendBytes(byte b[], int off, int numBytes);
080:
081: /**
082: * Read an integer from packet, and advance the read position past
083: * it. Integers are encoded as two unsigned bytes with the
084: * high-order byte first, and, as far as I can tell, in
085: * little-endian order within each byte.
086: */
087: public abstract int getInt();
088:
089: public abstract int peekInt();
090:
091: public abstract byte getByte();
092:
093: public abstract byte peekByte();
094:
095: public abstract void getBytes(MessageBytes mb);
096:
097: /**
098: * Copy a chunk of bytes from the packet into an array and advance
099: * the read position past the chunk. See appendBytes() for details
100: * on the encoding.
101: *
102: * @return The number of bytes copied.
103: */
104: public abstract int getBytes(byte dest[]);
105:
106: /**
107: * Read a 32 bits integer from packet, and advance the read position past
108: * it. Integers are encoded as four unsigned bytes with the
109: * high-order byte first, and, as far as I can tell, in
110: * little-endian order within each byte.
111: */
112: public abstract int getLongInt();
113:
114: public abstract int getHeaderLength();
115:
116: public abstract int processHeader();
117:
118: public abstract byte[] getBuffer();
119:
120: public abstract int getLen();
121:
122: public abstract void dump(String msg);
123:
124: /* -------------------- Utilities -------------------- */
125: // XXX Move to util package
126: public static String hexLine(byte buf[], int start, int len) {
127: StringBuffer sb = new StringBuffer();
128: for (int i = start; i < start + 16; i++) {
129: if (i < len + 4)
130: sb.append(hex(buf[i]) + " ");
131: else
132: sb.append(" ");
133: }
134: sb.append(" | ");
135: for (int i = start; i < start + 16 && i < len + 4; i++) {
136: if (!Character.isISOControl((char) buf[i]))
137: sb.append(new Character((char) buf[i]));
138: else
139: sb.append(".");
140: }
141: return sb.toString();
142: }
143:
144: private static String hex(int x) {
145: // if( x < 0) x=256 + x;
146: String h = Integer.toHexString(x);
147: if (h.length() == 1)
148: h = "0" + h;
149: return h.substring(h.length() - 2);
150: }
151:
152: }
|