File: SequenceIndexDelegate.java

package info (click to toggle)
jython 2.5.3-16%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 43,772 kB
  • ctags: 106,434
  • sloc: python: 351,322; java: 216,349; xml: 1,584; sh: 330; perl: 114; ansic: 102; makefile: 45
file content (129 lines) | stat: -rw-r--r-- 3,904 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package org.python.core;

import java.io.Serializable;

/**
 * Handles all the index checking and manipulation for get, set and del operations on a sequence.
 */
public abstract class SequenceIndexDelegate implements Serializable {

    public abstract int len();

    public abstract PyObject getItem(int idx);

    public abstract void setItem(int idx, PyObject value);

    public abstract void delItem(int idx);

    public abstract PyObject getSlice(int start, int stop, int step);

    public abstract void setSlice(int start, int stop, int step, PyObject value);

    public abstract void delItems(int start, int stop);

    public abstract String getTypeName();

    public void checkIdxAndSetItem(PyObject idx, PyObject value) {
        if (idx.isIndex()) {
            checkIdxAndSetItem(idx.asIndex(Py.IndexError), value);
        } else if (idx instanceof PySlice) {
            checkIdxAndSetSlice((PySlice)idx, value);
        } else {
            throw Py.TypeError(getTypeName() + " indices must be integers");
        }
    }

    public void checkIdxAndSetSlice(PySlice slice, PyObject value) {
        int[] indices = slice.indicesEx(len());
        if ((slice.step != Py.None) && value.__len__() != indices[3]) {
            throw Py.ValueError(String.format("attempt to assign sequence of size %d to extended "
                                              + "slice of size %d", value.__len__(), indices[3]));
        }
        setSlice(indices[0], indices[1], indices[2], value);
    }

    public void checkIdxAndSetItem(int idx, PyObject value) {
        setItem(checkIdx(idx), value);
    }

    public void checkIdxAndDelItem(PyObject idx) {
        if (idx.isIndex()) {
            delItem(checkIdx(idx.asIndex(Py.IndexError)));
        } else if (idx instanceof PySlice) {
            int[] indices = ((PySlice)idx).indicesEx(len());
            delSlice(indices[0], indices[1], indices[2]);
        } else {
            throw Py.TypeError(getTypeName() + " indices must be integers");
        }
    }

    public PyObject checkIdxAndGetItem(PyObject idx) {
        PyObject res = checkIdxAndFindItem(idx);
        if (res == null) {
            throw Py.IndexError("index out of range: " + idx);
        }
        return res;
    }

    public PyObject checkIdxAndFindItem(PyObject idx) {
        if (idx.isIndex()) {
            return checkIdxAndFindItem(idx.asIndex(Py.IndexError));
        } else if (idx instanceof PySlice) {
            return getSlice((PySlice)idx);
        } else {
            throw Py.TypeError(getTypeName() + " indices must be integers");
        }
    }

    public PyObject getSlice(PySlice slice) {
        int[] indices = slice.indicesEx(len());
        return getSlice(indices[0], indices[1], indices[2]);
    }

    public PyObject checkIdxAndFindItem(int idx) {
        idx = fixindex(idx);
        if(idx == -1) {
            return null;
        } else {
            return getItem(idx);
        }
    }

    private int checkIdx(int idx) {
        int i = fixindex(idx);
        if (i == -1) {
            throw Py.IndexError(getTypeName() + " assignment index out of range");
        }
        return i;
    }

    int fixindex(int index) {
        int l = len();
        if(index < 0) {
            index += l;
        }
        if(index < 0 || index >= l) {
            return -1;
        } else {
            return index;
        }
    }

    private void delSlice(int start, int stop, int step) {
        if(step == 1) {
            if (stop > start) {
                delItems(start, stop);
            }
        } else if(step > 1) {
            for(int i = start; i < stop; i += step) {
                delItem(i);
                i--;
                stop--;
            }
        } else if(step < 0) {
            for(int i = start; i >= 0 && i > stop; i += step) {
                delItem(i);
            }
        }
    }
}