0001: // Copyright (c) Corporation for National Research Initiatives
0002: package org.python.core;
0003:
0004: import java.io.FileInputStream;
0005: import java.io.FileOutputStream;
0006: import java.io.IOException;
0007: import java.io.InputStream;
0008: import java.io.OutputStream;
0009: import java.util.LinkedList;
0010:
0011: // To do:
0012: // - readinto(array)
0013: // - modes w, a should disallow reading
0014: // - what to do about buffer size?
0015: // - isatty()
0016: // - fileno() (defined, but always raises an exception, for urllib)
0017:
0018: /**
0019: * A python file wrapper around a java stream, reader/writer or file.
0020: */
0021: public class PyFile extends PyObject {
0022:
0023: private static class FileWrapper {
0024: protected boolean reading;
0025: protected boolean writing;
0026: protected boolean binary;
0027:
0028: void setMode(String mode) {
0029: reading = mode.indexOf('r') >= 0;
0030: writing = mode.indexOf('w') >= 0 || mode.indexOf("+") >= 0
0031: || mode.indexOf('a') >= 0;
0032: binary = mode.indexOf('b') >= 0;
0033: }
0034:
0035: public String read(int n) throws java.io.IOException {
0036: throw new java.io.IOException("file not open for reading");
0037: }
0038:
0039: public int read() throws java.io.IOException {
0040: throw new java.io.IOException("file not open for reading");
0041: }
0042:
0043: public int available() throws java.io.IOException {
0044: throw new java.io.IOException("file not open for reading");
0045: }
0046:
0047: public void unread(int c) throws java.io.IOException {
0048: throw new java.io.IOException("file doesn't support unread");
0049: }
0050:
0051: public void write(String s) throws java.io.IOException {
0052: throw new java.io.IOException("file not open for writing");
0053: }
0054:
0055: public long tell() throws java.io.IOException {
0056: throw new java.io.IOException(
0057: "file doesn't support tell/seek");
0058: }
0059:
0060: public void seek(long pos, int how) throws java.io.IOException {
0061: throw new java.io.IOException(
0062: "file doesn't support tell/seek");
0063: }
0064:
0065: public void flush() throws java.io.IOException {
0066: }
0067:
0068: public void close() throws java.io.IOException {
0069: }
0070:
0071: public void truncate(long position) throws java.io.IOException {
0072: throw new java.io.IOException(
0073: "file doesn't support truncate");
0074: }
0075:
0076: public Object __tojava__(Class cls) throws IOException {
0077: return null;
0078: }
0079:
0080: protected byte[] getBytes(String s) {
0081: // Yes, I known the method is depricated, but it is the fastest
0082: // way of converting between between byte[] and String
0083: if (binary) {
0084: byte[] buf = new byte[s.length()];
0085: s.getBytes(0, s.length(), buf, 0);
0086: return buf;
0087: } else
0088: return s.getBytes();
0089: }
0090:
0091: protected String getString(byte[] buf, int offset, int len) {
0092: // Yes, I known the method is depricated, but it is the fastest
0093: // way of converting between between byte[] and String
0094: if (binary) {
0095: return new String(buf, 0, offset, len);
0096: } else
0097: return new String(buf, offset, len);
0098: }
0099: }
0100:
0101: private static class InputStreamWrapper extends FileWrapper {
0102: java.io.InputStream istream;
0103:
0104: public InputStreamWrapper(java.io.InputStream s) {
0105: istream = s;
0106: }
0107:
0108: public String read(int n) throws java.io.IOException {
0109: if (n == 0)
0110: // nothing to do
0111: return "";
0112: if (n < 0) {
0113: // read until we hit EOF
0114: byte buf[] = new byte[1024];
0115: StringBuffer sbuf = new StringBuffer();
0116: for (int read = 0; read >= 0; read = istream.read(buf))
0117: sbuf.append(getString(buf, 0, read));
0118: return sbuf.toString();
0119: }
0120: // read the next chunk available, but make sure it's at least
0121: // one byte so as not to trip the `empty string' return value
0122: // test done by the caller
0123: //int avail = istream.available();
0124: //n = (n > avail) ? n : avail;
0125: byte buf[] = new byte[n];
0126: int read = istream.read(buf);
0127: if (read < 0)
0128: // EOF encountered
0129: return "";
0130: return new String(buf, 0, 0, read);
0131: }
0132:
0133: public int read() throws java.io.IOException {
0134: return istream.read();
0135: }
0136:
0137: public int available() throws java.io.IOException {
0138: return istream.available();
0139: }
0140:
0141: public void unread(int c) throws java.io.IOException {
0142: ((java.io.PushbackInputStream) istream).unread(c);
0143: }
0144:
0145: public void close() throws java.io.IOException {
0146: istream.close();
0147: }
0148:
0149: public Object __tojava__(Class cls) throws IOException {
0150: if (InputStream.class.isAssignableFrom(cls))
0151: return istream;
0152: return null;
0153: }
0154: }
0155:
0156: private static class OutputStreamWrapper extends FileWrapper {
0157: private java.io.OutputStream ostream;
0158:
0159: public OutputStreamWrapper(java.io.OutputStream s) {
0160: ostream = s;
0161: }
0162:
0163: private static final int MAX_WRITE = 30000;
0164:
0165: public void write(String s) throws java.io.IOException {
0166: byte[] bytes = getBytes(s);
0167: int n = bytes.length;
0168: int i = 0;
0169: while (i < n) {
0170: int sz = n - i;
0171: sz = sz > MAX_WRITE ? MAX_WRITE : sz;
0172: ostream.write(bytes, i, sz);
0173: i += sz;
0174: }
0175: }
0176:
0177: public void flush() throws java.io.IOException {
0178: ostream.flush();
0179: }
0180:
0181: public void close() throws java.io.IOException {
0182: ostream.close();
0183: }
0184:
0185: public Object __tojava__(Class cls) throws IOException {
0186: if (OutputStream.class.isAssignableFrom(cls))
0187: return ostream;
0188: return null;
0189: }
0190: }
0191:
0192: private static class IOStreamWrapper extends InputStreamWrapper {
0193: private java.io.OutputStream ostream;
0194:
0195: public IOStreamWrapper(java.io.InputStream istream,
0196: java.io.OutputStream ostream) {
0197: super (istream);
0198: this .ostream = ostream;
0199: }
0200:
0201: public void write(String s) throws java.io.IOException {
0202: ostream.write(getBytes(s));
0203: }
0204:
0205: public void flush() throws java.io.IOException {
0206: ostream.flush();
0207: }
0208:
0209: public void close() throws java.io.IOException {
0210: ostream.close();
0211: istream.close();
0212: }
0213:
0214: public Object __tojava__(Class cls) throws IOException {
0215: if (OutputStream.class.isAssignableFrom(cls))
0216: return ostream;
0217: return super .__tojava__(cls);
0218: }
0219: }
0220:
0221: private static class WriterWrapper extends FileWrapper {
0222: private java.io.Writer writer;
0223:
0224: public WriterWrapper(java.io.Writer s) {
0225: writer = s;
0226: }
0227:
0228: //private static final int MAX_WRITE = 30000;
0229:
0230: public void write(String s) throws java.io.IOException {
0231: writer.write(s);
0232: }
0233:
0234: public void flush() throws java.io.IOException {
0235: writer.flush();
0236: }
0237:
0238: public void close() throws java.io.IOException {
0239: writer.close();
0240: }
0241: }
0242:
0243: private static class RFileWrapper extends FileWrapper {
0244: /** The default buffer size, in bytes. */
0245: protected static final int defaultBufferSize = 4096;
0246:
0247: /** The underlying java.io.RandomAccessFile. */
0248: protected java.io.RandomAccessFile file;
0249:
0250: /** The offset in bytes from the file start, of the next read or
0251: * write operation. */
0252: protected long filePosition;
0253:
0254: /** The buffer used to load the data. */
0255: protected byte buffer[];
0256:
0257: /** The offset in bytes of the start of the buffer, from the start
0258: * of the file. */
0259: protected long bufferStart;
0260:
0261: /** The offset in bytes of the end of the data in the buffer, from
0262: * the start of the file. This can be calculated from
0263: * <code>bufferStart + dataSize</code>, but it is cached to speed
0264: * up the read( ) method. */
0265: protected long dataEnd;
0266:
0267: /** The size of the data stored in the buffer, in bytes. This may be
0268: * less than the size of the buffer.*/
0269: protected int dataSize;
0270:
0271: /** True if we are at the end of the file. */
0272: protected boolean endOfFile;
0273:
0274: /** True if the data in the buffer has been modified. */
0275: boolean bufferModified = false;
0276:
0277: public RFileWrapper(java.io.RandomAccessFile file) {
0278: this (file, 8092);
0279: }
0280:
0281: public RFileWrapper(java.io.RandomAccessFile file,
0282: int bufferSize) {
0283: this .file = file;
0284: bufferStart = 0;
0285: dataEnd = 0;
0286: dataSize = 0;
0287: filePosition = 0;
0288: buffer = new byte[bufferSize];
0289: endOfFile = false;
0290: }
0291:
0292: public String read(int n) throws java.io.IOException {
0293: if (n < 0) {
0294: n = (int) (file.length() - filePosition);
0295: if (n < 0)
0296: n = 0;
0297: }
0298: byte[] buf = new byte[n];
0299: n = readBytes(buf, 0, n);
0300: if (n < 0)
0301: n = 0;
0302: return getString(buf, 0, n);
0303: }
0304:
0305: private int readBytes(byte b[], int off, int len)
0306: throws IOException {
0307: // Check for end of file.
0308: if (endOfFile)
0309: return -1;
0310:
0311: // See how many bytes are available in the buffer - if none,
0312: // seek to the file position to update the buffer and try again.
0313: int bytesAvailable = (int) (dataEnd - filePosition);
0314: if (bytesAvailable < 1) {
0315: seek(filePosition, 0);
0316: return readBytes(b, off, len);
0317: }
0318:
0319: // Copy as much as we can.
0320: int copyLength = (bytesAvailable >= len) ? len
0321: : bytesAvailable;
0322: System.arraycopy(buffer,
0323: (int) (filePosition - bufferStart), b, off,
0324: copyLength);
0325: filePosition += copyLength;
0326:
0327: // If there is more to copy...
0328: if (copyLength < len) {
0329: int extraCopy = len - copyLength;
0330:
0331: // If the amount remaining is more than a buffer's
0332: // length, read it directly from the file.
0333: if (extraCopy > buffer.length) {
0334: file.seek(filePosition);
0335: extraCopy = file.read(b, off + copyLength, len
0336: - copyLength);
0337: } else {
0338: // ...or read a new buffer full, and copy as much
0339: // as possible...
0340: seek(filePosition, 0);
0341: if (!endOfFile) {
0342: extraCopy = (extraCopy > dataSize) ? dataSize
0343: : extraCopy;
0344: System.arraycopy(buffer, 0, b,
0345: off + copyLength, extraCopy);
0346: } else {
0347: extraCopy = -1;
0348: }
0349: }
0350:
0351: // If we did manage to copy any more, update the file
0352: // position and return the amount copied.
0353: if (extraCopy > 0) {
0354: filePosition += extraCopy;
0355: return copyLength + extraCopy;
0356: }
0357: }
0358:
0359: // Return the amount copied.
0360: return copyLength;
0361: }
0362:
0363: public int read() throws java.io.IOException {
0364: // If the file position is within the data, return the byte...
0365: if (filePosition < dataEnd) {
0366: return (int) (buffer[(int) (filePosition++ - bufferStart)] & 0xff);
0367: } else if (endOfFile) {
0368: // ...or should we indicate EOF...
0369: return -1;
0370: } else {
0371: // ...or seek to fill the buffer, and try again.
0372: seek(filePosition, 0);
0373: return read();
0374: }
0375: }
0376:
0377: public int available() throws java.io.IOException {
0378: return 1;
0379: }
0380:
0381: public void unread(int c) throws java.io.IOException {
0382: filePosition--;
0383: }
0384:
0385: public void write(String s) throws java.io.IOException {
0386: byte[] b = getBytes(s);
0387: int len = b.length;
0388:
0389: // If the amount of data is small (less than a full buffer)...
0390: if (len < buffer.length) {
0391: // If any of the data fits within the buffer...
0392: int spaceInBuffer = 0;
0393: int copyLength = 0;
0394: if (filePosition >= bufferStart)
0395: spaceInBuffer = (int) ((bufferStart + buffer.length) - filePosition);
0396: if (spaceInBuffer > 0) {
0397: // Copy as much as possible to the buffer.
0398: copyLength = (spaceInBuffer > len) ? len
0399: : spaceInBuffer;
0400: System.arraycopy(b, 0, buffer,
0401: (int) (filePosition - bufferStart),
0402: copyLength);
0403: bufferModified = true;
0404: long myDataEnd = filePosition + copyLength;
0405: dataEnd = myDataEnd > dataEnd ? myDataEnd : dataEnd;
0406: dataSize = (int) (dataEnd - bufferStart);
0407: filePosition += copyLength;
0408: }
0409:
0410: // If there is any data remaining, move to the
0411: // new position and copy to the new buffer.
0412: if (copyLength < len) {
0413: seek(filePosition, 0);
0414: System.arraycopy(b, copyLength, buffer,
0415: (int) (filePosition - bufferStart), len
0416: - copyLength);
0417: bufferModified = true;
0418: long myDataEnd = filePosition + (len - copyLength);
0419: dataEnd = myDataEnd > dataEnd ? myDataEnd : dataEnd;
0420: dataSize = (int) (dataEnd - bufferStart);
0421: filePosition += (len - copyLength);
0422: }
0423: } else {
0424: // ...or write a lot of data...
0425:
0426: // Flush the current buffer, and write this data to the file.
0427: if (bufferModified) {
0428: flush();
0429: bufferStart = dataEnd = dataSize = 0;
0430: }
0431: file.write(b, 0, len);
0432: filePosition += len;
0433: }
0434: }
0435:
0436: public long tell() throws java.io.IOException {
0437: return filePosition;
0438: }
0439:
0440: public void seek(long pos, int how) throws java.io.IOException {
0441: if (how == 1)
0442: pos += filePosition;
0443: else if (how == 2)
0444: pos += file.length();
0445: if (pos < 0)
0446: pos = 0;
0447:
0448: // If the seek is into the buffer, just update the file pointer.
0449: if (pos >= bufferStart && pos < dataEnd) {
0450: filePosition = pos;
0451: endOfFile = false;
0452: return;
0453: }
0454:
0455: // If the current buffer is modified, write it to disk.
0456: if (bufferModified)
0457: flush();
0458:
0459: // Move to the position on the disk.
0460: file.seek(pos);
0461: filePosition = file.getFilePointer();
0462: bufferStart = filePosition;
0463:
0464: // Fill the buffer from the disk.
0465: dataSize = file.read(buffer);
0466: if (dataSize < 0) {
0467: dataSize = 0;
0468: endOfFile = true;
0469: } else {
0470: endOfFile = false;
0471: }
0472:
0473: // Cache the position of the buffer end.
0474: dataEnd = bufferStart + dataSize;
0475: }
0476:
0477: public void flush() throws java.io.IOException {
0478: file.seek(bufferStart);
0479: file.write(buffer, 0, dataSize);
0480: bufferModified = false;
0481: file.getFD().sync();
0482: }
0483:
0484: public void close() throws java.io.IOException {
0485: if (writing && bufferModified) {
0486: file.seek(bufferStart);
0487: file.write(buffer, 0, (int) dataSize);
0488: }
0489:
0490: file.close();
0491: }
0492:
0493: public void truncate(long position) throws java.io.IOException {
0494: flush();
0495: try {
0496: // file.setLength(position);
0497: java.lang.reflect.Method m = file.getClass().getMethod(
0498: "setLength", new Class[] { Long.TYPE });
0499: m.invoke(file, new Object[] { new Long(position) });
0500: } catch (NoSuchMethodException exc) {
0501: super .truncate(position);
0502: } catch (SecurityException exc) {
0503: super .truncate(position);
0504: } catch (IllegalAccessException exc) {
0505: super .truncate(position);
0506: } catch (java.lang.reflect.InvocationTargetException exc) {
0507: if (exc.getTargetException() instanceof IOException)
0508: throw (IOException) exc.getTargetException();
0509: super .truncate(position);
0510: }
0511: }
0512:
0513: public Object __tojava__(Class cls) throws IOException {
0514: if (OutputStream.class.isAssignableFrom(cls) && writing)
0515: return new FileOutputStream(file.getFD());
0516: else if (InputStream.class.isAssignableFrom(cls) && reading)
0517: return new FileInputStream(file.getFD());
0518: return super .__tojava__(cls);
0519: }
0520:
0521: }
0522:
0523: private static class TextWrapper extends FileWrapper {
0524: private FileWrapper file;
0525: private String sep;
0526: private boolean sep_is_nl;
0527:
0528: public TextWrapper(FileWrapper file) {
0529: this .file = file;
0530: sep = System.getProperty("line.separator");
0531: sep_is_nl = (sep == "\n");
0532: }
0533:
0534: public String read(int n) throws java.io.IOException {
0535: String s = this .file.read(n);
0536: int index = s.indexOf('\r');
0537: if (index < 0)
0538: return s;
0539: StringBuffer buf = new StringBuffer();
0540: int start = 0;
0541: int end = s.length();
0542: do {
0543: buf.append(s.substring(start, index));
0544: buf.append('\n');
0545: start = index + 1;
0546: if (start < end && s.charAt(start) == '\n')
0547: start++;
0548: index = s.indexOf('\r', start);
0549: } while (index >= 0);
0550: buf.append(s.substring(start));
0551: if (s.endsWith("\r") && file.available() > 0) {
0552: int c = file.read();
0553: if (c != -1 && c != '\n')
0554: file.unread(c);
0555: }
0556: return buf.toString();
0557: }
0558:
0559: public int read() throws java.io.IOException {
0560: int c = file.read();
0561: if (c != '\r')
0562: return c;
0563: if (file.available() > 0) {
0564: c = file.read();
0565: if (c != -1 && c != '\n')
0566: file.unread(c);
0567: }
0568: return '\n';
0569: }
0570:
0571: public void write(String s) throws java.io.IOException {
0572: if (!sep_is_nl) {
0573: int index = s.indexOf('\n');
0574: if (index >= 0) {
0575: StringBuffer buf = new StringBuffer();
0576: int start = 0;
0577: do {
0578: buf.append(s.substring(start, index));
0579: buf.append(sep);
0580: start = index + 1;
0581: index = s.indexOf('\n', start);
0582: } while (index >= 0);
0583: buf.append(s.substring(start));
0584: s = buf.toString();
0585: }
0586: }
0587: this .file.write(s);
0588: }
0589:
0590: public long tell() throws java.io.IOException {
0591: return file.tell();
0592: }
0593:
0594: public void seek(long pos, int how) throws java.io.IOException {
0595: file.seek(pos, how);
0596: }
0597:
0598: public void flush() throws java.io.IOException {
0599: file.flush();
0600: }
0601:
0602: public void close() throws java.io.IOException {
0603: file.close();
0604: }
0605:
0606: public void truncate(long position) throws java.io.IOException {
0607: file.truncate(position);
0608: }
0609:
0610: public Object __tojava__(Class cls) throws IOException {
0611: return file.__tojava__(cls);
0612: }
0613: }
0614:
0615: //~ BEGIN GENERATED REGION -- DO NOT EDIT SEE gexpose.py
0616: /* type info */
0617:
0618: public static final String exposed_name = "file";
0619:
0620: public static final Class exposed_base = PyObject.class;
0621:
0622: public static void typeSetup(PyObject dict, PyType.Newstyle marker) {
0623: dict.__setitem__("mode", new PyGetSetDescr("mode",
0624: PyFile.class, "getMode", null, null));
0625: dict.__setitem__("name", new PyGetSetDescr("name",
0626: PyFile.class, "getName", null, null));
0627: dict.__setitem__("closed", new PyGetSetDescr("closed",
0628: PyFile.class, "getClosed", null, null));
0629: class exposed___cmp__ extends PyBuiltinMethodNarrow {
0630:
0631: exposed___cmp__(PyObject self, PyBuiltinFunction.Info info) {
0632: super (self, info);
0633: }
0634:
0635: public PyBuiltinFunction bind(PyObject self) {
0636: return new exposed___cmp__(self, info);
0637: }
0638:
0639: public PyObject __call__(PyObject arg0) {
0640: int ret = ((PyFile) self).file___cmp__(arg0);
0641: if (ret == -2) {
0642: throw Py.TypeError("file"
0643: + ".__cmp__(x,y) requires y to be '"
0644: + "file" + "', not a '"
0645: + (arg0).getType().fastGetName() + "'");
0646: }
0647: return Py.newInteger(ret);
0648: }
0649:
0650: }
0651: dict.__setitem__("__cmp__", new PyMethodDescr("__cmp__",
0652: PyFile.class, 1, 1, new exposed___cmp__(null, null)));
0653: class exposed___iter__ extends PyBuiltinMethodNarrow {
0654:
0655: exposed___iter__(PyObject self, PyBuiltinFunction.Info info) {
0656: super (self, info);
0657: }
0658:
0659: public PyBuiltinFunction bind(PyObject self) {
0660: return new exposed___iter__(self, info);
0661: }
0662:
0663: public PyObject __call__() {
0664: return ((PyFile) self).file___iter__();
0665: }
0666:
0667: }
0668: dict.__setitem__("__iter__", new PyMethodDescr("__iter__",
0669: PyFile.class, 0, 0, new exposed___iter__(null, null)));
0670: class exposed___iternext__ extends PyBuiltinMethodNarrow {
0671:
0672: exposed___iternext__(PyObject self,
0673: PyBuiltinFunction.Info info) {
0674: super (self, info);
0675: }
0676:
0677: public PyBuiltinFunction bind(PyObject self) {
0678: return new exposed___iternext__(self, info);
0679: }
0680:
0681: public PyObject __call__() {
0682: return ((PyFile) self).file___iternext__();
0683: }
0684:
0685: }
0686: dict.__setitem__("__iternext__", new PyMethodDescr(
0687: "__iternext__", PyFile.class, 0, 0,
0688: new exposed___iternext__(null, null)));
0689: class exposed___nonzero__ extends PyBuiltinMethodNarrow {
0690:
0691: exposed___nonzero__(PyObject self,
0692: PyBuiltinFunction.Info info) {
0693: super (self, info);
0694: }
0695:
0696: public PyBuiltinFunction bind(PyObject self) {
0697: return new exposed___nonzero__(self, info);
0698: }
0699:
0700: public PyObject __call__() {
0701: return Py
0702: .newBoolean(((PyFile) self).file___nonzero__());
0703: }
0704:
0705: }
0706: dict.__setitem__("__nonzero__", new PyMethodDescr(
0707: "__nonzero__", PyFile.class, 0, 0,
0708: new exposed___nonzero__(null, null)));
0709: class exposed___repr__ extends PyBuiltinMethodNarrow {
0710:
0711: exposed___repr__(PyObject self, PyBuiltinFunction.Info info) {
0712: super (self, info);
0713: }
0714:
0715: public PyBuiltinFunction bind(PyObject self) {
0716: return new exposed___repr__(self, info);
0717: }
0718:
0719: public PyObject __call__() {
0720: return new PyString(((PyFile) self).file_toString());
0721: }
0722:
0723: }
0724: dict.__setitem__("__repr__", new PyMethodDescr("__repr__",
0725: PyFile.class, 0, 0, new exposed___repr__(null, null)));
0726: class exposed___str__ extends PyBuiltinMethodNarrow {
0727:
0728: exposed___str__(PyObject self, PyBuiltinFunction.Info info) {
0729: super (self, info);
0730: }
0731:
0732: public PyBuiltinFunction bind(PyObject self) {
0733: return new exposed___str__(self, info);
0734: }
0735:
0736: public PyObject __call__() {
0737: return new PyString(((PyFile) self).file_toString());
0738: }
0739:
0740: }
0741: dict.__setitem__("__str__", new PyMethodDescr("__str__",
0742: PyFile.class, 0, 0, new exposed___str__(null, null)));
0743: class exposed_close extends PyBuiltinMethodNarrow {
0744:
0745: exposed_close(PyObject self, PyBuiltinFunction.Info info) {
0746: super (self, info);
0747: }
0748:
0749: public PyBuiltinFunction bind(PyObject self) {
0750: return new exposed_close(self, info);
0751: }
0752:
0753: public PyObject __call__() {
0754: ((PyFile) self).file_close();
0755: return Py.None;
0756: }
0757:
0758: }
0759: dict.__setitem__("close", new PyMethodDescr("close",
0760: PyFile.class, 0, 0, new exposed_close(null, null)));
0761: class exposed_flush extends PyBuiltinMethodNarrow {
0762:
0763: exposed_flush(PyObject self, PyBuiltinFunction.Info info) {
0764: super (self, info);
0765: }
0766:
0767: public PyBuiltinFunction bind(PyObject self) {
0768: return new exposed_flush(self, info);
0769: }
0770:
0771: public PyObject __call__() {
0772: ((PyFile) self).file_flush();
0773: return Py.None;
0774: }
0775:
0776: }
0777: dict.__setitem__("flush", new PyMethodDescr("flush",
0778: PyFile.class, 0, 0, new exposed_flush(null, null)));
0779: class exposed_read extends PyBuiltinMethodNarrow {
0780:
0781: exposed_read(PyObject self, PyBuiltinFunction.Info info) {
0782: super (self, info);
0783: }
0784:
0785: public PyBuiltinFunction bind(PyObject self) {
0786: return new exposed_read(self, info);
0787: }
0788:
0789: public PyObject __call__(PyObject arg0) {
0790: try {
0791: return new PyString(((PyFile) self).file_read(arg0
0792: .asInt(0)));
0793: } catch (PyObject.ConversionException e) {
0794: String msg;
0795: switch (e.index) {
0796: case 0:
0797: msg = "expected an integer";
0798: break;
0799: default:
0800: msg = "xxx";
0801: }
0802: throw Py.TypeError(msg);
0803: }
0804: }
0805:
0806: public PyObject __call__() {
0807: return new PyString(((PyFile) self).file_read());
0808: }
0809:
0810: }
0811: dict.__setitem__("read", new PyMethodDescr("read",
0812: PyFile.class, 0, 1, new exposed_read(null, null)));
0813: class exposed_readline extends PyBuiltinMethodNarrow {
0814:
0815: exposed_readline(PyObject self, PyBuiltinFunction.Info info) {
0816: super (self, info);
0817: }
0818:
0819: public PyBuiltinFunction bind(PyObject self) {
0820: return new exposed_readline(self, info);
0821: }
0822:
0823: public PyObject __call__(PyObject arg0) {
0824: try {
0825: return new PyString(((PyFile) self)
0826: .file_readline(arg0.asInt(0)));
0827: } catch (PyObject.ConversionException e) {
0828: String msg;
0829: switch (e.index) {
0830: case 0:
0831: msg = "expected an integer";
0832: break;
0833: default:
0834: msg = "xxx";
0835: }
0836: throw Py.TypeError(msg);
0837: }
0838: }
0839:
0840: public PyObject __call__() {
0841: return new PyString(((PyFile) self).file_readline());
0842: }
0843:
0844: }
0845: dict.__setitem__("readline", new PyMethodDescr("readline",
0846: PyFile.class, 0, 1, new exposed_readline(null, null)));
0847: class exposed_readlines extends PyBuiltinMethodNarrow {
0848:
0849: exposed_readlines(PyObject self, PyBuiltinFunction.Info info) {
0850: super (self, info);
0851: }
0852:
0853: public PyBuiltinFunction bind(PyObject self) {
0854: return new exposed_readlines(self, info);
0855: }
0856:
0857: public PyObject __call__(PyObject arg0) {
0858: try {
0859: return ((PyFile) self)
0860: .file_readlines(arg0.asInt(0));
0861: } catch (PyObject.ConversionException e) {
0862: String msg;
0863: switch (e.index) {
0864: case 0:
0865: msg = "expected an integer";
0866: break;
0867: default:
0868: msg = "xxx";
0869: }
0870: throw Py.TypeError(msg);
0871: }
0872: }
0873:
0874: public PyObject __call__() {
0875: return ((PyFile) self).file_readlines();
0876: }
0877:
0878: }
0879: dict.__setitem__("readlines", new PyMethodDescr("readlines",
0880: PyFile.class, 0, 1, new exposed_readlines(null, null)));
0881: class exposed_seek extends PyBuiltinMethodNarrow {
0882:
0883: exposed_seek(PyObject self, PyBuiltinFunction.Info info) {
0884: super (self, info);
0885: }
0886:
0887: public PyBuiltinFunction bind(PyObject self) {
0888: return new exposed_seek(self, info);
0889: }
0890:
0891: public PyObject __call__(PyObject arg0, PyObject arg1) {
0892: try {
0893: ((PyFile) self).file_seek(arg0.asLong(0), arg1
0894: .asInt(1));
0895: return Py.None;
0896: } catch (PyObject.ConversionException e) {
0897: String msg;
0898: switch (e.index) {
0899: case 0:
0900: msg = "expected a long";
0901: break;
0902: case 1:
0903: msg = "expected an integer";
0904: break;
0905: default:
0906: msg = "xxx";
0907: }
0908: throw Py.TypeError(msg);
0909: }
0910: }
0911:
0912: public PyObject __call__(PyObject arg0) {
0913: try {
0914: ((PyFile) self).file_seek(arg0.asLong(0));
0915: return Py.None;
0916: } catch (PyObject.ConversionException e) {
0917: String msg;
0918: switch (e.index) {
0919: case 0:
0920: msg = "expected a long";
0921: break;
0922: default:
0923: msg = "xxx";
0924: }
0925: throw Py.TypeError(msg);
0926: }
0927: }
0928:
0929: }
0930: dict.__setitem__("seek", new PyMethodDescr("seek",
0931: PyFile.class, 1, 2, new exposed_seek(null, null)));
0932: class exposed_tell extends PyBuiltinMethodNarrow {
0933:
0934: exposed_tell(PyObject self, PyBuiltinFunction.Info info) {
0935: super (self, info);
0936: }
0937:
0938: public PyBuiltinFunction bind(PyObject self) {
0939: return new exposed_tell(self, info);
0940: }
0941:
0942: public PyObject __call__() {
0943: return new PyLong(((PyFile) self).file_tell());
0944: }
0945:
0946: }
0947: dict.__setitem__("tell", new PyMethodDescr("tell",
0948: PyFile.class, 0, 0, new exposed_tell(null, null)));
0949: class exposed_next extends PyBuiltinMethodNarrow {
0950:
0951: exposed_next(PyObject self, PyBuiltinFunction.Info info) {
0952: super (self, info);
0953: }
0954:
0955: public PyBuiltinFunction bind(PyObject self) {
0956: return new exposed_next(self, info);
0957: }
0958:
0959: public PyObject __call__() {
0960: return ((PyFile) self).file_next();
0961: }
0962:
0963: }
0964: dict.__setitem__("next", new PyMethodDescr("next",
0965: PyFile.class, 0, 0, new exposed_next(null, null)));
0966: class exposed_truncate extends PyBuiltinMethodNarrow {
0967:
0968: exposed_truncate(PyObject self, PyBuiltinFunction.Info info) {
0969: super (self, info);
0970: }
0971:
0972: public PyBuiltinFunction bind(PyObject self) {
0973: return new exposed_truncate(self, info);
0974: }
0975:
0976: public PyObject __call__(PyObject arg0) {
0977: try {
0978: ((PyFile) self).file_truncate(arg0.asLong(0));
0979: return Py.None;
0980: } catch (PyObject.ConversionException e) {
0981: String msg;
0982: switch (e.index) {
0983: case 0:
0984: msg = "expected a long";
0985: break;
0986: default:
0987: msg = "xxx";
0988: }
0989: throw Py.TypeError(msg);
0990: }
0991: }
0992:
0993: public PyObject __call__() {
0994: ((PyFile) self).file_truncate();
0995: return Py.None;
0996: }
0997:
0998: }
0999: dict.__setitem__("truncate", new PyMethodDescr("truncate",
1000: PyFile.class, 0, 1, new exposed_truncate(null, null)));
1001: class exposed_write extends PyBuiltinMethodNarrow {
1002:
1003: exposed_write(PyObject self, PyBuiltinFunction.Info info) {
1004: super (self, info);
1005: }
1006:
1007: public PyBuiltinFunction bind(PyObject self) {
1008: return new exposed_write(self, info);
1009: }
1010:
1011: public PyObject __call__(PyObject arg0) {
1012: try {
1013: ((PyFile) self).file_write(arg0.asString(0));
1014: return Py.None;
1015: } catch (PyObject.ConversionException e) {
1016: String msg;
1017: switch (e.index) {
1018: case 0:
1019: msg = "expected a string";
1020: break;
1021: default:
1022: msg = "xxx";
1023: }
1024: throw Py.TypeError(msg);
1025: }
1026: }
1027:
1028: }
1029: dict.__setitem__("write", new PyMethodDescr("write",
1030: PyFile.class, 1, 1, new exposed_write(null, null)));
1031: class exposed_writelines extends PyBuiltinMethodNarrow {
1032:
1033: exposed_writelines(PyObject self,
1034: PyBuiltinFunction.Info info) {
1035: super (self, info);
1036: }
1037:
1038: public PyBuiltinFunction bind(PyObject self) {
1039: return new exposed_writelines(self, info);
1040: }
1041:
1042: public PyObject __call__(PyObject arg0) {
1043: ((PyFile) self).file_writelines(arg0);
1044: return Py.None;
1045: }
1046:
1047: }
1048: dict
1049: .__setitem__("writelines", new PyMethodDescr(
1050: "writelines", PyFile.class, 1, 1,
1051: new exposed_writelines(null, null)));
1052: class exposed_xreadlines extends PyBuiltinMethodNarrow {
1053:
1054: exposed_xreadlines(PyObject self,
1055: PyBuiltinFunction.Info info) {
1056: super (self, info);
1057: }
1058:
1059: public PyBuiltinFunction bind(PyObject self) {
1060: return new exposed_xreadlines(self, info);
1061: }
1062:
1063: public PyObject __call__() {
1064: return ((PyFile) self).file_xreadlines();
1065: }
1066:
1067: }
1068: dict
1069: .__setitem__("xreadlines", new PyMethodDescr(
1070: "xreadlines", PyFile.class, 0, 0,
1071: new exposed_xreadlines(null, null)));
1072: class exposed___init__ extends PyBuiltinMethod {
1073:
1074: exposed___init__(PyObject self, PyBuiltinFunction.Info info) {
1075: super (self, info);
1076: }
1077:
1078: public PyBuiltinFunction bind(PyObject self) {
1079: return new exposed___init__(self, info);
1080: }
1081:
1082: public PyObject __call__(PyObject[] args) {
1083: return __call__(args, Py.NoKeywords);
1084: }
1085:
1086: public PyObject __call__(PyObject[] args, String[] keywords) {
1087: ((PyFile) self).file_init(args, keywords);
1088: return Py.None;
1089: }
1090:
1091: }
1092: dict
1093: .__setitem__("__init__", new PyMethodDescr("__init__",
1094: PyFile.class, -1, -1, new exposed___init__(
1095: null, null)));
1096: dict.__setitem__("__new__", new PyNewWrapper(PyFile.class,
1097: "__new__", -1, -1) {
1098:
1099: public PyObject new_impl(boolean init, PyType subtype,
1100: PyObject[] args, String[] keywords) {
1101: PyFile newobj;
1102: if (for_type == subtype) {
1103: newobj = null;
1104: if (init) {
1105: if (args.length == 0) {
1106: newobj = new PyFile();
1107: newobj.file_init(args, keywords);
1108: } else if (args[0] instanceof PyString
1109: || (args[0] instanceof PyJavaInstance && ((PyJavaInstance) args[0]).javaProxy == String.class)) {
1110: // If first arg is a PyString or String, assume its being
1111: // called as a builtin.
1112: newobj = new PyFile();
1113: newobj.file_init(args, keywords);
1114: newobj.closer = new Closer(newobj.file);
1115: } else {
1116: // assume it's being called as a java class
1117: PyJavaClass pjc = new PyJavaClass(
1118: PyFile.class);
1119: newobj = (PyFile) pjc.__call__(args,
1120: keywords);
1121: }
1122: } else {
1123: newobj = new PyFile();
1124: }
1125: } else {
1126: newobj = new PyFileDerived(subtype);
1127: }
1128: return newobj;
1129: }
1130:
1131: });
1132: }
1133:
1134: //~ END GENERATED REGION -- DO NOT EDIT SEE gexpose.py
1135:
1136: public String name;
1137: public String mode;
1138: public boolean softspace;
1139: public boolean closed;
1140:
1141: private FileWrapper file;
1142:
1143: private static java.io.InputStream _pb(java.io.InputStream s,
1144: String mode) {
1145: if (mode.indexOf('b') < 0) {
1146: if (s instanceof java.io.PushbackInputStream) {
1147: return s;
1148: }
1149: return new java.io.PushbackInputStream(s);
1150: }
1151: return s;
1152: }
1153:
1154: final void file_init(PyObject[] args, String[] kwds) {
1155:
1156: ArgParser ap = new ArgParser("file", args, kwds, new String[] {
1157: "name", "mode", "bufsize" }, 1);
1158: String nameArg = ap.getString(0, null);
1159: String modeArg = ap.getString(1, "r");
1160: int buffArg = ap.getInt(2, 0);
1161: file_init(_setup(nameArg, modeArg, buffArg), nameArg, modeArg);
1162: }
1163:
1164: public PyFile() {
1165: //xxx: this constructor should only be used in conjunction with file_init
1166: }
1167:
1168: public PyFile(PyType subType) {
1169: super (subType);
1170: }
1171:
1172: public PyFile(FileWrapper file, String name, String mode) {
1173: file_init(file, name, mode);
1174: }
1175:
1176: private void file_init(FileWrapper file, String name, String mode) {
1177: file.setMode(mode);
1178: this .name = name;
1179: this .mode = mode;
1180: this .softspace = false;
1181: this .closed = false;
1182: if (mode.indexOf('b') < 0) {
1183: this .file = new TextWrapper(file);
1184: } else {
1185: this .file = file;
1186: }
1187: }
1188:
1189: public PyFile(java.io.InputStream istream,
1190: java.io.OutputStream ostream, String name, String mode) {
1191: this (new IOStreamWrapper(_pb(istream, mode), ostream), name,
1192: mode);
1193: }
1194:
1195: public PyFile(java.io.InputStream istream,
1196: java.io.OutputStream ostream, String name) {
1197: this (istream, ostream, name, "r+");
1198: }
1199:
1200: public PyFile(java.io.InputStream istream,
1201: java.io.OutputStream ostream) {
1202: this (istream, ostream, "<???>", "r+");
1203: }
1204:
1205: public PyFile(java.io.InputStream istream, String name, String mode) {
1206: this (new InputStreamWrapper(_pb(istream, mode)), name, mode);
1207: }
1208:
1209: public PyFile(java.io.InputStream istream, String name) {
1210: this (istream, name, "r");
1211: }
1212:
1213: public PyFile(java.io.InputStream istream) {
1214: this (istream, "<???>", "r");
1215: }
1216:
1217: public PyFile(java.io.OutputStream ostream, String name, String mode) {
1218: this (new OutputStreamWrapper(ostream), name, mode);
1219: }
1220:
1221: public PyFile(java.io.OutputStream ostream, String name) {
1222: this (ostream, name, "w");
1223: }
1224:
1225: public PyFile(java.io.OutputStream ostream) {
1226: this (ostream, "<???>", "w");
1227: }
1228:
1229: public PyFile(java.io.Writer ostream, String name, String mode) {
1230: this (new WriterWrapper(ostream), name, mode);
1231: }
1232:
1233: public PyFile(java.io.Writer ostream, String name) {
1234: this (ostream, name, "w");
1235: }
1236:
1237: public PyFile(java.io.Writer ostream) {
1238: this (ostream, "<???>", "w");
1239: }
1240:
1241: public PyFile(java.io.RandomAccessFile file, String name,
1242: String mode) {
1243: this (new RFileWrapper(file), name, mode);
1244: }
1245:
1246: public PyFile(java.io.RandomAccessFile file, String name) {
1247: this (file, name, "r+");
1248: }
1249:
1250: public PyFile(java.io.RandomAccessFile file) {
1251: this (file, "<???>", "r+");
1252: }
1253:
1254: public PyFile(String name, String mode, int bufsize) {
1255: this (_setup(name, mode, bufsize), name, mode);
1256: }
1257:
1258: public void __setattr__(String name, PyObject value) {
1259: // softspace is the only writeable file object attribute
1260: if (name == "softspace")
1261: softspace = value.__nonzero__();
1262: else if (name == "mode" || name == "closed" || name == "name")
1263: throw Py.TypeError("readonly attribute: " + name);
1264: else
1265: throw Py.AttributeError(name);
1266: }
1267:
1268: public Object __tojava__(Class cls) {
1269: Object o = null;
1270: try {
1271: o = file.__tojava__(cls);
1272: } catch (java.io.IOException exc) {
1273: }
1274: if (o == null)
1275: o = super .__tojava__(cls);
1276: return o;
1277: }
1278:
1279: private static FileWrapper _setup(String name, String mode,
1280: int bufsize) {
1281: char c1 = ' ';
1282: char c2 = ' ';
1283: char c3 = ' ';
1284: int n = mode.length();
1285: for (int i = 0; i < n; i++) {
1286: if ("awrtb+".indexOf(mode.charAt(i)) < 0)
1287: throw Py.IOError("Unknown open mode:" + mode);
1288: }
1289: if (n > 0) {
1290: c1 = mode.charAt(0);
1291: if (n > 1) {
1292: c2 = mode.charAt(1);
1293: if (n > 2)
1294: c3 = mode.charAt(2);
1295: }
1296: }
1297: String jmode = "r";
1298: if (c1 == 'r') {
1299: if (c2 == '+' || c3 == '+')
1300: jmode = "rw";
1301: else
1302: jmode = "r";
1303: } else if (c1 == 'w' || c1 == 'a')
1304: jmode = "rw";
1305: try {
1306: java.io.File f = new java.io.File(name);
1307: if (c1 == 'r') {
1308: if (!f.exists()) {
1309: throw new java.io.IOException(
1310: "No such file or directory: " + name);
1311: }
1312: }
1313: if (c1 == 'w') {
1314: // Hack to truncate the file without deleting it:
1315: // create a FileOutputStream for it and close it again.
1316: java.io.FileOutputStream fo = new java.io.FileOutputStream(
1317: f);
1318: fo.close();
1319: fo = null;
1320: }
1321: // What about bufsize?
1322: java.io.RandomAccessFile rfile = new java.io.RandomAccessFile(
1323: f, jmode);
1324: RFileWrapper iofile = new RFileWrapper(rfile);
1325: if (c1 == 'a')
1326: iofile.seek(0, 2);
1327: return iofile;
1328: } catch (java.io.IOException e) {
1329: throw Py.IOError(e);
1330: }
1331: }
1332:
1333: final String file_read(int n) {
1334: if (closed)
1335: err_closed();
1336: StringBuffer data = new StringBuffer();
1337: try {
1338: while (n != 0) {
1339: String s = file.read(n);
1340: int len = s.length();
1341: if (len == 0)
1342: break;
1343: data.append(s);
1344: if (n > 0) {
1345: n -= len;
1346: if (n <= 0)
1347: break;
1348: }
1349: }
1350: } catch (java.io.IOException e) {
1351: throw Py.IOError(e);
1352: }
1353: return data.toString();
1354: }
1355:
1356: public String read(int n) {
1357: return file_read(n);
1358: }
1359:
1360: final String file_read() {
1361: return file_read(-1);
1362: }
1363:
1364: public String read() {
1365: return file_read();
1366: }
1367:
1368: final String file_readline(int max) {
1369: if (closed)
1370: err_closed();
1371: StringBuffer s = new StringBuffer();
1372: while (max < 0 || s.length() < max) {
1373: int c;
1374: try {
1375: c = file.read();
1376: } catch (java.io.IOException e) {
1377: throw Py.IOError(e);
1378: }
1379: if (c < 0)
1380: break;
1381: s.append((char) c);
1382: if ((char) c == '\n')
1383: break;
1384: }
1385: return s.toString();
1386: }
1387:
1388: public String readline(int max) {
1389: return file_readline(max);
1390: }
1391:
1392: public String readline() {
1393: return file_readline();
1394: }
1395:
1396: final String file_readline() {
1397: return file_readline(-1);
1398: }
1399:
1400: final PyObject file_readlines(int sizehint) {
1401: if (closed)
1402: err_closed();
1403: PyList list = new PyList();
1404: int bytesread = 0;
1405: for (;;) {
1406: String s = readline();
1407: int len = s.length();
1408: if (len == 0)
1409: // EOF
1410: break;
1411: bytesread += len;
1412: list.append(new PyString(s));
1413: if (sizehint > 0 && bytesread > sizehint)
1414: break;
1415: }
1416: return list;
1417: }
1418:
1419: public PyObject readlines(int sizehint) {
1420: return file_readlines(sizehint);
1421: }
1422:
1423: final PyObject file_readlines() {
1424: return file_readlines(0);
1425: }
1426:
1427: public PyObject readlines() {
1428: return file_readlines();
1429: }
1430:
1431: public PyObject __iter__() {
1432: return file___iter__();
1433: }
1434:
1435: final PyObject file___iter__() {
1436: return this ;
1437: }
1438:
1439: public PyObject __iternext__() {
1440: return file___iternext__();
1441: }
1442:
1443: final PyObject file___iternext__() {
1444: PyString s = new PyString(readline());
1445: if (s.__len__() == 0)
1446: return null;
1447: return s;
1448: }
1449:
1450: final PyObject file_next() {
1451: PyObject ret = __iternext__();
1452: if (ret == null)
1453: throw Py.StopIteration("");
1454: return ret;
1455: }
1456:
1457: public PyObject next() {
1458: return file_next();
1459: }
1460:
1461: final PyObject file_xreadlines() {
1462: return this ;
1463: }
1464:
1465: public PyObject xreadlines() {
1466: return file_xreadlines();
1467: }
1468:
1469: final void file_write(String s) {
1470: if (closed)
1471: err_closed();
1472: try {
1473: file.write(s);
1474: softspace = false;
1475: } catch (java.io.IOException e) {
1476: throw Py.IOError(e);
1477: }
1478: }
1479:
1480: public void write(String s) {
1481: file_write(s);
1482: }
1483:
1484: final void file_writelines(PyObject a) {
1485: PyObject iter = Py.iter(a,
1486: "writelines() requires an iterable argument");
1487:
1488: PyObject item = null;
1489: while ((item = iter.__iternext__()) != null) {
1490: if (!(item instanceof PyString))
1491: throw Py.TypeError("writelines() argument must be a "
1492: + "sequence of strings");
1493: write(item.toString());
1494: }
1495: }
1496:
1497: public void writelines(PyObject a) {
1498: file_writelines(a);
1499: }
1500:
1501: final long file_tell() {
1502: if (closed)
1503: err_closed();
1504: try {
1505: return file.tell();
1506: } catch (java.io.IOException e) {
1507: throw Py.IOError(e);
1508: }
1509: }
1510:
1511: public long tell() {
1512: return file_tell();
1513: }
1514:
1515: final void file_seek(long pos, int how) {
1516: if (closed)
1517: err_closed();
1518: try {
1519: file.seek(pos, how);
1520: } catch (java.io.IOException e) {
1521: throw Py.IOError(e);
1522: }
1523: }
1524:
1525: public void seek(long pos, int how) {
1526: file_seek(pos, how);
1527: }
1528:
1529: final void file_seek(long pos) {
1530: seek(pos, 0);
1531: }
1532:
1533: public void seek(long pos) {
1534: file_seek(pos);
1535: }
1536:
1537: final void file_flush() {
1538: if (closed)
1539: err_closed();
1540: try {
1541: file.flush();
1542: } catch (java.io.IOException e) {
1543: throw Py.IOError(e);
1544: }
1545: }
1546:
1547: public void flush() {
1548: file_flush();
1549: }
1550:
1551: final void file_close() {
1552: if (closer != null) {
1553: closer.close();
1554: closer = null;
1555: } else {
1556: try {
1557: file.close();
1558: } catch (java.io.IOException e) {
1559: throw Py.IOError(e);
1560: }
1561: }
1562: closed = true;
1563: file = new FileWrapper();
1564: }
1565:
1566: public void close() {
1567: file_close();
1568: }
1569:
1570: final void file_truncate() {
1571: try {
1572: file.truncate(file.tell());
1573: } catch (java.io.IOException e) {
1574: throw Py.IOError(e);
1575: }
1576: }
1577:
1578: public void truncate() {
1579: file_truncate();
1580: }
1581:
1582: final void file_truncate(long position) {
1583: try {
1584: file.truncate(position);
1585: } catch (java.io.IOException e) {
1586: throw Py.IOError(e);
1587: }
1588: }
1589:
1590: public void truncate(long position) {
1591: file_truncate(position);
1592: }
1593:
1594: // TBD: should this be removed? I think it's better to raise an
1595: // AttributeError than an IOError here.
1596: public PyObject fileno() {
1597: throw Py.IOError("fileno() is not supported in jpython");
1598: }
1599:
1600: final String file_toString() {
1601: StringBuffer s = new StringBuffer("<");
1602: if (closed) {
1603: s.append("closed ");
1604: } else {
1605: s.append("open ");
1606: }
1607: s.append("file '");
1608: s.append(name);
1609: s.append("', mode '");
1610: s.append(mode);
1611: s.append("' ");
1612: s.append(Py.idstr(this ));
1613: s.append(">");
1614: return s.toString();
1615: }
1616:
1617: public String toString() {
1618: return file_toString();
1619: }
1620:
1621: final int file___cmp__(PyObject o) {
1622: return super .__cmp__(o);
1623: }
1624:
1625: final boolean file___nonzero__() {
1626: return super .__nonzero__();
1627: }
1628:
1629: private void err_closed() {
1630: throw Py.ValueError("I/O operation on closed file");
1631: }
1632:
1633: public String getMode() {
1634: return mode;
1635: }
1636:
1637: public String getName() {
1638: return name;
1639: }
1640:
1641: public boolean getClosed() {
1642: return closed;
1643: }
1644:
1645: protected void finalize() throws Throwable {
1646: super .finalize();
1647: if (closer != null) {
1648: closer.close();
1649: }
1650: }
1651:
1652: /**
1653: * A mechanism to make sure PyFiles are closed on exit. On creation Closer
1654: * adds itself to a list of Closers that will be run by PyFileCloser on JVM
1655: * shutdown. When a PyFile's close or finalize methods are called, PyFile calls
1656: * its Closer.close which clears Closer out of the shutdown queue.
1657: *
1658: * We use a regular object here rather than WeakReferences and their
1659: * ilk as they may be collected before the shutdown hook runs. There's no
1660: * guarantee that finalize will be called during shutdown, so we can't use
1661: * it. It's vital that this Closer has no reference to the PyFile it's
1662: * closing so the PyFile remains garbage collectable.
1663: */
1664: private static class Closer {
1665:
1666: public Closer(FileWrapper fw) {
1667: this .fw = fw;
1668: //Add ourselves to the queue of Closers to be run on shutdown
1669: synchronized (closers) {
1670: closers.add(this );
1671: }
1672: }
1673:
1674: public void close() {
1675: synchronized (closers) {
1676: if (!closers.remove(this )) {
1677: return;
1678: }
1679: }
1680: _close();
1681: }
1682:
1683: public void _close() {
1684: try {
1685: fw.close();
1686: } catch (java.io.IOException e) {
1687: throw Py.IOError(e);
1688: } finally {
1689: fw = null;
1690: }
1691: }
1692:
1693: private FileWrapper fw;
1694: }
1695:
1696: private Closer closer;
1697:
1698: private static LinkedList closers = new LinkedList();
1699: static {
1700: try {
1701: Runtime.getRuntime().addShutdownHook(new PyFileCloser());
1702: } catch (SecurityException e) {
1703: Py.writeDebug("PyFile", "Can't register file closer hook");
1704: }
1705: }
1706:
1707: private static class PyFileCloser extends Thread {
1708:
1709: public PyFileCloser() {
1710: super ("Jython Shutdown File Closer");
1711: }
1712:
1713: public void run() {
1714: synchronized (closers) {
1715: while (closers.size() > 0) {
1716: try {
1717: ((Closer) closers.removeFirst())._close();
1718: } catch (PyException e) {
1719: }
1720: }
1721: }
1722: }
1723: }
1724:
1725: }
|