📄 stringbuildervalue.java
字号:
/* * 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.env;import com.caucho.vfs.*;import com.caucho.quercus.lib.file.BinaryInput;import com.caucho.quercus.QuercusModuleException;import java.io.*;import java.util.IdentityHashMap;/** * Represents a PHP 5 style string builder (unicode.semantics = off) */public class StringBuilderValue extends StringValue{ public static final StringBuilderValue EMPTY = new StringBuilderValue(""); private final static StringBuilderValue []CHAR_STRINGS; protected char []_buffer; protected int _length; protected boolean _isCopy; private int _hashCode; protected String _value; public StringBuilderValue() { _buffer = new char[128]; } public StringBuilderValue(int capacity) { if (capacity < 64) capacity = 64; _buffer = new char[capacity]; } public StringBuilderValue(char []buffer, int offset, int length) { _buffer = new char[length]; _length = length; System.arraycopy(buffer, offset, _buffer, 0, length); } public StringBuilderValue(byte []buffer, int offset, int length) { _buffer = new char[length]; _length = length; for (int i = offset; i < length; i++) _buffer[i] = (char) buffer[i]; } public StringBuilderValue(byte []buffer) { this(buffer, 0, buffer.length); } public StringBuilderValue(Byte []buffer) { int length = buffer.length; _buffer = new char[length]; _length = length; for (int i = 0; i < length; i++) { _buffer[i] = (char) buffer[i].byteValue(); } } public StringBuilderValue(Character []buffer) { int length = buffer.length; _buffer = new char[length]; _length = length; for (int i = 0; i < length; i++) { _buffer[i] = buffer[i]; } } public StringBuilderValue(char ch) { _buffer = new char[1]; _length = 1; _buffer[0] = ch; } public StringBuilderValue(String s) { int len = s.length(); _buffer = new char[len]; _length = len; s.getChars(0, len, _buffer, 0); } public StringBuilderValue(char []s) { int len = s.length; _buffer = new char[len]; _length = len; System.arraycopy(s, 0, _buffer, 0, len); } public StringBuilderValue(char []s, Value v1) { int len = s.length; if (len < 128) _buffer = new char[128]; else _buffer = new char[len + 32]; _length = len; System.arraycopy(s, 0, _buffer, 0, len); v1.appendTo(this); } public StringBuilderValue(Value v1) { _buffer = new char[128]; v1.appendTo(this); } public StringBuilderValue(Value v1, Value v2) { _buffer = new char[128]; v1.appendTo(this); v2.appendTo(this); } public StringBuilderValue(Value v1, Value v2, Value v3) { _buffer = new char[128]; v1.appendTo(this); v2.appendTo(this); v3.appendTo(this); } /** * Creates the string. */ public static StringValue create(char value) { if (value < CHAR_STRINGS.length) return CHAR_STRINGS[value]; else return new StringBuilderValue(value); } /** * Creates a PHP string from a Java String. * If the value is null then NullValue is returned. */ public static Value create(String value) { if (value == null) return NullValue.NULL; else if (value.length() == 0) return StringBuilderValue.EMPTY; else return new StringBuilderValue(value); } /* * Creates an empty string builder of the same type. */ public StringValue createEmptyStringBuilder() { return new StringBuilderValue(); } /* * Returns the empty string of same type. */ public StringValue getEmptyString() { return EMPTY; } /** * Returns the value. */ public String getValue() { return toString(); } /** * Returns the type. */ @Override public String getType() { return "string"; } /** * Returns the ValueType. */ @Override public ValueType getValueType() { return UnicodeBuilderValue.getValueType(_buffer, 0, _length); } /** * Returns true for a scalar */ @Override public boolean isScalar() { return true; } /* * Returns true if this is a PHP5 string. */ @Override public boolean isPHP5String() { return true; } /** * Converts to a boolean. */ @Override public boolean toBoolean() { if (_length == 0) return false; else if (_length == 1 && _buffer[0] == '0') return false; else return true; } /** * Converts to a long. */ @Override public long toLong() { return parseLong(_buffer, 0, _length); } /** * Converts to a double. */ @Override public double toDouble() { return UnicodeBuilderValue.toDouble(_buffer, 0, _length); } /** * Convert to an input stream. */ @Override public InputStream toInputStream() { return new BuilderInputStream(); } /** * Converts to a string. */ @Override public String toString() { // XXX: encoding if (_value == null) _value = new String(_buffer, 0, _length); return _value; } /** * Converts to a BinaryValue. */ @Override public StringValue toBinaryValue(Env env) { return this; } /** * Converts to a BinaryValue in desired charset. */ @Override public StringValue toBinaryValue(Env env, String charset) { return this; } /** * Converts to a UnicodeValue. */ @Override public StringValue toUnicodeValue() { return this; } /** * Converts to a UnicodeValue. */ @Override public StringValue toUnicodeValue(Env env) { return toUnicodeValue(); } /** * Converts to a UnicodeValue in desired charset. */ @Override public StringValue toUnicodeValue(Env env, String charset) { return toUnicodeValue(); } /** * Converts to an object. */ @Override public Object toJavaObject() { if (_value == null) _value = new String(_buffer, 0, _length); return _value; } /** * Converts to a string builder */ @Override public StringValue toStringBuilder() { // XXX: can this just return this, or does it need to return a copy? return new StringBuilderValue(_buffer, 0, _length); } /** * Returns true if the value is empty. */ @Override public final boolean isEmpty() { return _length == 0 || _length == 1 && _buffer[0] == '0'; } /** * Writes to a stream */ @Override public void writeTo(OutputStream os) { try { int len = _length; for (int i = 0; i < len; i++) os.write(_buffer[i]); } catch (IOException e) { throw new QuercusModuleException(e); } } /** * Append to a string builder. */ @Override public StringValue appendTo(StringBuilderValue bb) { bb.append(_buffer, 0, _length); return bb; } /** * Append to a string builder. */ @Override public StringValue appendTo(UnicodeBuilderValue bb) { bb.append(_buffer, 0, _length); return bb; } /** * Append to a string builder. */ @Override public StringValue appendTo(LargeStringBuilderValue bb) { bb.append(_buffer, 0, _length); return bb; } /** * Append to a string builder. */ @Override public StringValue appendTo(BinaryBuilderValue bb) { bb.append(_buffer, 0, _length); return bb; } /** * Converts to a key. */ @Override public Value toKey() { char []buffer = _buffer; int len = _length; if (len == 0) return this; int sign = 1; long value = 0; int i = 0; int ch = buffer[i]; if (ch == '-') { sign = -1; i++; } for (; i < len; i++) { ch = buffer[i]; if ('0' <= ch && ch <= '9') value = 10 * value + ch - '0'; else return this; } return new LongValue(sign * value); } /** * Converts to a byte array, with no consideration of character encoding. * Each character becomes one byte, characters with values above 255 are * not correctly preserved. */ public byte[] toBytes() { byte[] bytes = new byte[_length]; for (int i = _length - 1; i >= 0; i--) bytes[i] = (byte) _buffer[i]; return bytes; } // // Operations // /** * Returns the character at an index */ public Value get(Value key) { return charValueAt(key.toLong()); } /** * Returns the character at an index */ public Value getRef(Value key) { return charValueAt(key.toLong()); } /** * Sets the array ref. */ @Override public Value put(Value index, Value value) { return setCharValueAt(index.toLong(), value.toString()); } /** * sets the character at an index */ /* public Value setCharAt(long index, String value) { int len = _length; if (index < 0 || len <= index) return this; else { StringBuilderValue sb = new StringBuilderValue(_buffer, 0, (int) index); sb.append(value); sb.append(_buffer, (int) (index + 1), (int) (len - index - 1)); return sb; } } */ // // CharSequence // /** * Returns the length of the string. */ @Override public final int length() { return _length; } /** * Returns the character at a particular location */ @Override public final char charAt(int index) { return _buffer[index]; } /** * Returns the character at an index */ @Override public Value charValueAt(long index) { int len = _length; if (index < 0 || len <= index) return UnsetStringValue.UNSET; else { int ch = _buffer[(int) index]; if (ch < CHAR_STRINGS.length) return CHAR_STRINGS[ch]; else return new StringBuilderValue((char) ch); } } /** * sets the character at an index */ @Override public Value setCharValueAt(long indexL, String value) { int len = _length; if (indexL < 0) return this; else { int index = (int) indexL; int padLen = index - len; if (padLen > 0) { ensureCapacity(index + 1); for (int i = 0; i < padLen; i++) { _buffer[i + len] = ' '; } _length = index + 1; } if (value.length() == 0) _buffer[index] = 0; else _buffer[index] = value.charAt(0); } return this; } /** * Returns the last index of the match string, starting from the head. */ public int indexOf(char match) { int length = _length; char []buffer = _buffer; for (int head = 0; head < length; head++) { if (buffer[head] == match) return head; } return -1; } /** * Returns the last index of the match string, starting from the head. */ @Override public int indexOf(char match, int head) { int length = _length; char []buffer = _buffer; for (; head < length; head++) { if (buffer[head] == match) return head; } return -1; } /** * Returns a subsequence */ @Override public CharSequence subSequence(int start, int end) { if (end <= start) return StringBuilderValue.EMPTY; return new StringBuilderValue(_buffer, start, end - start); } /** * Convert to lower case. */ @Override public StringValue toLowerCase() { int length = _length; StringBuilderValue string = new StringBuilderValue(length); char []srcBuffer = _buffer; char []dstBuffer = string._buffer; for (int i = 0; i < length; i++) { char ch = srcBuffer[i]; if ('A' <= ch && ch <= 'Z') dstBuffer[i] = (char) (ch + 'a' - 'A'); else dstBuffer[i] = ch; } string._length = length; return string; } /** * Convert to lower case. */ @Override public StringValue toUpperCase() { int length = _length; StringBuilderValue string = new StringBuilderValue(_length); char []srcBuffer = _buffer; char []dstBuffer = string._buffer; for (int i = 0; i < length; i++) { char ch = srcBuffer[i]; if ('a' <= ch && ch <= 'z') dstBuffer[i] = (char) (ch + 'A' - 'a'); else dstBuffer[i] = ch; } string._length = length; return string; } /** * Returns true if the region matches */ public boolean regionMatches(int offset, char []mBuffer, int mOffset, int mLength) { int length = _length; if (length < offset + mLength) return false; char []buffer = _buffer; for (int i = 0; i < mLength; i++) { if (buffer[offset + i] != mBuffer[mOffset + i]) return false; } return true; } /** * Returns true if the region matches */ public boolean regionMatchesIgnoreCase(int offset, char []mBuffer, int mOffset, int mLength) { int length = _length; if (length < offset + mLength) return false; char []buffer = _buffer; for (int i = 0; i < mLength; i++) { char a = buffer[offset + i]; char b = mBuffer[mOffset + i]; if ('A' <= a && a <= 'Z') a += 'a' - 'A'; if ('A' <= b && b <= 'Z') b += 'a' - 'A'; if (a != b) return false; } return true; } /** * Creates a string builder of the same type. */ @Override public StringValue createStringBuilder() { return new StringBuilderValue(); } /** * Creates a string builder of the same type. */ @Override public StringValue createStringBuilder(int length) { return new StringBuilderValue(length); } /** * Converts to a string builder */ @Override public StringValue toStringBuilder(Env env) { return new StringBuilderValue(_buffer, 0, _length); } // // append code // /** * Append a Java string to the value. */ @Override public final StringValue append(String s) { int sublen = s.length(); if (_buffer.length < _length + sublen) ensureCapacity(_length + sublen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -