001: // Copyright (c) Corporation for National Research Initiatives
002: package org.python.core;
003:
004: /**
005: * The abstract superclass of PyObjects that implements a Sequence.
006: * Minimize the work in creating such objects.
007: *
008: * Method names are designed to make it possible for PySequence to
009: * implement java.util.List interface when JDK 1.2 is ubiquitous.
010: *
011: * Subclasses must also implement get, getslice, and repeat methods.
012: *
013: * Subclasses that are mutable should also implement: set, setslice, del,
014: * and delRange.
015: */
016:
017: // this class doesn't "implement InitModule" because otherwise
018: // PyJavaClass.init() would try to instantiate it. That fails because this
019: // class is abstract. TBD: is there a way to test for whether a class is
020: // abstract?
021: abstract public class PySequence extends PyObject {
022: /**
023: * This constructor is used by PyJavaClass.init()
024: */
025: public PySequence() {
026: }
027:
028: protected PySequence(PyType type) {
029: super (type);
030: }
031:
032: // These methods must be defined for any sequence
033:
034: /**
035: * @param index index of element to return.
036: * @return the element at the given position in the list.
037: */
038: abstract protected PyObject pyget(int index);
039:
040: /**
041: * Returns a range of elements from the sequence.
042: *
043: * @param start the position of the first element.
044: * @param stop one more than the position of the last element.
045: * @param step the step size.
046: * @return a sequence corresponding the the given range of elements.
047: */
048: abstract protected PyObject getslice(int start, int stop, int step);
049:
050: /**
051: * Repeats the given sequence.
052: *
053: * @param count the number of times to repeat the sequence.
054: * @return this sequence repeated count times.
055: */
056: abstract protected PyObject repeat(int count);
057:
058: // These methods only apply to mutable sequences
059:
060: /**
061: * Sets the given element of the sequence.
062: *
063: * @param index index of the element to set.
064: * @param value the value to set this element to.
065: */
066: protected void set(int index, PyObject value) {
067: throw Py.TypeError("can't assign to immutable object");
068: }
069:
070: /**
071: * Sets the given range of elements.
072: */
073: protected void setslice(int start, int stop, int step,
074: PyObject value) {
075: throw Py.TypeError("can't assign to immutable object");
076: }
077:
078: protected void del(int i) throws PyException {
079: throw Py.TypeError("can't remove from immutable object");
080: }
081:
082: protected void delRange(int start, int stop, int step) {
083: throw Py.TypeError("can't remove from immutable object");
084: }
085:
086: public boolean __nonzero__() {
087: return seq___nonzero__();
088: }
089:
090: final boolean seq___nonzero__() {
091: return __len__() != 0;
092: }
093:
094: public PyObject __iter__() {
095: return seq___iter__();
096: }
097:
098: final PyObject seq___iter__() {
099: return new PySequenceIter(this );
100: }
101:
102: public synchronized PyObject __eq__(PyObject o) {
103: return seq___eq__(o);
104: }
105:
106: final synchronized PyObject seq___eq__(PyObject o) {
107: if (!(getType() == o.getType())
108: && !(getType().isSubType(o.getType()))) {
109: return null;
110: }
111: int tl = __len__();
112: int ol = o.__len__();
113: if (tl != ol)
114: return Py.Zero;
115: int i = cmp(this , tl, o, ol);
116: return (i < 0) ? Py.One : Py.Zero;
117: }
118:
119: public synchronized PyObject __ne__(PyObject o) {
120: return seq___ne__(o);
121: }
122:
123: final synchronized PyObject seq___ne__(PyObject o) {
124: if (!(getType() == o.getType())
125: && !(getType().isSubType(o.getType()))) {
126: return null;
127: }
128: int tl = __len__();
129: int ol = o.__len__();
130: if (tl != ol)
131: return Py.One;
132: int i = cmp(this , tl, o, ol);
133: return (i < 0) ? Py.Zero : Py.One;
134: }
135:
136: public synchronized PyObject __lt__(PyObject o) {
137: if (!(getType() == o.getType())
138: && !(getType().isSubType(o.getType()))) {
139: return null;
140: }
141: int i = cmp(this , -1, o, -1);
142: if (i < 0)
143: return (i == -1) ? Py.One : Py.Zero;
144: return __finditem__(i)._lt(o.__finditem__(i));
145: }
146:
147: final synchronized PyObject seq___lt__(PyObject o) {
148: return __lt__(o);
149: }
150:
151: public synchronized PyObject __le__(PyObject o) {
152: if (!(getType() == o.getType())
153: && !(getType().isSubType(o.getType()))) {
154: return null;
155: }
156: int i = cmp(this , -1, o, -1);
157: if (i < 0)
158: return (i == -1 || i == -2) ? Py.One : Py.Zero;
159: return __finditem__(i)._le(o.__finditem__(i));
160: }
161:
162: final synchronized PyObject seq___le__(PyObject o) {
163: return __le__(o);
164: }
165:
166: public synchronized PyObject __gt__(PyObject o) {
167: if (!(getType() == o.getType())
168: && !(getType().isSubType(o.getType()))) {
169: return null;
170: }
171: int i = cmp(this , -1, o, -1);
172: if (i < 0)
173: return (i == -3) ? Py.One : Py.Zero;
174: return __finditem__(i)._gt(o.__finditem__(i));
175: }
176:
177: final synchronized PyObject seq___gt__(PyObject o) {
178: return __gt__(o);
179: }
180:
181: public synchronized PyObject __ge__(PyObject o) {
182: if (!(getType() == o.getType())
183: && !(getType().isSubType(o.getType()))) {
184: return null;
185: }
186: int i = cmp(this , -1, o, -1);
187: if (i < 0)
188: return (i == -3 || i == -2) ? Py.One : Py.Zero;
189: return __finditem__(i)._ge(o.__finditem__(i));
190: }
191:
192: final synchronized PyObject seq___ge__(PyObject o) {
193: return __ge__(o);
194: }
195:
196: // Return value >= 0 is the index where the sequences differs.
197: // -1: reached the end of o1 without a difference
198: // -2: reached the end of both seqeunces without a difference
199: // -3: reached the end of o2 without a difference
200: protected static int cmp(PyObject o1, int ol1, PyObject o2, int ol2) {
201: if (ol1 < 0)
202: ol1 = o1.__len__();
203: if (ol2 < 0)
204: ol2 = o2.__len__();
205: int i = 0;
206: for (; i < ol1 && i < ol2; i++) {
207: if (!o1.__getitem__(i)._eq(o2.__getitem__(i)).__nonzero__())
208: return i;
209: }
210: if (ol1 == ol2)
211: return -2;
212: return (ol1 < ol2) ? -1 : -3;
213: }
214:
215: // Return a copy of a sequence where the __len__() method is
216: // telling the thruth.
217: protected static PyObject fastSequence(PyObject seq, String msg) {
218: if (seq instanceof PyList || seq instanceof PyTuple)
219: return seq;
220:
221: PyList list = new PyList();
222: PyObject iter = Py.iter(seq, msg);
223: for (PyObject item = null; (item = iter.__iternext__()) != null;) {
224: list.append(item);
225: }
226: return list;
227: }
228:
229: protected static final int sliceLength(int start, int stop, int step) {
230: //System.err.println("slice: "+start+", "+stop+", "+step);
231: int ret;
232: if (step > 0) {
233: ret = (stop - start + step - 1) / step;
234: } else {
235: ret = (stop - start + step + 1) / step;
236: }
237: if (ret < 0)
238: return 0;
239: return ret;
240: }
241:
242: private static final int getIndex(PyObject index, int defaultValue) {
243: if (index == Py.None || index == null)
244: return defaultValue;
245: if (index instanceof PyLong) {
246: try {
247: index = ((PyInteger) index.__int__());
248: } catch (PyException exc) {
249: if (Py.matchException(exc, Py.OverflowError)) {
250: if (new PyLong(0L).__cmp__(index) < 0)
251: return Integer.MAX_VALUE;
252: else
253: return 0;
254: }
255: }
256: }
257: if (!(index instanceof PyInteger))
258: throw Py.TypeError("slice index must be int");
259: return ((PyInteger) index).getValue();
260: }
261:
262: protected int fixindex(int index) {
263: int l = __len__();
264: if (index < 0)
265: index += l;
266: if (index < 0 || index >= l)
267: return -1;
268: //throw Py.IndexError("index out of range");
269: else
270: return index;
271: }
272:
273: public synchronized PyObject __finditem__(int index) {
274: index = fixindex(index);
275: if (index == -1)
276: return null;
277: else
278: return pyget(index);
279: }
280:
281: public PyObject __finditem__(PyObject index) {
282: return seq___finditem__(index);
283: }
284:
285: final PyObject seq___finditem__(PyObject index) {
286: if (index instanceof PyInteger)
287: return __finditem__(((PyInteger) index).getValue());
288: else if (index instanceof PySlice) {
289: PySlice s = (PySlice) index;
290: return __getslice__(s.start, s.stop, s.step);
291: } else if (index instanceof PyLong)
292: return __finditem__(((PyInteger) index.__int__())
293: .getValue());
294: else
295: throw Py
296: .TypeError("sequence subscript must be integer or slice");
297: }
298:
299: public PyObject __getitem__(PyObject index) {
300: return seq___getitem__(index);
301: }
302:
303: final PyObject seq___getitem__(PyObject index) {
304: PyObject ret = __finditem__(index);
305: if (ret == null) {
306: throw Py.IndexError("index out of range: " + index);
307: }
308: return ret;
309: }
310:
311: public boolean isMappingType() throws PyIgnoreMethodTag {
312: return false;
313: }
314:
315: public boolean isNumberType() throws PyIgnoreMethodTag {
316: return false;
317: }
318:
319: protected static final int getStep(PyObject s_step) {
320: int step = getIndex(s_step, 1);
321: if (step == 0) {
322: throw Py.TypeError("slice step of zero not allowed");
323: }
324: return step;
325: }
326:
327: protected static final int getStart(PyObject s_start, int step,
328: int length) {
329: int start;
330: if (step < 0) {
331: start = getIndex(s_start, length - 1);
332: if (start < 0)
333: start += length;
334: if (start < 0)
335: start = -1;
336: if (start >= length)
337: start = length - 1;
338: } else {
339: start = getIndex(s_start, 0);
340: if (start < 0)
341: start += length;
342: if (start < 0)
343: start = 0;
344: if (start >= length)
345: start = length;
346: }
347:
348: return start;
349: }
350:
351: protected static final int getStop(PyObject s_stop, int start,
352: int step, int length) {
353: int stop;
354: if (step < 0) {
355: stop = getIndex(s_stop, -1);
356: if (stop < -1)
357: stop = length + stop;
358: if (stop < -1)
359: stop = -1;
360: } else {
361: stop = getIndex(s_stop, length);
362: if (stop < 0)
363: stop = length + stop;
364: if (stop < 0)
365: stop = 0;
366: }
367: if (stop > length)
368: stop = length;
369:
370: return stop;
371: }
372:
373: public synchronized PyObject __getslice__(PyObject s_start,
374: PyObject s_stop, PyObject s_step) {
375: return seq___getslice__(s_start, s_stop, s_step);
376: }
377:
378: final synchronized PyObject seq___getslice__(PyObject s_start,
379: PyObject s_stop) {
380: return seq___getslice__(s_start, s_stop, null);
381: }
382:
383: final synchronized PyObject seq___getslice__(PyObject s_start,
384: PyObject s_stop, PyObject s_step) {
385: int length = __len__();
386: int step = getStep(s_step);
387: int start = getStart(s_start, step, length);
388: int stop = getStop(s_stop, start, step, length);
389: return getslice(start, stop, step);
390: }
391:
392: public synchronized void __setslice__(PyObject s_start,
393: PyObject s_stop, PyObject s_step, PyObject value) {
394: seq___setslice__(s_start, s_stop, s_step, value);
395: }
396:
397: final synchronized void seq___setslice__(PyObject s_start,
398: PyObject s_stop, PyObject value) {
399: seq___setslice__(s_start, s_stop, null, value);
400: }
401:
402: final synchronized void seq___setslice__(PyObject s_start,
403: PyObject s_stop, PyObject s_step, PyObject value) {
404: int length = __len__();
405: int step = getStep(s_step);
406: int start = getStart(s_start, step, length);
407: int stop = getStop(s_stop, start, step, length);
408: setslice(start, stop, step, value);
409: }
410:
411: public synchronized void __delslice__(PyObject s_start,
412: PyObject s_stop, PyObject s_step) {
413: seq___delslice__(s_start, s_stop, s_step);
414: }
415:
416: final synchronized void seq___delslice__(PyObject s_start,
417: PyObject s_stop, PyObject s_step) {
418: int length = __len__();
419: int step = getStep(s_step);
420: int start = getStart(s_start, step, length);
421: int stop = getStop(s_stop, start, step, length);
422: delRange(start, stop, step);
423: }
424:
425: public synchronized void __setitem__(int index, PyObject value) {
426: int i = fixindex(index);
427: if (i == -1)
428: throw Py.IndexError("index out of range: " + i);
429: set(i, value);
430: }
431:
432: public void __setitem__(PyObject index, PyObject value) {
433: seq___setitem__(index, value);
434: }
435:
436: final void seq___setitem__(PyObject index, PyObject value) {
437: if (index instanceof PyInteger)
438: __setitem__(((PyInteger) index).getValue(), value);
439: else {
440: if (index instanceof PySlice) {
441: PySlice s = (PySlice) index;
442: __setslice__(s.start, s.stop, s.step, value);
443: } else if (index instanceof PyLong) {
444: __setitem__(((PyInteger) index.__int__()).getValue(),
445: value);
446: } else {
447: throw Py
448: .TypeError("sequence subscript must be integer or slice");
449: }
450: }
451: }
452:
453: public synchronized void __delitem__(PyObject index) {
454: seq___delitem__(index);
455: }
456:
457: final synchronized void seq___delitem__(PyObject index) {
458: if (index instanceof PyInteger) {
459: int i = fixindex(((PyInteger) index).getValue());
460: if (i == -1)
461: throw Py.IndexError("index out of range: " + i);
462: del(i);
463: } else {
464: if (index instanceof PySlice) {
465: PySlice s = (PySlice) index;
466: __delslice__(s.start, s.stop, s.step);
467: } else if (index instanceof PyLong) {
468: int i = fixindex(((PyInteger) index.__int__())
469: .getValue());
470: if (i == -1)
471: throw Py.IndexError("index out of range: " + i);
472: del(i);
473: } else {
474: throw Py
475: .TypeError("sequence subscript must be integer or slice");
476: }
477: }
478: }
479:
480: public synchronized Object __tojava__(Class c)
481: throws PyIgnoreMethodTag {
482: if (c.isArray()) {
483: Class component = c.getComponentType();
484: //System.out.println("getting: "+component);
485: try {
486: int n = __len__();
487: PyArray array = new PyArray(component, n);
488: for (int i = 0; i < n; i++) {
489: PyObject o = pyget(i);
490: array.set(i, o);
491: }
492: //System.out.println("getting: "+component+", "+array.data);
493: return array.getArray();
494: } catch (Throwable t) {
495: ;//System.out.println("failed to get: "+component.getName());
496: }
497: }
498: return super.__tojava__(c);
499: }
500: }
|