KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > core > PySequence


1 // Copyright (c) Corporation for National Research Initiatives
2
package org.python.core;
3
4 class SeqFuncs extends PyBuiltinFunctionSet {
5     SeqFuncs(String JavaDoc name, int index, int argcount) {
6         super(name, index, argcount, argcount, true, null);
7     }
8
9     public PyObject __call__() {
10         PySequence seq = (PySequence)__self__;
11         switch (index) {
12         case 1:
13             return new PyInteger(seq.__nonzero__() ? 1 : 0);
14         default:
15             throw argCountError(0);
16         }
17     }
18
19     public PyObject __call__(PyObject arg) {
20         PySequence seq = (PySequence)__self__;
21         switch (index) {
22         case 11:
23             return seq.__getitem__(arg);
24         case 12:
25             seq.__delitem__(arg);
26             return Py.None;
27         case 13:
28             return seq.__mul__(arg);
29         case 14:
30             return seq.__rmul__(arg);
31         case 15:
32             return new PyInteger(seq.__cmp__(arg));
33         default:
34             throw argCountError(1);
35         }
36     }
37
38     public PyObject __call__(PyObject arg1, PyObject arg2) {
39         PySequence seq = (PySequence)__self__;
40         switch (index) {
41         case 21:
42             seq.__setitem__(arg1, arg2);
43             return Py.None;
44         default:
45             throw argCountError(1);
46         }
47     }
48
49     public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) {
50         PySequence seq = (PySequence)__self__;
51         switch (index) {
52         case 31:
53             return seq.__getslice__(arg1, arg2, arg3);
54         case 32:
55             seq.__delslice__(arg1, arg2, arg3);
56             return Py.None;
57         default:
58             throw argCountError(3);
59         }
60     }
61
62     public PyObject __call__(PyObject arg1, PyObject arg2,
63                              PyObject arg3, PyObject arg4)
64     {
65         PySequence seq = (PySequence)__self__;
66         switch (index) {
67         case 41:
68             seq.__setslice__(arg1, arg2, arg3, arg4);
69             return Py.None;
70         default:
71             throw argCountError(4);
72         }
73     }
74 }
75
76 /**
77  * The abstract superclass of PyObjects that implements a Sequence.
78  * Minimize the work in creating such objects.
79  *
80  * Method names are designed to make it possible for PySequence to
81  * implement java.util.List interface when JDK 1.2 is ubiquitous.
82  *
83  * All subclasses must declare that they implement the ClassDictInit
84  * interface, and provide an classDictInit() method that calls
85  * PySequence.classDictInit().
86  *
87  * Subclasses must also implement get, getslice, and repeat methods.
88  *
89  * Subclasses that are mutable should also implement: set, setslice, del,
90  * and delRange.
91  */

92
93 // this class doesn't "implement InitModule" because otherwise
94
// PyJavaClass.init() would try to instantiate it. That fails because this
95
// class is abstract. TBD: is there a way to test for whether a class is
96
// abstract?
97
abstract public class PySequence extends PyObject {
98     /**
99      * This constructor is used by PyJavaClass.init()
100      */

101     public PySequence() {}
102
103     protected PySequence(PyType type) {
104         super(type);
105     }
106
107     /** <i>Internal use only. Do not call this method explicit.</i> */
108     public static void classDictInit(PyObject dict) throws PyIgnoreMethodTag {
109         dict.__setitem__("__nonzero__", new SeqFuncs("__nonzero__", 1, 0));
110         dict.__setitem__("__getitem__", new SeqFuncs("__getitem__", 11, 1));
111         dict.__setitem__("__delitem__", new SeqFuncs("__delitem__", 12, 1));
112         dict.__setitem__("__mul__", new SeqFuncs("__mul__", 13, 1));
113         dict.__setitem__("__rmul__", new SeqFuncs("__rmul__", 14, 1));
114         dict.__setitem__("__cmp__", new SeqFuncs("__cmp__", 15, 1));
115         dict.__setitem__("__setitem__", new SeqFuncs("__setitem__", 21, 2));
116         dict.__setitem__("__getslice__", new SeqFuncs("__getslice__", 31, 3));
117         dict.__setitem__("__delslice__", new SeqFuncs("__delslice__", 32, 3));
118         dict.__setitem__("__setslice__", new SeqFuncs("__setslice__", 41, 4));
119         // TBD: __tojava__()
120
// hide these from Python!
121
dict.__setitem__("classDictInit", null);
122     }
123
124     // These methods must be defined for any sequence
125

126     /**
127      * @param index index of element to return.
128      * @return the element at the given position in the list.
129      */

130     abstract protected PyObject pyget(int index);
131
132     /**
133      * Returns a range of elements from the sequence.
134      *
135      * @param start the position of the first element.
136      * @param stop one more than the position of the last element.
137      * @param step the step size.
138      * @return a sequence corresponding the the given range of elements.
139      */

140     abstract protected PyObject getslice(int start, int stop, int step);
141
142     /**
143      * Repeats the given sequence.
144      *
145      * @param count the number of times to repeat the sequence.
146      * @return this sequence repeated count times.
147      */

148     abstract protected PyObject repeat(int count);
149
150     // These methods only apply to mutable sequences
151

152     /**
153      * Sets the given element of the sequence.
154      *
155      * @param index index of the element to set.
156      * @param value the value to set this element to.
157      */

158     protected void set(int index, PyObject value) {
159         throw Py.TypeError("can't assign to immutable object");
160     }
161
162     /**
163      * Sets the given range of elements.
164      */

165     protected void setslice(int start, int stop, int step, PyObject value) {
166         throw Py.TypeError("can't assign to immutable object");
167     }
168
169     protected void del(int i) throws PyException {
170         throw Py.TypeError("can't remove from immutable object");
171     }
172     protected void delRange(int start, int stop, int step) {
173         throw Py.TypeError("can't remove from immutable object");
174     }
175
176     public boolean __nonzero__() {
177         return seq___nonzero__();
178     }
179
180     final boolean seq___nonzero__() {
181         return __len__() != 0;
182     }
183
184     public PyObject __iter__() {
185         return new PySequenceIter(this);
186     }
187
188     public synchronized PyObject __eq__(PyObject o) {
189         return seq___eq__(o);
190     }
191
192     final synchronized PyObject seq___eq__(PyObject o) {
193         if (o.getType() != getType())
194             return null;
195         int tl = __len__();
196         int ol = o.__len__();
197         if (tl != ol)
198             return Py.Zero;
199         int i = cmp(this, tl, o, ol);
200         return (i < 0) ? Py.One : Py.Zero;
201     }
202
203     public synchronized PyObject __ne__(PyObject o) {
204         return seq___ne__(o);
205     }
206
207     final synchronized PyObject seq___ne__(PyObject o) {
208         if (o.getType() != getType())
209             return null;
210         int tl = __len__();
211         int ol = o.__len__();
212         if (tl != ol)
213             return Py.One;
214         int i = cmp(this, tl, o, ol);
215         return (i < 0) ? Py.Zero : Py.One;
216     }
217
218     public synchronized PyObject __lt__(PyObject o) {
219         if (o.getType() != getType())
220             return null;
221         int i = cmp(this, -1, o, -1);
222         if (i < 0)
223             return (i == -1) ? Py.One : Py.Zero;
224         return __finditem__(i)._lt(o.__finditem__(i));
225     }
226
227     public synchronized PyObject __le__(PyObject o) {
228         if (o.getType() != getType())
229             return null;
230         int i = cmp(this, -1, o, -1);
231         if (i < 0)
232             return (i == -1 || i == -2) ? Py.One : Py.Zero;
233         return __finditem__(i)._le(o.__finditem__(i));
234     }
235
236     public synchronized PyObject __gt__(PyObject o) {
237         if (o.getType() != getType())
238             return null;
239         int i = cmp(this, -1, o, -1);
240         if (i < 0)
241             return (i == -3) ? Py.One : Py.Zero;
242         return __finditem__(i)._gt(o.__finditem__(i));
243     }
244
245     public synchronized PyObject __ge__(PyObject o) {
246         if (o.getType() != getType())
247             return null;
248         int i = cmp(this, -1, o, -1);
249         if (i < 0)
250             return (i == -3 || i == -2) ? Py.One : Py.Zero;
251         return __finditem__(i)._ge(o.__finditem__(i));
252     }
253
254     // Return value >= 0 is the index where the sequences differs.
255
// -1: reached the end of o1 without a difference
256
// -2: reached the end of both seqeunces without a difference
257
// -3: reached the end of o2 without a difference
258
private static int cmp(PyObject o1, int ol1, PyObject o2, int ol2) {
259         if (ol1 < 0)
260             ol1 = o1.__len__();
261         if (ol2 < 0)
262             ol2 = o2.__len__();
263         int i = 0;
264         for ( ; i < ol1 && i < ol2; i++) {
265             if (!o1.__getitem__(i)._eq(o2.__getitem__(i)).__nonzero__())
266                 return i;
267         }
268         if (ol1 == ol2)
269             return -2;
270         return (ol1 < ol2) ? -1 : -3;
271     }
272
273
274     // Return a copy of a sequence where the __len__() method is
275
// telling the thruth.
276
protected static PyObject fastSequence(PyObject seq, String JavaDoc msg) {
277         if (seq instanceof PyList || seq instanceof PyTuple)
278             return seq;
279
280         PyList list = new PyList();
281         PyObject iter = Py.iter(seq, msg);
282         for (PyObject item = null; (item = iter.__iternext__()) != null; ) {
283             list.append(item);
284         }
285         return list;
286     }
287
288     protected static final int sliceLength(int start, int stop, int step) {
289         //System.err.println("slice: "+start+", "+stop+", "+step);
290
int ret;
291         if (step > 0) {
292             ret = (stop-start+step-1)/step;
293         } else {
294             ret = (stop-start+step+1)/step;
295         }
296         if (ret < 0) return 0;
297         return ret;
298     }
299
300     private static final int getIndex(PyObject index, int defaultValue) {
301         if (index == Py.None || index == null)
302             return defaultValue;
303         if (index instanceof PyLong) {
304             try {
305                 index = ((PyInteger)index.__int__());
306             } catch (PyException exc) {
307                 if (Py.matchException(exc, Py.OverflowError)) {
308                     if (new PyLong(0L).__cmp__(index) < 0)
309                         return Integer.MAX_VALUE;
310                     else
311                         return 0;
312                 }
313             }
314         }
315         if (!(index instanceof PyInteger))
316             throw Py.TypeError("slice index must be int");
317         return ((PyInteger)index).getValue();
318     }
319
320     protected int fixindex(int index) {
321         int l = __len__();
322         if (index < 0)
323             index += l;
324         if (index < 0 || index >= l)
325             return -1;
326         //throw Py.IndexError("index out of range");
327
else return index;
328     }
329
330     public synchronized PyObject __finditem__(int index) {
331         index = fixindex(index);
332         if (index == -1)
333             return null;
334         else
335             return pyget(index);
336     }
337
338     public PyObject __finditem__(PyObject index) {
339         return seq___finditem__(index);
340     }
341
342     final PyObject seq___finditem__(PyObject index) {
343         if (index instanceof PyInteger)
344             return __finditem__(((PyInteger)index).getValue());
345         else if (index instanceof PySlice) {
346             PySlice s = (PySlice)index;
347             return __getslice__(s.start, s.stop, s.step);
348         } else if (index instanceof PyLong)
349             return __finditem__(((PyInteger)index.__int__()).getValue());
350         else
351             throw Py.TypeError("sequence subscript must be integer or slice");
352     }
353
354     public PyObject __getitem__(PyObject index) {
355         PyObject ret = __finditem__(index);
356         if (ret == null) {
357             throw Py.IndexError("index out of range: "+index);
358         }
359         return ret;
360     }
361
362     public boolean isMappingType() throws PyIgnoreMethodTag { return false; }
363     public boolean isNumberType() throws PyIgnoreMethodTag { return false; }
364
365     protected static final int getStep(PyObject s_step) {
366         int step = getIndex(s_step, 1);
367         if (step == 0) {
368             throw Py.TypeError("slice step of zero not allowed");
369         }
370         return step;
371     }
372
373     protected static final int getStart(PyObject s_start, int step,
374                                         int length)
375     {
376         int start;
377         if (step < 0) {
378             start = getIndex(s_start, length - 1);
379             if (start < 0) start += length;
380             if (start < 0) start = -1;
381             if (start >= length) start = length - 1;
382         } else {
383             start = getIndex(s_start, 0);
384             if (start < 0) start += length;
385             if (start < 0) start = 0;
386             if (start >= length) start = length;
387         }
388
389         return start;
390     }
391
392     protected static final int getStop(PyObject s_stop, int start, int step,
393                                        int length)
394     {
395         int stop;
396         if (step < 0) {
397             stop = getIndex(s_stop, -1);
398             if (stop < -1) stop = length+stop;
399             if (stop < -1) stop = -1;
400         } else {
401             stop = getIndex(s_stop, length);
402             if (stop < 0) stop = length+stop;
403             if (stop < 0) stop = 0;
404         }
405         if (stop > length) stop = length;
406
407         return stop;
408     }
409
410     public synchronized PyObject __getslice__(PyObject s_start,
411                                               PyObject s_stop,
412                                               PyObject s_step) {
413         return seq___getslice__(s_start,s_stop,s_step);
414     }
415
416     final synchronized PyObject seq___getslice__(PyObject s_start,
417                                               PyObject s_stop,
418                                               PyObject s_step)
419     {
420         int length = __len__();
421         int step = getStep(s_step);
422         int start = getStart(s_start, step, length);
423         int stop = getStop(s_stop, start, step, length);
424         return getslice(start, stop, step);
425     }
426
427     public synchronized void __setslice__(PyObject s_start, PyObject s_stop,
428                                           PyObject s_step, PyObject value) {
429         seq___setslice__(s_start,s_stop,s_step,value);
430     }
431
432     final synchronized void seq___setslice__(PyObject s_start, PyObject s_stop,
433                                           PyObject s_step, PyObject value)
434     {
435         int length = __len__();
436         int step = getStep(s_step);
437         int start = getStart(s_start, step, length);
438         int stop = getStop(s_stop, start, step, length);
439         setslice(start, stop, step, value);
440     }
441
442     public synchronized void __delslice__(PyObject s_start, PyObject s_stop,
443                                           PyObject s_step) {
444         seq___delslice__(s_start,s_stop,s_step);
445     }
446
447     final synchronized void seq___delslice__(PyObject s_start, PyObject s_stop,
448                                           PyObject s_step)
449     {
450         int length = __len__();
451         int step = getStep(s_step);
452         int start = getStart(s_start, step, length);
453         int stop = getStop(s_stop, start, step, length);
454         delRange(start, stop, step);
455     }
456
457     public synchronized void __setitem__(int index, PyObject value) {
458         int i = fixindex(index);
459         if (i == -1)
460             throw Py.IndexError("index out of range: "+i);
461         set(i, value);
462     }
463
464     public void __setitem__(PyObject index, PyObject value) {
465         seq___setitem__(index,value);
466     }
467
468     final void seq___setitem__(PyObject index, PyObject value) {
469         if (index instanceof PyInteger)
470             __setitem__(((PyInteger)index).getValue(), value);
471         else {
472             if (index instanceof PySlice) {
473                 PySlice s = (PySlice)index;
474                 __setslice__(s.start, s.stop, s.step, value);
475             } else if (index instanceof PyLong) {
476                 __setitem__(((PyInteger)index.__int__()).getValue(), value);
477             } else {
478                 throw Py.TypeError(
479                     "sequence subscript must be integer or slice");
480             }
481         }
482     }
483
484     public synchronized void __delitem__(PyObject index) {
485         seq___delitem__(index);
486     }
487
488     final synchronized void seq___delitem__(PyObject index) {
489         if (index instanceof PyInteger) {
490             int i = fixindex(((PyInteger)index).getValue());
491             if (i == -1)
492                 throw Py.IndexError("index out of range: "+i);
493             del(i);
494         }
495         else {
496             if (index instanceof PySlice) {
497                 PySlice s = (PySlice)index;
498                 __delslice__(s.start, s.stop, s.step);
499             } else if (index instanceof PyLong) {
500                 int i = fixindex(((PyInteger)index.__int__()).getValue());
501                 if (i == -1)
502                     throw Py.IndexError("index out of range: "+i);
503                 del(i);
504             } else {
505                 throw Py.TypeError(
506                     "sequence subscript must be integer or slice");
507             }
508         }
509     }
510
511     public synchronized Object JavaDoc __tojava__(Class JavaDoc c) throws PyIgnoreMethodTag {
512         if (c.isArray()) {
513             Class JavaDoc component = c.getComponentType();
514             //System.out.println("getting: "+component);
515
try {
516                 int n = __len__();
517                 PyArray array = new PyArray(component, n);
518                 for (int i=0; i<n; i++) {
519                     PyObject o = pyget(i);
520                     array.set(i, o);
521                 }
522                 //System.out.println("getting: "+component+", "+array.data);
523
return array.getArray();
524             } catch (Throwable JavaDoc t) {
525                 ;//System.out.println("failed to get: "+component.getName());
526
}
527         }
528         return super.__tojava__(c);
529     }
530 }
531
Popular Tags