stringmodule.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,731 行 · 第 1/5 页
JAVA
2,731 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.quercus.lib.string;import com.caucho.quercus.QuercusException;import com.caucho.quercus.QuercusModuleException;import com.caucho.quercus.annotation.NotNull;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.Reference;import com.caucho.quercus.annotation.UsesSymbolTable;import com.caucho.quercus.env.*;import com.caucho.quercus.lib.file.BinaryOutput;import com.caucho.quercus.lib.file.FileModule;import com.caucho.quercus.module.AbstractQuercusModule;import com.caucho.util.CharBuffer;import com.caucho.util.L10N;import com.caucho.util.RandomUtil;import com.caucho.vfs.ByteToChar;import com.caucho.vfs.Path;import java.io.IOException;import java.io.InputStream;import java.nio.charset.Charset;import java.security.MessageDigest;import java.text.DecimalFormat;import java.text.DecimalFormatSymbols;import java.text.NumberFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Comparator;import java.util.Currency;import java.util.Iterator;import java.util.Locale;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;import java.util.zip.CRC32;/** * PHP functions implemented from the string module */public class StringModule extends AbstractQuercusModule { private static final Logger log = Logger.getLogger(StringModule.class.getName()); private static final L10N L = new L10N(StringModule.class); public static final int CRYPT_SALT_LENGTH = 2; public static final int CRYPT_STD_DES = 0; public static final int CRYPT_EXT_DES = 0; public static final int CRYPT_MD5 = 0; public static final int CRYPT_BLOWFISH = 0; public static final int CHAR_MAX = 1; public static final int LC_CTYPE = 1; public static final int LC_NUMERIC = 2; public static final int LC_TIME = 3; public static final int LC_COLLATE = 4; public static final int LC_MONETARY = 5; public static final int LC_ALL = 6; public static final int LC_MESSAGES = 7; public static final int STR_PAD_LEFT = 1; public static final int STR_PAD_RIGHT = 0; public static final int STR_PAD_BOTH = 2; private static final DecimalFormatSymbols DEFAULT_DECIMAL_FORMAT_SYMBOLS ; /** * Escapes a string using C syntax. * * @see #stripcslashes * * @param source the source string to convert * @param characters the set of characters to convert * @return the escaped string */ public static StringValue addcslashes(StringValue source, String characters) { if (characters == null) characters = ""; boolean []bitmap = parseCharsetBitmap(characters); int length = source.length(); StringValue sb = source.createStringBuilder(length * 5 / 4); for (int i = 0; i < length; i++) { char ch = source.charAt(i); if (ch >= 256 || ! bitmap[ch]) { sb.append(ch); continue; } switch (ch) { case 0x07: sb.append("\\a"); break; case '\b': sb.append("\\b"); break; case '\t': sb.append("\\t"); break; case '\n': sb.append("\\n"); break; case 0xb: sb.append("\\v"); break; case '\f': sb.append("\\f"); break; case '\r': sb.append("\\r"); break; default: if (ch < 0x20 || ch >= 0x7f) { // save as octal sb.append("\\"); sb.append((char) ('0' + ((ch >> 6) & 7))); sb.append((char) ('0' + ((ch >> 3) & 7))); sb.append((char) ('0' + ((ch) & 7))); break; } else { sb.append("\\"); sb.append(ch); break; } } } return sb; } /** * Parses the cslashes bitmap returning an actual bitmap. * * @param charset the bitmap string * @return the actual bitmap */ private static boolean []parseCharsetBitmap(String charset) { boolean []bitmap = new boolean[256]; int length = charset.length(); for (int i = 0; i < length; i++) { char ch = charset.charAt(i); // XXX: the bitmap eventual might need to deal with unicode if (ch >= 256) continue; bitmap[ch] = true; if (length <= i + 3) continue; if (charset.charAt(i + 1) != '.' || charset.charAt(i + 2) != '.') continue; char last = charset.charAt(i + 3); if (last < ch) { // XXX: exception type throw new RuntimeException(L.l("Invalid range.")); } i += 3; for (; ch <= last; ch++) { bitmap[ch] = true; } // XXX: handling of '@'? } return bitmap; } /** * Escapes a string for db characters. * * @param source the source string to convert * @return the escaped string */ public static StringValue addslashes(StringValue source) { StringValue sb = source.createStringBuilder(source.length() * 5 / 4); int length = source.length(); for (int i = 0; i < length; i++) { char ch = source.charAt(i); switch (ch) { case 0x0: sb.append("\\0"); break; case '\'': sb.append("\\'"); break; case '\"': sb.append("\\\""); break; case '\\': sb.append("\\\\"); break; default: sb.append(ch); break; } } return sb; } /** * Converts a binary value to a hex value. */ public static StringValue bin2hex(Env env, InputStream is) { try { StringValue sb = env.createUnicodeBuilder(); int ch; while ((ch = is.read()) >= 0) { int d = (ch >> 4) & 0xf; if (d < 10) sb.append((char) (d + '0')); else sb.append((char) (d + 'a' - 10)); d = (ch) & 0xf; if (d < 10) sb.append((char) (d + '0')); else sb.append((char) (d + 'a' - 10)); } return sb; } catch (IOException e) { throw new QuercusModuleException(e); } } /** * Alias of rtrim. Removes trailing whitespace. * * @param env the quercus environment * @param str the string to be trimmed * @param charset optional set of characters to trim * @return the trimmed string */ public static StringValue chop(Env env, StringValue str, @Optional String charset) { return rtrim(env, str, charset); } /** * converts a number to its character equivalent * * @param value the integer value * * @return the string equivalent */ public static StringValue chr(Env env, long value) { if (! env.isUnicodeSemantics()) value = value & 0xFF; StringValue sb = env.createUnicodeBuilder(); sb.append((char) value); return sb; } /** * Splits a string into chunks * * @param body the body string * @param chunkLen the optional chunk length, defaults to 76 * @param end the optional end value, defaults to "\r\n" */ public static String chunk_split(String body, @Optional("76") int chunkLen, @Optional("\"\\r\\n\"") String end) { if (body == null) body = ""; if (end == null) end = ""; if (chunkLen < 1) // XXX: real exn throw new IllegalArgumentException(L.l("bad value {0}", chunkLen)); StringBuilder sb = new StringBuilder(); int i = 0; for (; i + chunkLen <= body.length(); i += chunkLen) { sb.append(body.substring(i, i + chunkLen)); sb.append(end); } if (i < body.length()) { sb.append(body.substring(i)); sb.append(end); } return sb.toString(); } /** * Converts from one cyrillic set to another. * * This implementation does nothing, because quercus stores strings as * 16 bit unicode. */ public static String convert_cyr_string(Env env, String str, String from, String to) { env.stub("convert_cyr_string"); return str; } public static Value convert_uudecode(Env env, String source) { try { if (source == null || source.length() == 0) return BooleanValue.FALSE; ByteToChar byteToChar = env.getByteToChar(); int length = source.length(); int i = 0; while (i < length) { int ch1 = source.charAt(i++); if (ch1 == 0x60 || ch1 == 0x20) break; else if (ch1 < 0x20 || 0x5f < ch1) continue; int sublen = ch1 - 0x20; while (sublen > 0) { int code; code = ((source.charAt(i++) - 0x20) & 0x3f) << 18; code += ((source.charAt(i++) - 0x20) & 0x3f) << 12; code += ((source.charAt(i++) - 0x20) & 0x3f) << 6; code += ((source.charAt(i++) - 0x20) & 0x3f); byteToChar.addByte(code >> 16); if (sublen > 1) byteToChar.addByte(code >> 8); if (sublen > 2) byteToChar.addByte(code); sublen -= 3; } } return env.createString(byteToChar.getConvertedString()); } catch (IOException e) { throw new QuercusModuleException(e); } } /** * uuencode a string. */ public static Value convert_uuencode(StringValue source) { if (source == null || source.length() == 0) return BooleanValue.FALSE; StringValue result = source.createStringBuilder(); int i = 0; int length = source.length(); while (i < length) { int sublen = length - i; if (45 < sublen) sublen = 45; result.append((char) (sublen + 0x20)); int end = i + sublen; while (i < end) { int code = source.charAt(i++) << 16; if (i < length) code += source.charAt(i++) << 8; if (i < length) code += source.charAt(i++); result.append(toUUChar(((code >> 18) & 0x3f))); result.append(toUUChar(((code >> 12) & 0x3f))); result.append(toUUChar(((code >> 6) & 0x3f))); result.append(toUUChar(((code) & 0x3f))); } result.append('\n'); } result.append((char) 0x60); result.append('\n'); return result; } /** * Returns an array of information about the characters. */ public static Value count_chars(StringValue data, @Optional("0") int mode) { if (data == null) data = StringValue.EMPTY; int []count = new int[256]; int length = data.length(); for (int i = 0; i < length; i++) { count[data.charAt(i) & 0xff] += 1; } switch (mode) { case 0: { ArrayValue result = new ArrayValueImpl(); for (int i = 0; i < count.length; i++) { result.put(LongValue.create(i), LongValue.create(count[i])); } return result; } case 1: { ArrayValue result = new ArrayValueImpl(); for (int i = 0; i < count.length; i++) { if (count[i] > 0) result.put(LongValue.create(i), new LongValue(count[i])); } return result; } case 2: { ArrayValue result = new ArrayValueImpl(); for (int i = 0; i < count.length; i++) { if (count[i] == 0) result.put(new LongValue(i), new LongValue(count[i])); } return result; } case 3: { StringValue sb = data.createStringBuilder(); for (int i = 0; i < count.length; i++) { if (count[i] > 0) sb.append((char) i); } return sb; } case 4: { StringValue sb = data.createStringBuilder(); for (int i = 0; i < count.length; i++) { if (count[i] == 0) sb.append((char) i); } return sb; } default: return BooleanValue.FALSE; } } /** * Calculates the crc32 value for a string * * @param str the string value * * @return the crc32 hash */ public static long crc32(InputStream is) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?