
uk.org.retep.util.string.ParserUtils Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2010, Peter T Mount
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the retep.org.uk nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.org.retep.util.string;
import javax.annotation.concurrent.ThreadSafe;
/**
* Common string parsing methods used primarily in writing parsers
*
* @author peter
*/
@ThreadSafe
public final class ParserUtils
{
/** Creates a new instance of ParserUtils */
private ParserUtils()
{
}
/**
* Returns the character at a specific position in a CharSequence. If the
* requested position is not within the sequence's bounds, this returns
* (char)-1
* @param in CharSequence
* @param p position
* @return char at position p or (char)-1 if out of bounds
*/
public static char charAt( final CharSequence in, final int p )
{
return p < in.length() ? in.charAt( p ) : (char) -1;
}
/**
* Returns true if a starts with b
* @param a source array
* @param p Offset in source array
* @param b String to test for
* @return true if a starts with b
*/
public static boolean startsWith( final char[] a,
final int p,
final String b )
{
return startsWith( a, p, b.toCharArray() );
}
/**
* Returns true if a starts with b
* @param a source array
* @param p Offset in source array
* @param b test array (may be null)
* @return true if a starts with b
*/
public static boolean startsWith( final char[] a,
final int p,
final char... b )
{
if( a == null ||
b == null || b.length == 0 ||
(a.length - p) < b.length )
{
return false;
}
for( int i = 0; i < b.length; i++ )
{
if( a[p + i] != b[i] )
{
return false;
}
}
return true;
}
/**
* Skip over characters in the source while they match those in b
* @param a characters to skip over
* @param p start position within a
* @param b characters to skip
* @return position of first character found not in b, or a.length if the
* source ends before a character is found
*/
public static int skip( final char[] a, final int p, final char... b )
{
int q = p;
boolean skip = true;
while( skip && q < a.length )
{
skip = false;
char c = a[q];
for( int i = 0; i < b.length && !skip; i++ )
{
if( c == b[i] )
{
skip = true;
continue;
}
}
if( skip )
{
q++;
}
}
return q;
}
/**
* Skip over whitespace characters in the source
* @param a characters to skip over
* @param p start position within a
* @return position of first non-whitespace character found or a.length if the
* source ends before a non-whitespace character is found
*/
public static int skipWhitespace( final char[] a, final int p )
{
return skip( a, p, ' ', '\n', '\r', '\t' );
}
/**
* Count the number of times a character is repeated from a specific position
* @param a character source
* @param p start position within a
* @param c char to count
* @return number of times c is repeated
*/
public static int countChars( final char[] a, final int p, final char c )
{
int cnt = 0;
int i = p;
while( i < a.length && a[i] == c )
{
cnt++;
i++;
}
return cnt;
}
/**
* Backtrack if the previous chars in a match b
* @param a character source
* @param p start position within a
* @param b characters to backtrack over
* @return new position, or p if p -1; i-- )
{
int q = string.indexOf( delim.charAt( i ), start );
if( q > -1 && q < p )
{
p = q;
}
}
// if p is the string length, then return -1 indicating no delimiter found
return p == string.length() ? -1 : p;
}
}