0001: // Copyright (c) Corporation for National Research Initiatives
0002: package org.python.core;
0003:
0004: import java.io.ByteArrayInputStream;
0005: import java.io.ByteArrayOutputStream;
0006: import java.io.DataInputStream;
0007: import java.io.DataOutputStream;
0008: import java.io.EOFException;
0009: import java.io.IOException;
0010: import java.io.InputStream;
0011: import java.io.OutputStream;
0012: import java.io.UnsupportedEncodingException;
0013: import java.lang.reflect.Array;
0014:
0015: /**
0016: * A wrapper class around native java arrays.
0017: *
0018: * Instances of PyArray are created either by java functions or directly by the
0019: * jarray module.
0020: * <p>
0021: * See also the jarray module.
0022: */
0023: public class PyArray extends PySequence implements Cloneable {
0024: //~ BEGIN GENERATED REGION -- DO NOT EDIT SEE gexpose.py
0025: /* type info */
0026:
0027: public static final String exposed_name = "array";
0028:
0029: public static final Class exposed_base = PyObject.class;
0030:
0031: public static void typeSetup(PyObject dict, PyType.Newstyle marker) {
0032: class exposed___ne__ extends PyBuiltinMethodNarrow {
0033:
0034: exposed___ne__(PyObject self, PyBuiltinFunction.Info info) {
0035: super (self, info);
0036: }
0037:
0038: public PyBuiltinFunction bind(PyObject self) {
0039: return new exposed___ne__(self, info);
0040: }
0041:
0042: public PyObject __call__(PyObject arg0) {
0043: PyObject ret = ((PyArray) self).seq___ne__(arg0);
0044: if (ret == null)
0045: return Py.NotImplemented;
0046: return ret;
0047: }
0048:
0049: }
0050: dict.__setitem__("__ne__", new PyMethodDescr("__ne__",
0051: PyArray.class, 1, 1, new exposed___ne__(null, null)));
0052: class exposed___eq__ extends PyBuiltinMethodNarrow {
0053:
0054: exposed___eq__(PyObject self, PyBuiltinFunction.Info info) {
0055: super (self, info);
0056: }
0057:
0058: public PyBuiltinFunction bind(PyObject self) {
0059: return new exposed___eq__(self, info);
0060: }
0061:
0062: public PyObject __call__(PyObject arg0) {
0063: PyObject ret = ((PyArray) self).seq___eq__(arg0);
0064: if (ret == null)
0065: return Py.NotImplemented;
0066: return ret;
0067: }
0068:
0069: }
0070: dict.__setitem__("__eq__", new PyMethodDescr("__eq__",
0071: PyArray.class, 1, 1, new exposed___eq__(null, null)));
0072: class exposed___lt__ extends PyBuiltinMethodNarrow {
0073:
0074: exposed___lt__(PyObject self, PyBuiltinFunction.Info info) {
0075: super (self, info);
0076: }
0077:
0078: public PyBuiltinFunction bind(PyObject self) {
0079: return new exposed___lt__(self, info);
0080: }
0081:
0082: public PyObject __call__(PyObject arg0) {
0083: PyObject ret = ((PyArray) self).seq___lt__(arg0);
0084: if (ret == null)
0085: return Py.NotImplemented;
0086: return ret;
0087: }
0088:
0089: }
0090: dict.__setitem__("__lt__", new PyMethodDescr("__lt__",
0091: PyArray.class, 1, 1, new exposed___lt__(null, null)));
0092: class exposed___le__ extends PyBuiltinMethodNarrow {
0093:
0094: exposed___le__(PyObject self, PyBuiltinFunction.Info info) {
0095: super (self, info);
0096: }
0097:
0098: public PyBuiltinFunction bind(PyObject self) {
0099: return new exposed___le__(self, info);
0100: }
0101:
0102: public PyObject __call__(PyObject arg0) {
0103: PyObject ret = ((PyArray) self).seq___le__(arg0);
0104: if (ret == null)
0105: return Py.NotImplemented;
0106: return ret;
0107: }
0108:
0109: }
0110: dict.__setitem__("__le__", new PyMethodDescr("__le__",
0111: PyArray.class, 1, 1, new exposed___le__(null, null)));
0112: class exposed___gt__ extends PyBuiltinMethodNarrow {
0113:
0114: exposed___gt__(PyObject self, PyBuiltinFunction.Info info) {
0115: super (self, info);
0116: }
0117:
0118: public PyBuiltinFunction bind(PyObject self) {
0119: return new exposed___gt__(self, info);
0120: }
0121:
0122: public PyObject __call__(PyObject arg0) {
0123: PyObject ret = ((PyArray) self).seq___gt__(arg0);
0124: if (ret == null)
0125: return Py.NotImplemented;
0126: return ret;
0127: }
0128:
0129: }
0130: dict.__setitem__("__gt__", new PyMethodDescr("__gt__",
0131: PyArray.class, 1, 1, new exposed___gt__(null, null)));
0132: class exposed___ge__ extends PyBuiltinMethodNarrow {
0133:
0134: exposed___ge__(PyObject self, PyBuiltinFunction.Info info) {
0135: super (self, info);
0136: }
0137:
0138: public PyBuiltinFunction bind(PyObject self) {
0139: return new exposed___ge__(self, info);
0140: }
0141:
0142: public PyObject __call__(PyObject arg0) {
0143: PyObject ret = ((PyArray) self).seq___ge__(arg0);
0144: if (ret == null)
0145: return Py.NotImplemented;
0146: return ret;
0147: }
0148:
0149: }
0150: dict.__setitem__("__ge__", new PyMethodDescr("__ge__",
0151: PyArray.class, 1, 1, new exposed___ge__(null, null)));
0152: class exposed___getitem__ extends PyBuiltinMethodNarrow {
0153:
0154: exposed___getitem__(PyObject self,
0155: PyBuiltinFunction.Info info) {
0156: super (self, info);
0157: }
0158:
0159: public PyBuiltinFunction bind(PyObject self) {
0160: return new exposed___getitem__(self, info);
0161: }
0162:
0163: public PyObject __call__(PyObject arg0) {
0164: PyObject ret = ((PyArray) self).seq___finditem__(arg0);
0165: if (ret == null) {
0166: throw Py.IndexError("index out of range: " + arg0);
0167: }
0168: return ret;
0169: }
0170:
0171: }
0172: dict.__setitem__("__getitem__", new PyMethodDescr(
0173: "__getitem__", PyArray.class, 1, 1,
0174: new exposed___getitem__(null, null)));
0175: class exposed___contains__ extends PyBuiltinMethodNarrow {
0176:
0177: exposed___contains__(PyObject self,
0178: PyBuiltinFunction.Info info) {
0179: super (self, info);
0180: }
0181:
0182: public PyBuiltinFunction bind(PyObject self) {
0183: return new exposed___contains__(self, info);
0184: }
0185:
0186: public PyObject __call__(PyObject arg0) {
0187: return Py.newBoolean(((PyArray) self)
0188: .object___contains__(arg0));
0189: }
0190:
0191: }
0192: dict.__setitem__("__contains__", new PyMethodDescr(
0193: "__contains__", PyArray.class, 1, 1,
0194: new exposed___contains__(null, null)));
0195: class exposed___delitem__ extends PyBuiltinMethodNarrow {
0196:
0197: exposed___delitem__(PyObject self,
0198: PyBuiltinFunction.Info info) {
0199: super (self, info);
0200: }
0201:
0202: public PyBuiltinFunction bind(PyObject self) {
0203: return new exposed___delitem__(self, info);
0204: }
0205:
0206: public PyObject __call__(PyObject arg0) {
0207: ((PyArray) self).seq___delitem__(arg0);
0208: return Py.None;
0209: }
0210:
0211: }
0212: dict.__setitem__("__delitem__", new PyMethodDescr(
0213: "__delitem__", PyArray.class, 1, 1,
0214: new exposed___delitem__(null, null)));
0215: class exposed___setitem__ extends PyBuiltinMethodNarrow {
0216:
0217: exposed___setitem__(PyObject self,
0218: PyBuiltinFunction.Info info) {
0219: super (self, info);
0220: }
0221:
0222: public PyBuiltinFunction bind(PyObject self) {
0223: return new exposed___setitem__(self, info);
0224: }
0225:
0226: public PyObject __call__(PyObject arg0, PyObject arg1) {
0227: ((PyArray) self).seq___setitem__(arg0, arg1);
0228: return Py.None;
0229: }
0230:
0231: }
0232: dict.__setitem__("__setitem__", new PyMethodDescr(
0233: "__setitem__", PyArray.class, 2, 2,
0234: new exposed___setitem__(null, null)));
0235: class exposed___nonzero__ extends PyBuiltinMethodNarrow {
0236:
0237: exposed___nonzero__(PyObject self,
0238: PyBuiltinFunction.Info info) {
0239: super (self, info);
0240: }
0241:
0242: public PyBuiltinFunction bind(PyObject self) {
0243: return new exposed___nonzero__(self, info);
0244: }
0245:
0246: public PyObject __call__() {
0247: return Py
0248: .newBoolean(((PyArray) self).seq___nonzero__());
0249: }
0250:
0251: }
0252: dict.__setitem__("__nonzero__", new PyMethodDescr(
0253: "__nonzero__", PyArray.class, 0, 0,
0254: new exposed___nonzero__(null, null)));
0255: class exposed___getslice__ extends PyBuiltinMethodNarrow {
0256:
0257: exposed___getslice__(PyObject self,
0258: PyBuiltinFunction.Info info) {
0259: super (self, info);
0260: }
0261:
0262: public PyBuiltinFunction bind(PyObject self) {
0263: return new exposed___getslice__(self, info);
0264: }
0265:
0266: public PyObject __call__(PyObject arg0, PyObject arg1,
0267: PyObject arg2) {
0268: return ((PyArray) self).seq___getslice__(arg0, arg1,
0269: arg2);
0270: }
0271:
0272: public PyObject __call__(PyObject arg0, PyObject arg1) {
0273: return ((PyArray) self).seq___getslice__(arg0, arg1);
0274: }
0275:
0276: }
0277: dict.__setitem__("__getslice__", new PyMethodDescr(
0278: "__getslice__", PyArray.class, 2, 3,
0279: new exposed___getslice__(null, null)));
0280: class exposed___delslice__ extends PyBuiltinMethodNarrow {
0281:
0282: exposed___delslice__(PyObject self,
0283: PyBuiltinFunction.Info info) {
0284: super (self, info);
0285: }
0286:
0287: public PyBuiltinFunction bind(PyObject self) {
0288: return new exposed___delslice__(self, info);
0289: }
0290:
0291: public PyObject __call__(PyObject arg0, PyObject arg1,
0292: PyObject arg2) {
0293: ((PyArray) self).seq___delslice__(arg0, arg1, arg2);
0294: return Py.None;
0295: }
0296:
0297: }
0298: dict.__setitem__("__delslice__", new PyMethodDescr(
0299: "__delslice__", PyArray.class, 3, 3,
0300: new exposed___delslice__(null, null)));
0301: class exposed___setslice__ extends PyBuiltinMethodNarrow {
0302:
0303: exposed___setslice__(PyObject self,
0304: PyBuiltinFunction.Info info) {
0305: super (self, info);
0306: }
0307:
0308: public PyBuiltinFunction bind(PyObject self) {
0309: return new exposed___setslice__(self, info);
0310: }
0311:
0312: public PyObject __call__(PyObject arg0, PyObject arg1,
0313: PyObject arg2, PyObject arg3) {
0314: ((PyArray) self).seq___setslice__(arg0, arg1, arg2,
0315: arg3);
0316: return Py.None;
0317: }
0318:
0319: public PyObject __call__(PyObject arg0, PyObject arg1,
0320: PyObject arg2) {
0321: ((PyArray) self).seq___setslice__(arg0, arg1, arg2);
0322: return Py.None;
0323: }
0324:
0325: }
0326: dict.__setitem__("__setslice__", new PyMethodDescr(
0327: "__setslice__", PyArray.class, 3, 4,
0328: new exposed___setslice__(null, null)));
0329: dict.__setitem__("itemsize", new PyGetSetDescr("itemsize",
0330: PyArray.class, "getItemsize", null, null));
0331: dict.__setitem__("typecode", new PyGetSetDescr("typecode",
0332: PyArray.class, "getTypecode", null, null));
0333: class exposed_append extends PyBuiltinMethodNarrow {
0334:
0335: exposed_append(PyObject self, PyBuiltinFunction.Info info) {
0336: super (self, info);
0337: }
0338:
0339: public PyBuiltinFunction bind(PyObject self) {
0340: return new exposed_append(self, info);
0341: }
0342:
0343: public PyObject __call__(PyObject arg0) {
0344: ((PyArray) self).array_append(arg0);
0345: return Py.None;
0346: }
0347:
0348: }
0349: dict.__setitem__("append", new PyMethodDescr("append",
0350: PyArray.class, 1, 1, new exposed_append(null, null)));
0351: class exposed_byteswap extends PyBuiltinMethodNarrow {
0352:
0353: exposed_byteswap(PyObject self, PyBuiltinFunction.Info info) {
0354: super (self, info);
0355: }
0356:
0357: public PyBuiltinFunction bind(PyObject self) {
0358: return new exposed_byteswap(self, info);
0359: }
0360:
0361: public PyObject __call__() {
0362: ((PyArray) self).array_byteswap();
0363: return Py.None;
0364: }
0365:
0366: }
0367: dict.__setitem__("byteswap", new PyMethodDescr("byteswap",
0368: PyArray.class, 0, 0, new exposed_byteswap(null, null)));
0369: class exposed_count extends PyBuiltinMethodNarrow {
0370:
0371: exposed_count(PyObject self, PyBuiltinFunction.Info info) {
0372: super (self, info);
0373: }
0374:
0375: public PyBuiltinFunction bind(PyObject self) {
0376: return new exposed_count(self, info);
0377: }
0378:
0379: public PyObject __call__(PyObject arg0) {
0380: return Py
0381: .newInteger(((PyArray) self).array_count(arg0));
0382: }
0383:
0384: }
0385: dict.__setitem__("count", new PyMethodDescr("count",
0386: PyArray.class, 1, 1, new exposed_count(null, null)));
0387: class exposed_extend extends PyBuiltinMethodNarrow {
0388:
0389: exposed_extend(PyObject self, PyBuiltinFunction.Info info) {
0390: super (self, info);
0391: }
0392:
0393: public PyBuiltinFunction bind(PyObject self) {
0394: return new exposed_extend(self, info);
0395: }
0396:
0397: public PyObject __call__(PyObject arg0) {
0398: ((PyArray) self).array_extend(arg0);
0399: return Py.None;
0400: }
0401:
0402: }
0403: dict.__setitem__("extend", new PyMethodDescr("extend",
0404: PyArray.class, 1, 1, new exposed_extend(null, null)));
0405: class exposed_fromfile extends PyBuiltinMethodNarrow {
0406:
0407: exposed_fromfile(PyObject self, PyBuiltinFunction.Info info) {
0408: super (self, info);
0409: }
0410:
0411: public PyBuiltinFunction bind(PyObject self) {
0412: return new exposed_fromfile(self, info);
0413: }
0414:
0415: public PyObject __call__(PyObject arg0, PyObject arg1) {
0416: try {
0417: ((PyArray) self)
0418: .array_fromfile(arg0, arg1.asInt(1));
0419: return Py.None;
0420: } catch (PyObject.ConversionException e) {
0421: String msg;
0422: switch (e.index) {
0423: case 1:
0424: msg = "expected an integer";
0425: break;
0426: default:
0427: msg = "xxx";
0428: }
0429: throw Py.TypeError(msg);
0430: }
0431: }
0432:
0433: }
0434: dict.__setitem__("fromfile", new PyMethodDescr("fromfile",
0435: PyArray.class, 2, 2, new exposed_fromfile(null, null)));
0436: class exposed_fromlist extends PyBuiltinMethodNarrow {
0437:
0438: exposed_fromlist(PyObject self, PyBuiltinFunction.Info info) {
0439: super (self, info);
0440: }
0441:
0442: public PyBuiltinFunction bind(PyObject self) {
0443: return new exposed_fromlist(self, info);
0444: }
0445:
0446: public PyObject __call__(PyObject arg0) {
0447: ((PyArray) self).array_fromlist(arg0);
0448: return Py.None;
0449: }
0450:
0451: }
0452: dict.__setitem__("fromlist", new PyMethodDescr("fromlist",
0453: PyArray.class, 1, 1, new exposed_fromlist(null, null)));
0454: class exposed_index extends PyBuiltinMethodNarrow {
0455:
0456: exposed_index(PyObject self, PyBuiltinFunction.Info info) {
0457: super (self, info);
0458: }
0459:
0460: public PyBuiltinFunction bind(PyObject self) {
0461: return new exposed_index(self, info);
0462: }
0463:
0464: public PyObject __call__(PyObject arg0) {
0465: return Py
0466: .newInteger(((PyArray) self).array_index(arg0));
0467: }
0468:
0469: }
0470: dict.__setitem__("index", new PyMethodDescr("index",
0471: PyArray.class, 1, 1, new exposed_index(null, null)));
0472: class exposed_insert extends PyBuiltinMethodNarrow {
0473:
0474: exposed_insert(PyObject self, PyBuiltinFunction.Info info) {
0475: super (self, info);
0476: }
0477:
0478: public PyBuiltinFunction bind(PyObject self) {
0479: return new exposed_insert(self, info);
0480: }
0481:
0482: public PyObject __call__(PyObject arg0, PyObject arg1) {
0483: try {
0484: ((PyArray) self).array_insert(arg0.asInt(0), arg1);
0485: return Py.None;
0486: } catch (PyObject.ConversionException e) {
0487: String msg;
0488: switch (e.index) {
0489: case 0:
0490: msg = "expected an integer";
0491: break;
0492: default:
0493: msg = "xxx";
0494: }
0495: throw Py.TypeError(msg);
0496: }
0497: }
0498:
0499: }
0500: dict.__setitem__("insert", new PyMethodDescr("insert",
0501: PyArray.class, 2, 2, new exposed_insert(null, null)));
0502: class exposed_pop extends PyBuiltinMethodNarrow {
0503:
0504: exposed_pop(PyObject self, PyBuiltinFunction.Info info) {
0505: super (self, info);
0506: }
0507:
0508: public PyBuiltinFunction bind(PyObject self) {
0509: return new exposed_pop(self, info);
0510: }
0511:
0512: public PyObject __call__(PyObject arg0) {
0513: try {
0514: return ((PyArray) self).array_pop(arg0.asInt(0));
0515: } catch (PyObject.ConversionException e) {
0516: String msg;
0517: switch (e.index) {
0518: case 0:
0519: msg = "expected an integer";
0520: break;
0521: default:
0522: msg = "xxx";
0523: }
0524: throw Py.TypeError(msg);
0525: }
0526: }
0527:
0528: public PyObject __call__() {
0529: return ((PyArray) self).array_pop();
0530: }
0531:
0532: }
0533: dict.__setitem__("pop", new PyMethodDescr("pop", PyArray.class,
0534: 0, 1, new exposed_pop(null, null)));
0535: class exposed_remove extends PyBuiltinMethodNarrow {
0536:
0537: exposed_remove(PyObject self, PyBuiltinFunction.Info info) {
0538: super (self, info);
0539: }
0540:
0541: public PyBuiltinFunction bind(PyObject self) {
0542: return new exposed_remove(self, info);
0543: }
0544:
0545: public PyObject __call__(PyObject arg0) {
0546: ((PyArray) self).array_remove(arg0);
0547: return Py.None;
0548: }
0549:
0550: }
0551: dict.__setitem__("remove", new PyMethodDescr("remove",
0552: PyArray.class, 1, 1, new exposed_remove(null, null)));
0553: class exposed_reverse extends PyBuiltinMethodNarrow {
0554:
0555: exposed_reverse(PyObject self, PyBuiltinFunction.Info info) {
0556: super (self, info);
0557: }
0558:
0559: public PyBuiltinFunction bind(PyObject self) {
0560: return new exposed_reverse(self, info);
0561: }
0562:
0563: public PyObject __call__() {
0564: ((PyArray) self).array_reverse();
0565: return Py.None;
0566: }
0567:
0568: }
0569: dict.__setitem__("reverse", new PyMethodDescr("reverse",
0570: PyArray.class, 0, 0, new exposed_reverse(null, null)));
0571: class exposed_tofile extends PyBuiltinMethodNarrow {
0572:
0573: exposed_tofile(PyObject self, PyBuiltinFunction.Info info) {
0574: super (self, info);
0575: }
0576:
0577: public PyBuiltinFunction bind(PyObject self) {
0578: return new exposed_tofile(self, info);
0579: }
0580:
0581: public PyObject __call__(PyObject arg0) {
0582: ((PyArray) self).array_tofile(arg0);
0583: return Py.None;
0584: }
0585:
0586: }
0587: dict.__setitem__("tofile", new PyMethodDescr("tofile",
0588: PyArray.class, 1, 1, new exposed_tofile(null, null)));
0589: class exposed_tolist extends PyBuiltinMethodNarrow {
0590:
0591: exposed_tolist(PyObject self, PyBuiltinFunction.Info info) {
0592: super (self, info);
0593: }
0594:
0595: public PyBuiltinFunction bind(PyObject self) {
0596: return new exposed_tolist(self, info);
0597: }
0598:
0599: public PyObject __call__() {
0600: return ((PyArray) self).array_tolist();
0601: }
0602:
0603: }
0604: dict.__setitem__("tolist", new PyMethodDescr("tolist",
0605: PyArray.class, 0, 0, new exposed_tolist(null, null)));
0606: class exposed_tostring extends PyBuiltinMethodNarrow {
0607:
0608: exposed_tostring(PyObject self, PyBuiltinFunction.Info info) {
0609: super (self, info);
0610: }
0611:
0612: public PyBuiltinFunction bind(PyObject self) {
0613: return new exposed_tostring(self, info);
0614: }
0615:
0616: public PyObject __call__() {
0617: return ((PyArray) self).array_tostring();
0618: }
0619:
0620: }
0621: dict.__setitem__("tostring", new PyMethodDescr("tostring",
0622: PyArray.class, 0, 0, new exposed_tostring(null, null)));
0623: class exposed_write extends PyBuiltinMethodNarrow {
0624:
0625: exposed_write(PyObject self, PyBuiltinFunction.Info info) {
0626: super (self, info);
0627: }
0628:
0629: public PyBuiltinFunction bind(PyObject self) {
0630: return new exposed_write(self, info);
0631: }
0632:
0633: public PyObject __call__(PyObject arg0) {
0634: ((PyArray) self).array_write(arg0);
0635: return Py.None;
0636: }
0637:
0638: }
0639: dict.__setitem__("write", new PyMethodDescr("write",
0640: PyArray.class, 1, 1, new exposed_write(null, null)));
0641: class exposed___init__ extends PyBuiltinMethod {
0642:
0643: exposed___init__(PyObject self, PyBuiltinFunction.Info info) {
0644: super (self, info);
0645: }
0646:
0647: public PyBuiltinFunction bind(PyObject self) {
0648: return new exposed___init__(self, info);
0649: }
0650:
0651: public PyObject __call__(PyObject[] args) {
0652: return __call__(args, Py.NoKeywords);
0653: }
0654:
0655: public PyObject __call__(PyObject[] args, String[] keywords) {
0656: ((PyArray) self).array_init(args, keywords);
0657: return Py.None;
0658: }
0659:
0660: }
0661: dict.__setitem__("__init__",
0662: new PyMethodDescr("__init__", PyArray.class, -1, -1,
0663: new exposed___init__(null, null)));
0664: dict.__setitem__("__new__", new PyNewWrapper(PyArray.class,
0665: "__new__", -1, -1) {
0666:
0667: public PyObject new_impl(boolean init, PyType subtype,
0668: PyObject[] args, String[] keywords) {
0669: PyArray newobj;
0670: if (for_type == subtype) {
0671: newobj = new PyArray();
0672: if (init)
0673: newobj.array_init(args, keywords);
0674: } else {
0675: newobj = new PyArrayDerived(subtype);
0676: }
0677: return newobj;
0678: }
0679:
0680: });
0681: }
0682:
0683: //~ END GENERATED REGION -- DO NOT EDIT SEE gexpose.py
0684: private Object data;
0685:
0686: private Class type;
0687:
0688: private String typecode;
0689:
0690: private ArrayDelegate delegate;
0691:
0692: // PyArray can't extend anymore, so delegate
0693: private class ArrayDelegate extends AbstractArray {
0694:
0695: final PyArray pyArray;
0696:
0697: private ArrayDelegate(PyArray pyArray) {
0698: super ((pyArray.data == null) ? 0 : Array
0699: .getLength(pyArray.data));
0700: this .pyArray = pyArray;
0701: }
0702:
0703: protected Object getArray() {
0704: return pyArray.data;
0705: }
0706:
0707: protected void setArray(Object array) {
0708: pyArray.data = array;
0709: }
0710:
0711: protected void makeInsertSpace(int index) {
0712: super .makeInsertSpace(index, 1);
0713: }
0714:
0715: protected void makeInsertSpace(int index, int length) {
0716: super .makeInsertSpace(index, length);
0717: }
0718:
0719: public void remove(int index) {
0720: super .remove(index);
0721: }
0722: }
0723:
0724: private PyArray() {
0725: // do nothing, shell instance
0726: }
0727:
0728: public PyArray(PyType type) {
0729: super (type);
0730: }
0731:
0732: public PyArray(PyArray toCopy) {
0733: data = toCopy.delegate.copyArray();
0734: delegate = new ArrayDelegate(this );
0735: type = toCopy.type;
0736: }
0737:
0738: public PyArray(Class type, Object data) {
0739: this .type = type;
0740: this .data = data;
0741: delegate = new ArrayDelegate(this );
0742: }
0743:
0744: public PyArray(Class type, int n) {
0745: this (type, Array.newInstance(type, n));
0746: }
0747:
0748: private void array_init(PyObject[] args, String[] kwds) {
0749: ArgParser ap = new ArgParser("array", args, kwds, new String[] {
0750: "typecode", "seq" }, 1);
0751: PyObject obj = ap.getPyObject(0);
0752: if (obj instanceof PyString) {
0753: String code = obj.toString();
0754: if (code.length() != 1) {
0755: throw Py.ValueError("typecode must be in [zcbhilfd]");
0756: }
0757: type = char2class(code.charAt(0));
0758: typecode = code;
0759: } else if (obj instanceof PyJavaClass) {
0760: type = ((PyJavaClass) obj).proxyClass;
0761: typecode = type.getName();
0762: }
0763: data = Array.newInstance(type, 0);
0764: delegate = new ArrayDelegate(this );
0765:
0766: PyObject seq = ap.getPyObject(1, null);
0767: if (seq == null) {
0768: return;
0769: }
0770: extendInternal(seq);
0771: }
0772:
0773: public static PyArray zeros(int n, char typecode) {
0774: PyArray array = zeros(n, char2class(typecode));
0775: // Character.toString(char) is jdk 1.4
0776: // array.typecode = Character.toString(typecode);
0777: array.typecode = "" + typecode;
0778: return array;
0779: }
0780:
0781: public static PyArray zeros(int n, Class ctype) {
0782: PyArray array = new PyArray(ctype, n);
0783: array.typecode = ctype.getName();
0784: return array;
0785: }
0786:
0787: public static PyArray array(PyObject seq, char typecode) {
0788: PyArray array = PyArray.array(seq, char2class(typecode));
0789: array.typecode = Character.toString(typecode);
0790: return array;
0791: }
0792:
0793: /**
0794: * Create a PyArray storing <em>ctype</em> types and being initialised
0795: * with <em>initialiser</em>.
0796: *
0797: * @param init
0798: * an initialiser for the array - can be PyString or PySequence
0799: * (including PyArray) or iterable type.
0800: * @param ctype
0801: * <code>Class</code> type of the elements stored in the array.
0802: * @return a new PyArray
0803: */
0804: public static PyArray array(PyObject init, Class ctype) {
0805: PyArray array = new PyArray(ctype, 0);
0806: array.typecode = ctype.getName();
0807: array.extendInternal(init);
0808: return array;
0809: }
0810:
0811: /**
0812: * Adds (appends) two PyArrays together
0813: *
0814: * @param other
0815: * a PyArray to be added to the instance
0816: * @return the result of the addition as a new PyArray instance
0817: */
0818: public PyObject __add__(PyObject other) {
0819: PyArray otherArr = null;
0820: if (!(other instanceof PyArray)) {
0821: throw Py
0822: .TypeError("can only append another array to an array");
0823: }
0824: otherArr = (PyArray) other;
0825: if (!otherArr.type.equals(this .type)) {
0826: throw Py
0827: .TypeError("can only append arrays of the same type, "
0828: + "expected '"
0829: + this .type
0830: + ", found "
0831: + otherArr.type);
0832: }
0833: PyArray ret = new PyArray(this );
0834: ret.delegate.appendArray(otherArr.delegate.copyArray());
0835: return ret;
0836: }
0837:
0838: /**
0839: * Finds the attribute.
0840: *
0841: * @param name
0842: * the name of the attribute of interest
0843: * @return the value for the attribute of the specified name
0844: */
0845: public PyObject __findattr__(String name) {
0846: if ("typecode".equals(name)) {
0847: return new PyString(getTypecode());
0848: }
0849: return super .__findattr__(name);
0850: }
0851:
0852: /**
0853: * Length of the array
0854: *
0855: * @return number of elements in the array
0856: */
0857: public int __len__() {
0858: return delegate.getSize();
0859: }
0860:
0861: /**
0862: * String representation of PyArray
0863: *
0864: * @return string representation of PyArray
0865: */
0866: public PyString __repr__() {
0867: StringBuffer buf = new StringBuffer(128);
0868: buf.append("array(").append(class2char(type)).append(",[");
0869: for (int i = 0; i < __len__() - 1; i++) {
0870: buf.append(pyget(i).__repr__().toString());
0871: buf.append(", ");
0872: }
0873: if (__len__() > 0) {
0874: buf.append(pyget(__len__() - 1).__repr__().toString());
0875: }
0876: buf.append("]) ");
0877: return new PyString(buf.toString());
0878: }
0879:
0880: /**
0881: *
0882: * @param c
0883: * target <em>Class</em> for the conversion
0884: * @return Java object converted to required class type if possible.
0885: */
0886: public Object __tojava__(Class c) {
0887: if (c == Object.class
0888: || (c.isArray() && c.getComponentType()
0889: .isAssignableFrom(type))) {
0890: return data;
0891: }
0892: if (c.isInstance(this ))
0893: return this ;
0894: return Py.NoConversion;
0895: }
0896:
0897: public void array_append(PyObject value) {
0898: append(value);
0899: }
0900:
0901: /**
0902: * Append new value x to the end of the array.
0903: *
0904: * @param value
0905: * item to be appended to the array
0906: */
0907: public void append(PyObject value) {
0908: // Currently, this is asymmetric with extend, which
0909: // *will* do conversions like append(5.0) to an int array.
0910: // Also, cpython 2.2 will do the append coersion. However,
0911: // it is deprecated in cpython 2.3, so maybe we are just
0912: // ahead of our time ;-)
0913: int afterLast = delegate.getSize();
0914: delegate.makeInsertSpace(afterLast);
0915: try {
0916: set(afterLast, value);
0917: } catch (PyException e) {
0918: delegate.setSize(afterLast);
0919: throw new PyException(e.type, e.value);
0920: }
0921: }
0922:
0923: public void array_byteswap() {
0924: byteswap();
0925: }
0926:
0927: /**
0928: * "Byteswap" all items of the array. This is only supported for values
0929: * which are 1, 2, 4, or 8 bytes in size; for other types of values,
0930: * RuntimeError is raised. It is useful when reading data from a file
0931: * written on a machine with a different byte order.
0932: */
0933: public void byteswap() {
0934: // unknown type - throw RuntimeError
0935: if (getItemsize() == 0) {
0936: throw Py
0937: .RuntimeError("don't know how to byteswap this array type");
0938: }
0939: ByteSwapper.swap(data);
0940: }
0941:
0942: /**
0943: * Implementation of <em>Cloneable</em> interface.
0944: *
0945: * @return copy of current PyArray
0946: */
0947: public Object clone() {
0948: return new PyArray(this );
0949: }
0950:
0951: /**
0952: * Converts a character code for the array type to a Java <code>Class</code>.
0953: * <p />
0954: *
0955: * The following character codes and their native types are supported:<br />
0956: * <table>
0957: * <tr>
0958: * <td><strong>Type code</strong></td>
0959: * <td><strong>native type</strong></td>
0960: * </tr>
0961: * <tr>
0962: * <td>z</td>
0963: * <td><code>boolean</code></td>
0964: * </tr>
0965: * <tr>
0966: * <td>c</td>
0967: * <td><code>char</code></td>
0968: * </tr>
0969: * <tr>
0970: * <td>b</td>
0971: * <td><code>byte</code></td>
0972: * </tr>
0973: * <tr>
0974: * <td>h</td>
0975: * <td><code>short</code></td>
0976: * </tr>
0977: * <tr>
0978: * <td>i</td>
0979: * <td><code>int</code></td>
0980: * </tr>
0981: * <tr>
0982: * <td>l</td>
0983: * <td><code>long</code></td>
0984: * </tr>
0985: * <tr>
0986: * <td>f</td>
0987: * <td><code>float</code></td>
0988: * </tr>
0989: * <tr>
0990: * <td>d</td>
0991: * <td><code>double</code></td>
0992: * </tr>
0993: * </table>
0994: * <p />
0995: *
0996: * @param type
0997: * character code for the array type
0998: *
0999: * @return <code>Class</code> of the native type
1000: */
1001: public static Class char2class(char type) throws PyIgnoreMethodTag {
1002: switch (type) {
1003: case 'z':
1004: return Boolean.TYPE;
1005: case 'c':
1006: return Character.TYPE;
1007: case 'b':
1008: return Byte.TYPE;
1009: case 'h':
1010: return Short.TYPE;
1011: case 'i':
1012: return Integer.TYPE;
1013: case 'l':
1014: return Long.TYPE;
1015: case 'f':
1016: return Float.TYPE;
1017: case 'd':
1018: return Double.TYPE;
1019: default:
1020: throw Py.ValueError("typecode must be in [zcbhilfd]");
1021: }
1022: }
1023:
1024: private static String class2char(Class cls) {
1025: if (cls.equals(Boolean.TYPE))
1026: return "'z'";
1027: else if (cls.equals(Character.TYPE))
1028: return "'c'";
1029: else if (cls.equals(Byte.TYPE))
1030: return "'b'";
1031: else if (cls.equals(Short.TYPE))
1032: return "'h'";
1033: else if (cls.equals(Integer.TYPE))
1034: return "'i'";
1035: else if (cls.equals(Long.TYPE))
1036: return "'l'";
1037: else if (cls.equals(Float.TYPE))
1038: return "'f'";
1039: else if (cls.equals(Double.TYPE))
1040: return "'d'";
1041: else
1042: return cls.getName();
1043: }
1044:
1045: public int array_count(PyObject value) {
1046: // note: cpython does not raise type errors based on item type;
1047: int iCount = 0;
1048: for (int i = 0; i < delegate.getSize(); i++) {
1049: if (value.equals(Py.java2py(Array.get(data, i))))
1050: iCount++;
1051: }
1052: return iCount;
1053: }
1054:
1055: /**
1056: * Return the number of occurrences of x in the array.
1057: *
1058: * @param value
1059: * instances of the value to be counted
1060: * @return number of time value was found in the array.
1061: */
1062: public PyInteger count(PyObject value) {
1063: return Py.newInteger(array_count(value));
1064: }
1065:
1066: /**
1067: * Delete the element at position <em>i</em> from the array
1068: *
1069: * @param i
1070: * index of the item to be deleted from the array
1071: */
1072: protected void del(int i) {
1073: // Now the AbstractArray can support this:
1074: // throw Py.TypeError("can't remove from array");
1075: delegate.remove(i);
1076: }
1077:
1078: /**
1079: * Delete the slice defined by <em>start</em>, <em>stop</em> and
1080: * <em>step</em> from the array.
1081: *
1082: * @param start
1083: * starting index of slice
1084: * @param stop
1085: * finishing index of slice
1086: * @param step
1087: * stepping increment between start and stop
1088: */
1089: protected void delRange(int start, int stop, int step) {
1090: // Now the AbstractArray can support this:
1091: // throw Py.TypeError("can't remove from array");
1092: if (step > 0 && stop < start)
1093: stop = start;
1094: if (step == 1) {
1095: delegate.remove(start, stop);
1096: } else {
1097: int n = sliceLength(start, stop, step);
1098: for (int i = start, j = 0; j < n; i += step, j++) {
1099: delegate.remove(i);
1100: }
1101: }
1102: }
1103:
1104: public void array_extend(PyObject iterable) {
1105: extendInternal(iterable);
1106: }
1107:
1108: /**
1109: * Append items from <em>iterable</em> to the end of the array. If
1110: * iterable is another array, it must have exactly the same type code; if
1111: * not, TypeError will be raised. If iterable is not an array, it must be
1112: * iterable and its elements must be the right type to be appended to the
1113: * array. Changed in version 2.4: Formerly, the argument could only be
1114: * another array.
1115: *
1116: * @param iterable
1117: * iterable object used to extend the array
1118: */
1119: public void extend(PyObject iterable) {
1120: extendInternal(iterable);
1121: }
1122:
1123: /**
1124: * Internal extend function, provides basic interface for extending arrays.
1125: * Handles specific cases of <em>iterable</em> being PyStrings or
1126: * PyArrays. Default behaviour is to defer to
1127: * {@link #extendInternalIter(PyObject) extendInternalIter }
1128: *
1129: * @param iterable
1130: * object of type PyString, PyArray or any object that can be
1131: * iterated over.
1132: */
1133: private void extendInternal(PyObject iterable) {
1134: // string input
1135: if (iterable instanceof PyString) {
1136: fromstring(((PyString) iterable).toString());
1137: // PyArray input
1138: } else if (iterable instanceof PyArray) {
1139: PyArray source = (PyArray) iterable;
1140: if (!source.type.equals(this .type)) {
1141: throw Py
1142: .TypeError("can only extend with an array of the same kind");
1143: }
1144: delegate.appendArray(source.delegate.copyArray());
1145: } else {
1146: extendInternalIter(iterable);
1147: }
1148: }
1149:
1150: /**
1151: * Internal extend function to process iterable objects.
1152: *
1153: * @param iterable
1154: * any object that can be iterated over.
1155: */
1156: private void extendInternalIter(PyObject iterable) {
1157: PyObject iter = iterable.__iter__();
1158: PyObject item = null;
1159: // iterable object without a length property - cannot presize the
1160: // array, so append each item
1161: if (iterable.__findattr__("__len__") == null) {
1162: for (int i = 0; (item = iter.__iternext__()) != null; i++) {
1163: append(item);
1164: }
1165: } else {
1166: // create room
1167: int last = delegate.getSize();
1168: delegate.ensureCapacity(last + iterable.__len__());
1169: for (int i = last; (item = iter.__iternext__()) != null; i++) {
1170: set(i, item);
1171: delegate.size++;
1172: }
1173: }
1174: }
1175:
1176: private void array_fromfile(PyObject f, int count) {
1177: fromfile(f, count);
1178: }
1179:
1180: /**
1181: * Read <em>count</em> items (as machine values) from the file object
1182: * <em>f</em> and append them to the end of the array. If less than
1183: * <em>count</em> items are available, EOFError is raised, but the items
1184: * that were available are still inserted into the array. <em>f</em> must
1185: * be a real built-in file object; something else with a read() method won't
1186: * do.
1187: *
1188: * @param f
1189: * Python builtin file object to retrieve data
1190: * @param count
1191: * number of array elements to read
1192: */
1193: public void fromfile(PyObject f, int count) {
1194: // check for arg1 as file object
1195: if (!(f instanceof PyFile)) {
1196: throw Py.TypeError("arg1 must be open file");
1197: }
1198: PyFile file = (PyFile) f;
1199: // check for read only
1200: if (file.mode.indexOf("r") == -1) {
1201: throw Py.TypeError("file needs to be in read mode");
1202: }
1203: // read the data via the PyFile
1204: int readbytes = count * getItemsize();
1205: String buffer = file.read(readbytes).toString();
1206: // load whatever was collected into the array
1207: fromstring(buffer);
1208: // check for underflow
1209: if (buffer.length() < readbytes) {
1210: int readcount = buffer.length() / getItemsize();
1211: throw Py.EOFError("not enough items in file. "
1212: + Integer.toString(count) + " requested, "
1213: + Integer.toString(readcount) + " actually read");
1214: }
1215: }
1216:
1217: public void array_fromlist(PyObject obj) {
1218: fromlist(obj);
1219: }
1220:
1221: /**
1222: * Append items from the list. This is equivalent to "for x in list:
1223: * a.append(x)"except that if there is a type error, the array is unchanged.
1224: *
1225: * @param obj
1226: * input list object that will be appended to the array
1227: */
1228: public void fromlist(PyObject obj) {
1229: // check for list
1230: if (!(obj instanceof PyList))
1231: throw Py.TypeError("expected list argument");
1232: // store the current size of the internal array
1233: int size = delegate.getSize();
1234: try {
1235: extendInternalIter(obj);
1236: } catch (PyException e) {
1237: // trap any exception - any error invalidates the whole list
1238: delegate.setSize(size);
1239: // re-throw
1240: throw new PyException(e.type, e.value);
1241: }
1242: }
1243:
1244: /**
1245: * Generic stream reader to read the entire contents of a stream into the
1246: * array.
1247: *
1248: * @param is
1249: * InputStream to source the data from
1250: *
1251: * @return number of primitives successfully read
1252: *
1253: * @throws IOException
1254: * @throws EOFException
1255: */
1256: private int fromStream(InputStream is) throws IOException,
1257: EOFException {
1258: return fromStream(is, is.available() / getItemsize());
1259: }
1260:
1261: /**
1262: * Generic stream reader to read <em>count</em> primitive types from a
1263: * stream into the array.
1264: *
1265: * @param is
1266: * InputStream to source the data from
1267: * @param count
1268: * number of primitive types to read from the stream
1269: *
1270: * @return number of primitives successfully read
1271: *
1272: * @throws IOException
1273: * @throws EOFException
1274: */
1275: private int fromStream(InputStream is, int count)
1276: throws IOException, EOFException {
1277: DataInputStream dis = new DataInputStream(is);
1278: // current number of items present
1279: int origsize = delegate.getSize();
1280: // position to start inserting into
1281: int index = origsize;
1282: // create capacity for 'count' items
1283: delegate.ensureCapacity(index + count);
1284: if (type.isPrimitive()) {
1285: if (type == Boolean.TYPE) {
1286: for (int i = 0; i < count; i++, index++) {
1287: Array.setBoolean(data, index, dis.readBoolean());
1288: delegate.size++;
1289: }
1290: } else if (type == Byte.TYPE) {
1291: for (int i = 0; i < count; i++, index++) {
1292: Array.setByte(data, index, dis.readByte());
1293: delegate.size++;
1294: }
1295: } else if (type == Character.TYPE) {
1296: for (int i = 0; i < count; i++, index++) {
1297: Array.setChar(data, index, (char) dis.readByte());
1298: delegate.size++;
1299: }
1300: } else if (type == Integer.TYPE) {
1301: for (int i = 0; i < count; i++, index++) {
1302: Array.setInt(data, index, dis.readInt());
1303: delegate.size++;
1304: }
1305: } else if (type == Short.TYPE) {
1306: for (int i = 0; i < count; i++, index++) {
1307: Array.setShort(data, index, dis.readShort());
1308: delegate.size++;
1309: }
1310: } else if (type == Long.TYPE) {
1311: for (int i = 0; i < count; i++, index++) {
1312: Array.setLong(data, index, dis.readLong());
1313: delegate.size++;
1314: }
1315: } else if (type == Float.TYPE) {
1316: for (int i = 0; i < count; i++, index++) {
1317: Array.setFloat(data, index, dis.readFloat());
1318: delegate.size++;
1319: }
1320: } else if (type == Double.TYPE) {
1321: for (int i = 0; i < count; i++, index++) {
1322: Array.setDouble(data, index, dis.readDouble());
1323: delegate.size++;
1324: }
1325: }
1326: }
1327: dis.close();
1328: return (index - origsize);
1329: }
1330:
1331: /**
1332: * Appends items from the string, interpreting the string as an array of
1333: * machine values (as if it had been read from a file using the
1334: * {@link #fromfile(PyObject, int) fromfile()} method).
1335: *
1336: * @param input
1337: * string of bytes containing array data
1338: */
1339: public void fromstring(String input) {
1340: int itemsize = getItemsize();
1341: int strlen = input.length();
1342: if ((strlen % itemsize) != 0) {
1343: throw Py
1344: .ValueError("string length not a multiple of item size");
1345: }
1346: ByteArrayInputStream bis = new ByteArrayInputStream(input
1347: .getBytes());
1348: int origsize = delegate.getSize();
1349: try {
1350: fromStream(bis);
1351: } catch (EOFException e) {
1352: // stubbed catch for fromStream throws
1353: throw Py.EOFError("not enough items in string");
1354: } catch (IOException e) {
1355: // discard anything successfully loaded
1356: delegate.setSize(origsize);
1357: throw Py.IOError(e);
1358: }
1359: }
1360:
1361: /**
1362: * Get the element at position <em>i</em> from the array
1363: *
1364: * @param i
1365: * index of the item to be retrieved from the array
1366: */
1367: protected PyObject pyget(int i) {
1368: return Py.java2py(Array.get(data, i));
1369: }
1370:
1371: /**
1372: * Return the internal Java array storage of the PyArray instance
1373: *
1374: * @return the <code>Array</code> store.
1375: */
1376: public Object getArray() throws PyIgnoreMethodTag {
1377: return delegate.copyArray();
1378: }
1379:
1380: /**
1381: * Getter for the storage size of the array's type.
1382: * <p />
1383: *
1384: * The sizes returned by this method represent the number of bytes used to
1385: * store the type. In the case of streams, this is the number of bytes
1386: * written to, or read from a stream. For memory this value is the
1387: * <em>minimum</em> number of bytes required to store the type.
1388: * <p />
1389: *
1390: * This method is used by other methods to define read/write quanta from
1391: * strings and streams.
1392: * <p />
1393: *
1394: * Values returned are:<br />
1395: * <table>
1396: * <tr>
1397: * <td><strong>Type</strong></td>
1398: * <td><strong>Size</strong></td>
1399: * </tr>
1400: * <tr>
1401: * <td><code>boolean</code></td>
1402: * <td>1</td>
1403: * </tr>
1404: * <tr>
1405: * <td><code>byte</code></td>
1406: * <td>1</td>
1407: * </tr>
1408: * <tr>
1409: * <td><code>char</code></td>
1410: * <td>1</td>
1411: * </tr>
1412: * <tr>
1413: * <td><code>short</code></td>
1414: * <td>2</td>
1415: * </tr>
1416: * <tr>
1417: * <td><code>int</code></td>
1418: * <td>4</td>
1419: * </tr>
1420: * <tr>
1421: * <td><code>long</code></td>
1422: * <td>8</td>
1423: * </tr>
1424: * <tr>
1425: * <td><code>float</code></td>
1426: * <td>4</td>
1427: * </tr>
1428: * <tr>
1429: * <td><code>double</code></td>
1430: * <td>8</td>
1431: * </tr>
1432: * </table>
1433: *
1434: * @return number of bytes used to store array type.
1435: */
1436: public int getItemsize() {
1437: if (type.isPrimitive()) {
1438: if (type == Boolean.TYPE)
1439: return 1;
1440: else if (type == Byte.TYPE)
1441: return 1;
1442: else if (type == Character.TYPE)
1443: return 1;
1444: else if (type == Short.TYPE)
1445: return 2;
1446: else if (type == Integer.TYPE)
1447: return 4;
1448: else if (type == Long.TYPE)
1449: return 8;
1450: else if (type == Float.TYPE)
1451: return 4;
1452: else if (type == Double.TYPE)
1453: return 8;
1454: }
1455: // return something here... could be a calculated size?
1456: return 0;
1457: }
1458:
1459: /**
1460: * Retrieve a slice from the array specified by the <em>start</em>,
1461: * <em>stop</em> and <em>step</em>.
1462: *
1463: * @param start
1464: * start index of the slice
1465: * @param stop
1466: * stop index of the slice
1467: * @param step
1468: * stepping increment of the slice
1469: * @return A new PyArray object containing the described slice
1470: */
1471: protected PyObject getslice(int start, int stop, int step) {
1472: if (step > 0 && stop < start)
1473: stop = start;
1474: int n = sliceLength(start, stop, step);
1475: PyArray ret = new PyArray(type, n);
1476: if (step == 1) {
1477: System.arraycopy(data, start, ret.data, 0, n);
1478: return ret;
1479: }
1480: for (int i = start, j = 0; j < n; i += step, j++) {
1481: Array.set(ret.data, j, Array.get(data, i));
1482: }
1483: return ret;
1484: }
1485:
1486: /**
1487: * Getter for the type code of the array.
1488: * {@link #char2class(char) char2class} describes the possible type codes
1489: * and their meaning.
1490: *
1491: * @return single character type code for the array
1492: */
1493: public String getTypecode() throws PyIgnoreMethodTag {
1494: return typecode;
1495: }
1496:
1497: public int array_index(PyObject value) {
1498: int index = indexInternal(value);
1499: if (index != -1)
1500: return index;
1501: throw Py.ValueError("array.index(" + value + "): " + value
1502: + " not found in array");
1503: }
1504:
1505: /**
1506: * Return the smallest <em>i</em> such that <em>i</em> is the index of
1507: * the first occurrence of <em>value</em> in the array.
1508: *
1509: * @param value
1510: * value to find the index of
1511: * @return index of the first occurance of <em>value</em>
1512: */
1513: public PyObject index(PyObject value) {
1514: return Py.newInteger(array_index(value));
1515: }
1516:
1517: /**
1518: * Return the smallest <em>i</em> such that <em>i</em> is the index of
1519: * the first occurrence of <em>value</em> in the array.
1520: *
1521: * @param value
1522: * value to find the index of
1523: * @return index of the first occurance of <em>value</em>
1524: */
1525: private int indexInternal(PyObject value) {
1526: // note: cpython does not raise type errors based on item type
1527: for (int i = 0; i < delegate.getSize(); i++) {
1528: if (value.equals(Py.java2py(Array.get(data, i)))) {
1529: return i;
1530: }
1531: }
1532: return -1;
1533: }
1534:
1535: public void array_insert(int index, PyObject value) {
1536: insert(index, value);
1537: }
1538:
1539: /**
1540: * Insert a new item with value <em>value</em> in the array before
1541: * position <em>index</em>. Negative values are treated as being relative
1542: * to the end of the array.
1543: *
1544: * @param index
1545: * insert position
1546: * @param value
1547: * value to be inserted into array
1548: */
1549: public void insert(int index, PyObject value) {
1550: delegate.makeInsertSpace(index);
1551: Array.set(data, index, Py.tojava(value, type));
1552: }
1553:
1554: public PyObject array_pop() {
1555: return pop();
1556: }
1557:
1558: public PyObject array_pop(int i) {
1559: return pop(i);
1560: }
1561:
1562: /**
1563: * Removes the item with the index <em>index</em> from the array and
1564: * returns it. The optional argument defaults to -1, so that by default the
1565: * last item is removed and returned.
1566: */
1567: public PyObject pop() {
1568: return pop(-1);
1569: }
1570:
1571: /**
1572: * Removes the item with the index <em>index</em> from the array and
1573: * returns it. The optional argument defaults to -1, so that by default the
1574: * last item is removed and returned.
1575: *
1576: * @param index
1577: * array location to be popped from the array
1578: * @return array element popped from index
1579: */
1580: public PyObject pop(int index) {
1581: // todo: python-style error handling
1582: index = (index < 0) ? delegate.getSize() + index : index;
1583: PyObject ret = Py.java2py(Array.get(data, index));
1584: delegate.remove(index);
1585: return ret;
1586: }
1587:
1588: public void array_remove(PyObject value) {
1589: remove(value);
1590: }
1591:
1592: /**
1593: * Remove the first occurrence of <em>value</em> from the array.
1594: *
1595: * @param value
1596: * array value to be removed
1597: */
1598: public void remove(PyObject value) {
1599: int index = indexInternal(value);
1600: if (index != -1) {
1601: delegate.remove(index);
1602: return;
1603: }
1604: throw Py.ValueError("array.remove(" + value + "): " + value
1605: + " not found in array");
1606: }
1607:
1608: /**
1609: * Repeat the array <em>count</em> times.
1610: *
1611: * @param count
1612: * number of times to repeat the array
1613: * @return A new PyArray object containing the source object repeated
1614: * <em>count</em> times.
1615: */
1616: protected PyObject repeat(int count) {
1617: Object arraycopy = delegate.copyArray();
1618: PyArray ret = new PyArray(type, 0);
1619: for (int i = 0; i < count; i++) {
1620: ret.delegate.appendArray(arraycopy);
1621: }
1622: return ret;
1623: }
1624:
1625: public void array_reverse() {
1626: reverse();
1627: }
1628:
1629: /**
1630: * Reverse the elements in the array
1631: *
1632: */
1633: public void reverse() {
1634: // build a new reversed array and set this.data to it when done
1635: Object array = Array.newInstance(type, Array.getLength(data));
1636: for (int i = 0, lastIndex = delegate.getSize() - 1; i <= lastIndex; i++) {
1637: Array.set(array, lastIndex - i, Array.get(data, i));
1638: }
1639: data = array;
1640: }
1641:
1642: /**
1643: * Set an element in the array - the index needs to exist, this method does
1644: * not automatically extend the array. See
1645: * {@link AbstractArray#setSize(int) AbstractArray.setSize()} or
1646: * {@link AbstractArray#ensureCapacity(int) AbstractArray.ensureCapacity()}
1647: * for ways to extend capacity.
1648: * <p />
1649: *
1650: * This code specifically checks for overflows of the integral types: byte,
1651: * short, int and long.
1652: *
1653: * @param i
1654: * index of the element to be set
1655: * @param value
1656: * value to set the element to
1657: */
1658: protected void set(int i, PyObject value) {
1659: // check for overflow of the integral types
1660: if (type == Byte.TYPE) {
1661: long val;
1662: try {
1663: val = ((Long) value.__tojava__(Long.TYPE)).longValue();
1664: } catch (ClassCastException e) {
1665: throw Py
1666: .TypeError("Type not compatible with array type");
1667: }
1668: if (val < Byte.MIN_VALUE) {
1669: throw Py.OverflowError("value too small for "
1670: + type.getName());
1671: } else if (val > Byte.MAX_VALUE) {
1672: throw Py.OverflowError("value too large for "
1673: + type.getName());
1674: }
1675: } else if (type == Short.TYPE) {
1676: long val;
1677: try {
1678: val = ((Long) value.__tojava__(Long.TYPE)).longValue();
1679: } catch (ClassCastException e) {
1680: throw Py
1681: .TypeError("Type not compatible with array type");
1682: }
1683: if (val < Short.MIN_VALUE) {
1684: throw Py.OverflowError("value too small for "
1685: + type.getName());
1686: } else if (val > Short.MAX_VALUE) {
1687: throw Py.OverflowError("value too large for "
1688: + type.getName());
1689: }
1690: } else if (type == Integer.TYPE) {
1691: long val;
1692: try {
1693: val = ((Long) value.__tojava__(Long.TYPE)).longValue();
1694: } catch (ClassCastException e) {
1695: throw Py
1696: .TypeError("Type not compatible with array type");
1697: }
1698: if (val < Integer.MIN_VALUE) {
1699: throw Py.OverflowError("value too small for "
1700: + type.getName());
1701: } else if (val > Integer.MAX_VALUE) {
1702: throw Py.OverflowError("value too large for "
1703: + type.getName());
1704: }
1705: } else if (type == Long.TYPE) {
1706: Object o;
1707: try {
1708: o = value.__tojava__(Long.TYPE);
1709: } catch (ClassCastException e) {
1710: throw Py
1711: .TypeError("Type not compatible with array type");
1712: }
1713: if (o == Py.NoConversion) {
1714: throw Py.OverflowError("value out of range for long");
1715: }
1716: }
1717: Object o = Py.tojava(value, type);
1718: if (o == Py.NoConversion) {
1719: throw Py.TypeError("Type not compatible with array type");
1720: }
1721: Array.set(data, i, o);
1722: }
1723:
1724: /**
1725: * Sets a slice of the array. <em>value</em> can be a string (for
1726: * <code>byte</code> and <code>char</code> types) or PyArray. If a
1727: * PyArray, its type must be convertible into the type of the target
1728: * PyArray.
1729: *
1730: * @param start
1731: * start index of the delete slice
1732: * @param stop
1733: * end index of the delete slice
1734: * @param step
1735: * stepping increment of the slice
1736: */
1737: protected void setslice(int start, int stop, int step,
1738: PyObject value) {
1739: if (type == Character.TYPE && value instanceof PyString) {
1740: char[] chars = null;
1741: // if (value instanceof PyString) {
1742: if (step != 1) {
1743: throw Py
1744: .ValueError("invalid bounds for setting from string");
1745: }
1746: chars = value.toString().toCharArray();
1747: // }
1748: // else if (value instanceof PyArray &&
1749: // ((PyArray)value).type == Character.TYPE) {
1750: // PyArray other = (PyArray)value;
1751: // chars = (char[])other.delegate.copyArray();
1752: // }
1753: int insertSpace = chars.length - (stop - start);
1754: // adjust the array, either adding space or removing space
1755: if (insertSpace > 0) {
1756: delegate.makeInsertSpace(start, insertSpace);
1757: } else if (insertSpace < 0) {
1758: delegate.remove(start, -insertSpace + start - 1);
1759: }
1760: delegate.replaceSubArray(chars, start);
1761: } else {
1762: if (value instanceof PyString && type == Byte.TYPE) {
1763: byte[] chars = value.toString().getBytes();
1764: if (chars.length == stop - start && step == 1) {
1765: System.arraycopy(chars, 0, data, start,
1766: chars.length);
1767: } else {
1768: throw Py
1769: .ValueError("invalid bounds for setting from string");
1770: }
1771: } else if (value instanceof PyArray) {
1772: PyArray array = (PyArray) value;
1773: int insertSpace = array.delegate.getSize()
1774: - (stop - start);
1775: // adjust the array, either adding space or removing space
1776: // ...snapshot in case "value" is "this"
1777: Object arrayCopy = array.delegate.copyArray();
1778: if (insertSpace > 0) {
1779: delegate.makeInsertSpace(start, insertSpace);
1780: } else if (insertSpace < 0) {
1781: delegate.remove(start, -insertSpace + start - 1);
1782: }
1783: try {
1784: delegate.replaceSubArray(arrayCopy, start);
1785: } catch (IllegalArgumentException e) {
1786: throw Py
1787: .TypeError("Slice typecode '"
1788: + array.typecode
1789: + "' is not compatible with this array (typecode '"
1790: + this .typecode + "')");
1791: }
1792: }
1793: }
1794: }
1795:
1796: public void array_tofile(PyObject f) {
1797: tofile(f);
1798: }
1799:
1800: public void array_write(PyObject f) {
1801: tofile(f);
1802: }
1803:
1804: /**
1805: * Write all items (as machine values) to the file object <em>f</em>.
1806: *
1807: * @param f
1808: * Python builtin file object to write data
1809: */
1810: public void tofile(PyObject f) {
1811: if (!(f instanceof PyFile))
1812: throw Py.TypeError("arg must be open file");
1813: PyFile file = (PyFile) f;
1814: if (file.mode.indexOf("w") == -1
1815: && file.mode.indexOf("a") == -1) {
1816: throw Py
1817: .TypeError("file needs to be in write or append mode");
1818: }
1819: // write via the PyFile
1820: String buffer = tostring();
1821: file.write(buffer);
1822: }
1823:
1824: public PyObject array_tolist() {
1825: return tolist();
1826: }
1827:
1828: /**
1829: * Convert the array to an ordinary list with the same items.
1830: *
1831: * @return array contents as a list
1832: */
1833: public PyObject tolist() {
1834: PyList list = new PyList();
1835: for (int i = 0; i < delegate.getSize(); i++) {
1836: list.append(Py.java2py(Array.get(data, i)));
1837: }
1838: return list;
1839: }
1840:
1841: /**
1842: * Generic stream writer to write the entire contents of the array to the
1843: * stream as primitive types.
1844: *
1845: * @param os
1846: * OutputStream to sink the array data to
1847: *
1848: * @return number of primitives successfully written
1849: *
1850: * @throws IOException
1851: */
1852: private int toStream(OutputStream os) throws IOException {
1853: DataOutputStream dos = new DataOutputStream(os);
1854: if (type.isPrimitive()) {
1855: if (type == Boolean.TYPE) {
1856: for (int i = 0; i < delegate.getSize(); i++)
1857: dos.writeBoolean(Array.getBoolean(data, i));
1858: } else if (type == Byte.TYPE) {
1859: for (int i = 0; i < delegate.getSize(); i++)
1860: dos.writeByte(Array.getByte(data, i));
1861: } else if (type == Character.TYPE) {
1862: for (int i = 0; i < delegate.getSize(); i++)
1863: dos.writeByte((byte) Array.getChar(data, i));
1864: } else if (type == Integer.TYPE) {
1865: for (int i = 0; i < delegate.getSize(); i++)
1866: dos.writeInt(Array.getInt(data, i));
1867: } else if (type == Short.TYPE) {
1868: for (int i = 0; i < delegate.getSize(); i++)
1869: dos.writeShort(Array.getShort(data, i));
1870: } else if (type == Long.TYPE) {
1871: for (int i = 0; i < delegate.getSize(); i++)
1872: dos.writeLong(Array.getLong(data, i));
1873: } else if (type == Float.TYPE) {
1874: for (int i = 0; i < delegate.getSize(); i++)
1875: dos.writeFloat(Array.getFloat(data, i));
1876: } else if (type == Double.TYPE) {
1877: for (int i = 0; i < delegate.getSize(); i++)
1878: dos.writeDouble(Array.getDouble(data, i));
1879: }
1880: }
1881: return dos.size();
1882: }
1883:
1884: public PyObject array_tostring() {
1885: return new PyString(tostring());
1886: }
1887:
1888: /**
1889: * Convert the array to an array of machine values and return the string
1890: * representation (the same sequence of bytes that would be written to a
1891: * file by the {@link #tofile(PyObject) tofile()} method.)
1892: */
1893: public String tostring() {
1894: ByteArrayOutputStream bos = new ByteArrayOutputStream();
1895: try {
1896: toStream(bos);
1897: } catch (IOException e) {
1898: throw Py.IOError(e);
1899: }
1900: try {
1901: // The returned string is used as a Python str with values
1902: // from 0-255. iso-8859-1 maps the byte values into that range.
1903: return new String(bos.toByteArray(), "iso-8859-1");
1904: } catch (UnsupportedEncodingException e) {
1905: throw Py.JavaError(e);
1906: }
1907: }
1908: }
|