/** * get next format token Note: Supported format specifieres i,d,u - decimal o - octal x,X - * hexa-decimal c - character e,E,f,F,g,G,a,A - float/double s - string S - string with quotes y - * boolean Supported options: #,0,-, ,+,* - flags 1-9 - width . - precision {<name>}s - * enumeration <name> <x>s, <x>S - quoting character <x> <space>s,<space>S - accept spaces, ignore * quotes *s - accept all to eol h,l,j,z,t - length modifier * * @param format format string * @param formatIndex index in format string * @param formatToken format token * @return next format string index */ private static int getNextFormatToken(String format, int formatIndex, FormatToken formatToken) { formatToken.token = new StringBuffer(); formatToken.length = 0; formatToken.alternateFlag = false; formatToken.zeroPaddingFlag = false; formatToken.leftAdjustedFlag = false; formatToken.blankFlag = false; formatToken.greedyFlag = false; formatToken.width = 0; formatToken.precision = 0; formatToken.lengthType = LengthTypes.INTEGER; formatToken.quoteChar = '\0'; formatToken.enumClassName = null; formatToken.conversionChar = '\0'; /* format start character */ assert format.charAt(formatIndex) == '%'; formatToken.token.append('%'); formatIndex++; if (formatIndex >= format.length()) { return -1; } /* flags */ while ((formatIndex < format.length()) && ((format.charAt(formatIndex) == '#') || (format.charAt(formatIndex) == '0') || (format.charAt(formatIndex) == '-') || (format.charAt(formatIndex) == ' ') || (format.charAt(formatIndex) == '+') || (format.charAt(formatIndex) == '*'))) { formatToken.token.append(format.charAt(formatIndex)); switch (format.charAt(formatIndex)) { case '#': formatToken.alternateFlag = true; break; case '0': formatToken.zeroPaddingFlag = true; break; case '-': formatToken.leftAdjustedFlag = true; break; case ' ': formatToken.blankFlag = true; break; case '+': formatToken.blankFlag = true; break; case '*': formatToken.greedyFlag = true; break; default: return -1; } formatIndex++; } if (formatIndex >= format.length()) { return -1; } /* width, precision */ while ((formatIndex < format.length()) && (Character.isDigit(format.charAt(formatIndex)))) { formatToken.token.append(format.charAt(formatIndex)); formatToken.width = formatToken.width * 10 + (format.charAt(formatIndex) - '0'); formatIndex++; } if (formatIndex >= format.length()) { return -1; } /* precision */ if (format.charAt(formatIndex) == '.') { formatToken.token.append(format.charAt(formatIndex)); formatIndex++; while ((formatIndex < format.length()) && Character.isDigit(format.charAt(formatIndex))) { formatToken.token.append(format.charAt(formatIndex)); formatToken.precision = formatToken.precision * 10 + (format.charAt(formatIndex) - '0'); formatIndex++; } } /* quoting character */ if ((formatIndex + 1 < format.length()) && (format.charAt(formatIndex) != '{') && ((format.charAt(formatIndex + 1) == 's') || (format.charAt(formatIndex + 1) == 'S'))) { formatToken.quoteChar = format.charAt(formatIndex); formatIndex++; } /* length modifier */ if ((formatIndex + 1 < format.length()) && (format.charAt(formatIndex) == 'h') && (format.charAt(formatIndex + 1) == 'h')) { formatToken.token.append(format.charAt(formatIndex + 0)); formatToken.token.append(format.charAt(formatIndex + 1)); formatToken.lengthType = LengthTypes.INTEGER; formatIndex += 2; } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'h')) { formatToken.token.append(format.charAt(formatIndex)); formatToken.lengthType = LengthTypes.INTEGER; formatIndex++; } else if ((formatIndex + 1 < format.length()) && (format.charAt(formatIndex) == 'l') && (format.charAt(formatIndex + 1) == 'l')) { formatToken.token.append(format.charAt(formatIndex + 0)); formatToken.token.append(format.charAt(formatIndex + 1)); formatToken.lengthType = LengthTypes.LONG; formatIndex += 2; } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'l')) { formatToken.token.append(format.charAt(formatIndex)); formatToken.lengthType = LengthTypes.LONG; formatIndex++; } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'j')) { formatToken.token.append(format.charAt(formatIndex)); formatToken.lengthType = LengthTypes.INTEGER; formatIndex++; } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 'z')) { formatToken.token.append(format.charAt(formatIndex)); formatToken.lengthType = LengthTypes.INTEGER; formatIndex++; } else if ((formatIndex < format.length()) && (format.charAt(formatIndex) == 't')) { formatToken.token.append(format.charAt(formatIndex)); formatToken.lengthType = LengthTypes.INTEGER; formatIndex++; } if ((formatIndex < format.length()) && (format.charAt(formatIndex) == '{')) { /* enum name */ formatToken.token.append(format.charAt(formatIndex)); formatIndex++; StringBuffer buffer = new StringBuffer(); while ((formatIndex < format.length()) && (format.charAt(formatIndex) != '}')) { char ch = format.charAt(formatIndex); formatToken.token.append(ch); buffer.append((ch != '.') ? ch : '$'); formatIndex++; } formatIndex++; formatToken.enumClassName = buffer.toString(); } if (formatIndex >= format.length()) { return -1; } /* conversion character */ switch (format.charAt(formatIndex)) { case 'S': formatToken.token.append('s'); formatToken.conversionChar = 'S'; break; default: formatToken.token.append(format.charAt(formatIndex)); formatToken.conversionChar = format.charAt(formatIndex); break; } formatIndex++; return formatIndex; }