internal static boolean containsOnlyValidXChars( PhoneNumber number, String candidate, PhoneNumberUtil util) { // The characters 'x' and 'X' can be (1) a carrier code, in which case they always precede the // national significant number or (2) an extension sign, in which case they always precede the // extension number. We assume a carrier code is more than 1 digit, so the first case has to // have more than 1 consecutive 'x' or 'X', whereas the second case can only have exactly 1 'x' // or 'X'. We ignore the character if it appears as the last character of the string. for (int index = 0; index < candidate.length() - 1; index++) { char charAtIndex = candidate.charAt(index); if (charAtIndex == 'x' || charAtIndex == 'X') { char charAtNextIndex = candidate.charAt(index + 1); if (charAtNextIndex == 'x' || charAtNextIndex == 'X') { // This is the carrier code case, in which the 'X's always precede the national // significant number. index++; if (util.isNumberMatch(number, candidate.substring(index)) != MatchType.NSN_MATCH) { return(false); } // This is the extension sign case, in which the 'x' or 'X' should always precede the // extension number. } else if (!PhoneNumberUtil.normalizeDigitsOnly(candidate.substring(index)).equals( number.getExtension())) { return(false); } } } return(true); }
/** * Parses a phone number from the {@code candidate} using {@link PhoneNumberUtil#parse} and * verifies it matches the requested {@link #leniency}. If parsing and verification succeed, a * corresponding {@link PhoneNumberMatch} is returned, otherwise this method returns null. * * @param candidate the candidate match * @param offset the offset of {@code candidate} within {@link #text} * @return the parsed and validated phone number match, or null */ private PhoneNumberMatch parseAndVerify(String candidate, int offset) { try { // Check the candidate doesn't contain any formatting which would indicate that it really // isn't a phone number. if (!MATCHING_BRACKETS.matcher(candidate).matches()) { return(null); } // If leniency is set to VALID or stricter, we also want to skip numbers that are surrounded // by Latin alphabetic characters, to skip cases like abc8005001234 or 8005001234def. if (leniency.compareTo(Leniency.VALID) >= 0) { // If the candidate is not at the start of the text, and does not start with phone-number // punctuation, check the previous character. if (offset > 0 && !LEAD_CLASS.matcher(candidate).lookingAt()) { char previousChar = text.charAt(offset - 1); // We return null if it is a latin letter or an invalid punctuation symbol. if (isInvalidPunctuationSymbol(previousChar) || isLatinLetter(previousChar)) { return(null); } } int lastCharIndex = offset + candidate.length(); if (lastCharIndex < text.length()) { char nextChar = text.charAt(lastCharIndex); if (isInvalidPunctuationSymbol(nextChar) || isLatinLetter(nextChar)) { return(null); } } } PhoneNumber number = phoneUtil.parseAndKeepRawInput(candidate, preferredRegion); if (leniency.verify(number, candidate, phoneUtil)) { // We used parseAndKeepRawInput to create this number, but for now we don't return the extra // values parsed. TODO: stop clearing all values here and switch all users over // to using rawInput() rather than the rawString() of PhoneNumberMatch. number.clearCountryCodeSource(); number.clearRawInput(); number.clearPreferredDomesticCarrierCode(); return(new PhoneNumberMatch(offset, candidate, number)); } } catch (NumberParseException) { // ignore and continue } return(null); }
/* public void writeFloat(float v) { writeInt(Float.floatToIntBits(v)); } public void writeDouble(double v) { writeLong(Double.doubleToLongBits(v)); } */ public void writeBytes(String s) { int len = s.length(); for (int i = 0 ; i < len ; i++) { @out.write((byte)s.charAt(i)); } incCount(len); }
public static Long decode(String nm) { int radix = 10; int index = 0; boolean negative = false; Long result; if (nm.length() == 0) { throw new NumberFormatException("Zero length string"); } char firstChar = nm.charAt(0); // Handle sign, if present if (firstChar == '-') { negative = true; index++; } else if (firstChar == '+') { index++; } // Handle radix specifier, if present if (nm.startsWith(new String("0x"), index) || nm.startsWith(new String("0X"), index)) { index += 2; radix = 16; } else if (nm.startsWith(new String("#"), index)) { index++; radix = 16; } else if (nm.startsWith(new String("0"), index) && nm.length() > 1 + index) { index++; radix = 8; } if (nm.startsWith(new String("-"), index) || nm.startsWith(new String("+"), index)) { throw new NumberFormatException("Sign character in wrong position"); } try { result = Long.valueOf(nm.substring(index), radix); result = negative ? Long.valueOf(-result.longValue()) : result; } catch (NumberFormatException) { // If number is Long.MIN_VALUE, we'll end up here. The next line // handles this case, and causes any genuine format error to be // rethrown. String constant = negative ? new String("-" + nm.substring(index)) : nm.substring(index); result = Long.valueOf(constant, radix); } return(result); }
/* * public void writeFloat(float v) { * writeInt(Float.floatToIntBits(v)); * } * public void writeDouble(double v) { * writeLong(Double.doubleToLongBits(v)); * } */ public void writeBytes(String s) { int len = s.length(); for (int i = 0; i < len; i++) { @out.write((byte)s.charAt(i)); } incCount(len); }
public void writeChars(String s) { int len = s.length(); for (int i = 0; i < len; i++) { int v = s.charAt(i); @out.write((int)(((uint)v) >> 8) & 0xFF); @out.write((int)(((uint)v) >> 0) & 0xFF); } incCount(len * 2); }
public static String quoteReplacement(String s) { if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1)) return s; StringBuilder sb = new StringBuilder(); for (int i=0; i<s.length(); i++) { char c = s.charAt(i); if (c == '\\' || c == '$') { sb.append('\\'); } sb.append(c); } return sb.toString(); }
/** * Returns the current position in the partially formatted phone number of the character which was * previously passed in as the parameter of {@link #inputDigitAndRememberPosition}. */ public int getRememberedPosition() { if (!ableToFormat) { return(originalPosition); } int accruedInputIndex = 0, currentOutputIndex = 0; while (accruedInputIndex < positionToRemember && currentOutputIndex < currentOutput.length()) { if (accruedInputWithoutFormatting.charAt(accruedInputIndex) == currentOutput.charAt(currentOutputIndex)) { accruedInputIndex++; } currentOutputIndex++; } return(currentOutputIndex); }
public static String quoteReplacement(String s) { if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1)) { return(s); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '\\' || c == '$') { sb.append('\\'); } sb.append(c); } return(sb.toString()); }
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) throw new InvalidOperationException("No match available"); // Process substitution string to replace group references with groups int cursor = 0; StringBuilder result = new StringBuilder(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // A StringIndexOutOfBoundsException is thrown if // this "$" is the last character in replacement // string in current implementation, a IAE might be // more appropriate. nextChar = replacement.charAt(cursor); int refNum = -1; if (nextChar == '{') { cursor++; StringBuilder gsb = new StringBuilder(); while (cursor < replacement.length()) { nextChar = replacement.charAt(cursor); if (ASCII.isLower(nextChar) || ASCII.isUpper(nextChar) || ASCII.isDigit(nextChar)) { gsb.append(nextChar); cursor++; } else { break; } } if (gsb.length() == 0) throw new IllegalArgumentException( "named capturing group has 0 length name"); if (nextChar != '}') throw new IllegalArgumentException( "named capturing group is missing trailing '}'"); String gname = gsb.toString(); if (ASCII.isDigit(gname.charAt(0))) throw new IllegalArgumentException( "capturing group name {" + gname + "} starts with digit character"); if (!parentPattern.namedGroups().containsKey(gname)) throw new IllegalArgumentException( "No group with name {" + gname + "}"); refNum = parentPattern.namedGroups().get(gname); cursor++; } else { // The first number is always a group refNum = (int)nextChar - '0'; if ((refNum < 0)||(refNum > 9)) throw new IllegalArgumentException( "Illegal group reference"); cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0)||(nextDigit > 9)) { // not a number break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } } // Append group if (start(refNum) != -1 && end(refNum) != -1) result.append(text, start(refNum), end(refNum)); } else { result.append(nextChar); cursor++; } } // Append the intervening text sb.append(text, lastAppendPosition, first); // Append the match substitution sb.append(result); lastAppendPosition = last; return this; }
public static long parseLong(String s, int radix) { if (s == null) { throw new NumberFormatException("null"); } if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } long result = 0; boolean negative = false; int i = 0, len = s.length(); long limit = -Long.MAX_VALUE; long multmin; int digit; if (len > 0) { char firstChar = s.charAt(0); if (firstChar < '0') // Possible leading "+" or "-" { if (firstChar == '-') { negative = true; limit = Long.MIN_VALUE; } else if (firstChar != '+') { throw NumberFormatException.forInputString(s); } if (len == 1) // Cannot have lone "+" or "-" { throw NumberFormatException.forInputString(s); } i++; } multmin = limit / radix; while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++), radix); if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); } result -= digit; } } else { throw NumberFormatException.forInputString(s); } return(negative ? result : -result); }
public void writeChars(String s) { int len = s.length(); for (int i = 0 ; i < len ; i++) { int v = s.charAt(i); @out.write((int)(((uint)v) >> 8) & 0xFF); @out.write((int)(((uint)v) >> 0) & 0xFF); } incCount(len * 2); }
static int writeUTF(String str, DataOutputStream @out) { int strlen = str.length(); int utflen = 0; int c, count = 0; /* use charAt instead of copying String to char array */ int i; for (i = 0; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { utflen++; } else if (c > 0x07FF) { utflen += 3; } else { utflen += 2; } } if (utflen > 65535) throw new Exception( "encoded string too long: " + utflen + " bytes"); byte[] bytearr = null; if (@out is DataOutputStream) { DataOutputStream dos = (DataOutputStream)@out; if(dos.bytearr == null || (dos.bytearr.Length < (utflen+2))) dos.bytearr = new byte[(utflen*2) + 2]; bytearr = dos.bytearr; } else { bytearr = new byte[utflen+2]; } bytearr[count++] = (byte) ((int)(((uint)utflen) >> 8) & 0xFF); bytearr[count++] = (byte) ((int)(((uint)utflen) >> 0) & 0xFF); i=0; for (i=0; i<strlen; i++) { c = str.charAt(i); if (!((c >= 0x0001) && (c <= 0x007F))) break; bytearr[count++] = (byte) c; } for (;i < strlen; i++){ c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { bytearr[count++] = (byte) c; } else if (c > 0x07FF) { bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F)); bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); } else { bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); } } @out.write(bytearr, 0, utflen+2); return utflen + 2; }
static int writeUTF(String str, DataOutputStream @out) { int strlen = str.length(); int utflen = 0; int c, count = 0; /* use charAt instead of copying String to char array */ int i; for (i = 0; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { utflen++; } else if (c > 0x07FF) { utflen += 3; } else { utflen += 2; } } if (utflen > 65535) { throw new Exception( "encoded string too long: " + utflen + " bytes"); } byte[] bytearr = null; if (@out is DataOutputStream) { DataOutputStream dos = (DataOutputStream)@out; if (dos.bytearr == null || (dos.bytearr.Length < (utflen + 2))) { dos.bytearr = new byte[(utflen * 2) + 2]; } bytearr = dos.bytearr; } else { bytearr = new byte[utflen + 2]; } bytearr[count++] = (byte)((int)(((uint)utflen) >> 8) & 0xFF); bytearr[count++] = (byte)((int)(((uint)utflen) >> 0) & 0xFF); i = 0; for (i = 0; i < strlen; i++) { c = str.charAt(i); if (!((c >= 0x0001) && (c <= 0x007F))) { break; } bytearr[count++] = (byte)c; } for (; i < strlen; i++) { c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { bytearr[count++] = (byte)c; } else if (c > 0x07FF) { bytearr[count++] = (byte)(0xE0 | ((c >> 12) & 0x0F)); bytearr[count++] = (byte)(0x80 | ((c >> 6) & 0x3F)); bytearr[count++] = (byte)(0x80 | ((c >> 0) & 0x3F)); } else { bytearr[count++] = (byte)(0xC0 | ((c >> 6) & 0x1F)); bytearr[count++] = (byte)(0x80 | ((c >> 0) & 0x3F)); } } @out.write(bytearr, 0, utflen + 2); return(utflen + 2); }
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) { throw new InvalidOperationException("No match available"); } // Process substitution string to replace group references with groups int cursor = 0; StringBuilder result = new StringBuilder(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // A StringIndexOutOfBoundsException is thrown if // this "$" is the last character in replacement // string in current implementation, a IAE might be // more appropriate. nextChar = replacement.charAt(cursor); int refNum = -1; if (nextChar == '{') { cursor++; StringBuilder gsb = new StringBuilder(); while (cursor < replacement.length()) { nextChar = replacement.charAt(cursor); if (ASCII.isLower(nextChar) || ASCII.isUpper(nextChar) || ASCII.isDigit(nextChar)) { gsb.append(nextChar); cursor++; } else { break; } } if (gsb.length() == 0) { throw new IllegalArgumentException( "named capturing group has 0 length name"); } if (nextChar != '}') { throw new IllegalArgumentException( "named capturing group is missing trailing '}'"); } String gname = gsb.toString(); if (ASCII.isDigit(gname.charAt(0))) { throw new IllegalArgumentException( "capturing group name {" + gname + "} starts with digit character"); } if (!parentPattern.namedGroups().containsKey(gname)) { throw new IllegalArgumentException( "No group with name {" + gname + "}"); } refNum = parentPattern.namedGroups().get(gname); cursor++; } else { // The first number is always a group refNum = (int)nextChar - '0'; if ((refNum < 0) || (refNum > 9)) { throw new IllegalArgumentException( "Illegal group reference"); } cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0) || (nextDigit > 9)) // not a number { break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } } // Append group if (start(refNum) != -1 && end(refNum) != -1) { result.append(text, start(refNum), end(refNum)); } } else { result.append(nextChar); cursor++; } } // Append the intervening text sb.append(text, lastAppendPosition, first); // Append the match substitution sb.append(result); lastAppendPosition = last; return(this); }
public static int parseInt(String s, int radix) { /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */ if (s == null) { throw new NumberFormatException("null"); } if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } int result = 0; boolean negative = false; int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; if (len > 0) { char firstChar = s.charAt(0); if (firstChar < '0') // Possible leading "+" or "-" { if (firstChar == '-') { negative = true; limit = Integer.MIN_VALUE; } else if (firstChar != '+') { throw NumberFormatException.forInputString(s); } if (len == 1) // Cannot have lone "+" or "-" { throw NumberFormatException.forInputString(s); } i++; } multmin = limit / radix; while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++), radix); if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); } result -= digit; } } else { throw NumberFormatException.forInputString(s); } return(negative ? result : -result); }