001: // DAVParser.java
002: // $Id: DAVParser.java,v 1.4 2000/10/20 16:12:46 bmahe Exp $
003: // (c) COPYRIGHT MIT, INRIA and Keio, 2000.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005: package org.w3c.www.webdav;
006:
007: import java.io.InputStream;
008: import java.io.IOException;
009:
010: import org.w3c.www.http.HttpInvalidValueException;
011:
012: /**
013: * @version $Revision: 1.4 $
014: * @author Benoît Mahé (bmahe@w3.org)
015: */
016: public class DAVParser {
017:
018: private static final boolean debug = false;
019:
020: /**
021: * Emit an error.
022: * @param mth The method trigerring the error.
023: * @param msg An associated message.
024: * @exception HttpInvalidValueException To indicate the error to caller.
025: */
026:
027: protected static void error(String mth, String msg)
028: throws HttpInvalidValueException {
029: throw new HttpInvalidValueException(mth + ": " + msg);
030: }
031:
032: /**
033: * Skip leading LWS, <em>not</em> including CR LF.
034: * Update the input offset, <em>after</em> any leading space.
035: * @param buf The buffer to be parsed.
036: * @param ptr The buffer pointer to be updated on return.
037: * @return The potentially advanced buffer input offset.
038: */
039:
040: public static final int skipSpaces(byte buf[], ParseState ps) {
041: int len = (ps.bufend > 0) ? ps.bufend : buf.length;
042: int off = ps.ioff;
043: while (off < len) {
044: if ((buf[off] != (byte) ' ') && (buf[off] != (byte) '\t')
045: && (buf[off] != (byte) ps.separator)) {
046: ps.ioff = off;
047: return off;
048: }
049: off++;
050: }
051: return off;
052: }
053:
054: public static final boolean startsWith(byte buf[], ParseState ps,
055: char c) {
056: return (buf[ps.start] == (byte) c);
057: }
058:
059: /**
060: * Parse list of items, taking care of quotes and optional LWS.
061: * The output offset points to the <em>next</em> element of the list.
062: * @return The starting location (i.e. <code>ps.start</code> value), or
063: * <strong>-1</strong> if no item available (end of list).
064: */
065:
066: public static final int nextItem(byte buf[], ParseState ps) {
067: // Skip leading spaces, if needed:
068: int off = -1;
069: int len = -1;
070: if (ps.isSkipable)
071: ps.start = off = skipSpaces(buf, ps);
072: else
073: ps.start = off = ps.ioff;
074: len = (ps.bufend > 0) ? ps.bufend : buf.length;
075: if (debug)
076: System.out.println("parsing: ["
077: + new String(buf, 0, off, len - off) + "]");
078: // Parse !
079: if (off >= len)
080: return -1;
081: // Setup for parsing, and parse
082: ps.start = off;
083: loop: while (off < len) {
084: if (buf[off] == (byte) '"') {
085: // A quoted item, read as one chunk
086: off++;
087: while (off < len) {
088: if (buf[off] == (byte) '\\') {
089: off += 2;
090: } else if (buf[off] == (byte) '"') {
091: off++;
092: continue loop;
093: } else {
094: off++;
095: }
096: }
097: if (off == len)
098: error("nextItem", "Un-terminated quoted item.");
099: } else if ((buf[off] == ps.separator)
100: || (ps.spaceIsSep && ((buf[off] == ' ') || (buf[off] == '\t')))) {
101: break loop;
102: }
103: off++;
104: }
105: ps.end = off;
106: // Item start is set, we are right at the end of item
107: if (ps.isSkipable) {
108: ps.ioff = off;
109: ps.ooff = skipSpaces(buf, ps);
110: }
111: // Check for either the end of the list, or the separator:
112: if (ps.ooff < ps.bufend) {
113: if (buf[ps.ooff] == (byte) ps.separator)
114: ps.ooff++;
115: }
116: if (debug)
117: System.out.println("nextItem = ["
118: + new String(buf, 0, ps.start, ps.end - ps.start)
119: + "]");
120: return (ps.end > ps.start) ? ps.start : -1;
121: }
122:
123: /**
124: * <URI> -> URI
125: */
126: public static final String decodeURL(String encoded)
127: throws HttpInvalidValueException {
128: int idx1 = encoded.indexOf('<');
129: int idx2 = encoded.indexOf('>');
130: if (idx1 == -1 || idx2 == -1) {
131: throw new HttpInvalidValueException(encoded);
132: }
133: return encoded.substring(idx1 + 1, idx2);
134: }
135:
136: /**
137: * [ETag] -> ETag
138: */
139: public static final String decodeETag(String encoded)
140: throws HttpInvalidValueException {
141: int idx1 = encoded.indexOf('[');
142: int idx2 = encoded.indexOf(']');
143: if (idx1 == -1 || idx2 == -1) {
144: throw new HttpInvalidValueException(encoded);
145: }
146: return encoded.substring(idx1 + 1, idx2);
147: }
148:
149: }
|