--- /dev/null
+// BasicValue.java\r
+// $Id: BasicValue.java,v 1.1 2010/06/15 12:19:52 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.www.http;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+\r
+public abstract class BasicValue implements HeaderValue, Cloneable {\r
+ /**\r
+ * The header value, as a byte array, if available.\r
+ */\r
+ protected byte raw[] = null;\r
+ /**\r
+ * The offset of the value in the above buffer, in case the buffer is\r
+ * shared.\r
+ */\r
+ protected int roff = -1;\r
+ /**\r
+ * The length of the byte value in case the above buffer is shared.\r
+ */\r
+ protected int rlen = -1;\r
+ /**\r
+ * Are the parsed values up to date with the lastly set unparsed value ?\r
+ */\r
+ protected boolean isValid = false;\r
+\r
+ /**\r
+ * Parse this header value into its various components.\r
+ * @exception HttpParserException if unable to parse.\r
+ */\r
+\r
+ abstract protected void parse()\r
+ throws HttpParserException;\r
+\r
+ /**\r
+ * Update the RFC822 compatible header value for this object.\r
+ */\r
+\r
+ abstract protected void updateByteValue();\r
+\r
+ /**\r
+ * Compute the new RFC822 compatible representation of this header value.\r
+ * If our value is up to date, we just return, otherwise, the abstract\r
+ * <code>updateByteValue</code> is called to perform the job.\r
+ */\r
+\r
+ protected final void checkByteValue() {\r
+ if ( raw == null ) {\r
+ updateByteValue();\r
+ roff = 0;\r
+ rlen = raw.length;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Validate the parsed value according to the last set raw value.\r
+ * This will trigger the header value parsing, if it is required at this\r
+ * point.\r
+ * @exception HttpInvalidValueException If the value couldn't be parsed \r
+ * properly.\r
+ */\r
+\r
+ protected final void validate()\r
+ throws HttpInvalidValueException\r
+ {\r
+ if ( isValid )\r
+ return;\r
+ try {\r
+ parse();\r
+ } catch (HttpParserException ex) {\r
+ throw new HttpInvalidValueException(ex.getMessage());\r
+ }\r
+ isValid = true;\r
+ }\r
+\r
+ /**\r
+ * Invalidate the current byte value for this header, if any.\r
+ */\r
+\r
+ protected void invalidateByteValue() {\r
+ raw = null;\r
+ }\r
+\r
+ /**\r
+ * Emit a parsing error.\r
+ * @param msg The error message.\r
+ * @exception HttpParserException If the parsing failed.\r
+ */\r
+\r
+ protected void error(String msg) \r
+ throws HttpParserException\r
+ {\r
+ throw new HttpParserException(msg);\r
+ }\r
+\r
+ /**\r
+ * Append this header value to the given output buffer.\r
+ * @return The header value as a byte array.\r
+ */\r
+\r
+ public void appendValue(HttpBuffer buf) {\r
+ checkByteValue();\r
+ buf.append(raw, roff, rlen);\r
+ }\r
+\r
+ /**\r
+ * Return a String encoding this header value in an HTTP compatible way.\r
+ * @return A String.\r
+ */\r
+\r
+ public String toExternalForm() {\r
+ checkByteValue();\r
+ return new String(raw, 0, roff, rlen-roff);\r
+ }\r
+\r
+ /**\r
+ * Print this header value as it would be emited.\r
+ * @return A String representation of this header value.\r
+ */\r
+\r
+ public String toString() {\r
+ return toExternalForm();\r
+ }\r
+\r
+ /**\r
+ * HeaderValue implementation - Emit this header value to the given output\r
+ * stream.\r
+ * @param out The output stream to emit the header value to.\r
+ * @exception IOException If some IO error occured.\r
+ */\r
+\r
+ public void emit(OutputStream out) \r
+ throws IOException\r
+ {\r
+ checkByteValue();\r
+ out.write(raw);\r
+ }\r
+\r
+ /**\r
+ * HeaderValue implementation - Add these bytes to the header raw value.\r
+ * @param buf The byte buffer containing some part of the header value.\r
+ * @param off The offset of the header value in above buffer.\r
+ * @param len The length of the header value in above buffer.\r
+ */\r
+\r
+ public void addBytes(byte buf[], int off, int len) {\r
+ if ( raw != null ) {\r
+ int nl = len + rlen;\r
+ byte nr[] = new byte[nl+1];\r
+ System.arraycopy(raw, roff, nr, 0, rlen);\r
+ nr[rlen] = (byte) ',';\r
+ System.arraycopy(buf, off, nr, rlen+1, len);\r
+ raw = nr;\r
+ } else {\r
+ raw = new byte[len];\r
+ System.arraycopy(buf, off, raw, 0, len);\r
+ }\r
+ roff = 0;\r
+ rlen = raw.length;\r
+ isValid = false;\r
+ }\r
+\r
+ /**\r
+ * HeaderValue implementation - Reset the header byte value.\r
+ * @param buf The byte buffer containing some part of the header value.\r
+ * @param off The offset of the header value in above buffer.\r
+ * @param len The length of the header value in above buffer.\r
+ */\r
+\r
+ public void setBytes(byte buf[], int off, int len) {\r
+ raw = new byte[len];\r
+ System.arraycopy(buf, off, raw, 0, len);\r
+ roff = 0;\r
+ rlen = raw.length;\r
+ isValid = false;\r
+ }\r
+\r
+ /**\r
+ * Set this Header Value by parsing the given String.\r
+ * @param strval The String value for that object.\r
+ * @return Itself.\r
+ */\r
+\r
+ public void setString(String strval) {\r
+ int slen = strval.length();\r
+ raw = new byte[slen];\r
+ roff = 0;\r
+ rlen = slen;\r
+ strval.getBytes(0, slen, raw, 0);\r
+ isValid = false;\r
+ }\r
+\r
+ /**\r
+ * HeaderValue implemenntation - Get this header value.\r
+ * @return An object representing the parsed value for this header.\r
+ */\r
+\r
+ abstract public Object getValue() ;\r
+\r
+ // needs to define it as this is an abstract class\r
+ protected Object clone()\r
+ throws CloneNotSupportedException \r
+ {\r
+ return super.clone();\r
+ }\r
+\r
+ public BasicValue() {\r
+ isValid = false;\r
+ }\r
+\r
+}\r