
net.darkmist.alib.str.Escape Maven / Gradle / Ivy
/*
* Copyright (C) 2012 Ed Schaller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.darkmist.alib.str;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Escape
{
private static final char DEFAULT_ESCAPE = '\\';
private static final boolean DEFAULT_IGNORE_ERROR = true;
private static final char[] EMPTY_CHAR_ARRAY = new char[0];
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public static Appendable unescape(CharSequence src, Appendable dst, char escapeChar, boolean ignoreError) throws IOException, EscapeException
{
int srcLen = src.length();
char ch; // char from src we're looking at
int left = srcLen; // amount left in src
int i;
srcloop: for(i=0;i=srcLen)
if(ignoreError)
return dst;
else
throw new EscapeException("String to escape ends in unescaped escape char.");
ch=src.charAt(i);
switch(ch)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
// octal bleh...
left = srcLen - i;
// check for just one octal
if(!(left>=2 && Octal.isOctal(src.charAt(i+1))))
{ // only one octal
dst.append((char)Octal.unoctByte(src,i,1));
continue srcloop;
}
// check for two octals
if(!(left>=3 && Octal.isOctal(src.charAt(i+2))))
{ // two octal chars
dst.append((char)Octal.unoctByte(src,i,2));
i++;
continue srcloop;
}
// three octal chars (ha ha ha)
//System.err.println("escaped=" + src.subSequence(i,i+3));
dst.append((char)Octal.unoctShort(src,i,3));
i+=2;
continue srcloop;
case 'a':
dst.append('\u0007');
continue srcloop;
case 'b':
dst.append('\b');
continue srcloop;
case 't':
dst.append('\t');
continue srcloop;
case 'n':
dst.append('\n');
continue srcloop;
case 'v':
dst.append('\u000b');
continue srcloop;
case 'f':
dst.append('\f');
continue srcloop;
case 'r':
dst.append('\r');
continue srcloop;
case 'x':
case 'X':
// hex escape
if(srcLen - i < 3)
if(ignoreError)
return dst;
else
throw new EscapeException("String to escape ends in truncated hex escape");
i++;
dst.append((char)(Hex.unhexByte(src,i,2)&0xff));
i++;
continue srcloop;
case 'u':
case 'U':
// unicode hex escape
if(srcLen - i < 5)
if(ignoreError)
return dst;
else
throw new EscapeException("String to escape ends in truncated unicode hex escape");
i++;
//System.err.println("unescaped=" + src.subSequence(i,i+4));
//System.err.println("unhexShort=" + Integer.toHexString(unhexShort(src,i,4)) + '=');
dst.append((char)(Hex.unhexShort(src,i,4)&0xffff));
i+=3;
continue srcloop;
default:
dst.append(ch);
continue srcloop;
}
}
return dst;
}
public static Appendable unescape(CharSequence src, Appendable dst, char escapeChar) throws IOException, EscapeException
{
return unescape(src,dst,escapeChar,DEFAULT_IGNORE_ERROR);
}
public static Appendable unescape(CharSequence src, Appendable dst, boolean ignoreError) throws IOException, EscapeException
{
return unescape(src,dst, DEFAULT_ESCAPE, ignoreError);
}
public static Appendable unescape(CharSequence src, Appendable dst) throws IOException, EscapeException
{
return unescape(src,dst, DEFAULT_ESCAPE, DEFAULT_IGNORE_ERROR);
}
public static String unescape(CharSequence src, char escapeChar, boolean ignoreError) throws EscapeException
{
try
{
return unescape(src, new StringBuilder(), escapeChar, ignoreError).toString();
}
catch(IOException e)
{
throw new IllegalStateException("IOException caught when appending to a " + StringBuilder.class.getName(), e);
}
}
public static String unescape(CharSequence src, char escapeChar) throws EscapeException
{
return unescape(src, escapeChar, DEFAULT_IGNORE_ERROR);
}
public static String unescape(CharSequence src, boolean ignoreError) throws EscapeException
{
return unescape(src, DEFAULT_ESCAPE, ignoreError);
}
public static String unescape(CharSequence src) throws EscapeException
{
return unescape(src, DEFAULT_ESCAPE, DEFAULT_IGNORE_ERROR);
}
public static Appendable escape(CharSequence src, Appendable dst, char[] alsoEscape, char escapeChar) throws IOException
{
int srcLen = src.length();
char ch; // char from src we're looking at
int c; // postive int form of ch
int i; // src position
int j; // alsoEscape position
srcloop: for(i=0;i0xff)
{
dst.append(escapeChar);
dst.append("u");
Hex.hexShort(dst, c);
continue srcloop;
}
if(c>=0x7f||c<0x20)
{
dst.append(escapeChar);
dst.append('x');
Hex.hexByte(dst,c);
continue srcloop;
}
if(ch==escapeChar)
{
dst.append(escapeChar);
dst.append(escapeChar);
continue srcloop;
}
for(j=0;j parts = new ArrayList(len/2);
for(int end=off+len;off 0)
part = src.subSequence(start, off).toString();
else
part = "";
parts.add(part);
return parts.toArray(EMPTY_STRING_ARRAY);
}
public static String[] splitUnescaped(CharSequence src, int off, int len, char delim)
{
return splitUnescaped(src, off, len, delim, DEFAULT_ESCAPE);
}
public static String[] splitUnescaped(CharSequence src, int off, char delim)
{
return splitUnescaped(src, off, src.length()-off, delim, DEFAULT_ESCAPE);
}
public static String[] splitUnescaped(CharSequence src, char delim)
{
return splitUnescaped(src, 0, src.length(), delim, DEFAULT_ESCAPE);
}
public static Appendable joinEscaped(Appendable dst, char delim, char escapeChar, String... strs) throws IOException
{
char[] alsoEscape;
int i;
if(strs == null || strs.length==0)
return dst;
alsoEscape = new char[1];
alsoEscape[0] = delim;
for(i=0;i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy