001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Sam
028: */
029:
030: package com.caucho.quercus.lib.spl;
031:
032: import com.caucho.quercus.annotation.Name;
033: import com.caucho.quercus.annotation.Optional;
034: import com.caucho.quercus.env.*;
035: import com.caucho.quercus.lib.ArrayModule;
036: import com.caucho.util.L10N;
037: import com.caucho.vfs.WriteStream;
038:
039: import java.io.IOException;
040: import java.util.IdentityHashMap;
041: import java.util.Map;
042:
043: public class ArrayObject implements ArrayAccess, Countable,
044: IteratorAggregate, Traversable {
045: private static L10N L = new L10N(ArrayObject.class);
046:
047: public static final int STD_PROP_LIST = 0x00000001;
048: public static final int ARRAY_AS_PROPS = 0x00000002;
049:
050: private final Env _env;
051: private Value _value;
052: private int _flags;
053: private QuercusClass _iteratorClass;
054:
055: @Name("__construct")
056: public ArrayObject(Env env, @Optional
057: Value value, @Optional
058: int flags, @Optional("ArrayIterator")
059: String iteratorClassName) {
060: if (value.isNull())
061: value = new ArrayValueImpl();
062:
063: _env = env;
064: _value = value;
065: _flags = flags;
066:
067: QuercusClass iteratorClass = _env.findClass(iteratorClassName);
068:
069: if (iteratorClass == null || !iteratorClass.isA("Iterator"))
070: throw new IllegalArgumentException(
071: L
072: .l("A class that implements Iterator must be specified"));
073:
074: _iteratorClass = iteratorClass;
075: }
076:
077: public void append(Value value) {
078: _value.put(value);
079: }
080:
081: public void asort(@Optional
082: long sortFlag) {
083: sortFlag = 0; // qa/4a46
084:
085: if (_value instanceof ArrayValue)
086: ArrayModule.asort(_env, (ArrayValue) _value, sortFlag);
087: }
088:
089: public int count() {
090: return _value.getCount(_env);
091: }
092:
093: public Value exchangeArray(ArrayValue array) {
094: Value oldValue = _value;
095:
096: _value = array;
097:
098: return oldValue;
099: }
100:
101: public Value getArrayCopy() {
102: return _value.copy();
103: }
104:
105: public int getFlags() {
106: return _flags;
107: }
108:
109: public ObjectValue getIterator() {
110: Value[] args = new Value[] { _value, LongValue.create(_flags) };
111:
112: return (ObjectValue) _iteratorClass.callNew(_env, args);
113: }
114:
115: public String getIteratorClass() {
116: return _iteratorClass.getName();
117: }
118:
119: public void ksort(@Optional
120: long sortFlag) {
121: if (_value instanceof ArrayValue)
122: ArrayModule.ksort(_env, (ArrayValue) _value, sortFlag);
123: }
124:
125: public void natcasesort() {
126: if (_value instanceof ArrayValue)
127: ArrayModule.natcasesort((ArrayValue) _value);
128: }
129:
130: public void natsort() {
131: if (_value instanceof ArrayValue)
132: ArrayModule.natsort((ArrayValue) _value);
133: }
134:
135: public boolean offsetExists(Value offset) {
136: return _value.get(offset).isset();
137: }
138:
139: public Value offsetGet(Value offset) {
140: return _value.get(offset);
141: }
142:
143: public Value offsetSet(Value offset, Value value) {
144: return _value.put(offset, value);
145: }
146:
147: public Value offsetUnset(Value offset) {
148: return _value.remove(offset);
149: }
150:
151: public void setFlags(Value flags) {
152: _flags = flags.toInt();
153: }
154:
155: public void setIteratorClass(String iteratorClass) {
156: _iteratorClass = _env.findClass(iteratorClass);
157: }
158:
159: public void uasort(Callback func) {
160: if (_value instanceof ArrayValue)
161: ArrayModule.uasort(_env, (ArrayValue) _value, func, 0);
162: }
163:
164: public void uksort(Callback func, @Optional
165: long sortFlag) {
166: if (_value instanceof ArrayValue)
167: ArrayModule.uksort(_env, (ArrayValue) _value, func,
168: sortFlag);
169: }
170:
171: public Value __getField(StringValue key) {
172: //php/4a4r
173: return _value.get(key);
174:
175: /*
176: if ((_flags & ARRAY_AS_PROPS) != 0) {
177: return _value.get(key);
178: }
179: else {
180: return NullValue.NULL;
181: }
182: */
183: }
184:
185: static private void printDepth(WriteStream out, int depth)
186: throws java.io.IOException {
187: for (int i = depth; i > 0; i--)
188: out.print(' ');
189: }
190:
191: public void printRImpl(Env env, WriteStream out, int depth,
192: IdentityHashMap<Value, String> valueSet) throws IOException {
193:
194: if ((_flags & STD_PROP_LIST) != 0) {
195: // XXX:
196: out.print("ArrayObject");
197: out.print(' ');
198: out.println("Object");
199: printDepth(out, 4 * depth);
200: out.println("(");
201: out.print(")");
202: } else {
203: out.print("ArrayObject");
204: out.print(' ');
205: out.println("Object");
206: printDepth(out, 4 * depth);
207: out.println("(");
208:
209: depth++;
210:
211: java.util.Iterator<Map.Entry<Value, Value>> iterator = _value
212: .getIterator(env);
213:
214: while (iterator.hasNext()) {
215: Map.Entry<Value, Value> entry = iterator.next();
216:
217: Value key = entry.getKey();
218: Value value = entry.getValue();
219:
220: printDepth(out, 4 * depth);
221:
222: out.print("[" + key + "] => ");
223:
224: value.printR(env, out, depth + 1, valueSet);
225:
226: out.println();
227: }
228:
229: depth--;
230:
231: printDepth(out, 4 * depth);
232: out.println(")");
233: }
234: }
235:
236: public void varDumpImpl(Env env, WriteStream out, int depth,
237: IdentityHashMap<Value, String> valueSet) throws IOException {
238: if ((_flags & STD_PROP_LIST) != 0) {
239: // XXX:
240: out.println("object(ArrayObject) (0) {");
241: out.print("}");
242:
243: } else {
244: out.println("object(ArrayObject) (" + _value.getSize()
245: + ") {");
246:
247: depth++;
248:
249: java.util.Iterator<Map.Entry<Value, Value>> iterator = _value
250: .getIterator(env);
251:
252: while (iterator.hasNext()) {
253: Map.Entry<Value, Value> entry = iterator.next();
254:
255: Value key = entry.getKey();
256: Value value = entry.getValue();
257:
258: printDepth(out, 2 * depth);
259:
260: out.print("[");
261:
262: if (key instanceof StringValue)
263: out.print("\"" + key + "\"");
264: else
265: out.print(key);
266:
267: out.println("]=>");
268:
269: printDepth(out, 2 * depth);
270:
271: value.varDump(env, out, depth, valueSet);
272:
273: out.println();
274: }
275:
276: depth--;
277:
278: printDepth(out, 2 * depth);
279:
280: out.print("}");
281: }
282: }
283: }
|