stringmodule.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,731 行 · 第 1/5 页
JAVA
2,731 行
char ch = 0; while (i < len && (ch = localeName.charAt(i++)) != '-' && ch != '_') { sb.append(ch); } language = sb.toString(); sb.clear(); while (i < len && (ch = localeName.charAt(i)) != '.' && ch != '@') { sb.append(ch); i++; } if (ch == '.') i++; country = sb.toString(); sb.clear(); while (i < len && (ch = localeName.charAt(i)) != '@') { sb.append(ch); i++; } if (sb.length() > 0) charset = sb.toString(); if (i + 1 < len) variant = localeName.substring(i + 1); Locale locale; // java versions >= 1.5 should automatically use the euro sign if (variant != null && ! variant.equalsIgnoreCase("euro")) locale = new Locale(language, country, variant); else if (country != null) locale = new Locale(language, country); else locale = new Locale(language); if (isValidLocale(locale)) return new QuercusLocale(locale, charset); else return null; } /** * Returns true if the locale is supported. */ private static boolean isValidLocale(Locale locale) { Locale []validLocales = Locale.getAvailableLocales(); for (int i = 0; i < validLocales.length; i++) { if (validLocales[i].equals(locale)) { return true; } } return false; } /** * returns the md5 hash * * @param source the string * @param rawOutput if true, return the raw binary * * @return a string of imploded values */ public static Value sha1(Env env, String source, @Optional boolean rawOutput) { if (source == null) source = ""; try { MessageDigest md = MessageDigest.getInstance("SHA1"); // XXX: iso-8859-1 for (int i = 0; i < source.length(); i++) { char ch = source.charAt(i); md.update((byte) ch); } byte []digest = md.digest(); return hashToValue(env, digest, rawOutput); } catch (Exception e) { throw new QuercusException(e); } } /** * returns the md5 hash * * @param source the string * @param rawOutput if true, return the raw binary * * @return a string of imploded values */ public static Value sha1_file(Env env, Path source, @Optional boolean rawOutput) { try { MessageDigest md = MessageDigest.getInstance("SHA1"); InputStream is = null; try { is = source.openRead(); int d; while ((d = is.read()) >= 0) { md.update((byte) d); } byte []digest = md.digest(); return hashToValue(env, digest, rawOutput); } catch (IOException e) { log.log(Level.FINE, e.toString(), e); return BooleanValue.FALSE; } finally { try { if (is != null) is.close(); } catch (IOException e) { } } } catch (Exception e) { throw new QuercusException(e); } } private static Value hashToValue(Env env, byte []bytes, boolean isBinary) { if (isBinary) { StringValue v = env.createBinaryBuilder(); v.append(bytes, 0, bytes.length); return v; } else { StringValue v = env.createUnicodeBuilder(); for (int i = 0; i < bytes.length; i++) { int ch = bytes[i]; int d1 = (ch >> 4) & 0xf; int d2 = (ch) & 0xf; if (d1 < 10) v.append((char) ('0' + d1)); else v.append((char) ('a' + d1 - 10)); if (d2 < 10) v.append((char) ('0' + d2)); else v.append((char) ('a' + d2 - 10)); } return v; } } // XXX: similar_text private static final char[] SOUNDEX_VALUES = "01230120022455012623010202".toCharArray(); public static Value soundex(StringValue string) { int length = string.length(); if (length == 0) return BooleanValue.FALSE; StringValue result = string.createStringBuilder(); int count = 0; char lastCode = 0; for (int i = 0; i < length && count < 4; i++) { char ch = toUpperCase(string.charAt(i)); if ('A' <= ch && ch <= 'Z') { char code = SOUNDEX_VALUES[ch - 'A']; if (count == 0) { result.append(ch); count++; } else if (code != '0' && code != lastCode) { result.append(code); count++; } lastCode = code; } } for (; count < 4; count++) { result.append('0'); } return result; } /** * Print to a string with a formatter * * @param format the format string * @param args the format arguments * * @return the formatted string */ public static Value sprintf(Env env, StringValue format, Value []args) { ArrayList<PrintfSegment> segments = parsePrintfFormat(env, format); StringValue sb = format.createStringBuilder(); for (PrintfSegment segment : segments) segment.apply(sb, args); return sb; } private static ArrayList<PrintfSegment> parsePrintfFormat(Env env, StringValue format) { ArrayList<PrintfSegment> segments = new ArrayList<PrintfSegment>(); StringBuilder sb = new StringBuilder(); StringBuilder flags = new StringBuilder(); int length = format.length(); int index = 0; for (int i = 0; i < length; i++) { char ch = format.charAt(i); if (i + 1 < length && ch == '%') { // The C printf silently ignores invalid flags, so we need to // remove them if present. sb.append(ch); boolean isLeft = false; boolean isAlt = false; boolean isZero = false; flags.setLength(0); int j = i + 1; loop: for (; j < length; j++) { ch = format.charAt(j); switch (ch) { case '-': isLeft = true; break; case '#': isAlt = true; break; case '0': isZero = true; flags.append(ch); break; case '+': case ' ': case ',': case '(': flags.append(ch); break; default: break loop; } } int head = j; loop: for (; j < length; j++) { ch = format.charAt(j); switch (ch) { case '%': i = j; segments.add(new TextPrintfSegment(sb)); sb.setLength(0); break loop; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '$': break; case 'b': case 'B': if (isLeft) sb.append('-'); if (isAlt) sb.append('#'); sb.append(format, head, j); sb.append(ch); i = j; break loop; case 's': case 'S': sb.setLength(sb.length() - 1); segments.add(new StringPrintfSegment(sb, isLeft || isAlt, isZero, ch == 'S', format.substring(head, j).toString(), index++)); sb.setLength(0); i = j; break loop; case 'c': case 'C': sb.setLength(sb.length() - 1); segments.add(new CharPrintfSegment(sb, isLeft || isAlt, isZero, ch == 'C', format.substring(head, j).toString(), index++)); sb.setLength(0); i = j; break loop; case 'i': case 'u': ch = 'd'; case 'd': case 'x': case 'o': case 'X': sb.setLength(sb.length() - 1); if (sb.length() > 0) segments.add(new TextPrintfSegment(sb)); sb.setLength(0); if (isLeft) sb.append('-'); if (isAlt) sb.append('#'); sb.append(flags); sb.append(format, head, j); sb.append(ch); segments.add(LongPrintfSegment.create(env, sb.toString(), index++)); sb.setLength(0); i = j; break loop; case 'e': case 'E': case 'f': case 'g': case 'G': case 'F': QuercusLocale locale = null; if (ch == 'F') ch = 'f'; else locale = env.getLocaleInfo().getNumeric(); sb.setLength(sb.length() - 1); if (sb.length() > 0) segments.add(new TextPrintfSegment(sb)); sb.setLength(0); if (isLeft) sb.append('-'); if (isAlt) sb.append('#'); sb.append(flags); sb.append(format, head, j); sb.append(ch); segments.add(new DoublePrintfSegment(sb.toString(), index++, locale)); sb.setLength(0); i = j; break loop; default: if (isLeft) sb.append('-'); if (isAlt) sb.append('#'); sb.append(flags); sb.append(format, head, j); sb.append(ch); i = j; break loop; } } } else sb.append(ch); } if (sb.length() > 0) segments.add(new TextPrintfSegment(sb)); return segments; } /** * scans a string * * @param format the format string * @param args the format arguments * * @return the formatted string */ public static Value sscanf(Env env, StringValue string, StringValue format, @Optional @Reference Value []args) { int fmtLen = format.length(); int strlen = string.length(); int sIndex = 0; int fIndex = 0; boolean isAssign = args.length != 0; int argIndex = 0; ArrayValue array = new ArrayValueImpl(); while (fIndex < fmtLen) { char ch = format.charAt(fIndex++); if (isWhitespace(ch)) { for (; (fIndex < fmtLen && isWhitespace(ch = format.charAt(fIndex))); fIndex++) { } ch = string.charAt(sIndex); if (! isWhitespace(ch)) { // XXX: return false? return sscanfReturn(env, array, args, argIndex, isAssign); } for (sIndex++; sIndex < strlen && isWhitespace(string.charAt(sIndex)); sIndex++) { } } else if (ch == '%') { int maxLen = -1; loop: while (fIndex < fmtLen) { ch = format.charAt(fIndex++); if (sIndex >= strlen) { array.append(NullValue.NULL); break loop; } Value obj; if (isAssign) { if (argIndex < args.length) obj = args[argIndex++]; else { env.warning(L.l("not enough vars passed in")); break loop; } } else obj = array; switch (ch) { case '%': if (string.charAt(sIndex) != '%') return sscanfReturn(env, array, args, argIndex, isAssign); else break loop; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (maxLen < 0) maxLen = 0; maxLen = 10 * maxLen + ch - '0'; break; case 's': sIndex = sscanfString(string, sIndex, maxLen, obj, isAssign); break loop; case 'c': if ( maxLen < 0) maxLen = 1; sIndex = sscanfString(string, sIndex, maxLen, obj, isAssign); break loop; case 'd': sIndex = sscanfInteger(string, sIndex, maxLen, obj, isAssign, 10, false); break loop; case 'u': sIndex = sscanfInteger(string, sIndex, maxLen, obj, isAssign, 10, true); break loop; case 'o': sIndex = sscanfInteger(string, sIndex, maxLen, obj, isAssign, 8, false); break loop; case 'x': case 'X': sIndex = sscanfHex(string, sIndex, maxLen, obj, isAssign); break loop; case 'e': case 'f': sIndex = sscanfScientific(string, sIndex, maxLen, obj, isAssign); break loop; default: log.fine(L.l("'{0}' is a bad sscanf string.", format)); env.warning(L.l("'{0}' is a bad sscanf string.", format)); return isAssign ? LongValue.create(argIndex) : array; } } } else if (ch == string.charAt(sIndex)) { sIndex++; } else return sscanfReturn(env, array, args, argIndex, isAssign); } return sscanfReturn(env, array, args, argIndex, isAssign); } private static Value sscanfReturn(Env env, ArrayValue array, Value []args, int argIndex, boolean isAssign)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?