package com.paessler.prtg.util; import java.text.CharacterIterator; import java.text.StringCharacterIterator; /****************************************************************************** * A library of static byte utility functions * @author JR Andreassen * @version 0.1 *****************************************************************************/ public abstract class CharacterUtility { /** Constant for use as Invalid poss or not found with indexOf() etc */ public static final int INVALID_POSSITION = -1; //----------------------------------------------------------- public static final char char_0 = '0'; public static final char char_1 = '1'; public static final char char_2 = '2'; public static final char char_3 = '3'; public static final char char_4 = '4'; public static final char char_5 = '5'; public static final char char_6 = '6'; public static final char char_7 = '7'; public static final char char_8 = '8'; public static final char char_9 = '9'; //----------------------------------------------------------- public static final char char_A = 'A'; public static final char char_a = 'a'; public static final char char_F = 'F'; public static final char char_f = 'f'; public static final char char_Z = 'Z'; public static final char char_z = 'z'; //----------------------------------------------------------- public static final char QuestionMark = '?'; public static final char Blank = ' '; public static final char Period = '.'; public static final char Comma = ','; public static final char Colon = ':'; public static final char SemiColon = ';'; public static final char Bang = '!'; public static final char CaretSign = '^'; public static final char AtSign = '@'; public static final char Asterisk = '*'; public static final char HashMark = '#'; public static final char PercentSign = '%'; public static final char DollarSign = '$'; public static final char Tilde = '~'; public static final char Bar = '|'; public static final char Plus = '+'; public static final char Equal = '='; public static final char Minus = '-'; public static final char Hyphen = Minus; public static final char Underscore = '_'; public static final char ForwardSlash = '/'; public static final char BackSlash = '\\'; public static final char Quote = '\''; public static final char LeftParen = '('; public static final char RightParen = ')'; public static final char LineFeed = '\n'; public static final char CarriageRet = '\r'; public static final char HorizTab = '\t'; public static final char LeftCurlyBrace = '{'; public static final char RightCurlyBrace= '}'; public static final char LeftSquareBrace= '['; public static final char RightSquareBrace= ']'; public static final char GreaterThan = '<'; public static final char LessThan = '>'; //----------------------------------------------------------- /** * Convert character to a readable String * @param ch Character to convert * @return String String representation of the character */ public static String toReadableString(char ch) { String retVal = null; if(ch <= ByteUtility.ASCII_CONTROL_US) { retVal = ByteUtility.controlTable[ch];} else { retVal = String.valueOf(ch); } return retVal; } //----------------------------------------------------------- /** * Convert character to a readable String * @param ch Character Array to convert * @return String String representation of the character array */ public static String toReadableString(char[] charr) { StringBuffer retVal = new StringBuffer(); for(int i = 0; i < charr.length; i++) { if(charr[i] <= ByteUtility.ASCII_CONTROL_US) { retVal.append(LeftSquareBrace); retVal.append(ByteUtility.controlTable[charr[i]]); retVal.append(RightSquareBrace); } else { retVal.append(charr[i]); } } // while return retVal.toString(); } //----------------------------------------------------------- /** * Find the Index of a character(case sensitive) in a character sequence * @param src Sequence of characters to look through * @param what What character to look for in the string * @return int Index of the character to look for. */ public static int indexOf(char[] src, char what) { return indexOf(src, what, true); } //----------------------------------------------------------- /** * Find the Index of a character in a character sequence * @param src Sequence of characters to look through * @param what What character to look for in the string * @param casesens What character to look for in the string * @return int Index of the character to look for. */ public static int indexOf(char[] src, char what, boolean casesens) { int retVal = CharacterIterator.DONE; for (int i = 0; i < src.length;i++) { if(equals(what, src[i], casesens)) { retVal = i; break; } } return retVal; } //----------------------------------------------------------- /** * Scans until Character.isWhitespace() fails * @param itr Iterator Source * @return int Count of chars skipped */ public static int eatWhitespace(CharacterIterator itr) { int retVal= 0; char curr = itr.current(); while (Character.isWhitespace(curr) && curr != CharacterIterator.DONE) { retVal++; curr = itr.next(); } return retVal; } //----------------------------------------------------------- /** * Scans until iter.current == term * @param itr Iterator Source * @param term Terminating char value * @return String Sequence/String of characters scanned */ public static String scanAllUntil(CharacterIterator itr, char term) { StringBuffer retVal = new StringBuffer(); char curr = itr.current(); while (curr != term && curr != CharacterIterator.DONE) { retVal.append(curr); curr = itr.next(); } return retVal.toString(); } //----------------------------------------------------------- /** * Converts a CharacterIterator to String * *** NOTE *** Does not Advance iterator. * @param itr Iterator Source * @return String String representation of characters */ public static String toString(CharacterIterator itr) { StringBuffer retVal = new StringBuffer(); int currIdx = itr.getIndex(); for(char curr = itr.current();curr != CharacterIterator.DONE; curr = itr.next()) { retVal.append(curr); } itr.setIndex(currIdx); return retVal.toString(); } //----------------------------------------------------------- /** * Gets substring (n characters from startingpoint. * *** NOTE *** Advances iterator. * @param itr Iterator Source * @param cnt Number of characters to fetch * @return String Sub-Sequence/String of characters scanned */ public static String substring(CharacterIterator itr, int cnt) { StringBuffer retVal = new StringBuffer(); char curr = itr.current(); // int currIdx = itr.getIndex(); for(int i = 0; i < cnt && curr != CharacterIterator.DONE; i++) { retVal.append(curr); curr = itr.next(); } // itr.setIndex(currIdx); return retVal.toString(); } //----------------------------------------------------------- /** * Scans/ignores until iter.current == term * @param itr Iterator Source * @param term Terminating char value * @return int Count of chars skipped */ public static int ignoreAllUntil(CharacterIterator itr, char term) { int retVal= 0; char curr = itr.current(); while (curr != term && curr != CharacterIterator.DONE) { retVal++; curr = itr.next(); } return retVal; } //----------------------------------------------------------- public static class javaIdentTermTest implements CharacterTest { /** * Tests wether character is a terminator */ public boolean isTerminatorCharacter(char ch) { return !Character.isJavaIdentifierPart(ch);} } // public static class javaIdentTermTest //----------------------------------------------------------- /** * Convert/extract number, scans until Character.isJavaIdentifierPart() fails * @param itr Iterator Source * @return String Number */ public static String getIdentifier(CharacterIterator itr) { return getTerminatedString(itr, new javaIdentTermTest()); } //----------------------------------------------------------- /** * Find starting index of String. * It will return the starting Index of the matching string. * ! NOTE ! Curren possition will be left at the character <b>after</b> of the matching string. * IE save starting pos before calling if it's needed. * @param iter Iterator Source * @param str Iterator Source * @param casesens Flag for wether to do a case sensitive match * @param exactmatch Flag for exact match * @return int The starting index of the match or 'CharacterIterator.DONE' if failed. */ public static int findStartIndex(CharacterIterator iter, String str, boolean casesens, boolean exactmatch) { int retVal = CharacterIterator.DONE; CharacterIterator strIter = new StringCharacterIterator(str); char litCurr = strIter.current(); int strStartIdx = strIter.getIndex(); int iterStartIdx = iter.getIndex(); char lastnonmatch = CharacterIterator.DONE; int startMatch = CharacterIterator.DONE; char itrCurr = iter.current(); // if( Log.DEBUG) // && myLog != null && myLog.getLevel() > 5 ) // { System.out.println("CharacterUtility.findStartIndex(itr, \""+str+"\", casese="+casesens+", exact="+exactmatch+")");} while(retVal == CharacterIterator.DONE) { if (litCurr == CharacterIterator.DONE) { if (exactmatch) { if (Character.isWhitespace(lastnonmatch)) { if(itrCurr == CharacterIterator.DONE) { retVal = startMatch;} else if (Character.isWhitespace(itrCurr)) { retVal = startMatch;} } // if (Character.isWhitespace(lastnonmatch)) } // if (isExactMatch()) else { retVal = startMatch; } // Success if (retVal != CharacterIterator.DONE) { break;} strIter.setIndex(strStartIdx); litCurr = strIter.current(); lastnonmatch = itrCurr; startMatch = CharacterIterator.DONE; } // if (litCurr == CharacterIterator.DONE) else if(!CharacterUtility.equals(litCurr, itrCurr, casesens)) { lastnonmatch = itrCurr; strIter.setIndex(strStartIdx); litCurr = strIter.current(); startMatch= CharacterIterator.DONE; } // else if(litCurr != itrCurr) else if(CharacterUtility.equals(litCurr, itrCurr, casesens)) { litCurr = strIter.next(); if (startMatch == CharacterIterator.DONE) { startMatch = iter.getIndex();} } // else if(litCurr == itrCurr) if (itrCurr == CharacterIterator.DONE) { break;} else { itrCurr = iter.next();} } // while return retVal; } // findStartIndex // --------------------------------------------------------------------------- /** * This method finds a matching pair of token's * <PRE> * findMatching("....(xxx)....", 0, "(", ")"); * Should then return the possition index of ')'. * </PRE> * ! NOTE ! Curren possition will be left at the character <b>after</b> of the matching string. * IE save starting pos before calling if it's needed. * @param iter Source CharacterIterator * @param starttoken Start token * @param endtoken End token * @return int ending Token Index */ public static int findMatching(CharacterIterator iter, char starttoken, char endtoken) { int retVal = CharacterIterator.DONE; int level = 0; // System.out.println("CharacterUtility.findMatching(Iter["+iter.getIndex()+"=\'"+iter.current()+"\']) starttoken="+starttoken+", endtoken="+endtoken); for(char itrCurr = iter.current(); itrCurr != CharacterIterator.DONE;itrCurr = iter.next()) { // System.out.println("CharacterUtility.findMatching(Iter["+iter.getIndex()+"=\'"+iter.current()+"\'])"); if(CharacterUtility.equals(itrCurr, endtoken)) { if (level == 0) { retVal = iter.getIndex(); break; } else { level--; } } else if(CharacterUtility.equals(itrCurr, starttoken)) { level++; } } return retVal; } //----------------------------------------------------------- /** * Convert/extract number, scans until Character.isJavaIdentifierPart() fails * @param itr Iterator Source * @return String Number */ public static String getTerminatedString(CharacterIterator itr, CharacterTest test) { StringBuffer retVal= new StringBuffer(); char curr = itr.current(); while (!test.isTerminatorCharacter(curr) && curr != CharacterIterator.DONE) { retVal.append(curr); curr = itr.next(); } return retVal.toString(); } //----------------------------------------------------------- /** * Convert/extract number, scans until Character.isDigit() fails * @param itr Iterator Source * @return String Number */ public static String getNumber(CharacterIterator itr) { StringBuffer retVal= new StringBuffer(); char curr = itr.current(); while (Character.isDigit(curr) && curr != CharacterIterator.DONE) { retVal.append(curr); curr = itr.next(); } return retVal.toString(); } //----------------------------------------------------------- /** * Returns the next character in the sequence without * advancing the current. * @param itr Iterator Source * @return char Next character */ public static char peek(CharacterIterator itr) { int savePos = itr.getIndex(); char retVal = itr.next(); itr.setIndex(savePos); return retVal; } //----------------------------------------------------------- /** * Get ASCII value for the given character * @param ch Iterator Source * @return byte Ascii value of the character */ /* *** NOT ACCURATE public static byte getASCII(char ch) { byte retVal= (byte) ch; return retVal; } */ //----------------------------------------------------------- /** * Get ASCII value for the given character * @param ch Iterator Source * @return byte Ascii value of the character */ /* *** NOT ACCURATE public static byte getASCII(Character ch) { byte retVal= (byte) ch.charValue(); return retVal; } */ //----------------------------------------------------------- /** * Equality check with case sensitivity option * @param a Character a * @param b Character b * @return boolean equality */ public static boolean equals(char a, char b) { return equals(a, b, false); } //----------------------------------------------------------- /** * Equality check with case sensitivity option * @param a Character a * @param b Character b * @param casesensitive Flag to check case insensitive * @return boolean equality */ public static boolean equals(char a, char b, boolean casesensitive) { boolean retVal = (a==b); if (!retVal && !casesensitive) { retVal = (Character.toUpperCase(a) == Character.toUpperCase(b));} return retVal; } //////////////////////////////////////////////////////////////////// /** * returns true iff the char given is in the ascii set */ public static boolean isASCIIChar(char c) { return c >= 0 && c <= 127; //use the posix regular expression.. //return Character.toString(c).matches("\\p{ASCII}"); }//method } // class