001: // BasicValue.java
002: // $Id: BasicValue.java,v 1.13 2005/08/30 14:39:37 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.www.http;
007:
008: import java.io.IOException;
009: import java.io.OutputStream;
010:
011: public abstract class BasicValue implements HeaderValue, Cloneable {
012: /**
013: * The header value, as a byte array, if available.
014: */
015: protected byte raw[] = null;
016: /**
017: * The offset of the value in the above buffer, in case the buffer is
018: * shared.
019: */
020: protected int roff = -1;
021: /**
022: * The length of the byte value in case the above buffer is shared.
023: */
024: protected int rlen = -1;
025: /**
026: * Are the parsed values up to date with the lastly set unparsed value ?
027: */
028: protected boolean isValid = false;
029:
030: /**
031: * Parse this header value into its various components.
032: * @exception HttpParserException if unable to parse.
033: */
034:
035: abstract protected void parse() throws HttpParserException;
036:
037: /**
038: * Update the RFC822 compatible header value for this object.
039: */
040:
041: abstract protected void updateByteValue();
042:
043: /**
044: * Compute the new RFC822 compatible representation of this header value.
045: * If our value is up to date, we just return, otherwise, the abstract
046: * <code>updateByteValue</code> is called to perform the job.
047: */
048:
049: protected final void checkByteValue() {
050: if (raw == null) {
051: updateByteValue();
052: roff = 0;
053: rlen = raw.length;
054: }
055: }
056:
057: /**
058: * Validate the parsed value according to the last set raw value.
059: * This will trigger the header value parsing, if it is required at this
060: * point.
061: * @exception HttpInvalidValueException If the value couldn't be parsed
062: * properly.
063: */
064:
065: protected final void validate() throws HttpInvalidValueException {
066: if (isValid)
067: return;
068: try {
069: parse();
070: } catch (HttpParserException ex) {
071: throw new HttpInvalidValueException(ex.getMessage());
072: }
073: isValid = true;
074: }
075:
076: /**
077: * Invalidate the current byte value for this header, if any.
078: */
079:
080: protected void invalidateByteValue() {
081: raw = null;
082: }
083:
084: /**
085: * Emit a parsing error.
086: * @param msg The error message.
087: * @exception HttpParserException If the parsing failed.
088: */
089:
090: protected void error(String msg) throws HttpParserException {
091: throw new HttpParserException(msg);
092: }
093:
094: /**
095: * Append this header value to the given output buffer.
096: * @return The header value as a byte array.
097: */
098:
099: public void appendValue(HttpBuffer buf) {
100: checkByteValue();
101: buf.append(raw, roff, rlen);
102: }
103:
104: /**
105: * Return a String encoding this header value in an HTTP compatible way.
106: * @return A String.
107: */
108:
109: public String toExternalForm() {
110: checkByteValue();
111: return new String(raw, 0, roff, rlen - roff);
112: }
113:
114: /**
115: * Print this header value as it would be emited.
116: * @return A String representation of this header value.
117: */
118:
119: public String toString() {
120: return toExternalForm();
121: }
122:
123: /**
124: * HeaderValue implementation - Emit this header value to the given output
125: * stream.
126: * @param out The output stream to emit the header value to.
127: * @exception IOException If some IO error occured.
128: */
129:
130: public void emit(OutputStream out) throws IOException {
131: checkByteValue();
132: out.write(raw);
133: }
134:
135: /**
136: * HeaderValue implementation - Add these bytes to the header raw value.
137: * @param buf The byte buffer containing some part of the header value.
138: * @param off The offset of the header value in above buffer.
139: * @param len The length of the header value in above buffer.
140: */
141:
142: public void addBytes(byte buf[], int off, int len) {
143: if (raw != null) {
144: int nl = len + rlen;
145: byte nr[] = new byte[nl + 1];
146: System.arraycopy(raw, roff, nr, 0, rlen);
147: nr[rlen] = (byte) ',';
148: System.arraycopy(buf, off, nr, rlen + 1, len);
149: raw = nr;
150: } else {
151: raw = new byte[len];
152: System.arraycopy(buf, off, raw, 0, len);
153: }
154: roff = 0;
155: rlen = raw.length;
156: isValid = false;
157: }
158:
159: /**
160: * HeaderValue implementation - Reset the header byte value.
161: * @param buf The byte buffer containing some part of the header value.
162: * @param off The offset of the header value in above buffer.
163: * @param len The length of the header value in above buffer.
164: */
165:
166: public void setBytes(byte buf[], int off, int len) {
167: raw = new byte[len];
168: System.arraycopy(buf, off, raw, 0, len);
169: roff = 0;
170: rlen = raw.length;
171: isValid = false;
172: }
173:
174: /**
175: * Set this Header Value by parsing the given String.
176: * @param strval The String value for that object.
177: * @return Itself.
178: */
179:
180: public void setString(String strval) {
181: int slen = strval.length();
182: raw = new byte[slen];
183: roff = 0;
184: rlen = slen;
185: strval.getBytes(0, slen, raw, 0);
186: isValid = false;
187: }
188:
189: /**
190: * HeaderValue implemenntation - Get this header value.
191: * @return An object representing the parsed value for this header.
192: */
193:
194: abstract public Object getValue();
195:
196: // needs to define it as this is an abstract class
197: protected Object clone() throws CloneNotSupportedException {
198: return super .clone();
199: }
200:
201: public BasicValue() {
202: isValid = false;
203: }
204:
205: }
|