
net.lightbody.bmp.proxy.jetty.util.QuotedStringTokenizer Maven / Gradle / Ivy
// ========================================================================
// $Id: QuotedStringTokenizer.java,v 1.5 2006/11/23 08:56:53 gregwilkins Exp $
// Copyright 1999-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package net.lightbody.bmp.proxy.jetty.util;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
/**
* StringTokenizer with Quoting support.
*
* This class is a copy of the java.util.StringTokenizer API and
* the behaviour is the same, except that single and double quoted string values are recognized.
* Delimiters within quotes are not considered delimiters. Quotes can be escaped with '\'.
*
* @author Greg Wilkins (gregw)
* @version $Id: QuotedStringTokenizer.java,v 1.5 2006/11/23 08:56:53 gregwilkins Exp $
* @see java.util.StringTokenizer
*/
public class QuotedStringTokenizer extends StringTokenizer {
private final static String __delim = "\t\n\r";
private final String _string;
private String _delim = __delim;
private boolean _returnQuotes = false;
private boolean _returnTokens = false;
private StringBuffer _token;
private boolean _hasToken = false;
private int _i = 0;
private int _lastStart = 0;
private boolean _single = true;
private boolean _double = true;
public QuotedStringTokenizer(String str, String delim, boolean returnTokens, boolean returnQuotes) {
super("");
_string = str;
if (delim != null) {
_delim = delim;
}
_returnTokens = returnTokens;
_returnQuotes = returnQuotes;
if (_delim.indexOf('\'') >= 0 || _delim.indexOf('"') >= 0) {
throw new Error("Can't use quotes as delimiters: " + _delim);
}
_token = new StringBuffer(_string.length() > 1024 ? 512 : _string.length() / 2);
}
public QuotedStringTokenizer(String str, String delim, boolean returnTokens) {
this(str, delim, returnTokens, false);
}
public QuotedStringTokenizer(String str, String delim) {
this(str, delim, false, false);
}
public QuotedStringTokenizer(String str) {
this(str, null, false, false);
}
/**
* Quote a string.
* The string is quoted only if quoting is required due to embedded delimiters, quote characters or the empty string.
*
* @param s The string to quote.
* @return quoted string
*/
public static String quote(String s, String delim) {
if (s == null) {
return null;
}
if (s.length() == 0) {
return "\"\"";
}
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '"' || c == '\\' || c == '\'' || delim.indexOf(c) >= 0) {
StringBuffer b = new StringBuffer(s.length() + 8);
quote(b, s);
return b.toString();
}
}
return s;
}
/**
* Quote a string into a StringBuffer.
*
* @param buf The StringBuffer
* @param s The String to quote.
*/
public static void quote(StringBuffer buf, String s) {
synchronized (buf) {
buf.append('"');
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '"') {
buf.append("\\\"");
continue;
}
if (c == '\\') {
buf.append("\\\\");
continue;
}
buf.append(c);
continue;
}
buf.append('"');
}
}
/**
* Unquote a string.
*
* @param s The string to unquote.
* @return quoted string
*/
public static String unquote(String s) {
if (s == null) {
return null;
}
if (s.length() < 2) {
return s;
}
char first = s.charAt(0);
char last = s.charAt(s.length() - 1);
if (first != last || (first != '"' && first != '\'')) {
return s;
}
StringBuffer b = new StringBuffer(s.length() - 2);
synchronized (b) {
boolean quote = false;
for (int i = 1; i < s.length() - 1; i++) {
char c = s.charAt(i);
if (c == '\\' && !quote) {
quote = true;
continue;
}
quote = false;
b.append(c);
}
return b.toString();
}
}
/**
* Unquote a string.
*
* @param s The string to unquote.
* @return quoted string
*/
public static String unquoteDouble(String s) {
if (s == null) {
return null;
}
if (s.length() < 2) {
return s;
}
char first = s.charAt(0);
char last = s.charAt(s.length() - 1);
if (first != last || first != '"') {
return s;
}
StringBuffer b = new StringBuffer(s.length() - 2);
synchronized (b) {
boolean quote = false;
for (int i = 1; i < s.length() - 1; i++) {
char c = s.charAt(i);
if (c == '\\' && !quote) {
quote = true;
continue;
}
quote = false;
b.append(c);
}
return b.toString();
}
}
public boolean hasMoreTokens() {
// Already found a token
if (_hasToken) {
return true;
}
_lastStart = _i;
int state = 0;
boolean escape = false;
while (_i < _string.length()) {
char c = _string.charAt(_i++);
switch (state) {
case 0: // Start
if (_delim.indexOf(c) >= 0) {
if (_returnTokens) {
_token.append(c);
return _hasToken = true;
}
} else if (c == '\'' && _single) {
if (_returnQuotes) {
_token.append(c);
}
state = 2;
} else if (c == '\"' && _double) {
if (_returnQuotes) {
_token.append(c);
}
state = 3;
} else {
_token.append(c);
_hasToken = true;
state = 1;
}
continue;
case 1: // Token
_hasToken = true;
if (_delim.indexOf(c) >= 0) {
if (_returnTokens) {
_i--;
}
return _hasToken;
} else if (c == '\'' && _single) {
if (_returnQuotes) {
_token.append(c);
}
state = 2;
} else if (c == '\"' && _double) {
if (_returnQuotes) {
_token.append(c);
}
state = 3;
} else
_token.append(c);
continue;
case 2: // Single Quote
_hasToken = true;
if (escape) {
escape = false;
_token.append(c);
} else if (c == '\'') {
if (_returnQuotes) {
_token.append(c);
}
state = 1;
} else if (c == '\\') {
if (_returnQuotes) {
_token.append(c);
}
escape = true;
} else {
_token.append(c);
}
continue;
case 3: // Double Quote
_hasToken = true;
if (escape) {
escape = false;
_token.append(c);
} else if (c == '\"') {
if (_returnQuotes) {
_token.append(c);
}
state = 1;
} else if (c == '\\') {
if (_returnQuotes) {
_token.append(c);
}
escape = true;
} else {
_token.append(c);
}
continue;
}
}
return _hasToken;
}
public String nextToken() throws NoSuchElementException {
if (!hasMoreTokens() || _token == null) {
throw new NoSuchElementException();
}
String t = _token.toString();
_token.setLength(0);
_hasToken = false;
return t;
}
public String nextToken(String delim) throws NoSuchElementException {
_delim = delim;
_i = _lastStart;
_token.setLength(0);
_hasToken = false;
return nextToken();
}
public boolean hasMoreElements() {
return hasMoreTokens();
}
public Object nextElement() throws NoSuchElementException {
return nextToken();
}
/**
* Not implemented.
*/
public int countTokens() {
return -1;
}
public boolean getDouble() {
return _double;
}
public void setDouble(boolean d) {
_double = d;
}
public boolean getSingle() {
return _single;
}
public void setSingle(boolean single) {
_single = single;
}
}