org.eclipse.jetty.util.QuotedStringTokenizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import java.io.IOException;
import java.util.Arrays;
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 recognised.
* Delimiters within quotes are not considered delimiters.
* Quotes can be escaped with '\'.
*
* @see java.util.StringTokenizer
*
*/
public class QuotedStringTokenizer
extends StringTokenizer
{
private final static String __delim="\t\n\r";
private String _string;
private String _delim = __delim;
private boolean _returnQuotes=false;
private boolean _returnDelimiters=false;
private StringBuffer _token;
private boolean _hasToken=false;
private int _i=0;
private int _lastStart=0;
private boolean _double=true;
private boolean _single=true;
/* ------------------------------------------------------------ */
public QuotedStringTokenizer(String str,
String delim,
boolean returnDelimiters,
boolean returnQuotes)
{
super("");
_string=str;
if (delim!=null)
_delim=delim;
_returnDelimiters=returnDelimiters;
_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 returnDelimiters)
{
this(str,delim,returnDelimiters,false);
}
/* ------------------------------------------------------------ */
public QuotedStringTokenizer(String str,
String delim)
{
this(str,delim,false,false);
}
/* ------------------------------------------------------------ */
public QuotedStringTokenizer(String str)
{
this(str,null,false,false);
}
/* ------------------------------------------------------------ */
@Override
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 (_returnDelimiters)
{
_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;
}
break;
case 1: // Token
_hasToken=true;
if(_delim.indexOf(c)>=0)
{
if (_returnDelimiters)
_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);
}
break;
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);
}
break;
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);
}
break;
}
}
return _hasToken;
}
/* ------------------------------------------------------------ */
@Override
public String nextToken()
throws NoSuchElementException
{
if (!hasMoreTokens() || _token==null)
throw new NoSuchElementException();
String t=_token.toString();
_token.setLength(0);
_hasToken=false;
return t;
}
/* ------------------------------------------------------------ */
@Override
public String nextToken(String delim)
throws NoSuchElementException
{
_delim=delim;
_i=_lastStart;
_token.setLength(0);
_hasToken=false;
return nextToken();
}
/* ------------------------------------------------------------ */
@Override
public boolean hasMoreElements()
{
return hasMoreTokens();
}
/* ------------------------------------------------------------ */
@Override
public Object nextElement()
throws NoSuchElementException
{
return nextToken();
}
/* ------------------------------------------------------------ */
/** Not implemented.
*/
@Override
public int countTokens()
{
return -1;
}
/* ------------------------------------------------------------ */
/** 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.
* @param delim the delimiter to use to quote the string
* @return quoted string
*/
public static String quoteIfNeeded(String s, String delim)
{
if (s==null)
return null;
if (s.length()==0)
return "\"\"";
for (int i=0;i=0)
{
StringBuffer b=new StringBuffer(s.length()+8);
quote(b,s);
return b.toString();
}
}
return s;
}
/* ------------------------------------------------------------ */
/** Quote a string.
* The string is quoted only if quoting is required due to
* embeded delimiters, quote characters or the
* empty string.
* @param s The string to quote.
* @return quoted string
*/
public static String quote(String s)
{
if (s==null)
return null;
if (s.length()==0)
return "\"\"";
StringBuffer b=new StringBuffer(s.length()+8);
quote(b,s);
return b.toString();
}
private static final char[] escapes = new char[32];
static
{
Arrays.fill(escapes, (char)0xFFFF);
escapes['\b'] = 'b';
escapes['\t'] = 't';
escapes['\n'] = 'n';
escapes['\f'] = 'f';
escapes['\r'] = 'r';
}
/* ------------------------------------------------------------ */
/** Quote a string into an Appendable.
* The characters ", \, \n, \r, \t, \f and \b are escaped
* @param buffer The Appendable
* @param input The String to quote.
*/
public static void quote(Appendable buffer, String input)
{
try
{
buffer.append('"');
for (int i = 0; i < input.length(); ++i)
{
char c = input.charAt(i);
if (c >= 32)
{
if (c == '"' || c == '\\')
buffer.append('\\');
buffer.append(c);
}
else
{
char escape = escapes[c];
if (escape == 0xFFFF)
{
// Unicode escape
buffer.append('\\').append('u').append('0').append('0');
if (c < 0x10)
buffer.append('0');
buffer.append(Integer.toString(c, 16));
}
else
{
buffer.append('\\').append(escape);
}
}
}
buffer.append('"');
}
catch (IOException x)
{
throw new RuntimeException(x);
}
}
/* ------------------------------------------------------------ */
/** Quote a string into a StringBuffer only if needed.
* Quotes are forced if any delim characters are present.
*
* @param buf The StringBuffer
* @param s The String to quote.
* @param delim String of characters that must be quoted.
* @return true if quoted;
*/
public static boolean quoteIfNeeded(Appendable buf, String s,String delim)
{
for (int i=0;i=0)
{
quote(buf,s);
return true;
}
}
try
{
buf.append(s);
return false;
}
catch(IOException e)
{
throw new RuntimeException(e);
}
}
/* ------------------------------------------------------------ */
public static String unquoteOnly(String s)
{
return unquoteOnly(s, false);
}
/* ------------------------------------------------------------ */
/** Unquote a string, NOT converting unicode sequences
* @param s The string to unquote.
* @param lenient if true, will leave in backslashes that aren't valid escapes
* @return quoted string
*/
public static String unquoteOnly(String s, boolean lenient)
{
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;
StringBuilder b = new StringBuilder(s.length() - 2);
boolean escape=false;
for (int i=1;i