📄 largestringbuildervalue.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 java.io.*;import java.util.*;import com.caucho.vfs.*;import com.caucho.quercus.QuercusRuntimeException;import com.caucho.util.*;/** * Represents a 8-bit PHP 5 style binary builder (unicode.semantics = off), * used for large data like file reads. */public class LargeStringBuilderValue extends StringValue{ public static final int SIZE = 4 * 1024; protected byte [][]_bufferList; protected int _length; private int _hashCode; private String _value; public LargeStringBuilderValue() { _bufferList = new byte[32][]; _bufferList[0] = new byte[SIZE]; } public LargeStringBuilderValue(byte [][]bufferList, int length) { _bufferList = bufferList; _length = length; } /* * 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 StringBuilderValue.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 BinaryBuilderValue.getValueType(_bufferList[0], 0, _length); } /** * Returns true for a long */ @Override public boolean isLongConvertible() { return false; } /** * Returns true for a double */ public boolean isDouble() { return false; } /** * Returns true for a number */ @Override public boolean isNumber() { return false; } /** * Returns true for a scalar */ @Override public boolean isScalar() { return true; } /** * Converts to a boolean. */ @Override public boolean toBoolean() { if (_length == 0) return false; else if (_length == 1 && _bufferList[0][0] == '0') return false; else return true; } /** * Converts to a long. */ @Override public long toLong() { return parseLong(_bufferList[0], 0, _length); } /** * Converts to a double. */ @Override public double toDouble() { return BinaryBuilderValue.toDouble(_bufferList[0], 0, _length); } /** * Convert to an input stream. */ @Override public InputStream toInputStream() { return new BuilderInputStream(); } /** * Converts to a string. */ @Override public String toString() { char []buffer = new char[_length]; byte [][]bufferList = _bufferList; for (int i = _length - 1; i >= 0; i--) { buffer[i] = (char) bufferList[i / SIZE][i % SIZE]; } return new String(buffer, 0, _length); } /** * Converts to an object. */ @Override public Object toJavaObject() { return toString(); } /** * 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 LargeStringBuilderValue(_bufferList, _length); } /** * 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; } /** * Append to a string builder. */ public void appendTo(StringValue bb) { int tail = _length % SIZE; int fixedLength = (_length - tail) / SIZE; int i = 0; for (; i < fixedLength; i++) { bb.append(_bufferList[i], 0, SIZE); } bb.append(_bufferList[i], 0, tail); } /** * Converts to a key. */ @Override public Value toKey() { if (getValueType().isLongAdd()) return LongValue.create(toLong()); else return this; } /** * 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]; byte [][]bufferList = _bufferList; for (int i = _length - 1; i >= 0; i--) { bytes[i] = bufferList[i / SIZE][i % SIZE]; } 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()); } /** * 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 data = _bufferList[(int) (index / SIZE)][(int) (index % SIZE)]; return StringBuilderValue.create((char) (data & 0xff)); } } // // CharSequence // /** * Returns the length of the string. */ @Override public int length() { return _length; } /** * Returns the character at a particular location */ @Override public char charAt(int index) { int data = _bufferList[index / SIZE][index % SIZE] & 0xff; return (char) data; } /** * Returns a subsequence */ @Override public CharSequence subSequence(int start, int end) { if (end <= start) return StringBuilderValue.EMPTY; StringValue stringValue; if (end - start < 1024) stringValue = new StringBuilderValue(end - start); else stringValue = new LargeStringBuilderValue(); int endChunk = end / SIZE; while (start < end) { int startChunk = start / SIZE; int startOffset = start % SIZE; if (startChunk == endChunk) { stringValue.append(_bufferList[startChunk], startOffset, (end - start)); return stringValue; } else { int len = SIZE - startOffset; stringValue.append(_bufferList[startChunk], startOffset, len); start += len; } } return stringValue; } /** * Convert to lower case. */ @Override public StringValue toLowerCase() { int length = _length; StringValue string = new LargeStringBuilderValue(); byte [][]bufferList = _bufferList; for (int i = 0; i < length; i++) { int ch = bufferList[i / SIZE][i % SIZE] & 0xff; if ('A' <= ch && ch <= 'Z') ch = (ch + 'a' - 'A'); string.append((char) ch); } return string; } /** * Convert to lower case. */ @Override public StringValue toUpperCase() { int length = _length; StringValue string = new LargeStringBuilderValue(); byte [][]bufferList = _bufferList; for (int i = 0; i < length; i++) { int ch = bufferList[i / SIZE][i % SIZE] & 0xff; if ('a' <= ch && ch <= 'z') ch = (ch + 'A' - 'a'); string.append((char) ch); } return string; } // // append code // /** * 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 LargeStringBuilderValue(_bufferList, _length); } /** * Append a Java buffer to the value. */ @Override
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -