Source Code Cross Referenced for cPickle.java in  » Scripting » jython » org » python » modules » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jython » org.python.modules 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1998 Finn Bock.
0003:         *
0004:         * This program contains material copyrighted by:
0005:         * Copyright (c) 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
0006:         * The Netherlands.
0007:         */
0008:
0009:        /* note about impl:
0010:         instanceof vs. CPython type(.) is .
0011:         */
0012:
0013:        package org.python.modules;
0014:
0015:        import java.util.*;
0016:
0017:        import org.python.core.*;
0018:        import org.python.core.imp;
0019:
0020:        /**
0021:         *
0022:         * From the python documentation:
0023:         * <p>
0024:         * The <tt>cPickle.java</tt> module implements a basic but powerful algorithm
0025:         * for ``pickling'' (a.k.a. serializing, marshalling or flattening) nearly
0026:         * arbitrary Python objects.  This is the act of converting objects to a
0027:         * stream of bytes (and back: ``unpickling'').
0028:         * This is a more primitive notion than
0029:         * persistency -- although <tt>cPickle.java</tt> reads and writes file
0030:         * objects, it does not handle the issue of naming persistent objects, nor
0031:         * the (even more complicated) area of concurrent access to persistent
0032:         * objects.  The <tt>cPickle.java</tt> module can transform a complex object
0033:         * into a byte stream and it can transform the byte stream into an object
0034:         * with the same internal structure.  The most obvious thing to do with these
0035:         * byte streams is to write them onto a file, but it is also conceivable
0036:         * to send them across a network or store them in a database.  The module
0037:         * <tt>shelve</tt> provides a simple interface to pickle and unpickle
0038:         * objects on ``dbm''-style database files.
0039:         * <P>
0040:         * <b>Note:</b> The <tt>cPickle.java</tt> have the same interface as the
0041:         * standard module <tt>pickle</tt>except that <tt>Pickler</tt> and
0042:         * <tt>Unpickler</tt> are factory functions, not classes (so they cannot be
0043:         * used as base classes for inheritance).
0044:         * This limitation is similar for the original cPickle.c version.
0045:         *
0046:         * <P>
0047:         * Unlike the built-in module <tt>marshal</tt>, <tt>cPickle.java</tt> handles
0048:         * the following correctly:
0049:         * <P>
0050:         *
0051:         * <UL><LI>recursive objects (objects containing references to themselves)
0052:         *
0053:         * <P>
0054:         *
0055:         * <LI>object sharing (references to the same object in different places)
0056:         *
0057:         * <P>
0058:         *
0059:         * <LI>user-defined classes and their instances
0060:         *
0061:         * <P>
0062:         *
0063:         * </UL>
0064:         *
0065:         * <P>
0066:         * The data format used by <tt>cPickle.java</tt> is Python-specific.  This has
0067:         * the advantage that there are no restrictions imposed by external
0068:         * standards such as XDR (which can't represent pointer sharing); however
0069:         * it means that non-Python programs may not be able to reconstruct
0070:         * pickled Python objects.
0071:         *
0072:         * <P>
0073:         * By default, the <tt>cPickle.java</tt> data format uses a printable ASCII
0074:         * representation.  This is slightly more voluminous than a binary
0075:         * representation.  The big advantage of using printable ASCII (and of
0076:         * some other characteristics of <tt>cPickle.java</tt>'s representation) is
0077:         * that for debugging or recovery purposes it is possible for a human to read
0078:         * the pickled file with a standard text editor.
0079:         *
0080:         * <P>
0081:         * A binary format, which is slightly more efficient, can be chosen by
0082:         * specifying a nonzero (true) value for the <i>bin</i> argument to the
0083:         * <tt>Pickler</tt> constructor or the <tt>dump()</tt> and <tt>dumps()</tt>
0084:         * functions.  The binary format is not the default because of backwards
0085:         * compatibility with the Python 1.4 pickle module.  In a future version,
0086:         * the default may change to binary.
0087:         *
0088:         * <P>
0089:         * The <tt>cPickle.java</tt> module doesn't handle code objects.
0090:         * <P>
0091:         * For the benefit of persistency modules written using <tt>cPickle.java</tt>,
0092:         * it supports the notion of a reference to an object outside the pickled
0093:         * data stream.  Such objects are referenced by a name, which is an
0094:         * arbitrary string of printable ASCII characters.  The resolution of
0095:         * such names is not defined by the <tt>cPickle.java</tt> module -- the
0096:         * persistent object module will have to implement a method
0097:         * <tt>persistent_load()</tt>.  To write references to persistent objects,
0098:         * the persistent module must define a method <tt>persistent_id()</tt> which
0099:         * returns either <tt>None</tt> or the persistent ID of the object.
0100:         *
0101:         * <P>
0102:         * There are some restrictions on the pickling of class instances.
0103:         *
0104:         * <P>
0105:         * First of all, the class must be defined at the top level in a module.
0106:         * Furthermore, all its instance variables must be picklable.
0107:         *
0108:         * <P>
0109:         *
0110:         * <P>
0111:         * When a pickled class instance is unpickled, its <tt>__init__()</tt> method
0112:         * is normally <i>not</i> invoked.  <b>Note:</b> This is a deviation
0113:         * from previous versions of this module; the change was introduced in
0114:         * Python 1.5b2.  The reason for the change is that in many cases it is
0115:         * desirable to have a constructor that requires arguments; it is a
0116:         * (minor) nuisance to have to provide a <tt>__getinitargs__()</tt> method.
0117:         *
0118:         * <P>
0119:         * If it is desirable that the <tt>__init__()</tt> method be called on
0120:         * unpickling, a class can define a method <tt>__getinitargs__()</tt>,
0121:         * which should return a <i>tuple</i> containing the arguments to be
0122:         * passed to the class constructor (<tt>__init__()</tt>).  This method is
0123:         * called at pickle time; the tuple it returns is incorporated in the
0124:         * pickle for the instance.
0125:         * <P>
0126:         * Classes can further influence how their instances are pickled -- if the
0127:         * class defines the method <tt>__getstate__()</tt>, it is called and the
0128:         * return state is pickled as the contents for the instance, and if the class
0129:         * defines the method <tt>__setstate__()</tt>, it is called with the
0130:         * unpickled state.  (Note that these methods can also be used to
0131:         * implement copying class instances.)  If there is no
0132:         * <tt>__getstate__()</tt> method, the instance's <tt>__dict__</tt> is
0133:         * pickled.  If there is no <tt>__setstate__()</tt> method, the pickled
0134:         * object must be a dictionary and its items are assigned to the new
0135:         * instance's dictionary.  (If a class defines both <tt>__getstate__()</tt>
0136:         * and <tt>__setstate__()</tt>, the state object needn't be a dictionary
0137:         * -- these methods can do what they want.)  This protocol is also used
0138:         * by the shallow and deep copying operations defined in the <tt>copy</tt>
0139:         * module.
0140:         * <P>
0141:         * Note that when class instances are pickled, their class's code and
0142:         * data are not pickled along with them.  Only the instance data are
0143:         * pickled.  This is done on purpose, so you can fix bugs in a class or
0144:         * add methods and still load objects that were created with an earlier
0145:         * version of the class.  If you plan to have long-lived objects that
0146:         * will see many versions of a class, it may be worthwhile to put a version
0147:         * number in the objects so that suitable conversions can be made by the
0148:         * class's <tt>__setstate__()</tt> method.
0149:         *
0150:         * <P>
0151:         * When a class itself is pickled, only its name is pickled -- the class
0152:         * definition is not pickled, but re-imported by the unpickling process.
0153:         * Therefore, the restriction that the class must be defined at the top
0154:         * level in a module applies to pickled classes as well.
0155:         *
0156:         * <P>
0157:         *
0158:         * <P>
0159:         * The interface can be summarized as follows.
0160:         *
0161:         * <P>
0162:         * To pickle an object <tt>x</tt> onto a file <tt>f</tt>, open for writing:
0163:         *
0164:         * <P>
0165:         * <dl><dd><pre>
0166:         * p = pickle.Pickler(f)
0167:         * p.dump(x)
0168:         * </pre></dl>
0169:         *
0170:         * <P>
0171:         * A shorthand for this is:
0172:         *
0173:         * <P>
0174:         * <dl><dd><pre>
0175:         * pickle.dump(x, f)
0176:         * </pre></dl>
0177:         *
0178:         * <P>
0179:         * To unpickle an object <tt>x</tt> from a file <tt>f</tt>, open for reading:
0180:         *
0181:         * <P>
0182:         * <dl><dd><pre>
0183:         * u = pickle.Unpickler(f)
0184:         * x = u.load()
0185:         * </pre></dl>
0186:         *
0187:         * <P>
0188:         * A shorthand is:
0189:         *
0190:         * <P>
0191:         * <dl><dd><pre>
0192:         * x = pickle.load(f)
0193:         * </pre></dl>
0194:         *
0195:         * <P>
0196:         * The <tt>Pickler</tt> class only calls the method <tt>f.write()</tt> with a
0197:         * string argument.  The <tt>Unpickler</tt> calls the methods
0198:         * <tt>f.read()</tt> (with an integer argument) and <tt>f.readline()</tt>
0199:         * (without argument), both returning a string.  It is explicitly allowed to
0200:         * pass non-file objects here, as long as they have the right methods.
0201:         *
0202:         * <P>
0203:         * The constructor for the <tt>Pickler</tt> class has an optional second
0204:         * argument, <i>bin</i>.  If this is present and nonzero, the binary
0205:         * pickle format is used; if it is zero or absent, the (less efficient,
0206:         * but backwards compatible) text pickle format is used.  The
0207:         * <tt>Unpickler</tt> class does not have an argument to distinguish
0208:         * between binary and text pickle formats; it accepts either format.
0209:         *
0210:         * <P>
0211:         * The following types can be pickled:
0212:         *
0213:         * <UL><LI><tt>None</tt>
0214:         *
0215:         * <P>
0216:         *
0217:         * <LI>integers, long integers, floating point numbers
0218:         *
0219:         * <P>
0220:         *
0221:         * <LI>strings
0222:         *
0223:         * <P>
0224:         *
0225:         * <LI>tuples, lists and dictionaries containing only picklable objects
0226:         *
0227:         * <P>
0228:         *
0229:         * <LI>classes that are defined at the top level in a module
0230:         *
0231:         * <P>
0232:         *
0233:         * <LI>instances of such classes whose <tt>__dict__</tt> or
0234:         * <tt>__setstate__()</tt> is picklable
0235:         *
0236:         * <P>
0237:         *
0238:         * </UL>
0239:         *
0240:         * <P>
0241:         * Attempts to pickle unpicklable objects will raise the
0242:         * <tt>PicklingError</tt> exception; when this happens, an unspecified
0243:         * number of bytes may have been written to the file.
0244:         *
0245:         * <P>
0246:         * It is possible to make multiple calls to the <tt>dump()</tt> method of
0247:         * the same <tt>Pickler</tt> instance.  These must then be matched to the
0248:         * same number of calls to the <tt>load()</tt> method of the
0249:         * corresponding <tt>Unpickler</tt> instance.  If the same object is
0250:         * pickled by multiple <tt>dump()</tt> calls, the <tt>load()</tt> will all
0251:         * yield references to the same object.  <i>Warning</i>: this is intended
0252:         * for pickling multiple objects without intervening modifications to the
0253:         * objects or their parts.  If you modify an object and then pickle it
0254:         * again using the same <tt>Pickler</tt> instance, the object is not
0255:         * pickled again -- a reference to it is pickled and the
0256:         * <tt>Unpickler</tt> will return the old value, not the modified one.
0257:         * (There are two problems here: (a) detecting changes, and (b)
0258:         * marshalling a minimal set of changes.  I have no answers.  Garbage
0259:         * Collection may also become a problem here.)
0260:         *
0261:         * <P>
0262:         * Apart from the <tt>Pickler</tt> and <tt>Unpickler</tt> classes, the
0263:         * module defines the following functions, and an exception:
0264:         *
0265:         * <P>
0266:         * <dl><dt><b><tt>dump</tt></a></b> (<var>object, file</var><big>[</big><var>,
0267:         *      bin</var><big>]</big>)
0268:         * <dd>
0269:         * Write a pickled representation of <i>obect</i> to the open file object
0270:         * <i>file</i>.  This is equivalent to
0271:         * "<tt>Pickler(<i>file</i>, <i>bin</i>).dump(<i>object</i>)</tt>".
0272:         * If the optional <i>bin</i> argument is present and nonzero, the binary
0273:         * pickle format is used; if it is zero or absent, the (less efficient)
0274:         * text pickle format is used.
0275:         * </dl>
0276:         *
0277:         * <P>
0278:         * <dl><dt><b><tt>load</tt></a></b> (<var>file</var>)
0279:         * <dd>
0280:         * Read a pickled object from the open file object <i>file</i>.  This is
0281:         * equivalent to "<tt>Unpickler(<i>file</i>).load()</tt>".
0282:         * </dl>
0283:         *
0284:         * <P>
0285:         * <dl><dt><b><tt>dumps</tt></a></b> (<var>object</var><big>[</big><var>,
0286:         *     bin</var><big>]</big>)
0287:         * <dd>
0288:         * Return the pickled representation of the object as a string, instead
0289:         * of writing it to a file.  If the optional <i>bin</i> argument is
0290:         * present and nonzero, the binary pickle format is used; if it is zero
0291:         * or absent, the (less efficient) text pickle format is used.
0292:         * </dl>
0293:         *
0294:         * <P>
0295:         * <dl><dt><b><tt>loads</tt></a></b> (<var>string</var>)
0296:         * <dd>
0297:         * Read a pickled object from a string instead of a file.  Characters in
0298:         * the string past the pickled object's representation are ignored.
0299:         * </dl>
0300:         *
0301:         * <P>
0302:         * <dl><dt><b><a name="l2h-3763"><tt>PicklingError</tt></a></b>
0303:         * <dd>
0304:         * This exception is raised when an unpicklable object is passed to
0305:         * <tt>Pickler.dump()</tt>.
0306:         * </dl>
0307:         *
0308:         *
0309:         * <p>
0310:         * For the complete documentation on the pickle module, please see the
0311:         * "Python Library Reference"
0312:         * <p><hr><p>
0313:         *
0314:         * The module is based on both original pickle.py and the cPickle.c
0315:         * version, except that all mistakes and errors are my own.
0316:         * <p>
0317:         * @author Finn Bock, bckfnn@pipmail.dknet.dk
0318:         * @version cPickle.java,v 1.30 1999/05/15 17:40:12 fb Exp
0319:         */
0320:        public class cPickle implements  ClassDictInit {
0321:            /**
0322:             * The doc string
0323:             */
0324:            public static String __doc__ = "Java implementation and optimization of the Python pickle module\n"
0325:                    + "\n"
0326:                    + "$Id: cPickle.java 2945 2006-09-23 19:35:44Z cgroves $\n";
0327:
0328:            /**
0329:             * The program version.
0330:             */
0331:            public static String __version__ = "1.30";
0332:
0333:            /**
0334:             * File format version we write.
0335:             */
0336:            public static final String format_version = "1.3";
0337:
0338:            /**
0339:             * Old format versions we can read.
0340:             */
0341:            public static final String[] compatible_formats = new String[] {
0342:                    "1.0", "1.1", "1.2" };
0343:
0344:            public static String[] __depends__ = new String[] { "copy_reg", };
0345:
0346:            public static PyObject PickleError;
0347:            public static PyObject PicklingError;
0348:            public static PyObject UnpickleableError;
0349:            public static PyObject UnpicklingError;
0350:
0351:            public static final PyString BadPickleGet = new PyString(
0352:                    "cPickle.BadPickleGet");
0353:
0354:            final static char MARK = '(';
0355:            final static char STOP = '.';
0356:            final static char POP = '0';
0357:            final static char POP_MARK = '1';
0358:            final static char DUP = '2';
0359:            final static char FLOAT = 'F';
0360:            final static char INT = 'I';
0361:            final static char BININT = 'J';
0362:            final static char BININT1 = 'K';
0363:            final static char LONG = 'L';
0364:            final static char BININT2 = 'M';
0365:            final static char NONE = 'N';
0366:            final static char PERSID = 'P';
0367:            final static char BINPERSID = 'Q';
0368:            final static char REDUCE = 'R';
0369:            final static char STRING = 'S';
0370:            final static char BINSTRING = 'T';
0371:            final static char SHORT_BINSTRING = 'U';
0372:            final static char UNICODE = 'V';
0373:            final static char BINUNICODE = 'X';
0374:            final static char APPEND = 'a';
0375:            final static char BUILD = 'b';
0376:            final static char GLOBAL = 'c';
0377:            final static char DICT = 'd';
0378:            final static char EMPTY_DICT = '}';
0379:            final static char APPENDS = 'e';
0380:            final static char GET = 'g';
0381:            final static char BINGET = 'h';
0382:            final static char INST = 'i';
0383:            final static char LONG_BINGET = 'j';
0384:            final static char LIST = 'l';
0385:            final static char EMPTY_LIST = ']';
0386:            final static char OBJ = 'o';
0387:            final static char PUT = 'p';
0388:            final static char BINPUT = 'q';
0389:            final static char LONG_BINPUT = 'r';
0390:            final static char SETITEM = 's';
0391:            final static char TUPLE = 't';
0392:            final static char EMPTY_TUPLE = ')';
0393:            final static char SETITEMS = 'u';
0394:            final static char BINFLOAT = 'G';
0395:
0396:            private static PyDictionary dispatch_table = null;
0397:            private static PyDictionary safe_constructors = null;
0398:
0399:            private static PyType BuiltinFunctionType = PyType
0400:                    .fromClass(PyReflectedFunction.class);
0401:            private static PyType BuiltinMethodType = PyType
0402:                    .fromClass(PyMethod.class);
0403:            private static PyType ClassType = PyType.fromClass(PyClass.class);
0404:            private static PyType TypeType = PyType.fromClass(PyType.class);
0405:            private static PyType DictionaryType = PyType
0406:                    .fromClass(PyDictionary.class);
0407:            private static PyType StringMapType = PyType
0408:                    .fromClass(PyStringMap.class);
0409:            private static PyType FloatType = PyType.fromClass(PyFloat.class);
0410:            private static PyType FunctionType = PyType
0411:                    .fromClass(PyFunction.class);
0412:            private static PyType InstanceType = PyType
0413:                    .fromClass(PyInstance.class);
0414:            private static PyType IntType = PyType.fromClass(PyInteger.class);
0415:            private static PyType ListType = PyType.fromClass(PyList.class);
0416:            private static PyType LongType = PyType.fromClass(PyLong.class);
0417:            private static PyType NoneType = PyType.fromClass(PyNone.class);
0418:            private static PyType StringType = PyType.fromClass(PyString.class);
0419:            private static PyType TupleType = PyType.fromClass(PyTuple.class);
0420:            private static PyType FileType = PyType.fromClass(PyFile.class);
0421:
0422:            private static PyObject dict;
0423:
0424:            /**
0425:             * Initialization when module is imported.
0426:             */
0427:            public static void classDictInit(PyObject dict) {
0428:                cPickle.dict = dict;
0429:
0430:                // XXX: Hack for JPython 1.0.1. By default __builtin__ is not in
0431:                // sys.modules.
0432:                imp.importName("__builtin__", true);
0433:
0434:                PyModule copyreg = (PyModule) importModule("copy_reg");
0435:
0436:                dispatch_table = (PyDictionary) copyreg
0437:                        .__getattr__("dispatch_table");
0438:                safe_constructors = (PyDictionary) copyreg
0439:                        .__getattr__("safe_constructors");
0440:
0441:                PickleError = buildClass("PickleError", Py.Exception,
0442:                        "_PickleError", "");
0443:                PicklingError = buildClass("PicklingError", PickleError,
0444:                        "_empty__init__", "");
0445:                UnpickleableError = buildClass("UnpickleableError",
0446:                        PicklingError, "_UnpickleableError", "");
0447:                UnpicklingError = buildClass("UnpicklingError", PickleError,
0448:                        "_empty__init__", "");
0449:            }
0450:
0451:            // An empty __init__ method
0452:            public static PyObject _empty__init__(PyObject[] arg, String[] kws) {
0453:                PyObject dict = new PyStringMap();
0454:                dict.__setitem__("__module__", new PyString("cPickle"));
0455:                return dict;
0456:            }
0457:
0458:            public static PyObject _PickleError(PyObject[] arg, String[] kws) {
0459:                PyObject dict = _empty__init__(arg, kws);
0460:                dict.__setitem__("__init__",
0461:                        getJavaFunc("_PickleError__init__"));
0462:                dict.__setitem__("__str__", getJavaFunc("_PickleError__str__"));
0463:                return dict;
0464:            }
0465:
0466:            public static void _PickleError__init__(PyObject[] arg, String[] kws) {
0467:                ArgParser ap = new ArgParser("__init__", arg, kws, "self",
0468:                        "args");
0469:                PyObject self = ap.getPyObject(0);
0470:                PyObject args = ap.getList(1);
0471:
0472:                self.__setattr__("args", args);
0473:            }
0474:
0475:            public static PyString _PickleError__str__(PyObject[] arg,
0476:                    String[] kws) {
0477:                ArgParser ap = new ArgParser("__str__", arg, kws, "self");
0478:                PyObject self = ap.getPyObject(0);
0479:
0480:                PyObject args = self.__getattr__("args");
0481:                if (args.__len__() > 0 && args.__getitem__(0).__len__() > 0)
0482:                    return args.__getitem__(0).__str__();
0483:                else
0484:                    return new PyString("(what)");
0485:            }
0486:
0487:            public static PyObject _UnpickleableError(PyObject[] arg,
0488:                    String[] kws) {
0489:                PyObject dict = _empty__init__(arg, kws);
0490:                dict.__setitem__("__init__",
0491:                        getJavaFunc("_UnpickleableError__init__"));
0492:                dict.__setitem__("__str__",
0493:                        getJavaFunc("_UnpickleableError__str__"));
0494:                return dict;
0495:            }
0496:
0497:            public static void _UnpickleableError__init__(PyObject[] arg,
0498:                    String[] kws) {
0499:                ArgParser ap = new ArgParser("__init__", arg, kws, "self",
0500:                        "args");
0501:                PyObject self = ap.getPyObject(0);
0502:                PyObject args = ap.getList(1);
0503:
0504:                self.__setattr__("args", args);
0505:            }
0506:
0507:            public static PyString _UnpickleableError__str__(PyObject[] arg,
0508:                    String[] kws) {
0509:                ArgParser ap = new ArgParser("__str__", arg, kws, "self");
0510:                PyObject self = ap.getPyObject(0);
0511:
0512:                PyObject args = self.__getattr__("args");
0513:                PyObject a = args.__len__() > 0 ? args.__getitem__(0)
0514:                        : new PyString("(what)");
0515:                return new PyString("Cannot pickle %s objects").__mod__(a)
0516:                        .__str__();
0517:            }
0518:
0519:            public cPickle() {
0520:            }
0521:
0522:            /**
0523:             * Returns a pickler instance.
0524:             * @param file      a file-like object, can be a cStringIO.StringIO,
0525:             *                  a PyFile or any python object which implements a
0526:             *                  <i>write</i> method. The data will be written as text.
0527:             * @returns a new Pickler instance.
0528:             */
0529:            public static Pickler Pickler(PyObject file) {
0530:                return new Pickler(file, false);
0531:            }
0532:
0533:            /**
0534:             * Returns a pickler instance.
0535:             * @param file      a file-like object, can be a cStringIO.StringIO,
0536:             *                  a PyFile or any python object which implements a
0537:             *                  <i>write</i> method.
0538:             * @param bin       when true, the output will be written as binary data.
0539:             * @returns         a new Pickler instance.
0540:             */
0541:            public static Pickler Pickler(PyObject file, boolean bin) {
0542:                return new Pickler(file, bin);
0543:            }
0544:
0545:            /**
0546:             * Returns a unpickler instance.
0547:             * @param file      a file-like object, can be a cStringIO.StringIO,
0548:             *                  a PyFile or any python object which implements a
0549:             *                  <i>read</i> and <i>readline</i> method.
0550:             * @returns         a new Unpickler instance.
0551:             */
0552:            public static Unpickler Unpickler(PyObject file) {
0553:                return new Unpickler(file);
0554:            }
0555:
0556:            /**
0557:             * Shorthand function which pickles the object on the file.
0558:             * @param object    a data object which should be pickled.
0559:             * @param file      a file-like object, can be a cStringIO.StringIO,
0560:             *                  a PyFile or any python object which implements a
0561:             *                  <i>write</i>  method. The data will be written as
0562:             *                  text.
0563:             * @returns         a new Unpickler instance.
0564:             */
0565:            public static void dump(PyObject object, PyObject file) {
0566:                dump(object, file, false);
0567:            }
0568:
0569:            /**
0570:             * Shorthand function which pickles the object on the file.
0571:             * @param object    a data object which should be pickled.
0572:             * @param file      a file-like object, can be a cStringIO.StringIO,
0573:             *                  a PyFile or any python object which implements a
0574:             *                  <i>write</i> method.
0575:             * @param bin       when true, the output will be written as binary data.
0576:             * @returns         a new Unpickler instance.
0577:             */
0578:            public static void dump(PyObject object, PyObject file, boolean bin) {
0579:                new Pickler(file, bin).dump(object);
0580:            }
0581:
0582:            /**
0583:             * Shorthand function which pickles and returns the string representation.
0584:             * @param object    a data object which should be pickled.
0585:             * @returns         a string representing the pickled object.
0586:             */
0587:            public static String dumps(PyObject object) {
0588:                return dumps(object, false);
0589:            }
0590:
0591:            /**
0592:             * Shorthand function which pickles and returns the string representation.
0593:             * @param object    a data object which should be pickled.
0594:             * @param bin       when true, the output will be written as binary data.
0595:             * @returns         a string representing the pickled object.
0596:             */
0597:            public static String dumps(PyObject object, boolean bin) {
0598:                cStringIO.StringIO file = cStringIO.StringIO();
0599:                dump(object, file, bin);
0600:                return file.getvalue();
0601:            }
0602:
0603:            /**
0604:             * Shorthand function which unpickles a object from the file and returns
0605:             * the new object.
0606:             * @param file      a file-like object, can be a cStringIO.StringIO,
0607:             *                  a PyFile or any python object which implements a
0608:             *                  <i>read</i> and <i>readline</i> method.
0609:             * @returns         a new object.
0610:             */
0611:            public static Object load(PyObject file) {
0612:                return new Unpickler(file).load();
0613:            }
0614:
0615:            /**
0616:             * Shorthand function which unpickles a object from the string and
0617:             * returns the new object.
0618:             * @param str       a strings which must contain a pickled object
0619:             *                  representation.
0620:             * @returns         a new object.
0621:             */
0622:            public static Object loads(PyObject str) {
0623:                cStringIO.StringIO file = cStringIO.StringIO(str.toString());
0624:                return new Unpickler(file).load();
0625:            }
0626:
0627:            // Factory for creating IOFile representation.
0628:            private static IOFile createIOFile(PyObject file) {
0629:                Object f = file.__tojava__(cStringIO.StringIO.class);
0630:                if (f != Py.NoConversion)
0631:                    return new cStringIOFile((cStringIO.StringIO) file);
0632:                else if (__builtin__.isinstance(file, FileType))
0633:                    return new FileIOFile(file);
0634:                else
0635:                    return new ObjectIOFile(file);
0636:            }
0637:
0638:            // IOFiles encapsulates and optimise access to the different file
0639:            // representation.
0640:            interface IOFile {
0641:                public abstract void write(String str);
0642:
0643:                // Usefull optimization since most data written are chars.
0644:                public abstract void write(char str);
0645:
0646:                public abstract void flush();
0647:
0648:                public abstract String read(int len);
0649:
0650:                // Usefull optimization since all readlines removes the
0651:                // trainling newline.
0652:                public abstract String readlineNoNl();
0653:
0654:            }
0655:
0656:            // Use a cStringIO as a file.
0657:            static class cStringIOFile implements  IOFile {
0658:                cStringIO.StringIO file;
0659:
0660:                cStringIOFile(PyObject file) {
0661:                    this .file = (cStringIO.StringIO) file
0662:                            .__tojava__(Object.class);
0663:                }
0664:
0665:                public void write(String str) {
0666:                    file.write(str);
0667:                }
0668:
0669:                public void write(char ch) {
0670:                    file.writeChar(ch);
0671:                }
0672:
0673:                public void flush() {
0674:                }
0675:
0676:                public String read(int len) {
0677:                    return file.read(len);
0678:                }
0679:
0680:                public String readlineNoNl() {
0681:                    return file.readlineNoNl();
0682:                }
0683:            }
0684:
0685:            // Use a PyFile as a file.
0686:            static class FileIOFile implements  IOFile {
0687:                PyFile file;
0688:
0689:                FileIOFile(PyObject file) {
0690:                    this .file = (PyFile) file.__tojava__(PyFile.class);
0691:                    if (this .file.closed)
0692:                        throw Py.ValueError("I/O operation on closed file");
0693:                }
0694:
0695:                public void write(String str) {
0696:                    file.write(str);
0697:                }
0698:
0699:                public void write(char ch) {
0700:                    file.write(cStringIO.getString(ch));
0701:                }
0702:
0703:                public void flush() {
0704:                }
0705:
0706:                public String read(int len) {
0707:                    return file.read(len).toString();
0708:                }
0709:
0710:                public String readlineNoNl() {
0711:                    String line = file.readline().toString();
0712:                    return line.substring(0, line.length() - 1);
0713:                }
0714:            }
0715:
0716:            // Use any python object as a file.
0717:            static class ObjectIOFile implements  IOFile {
0718:                char[] charr = new char[1];
0719:                StringBuffer buff = new StringBuffer();
0720:                PyObject write;
0721:                PyObject read;
0722:                PyObject readline;
0723:                final int BUF_SIZE = 256;
0724:
0725:                ObjectIOFile(PyObject file) {
0726:                    //          this.file = file;
0727:                    write = file.__findattr__("write");
0728:                    read = file.__findattr__("read");
0729:                    readline = file.__findattr__("readline");
0730:                }
0731:
0732:                public void write(String str) {
0733:                    buff.append(str);
0734:                    if (buff.length() > BUF_SIZE)
0735:                        flush();
0736:                }
0737:
0738:                public void write(char ch) {
0739:                    buff.append(ch);
0740:                    if (buff.length() > BUF_SIZE)
0741:                        flush();
0742:                }
0743:
0744:                public void flush() {
0745:                    write.__call__(new PyString(buff.toString()));
0746:                    buff.setLength(0);
0747:                }
0748:
0749:                public String read(int len) {
0750:                    return read.__call__(new PyInteger(len)).toString();
0751:                }
0752:
0753:                public String readlineNoNl() {
0754:                    String line = readline.__call__().toString();
0755:                    return line.substring(0, line.length() - 1);
0756:                }
0757:            }
0758:
0759:            /**
0760:             * The Pickler object
0761:             * @see cPickle#Pickler(PyObject)
0762:             * @see cPickle#Pickler(PyObject,boolean)
0763:             */
0764:            static public class Pickler {
0765:                private IOFile file;
0766:                private boolean bin;
0767:
0768:                /**
0769:                 * The undocumented attribute fast of the C version of cPickle disables
0770:                 * memoization. Since having memoization on won't break anything, having
0771:                 * this dummy setter for fast here won't break any code expecting it to
0772:                 * do something. However without it code that sets fast fails(ie
0773:                 * test_cpickle.py), so it's worth having.
0774:                 */
0775:                public boolean fast = false;
0776:
0777:                /**
0778:                 * Hmm, not documented, perhaps it shouldn't be public? XXX: fixme.
0779:                 */
0780:                private PickleMemo memo = new PickleMemo();
0781:
0782:                /**
0783:                 * To write references to persistent objects, the persistent module
0784:                 * must assign a method to persistent_id which returns either None
0785:                 * or the persistent ID of the object.
0786:                 * For the benefit of persistency modules written using pickle,
0787:                 * it supports the notion of a reference to an object outside
0788:                 * the pickled data stream.
0789:                 * Such objects are referenced by a name, which is an arbitrary
0790:                 * string of printable ASCII characters.
0791:                 */
0792:                public PyObject persistent_id = null;
0793:
0794:                /**
0795:                 * Hmm, not documented, perhaps it shouldn't be public? XXX: fixme.
0796:                 */
0797:                public PyObject inst_persistent_id = null;
0798:
0799:                public Pickler(PyObject file, boolean bin) {
0800:                    this .file = createIOFile(file);
0801:                    this .bin = bin;
0802:                }
0803:
0804:                /**
0805:                 * Write a pickled representation of the object.
0806:                 * @param object        The object which will be pickled.
0807:                 */
0808:                public void dump(PyObject object) {
0809:                    save(object);
0810:                    file.write(STOP);
0811:                    file.flush();
0812:                }
0813:
0814:                private static final int get_id(PyObject o) {
0815:                    // we don't pickle Java instances so we don't have to consider that case
0816:                    return System.identityHashCode(o);
0817:                }
0818:
0819:                // Save name as in pickle.py but semantics are slightly changed.
0820:                private void put(int i) {
0821:                    if (bin) {
0822:                        if (i < 256) {
0823:                            file.write(BINPUT);
0824:                            file.write((char) i);
0825:                            return;
0826:                        }
0827:                        file.write(LONG_BINPUT);
0828:                        file.write((char) (i & 0xFF));
0829:                        file.write((char) ((i >>> 8) & 0xFF));
0830:                        file.write((char) ((i >>> 16) & 0xFF));
0831:                        file.write((char) ((i >>> 24) & 0xFF));
0832:                        return;
0833:                    }
0834:                    file.write(PUT);
0835:                    file.write(String.valueOf(i));
0836:                    file.write("\n");
0837:                }
0838:
0839:                // Same name as in pickle.py but semantics are slightly changed.
0840:                private void get(int i) {
0841:                    if (bin) {
0842:                        if (i < 256) {
0843:                            file.write(BINGET);
0844:                            file.write((char) i);
0845:                            return;
0846:                        }
0847:                        file.write(LONG_BINGET);
0848:                        file.write((char) (i & 0xFF));
0849:                        file.write((char) ((i >>> 8) & 0xFF));
0850:                        file.write((char) ((i >>> 16) & 0xFF));
0851:                        file.write((char) ((i >>> 24) & 0xFF));
0852:                        return;
0853:                    }
0854:                    file.write(GET);
0855:                    file.write(String.valueOf(i));
0856:                    file.write("\n");
0857:                }
0858:
0859:                private void save(PyObject object) {
0860:                    save(object, false);
0861:                }
0862:
0863:                private void save(PyObject object, boolean pers_save) {
0864:                    if (!pers_save) {
0865:                        if (persistent_id != null) {
0866:                            PyObject pid = persistent_id.__call__(object);
0867:                            if (pid != Py.None) {
0868:                                save_pers(pid);
0869:                                return;
0870:                            }
0871:                        }
0872:                    }
0873:
0874:                    int d = get_id(object);
0875:
0876:                    PyType t = object.getType();
0877:
0878:                    if (t == TupleType && object.__len__() == 0) {
0879:                        if (bin)
0880:                            save_empty_tuple(object);
0881:                        else
0882:                            save_tuple(object);
0883:                        return;
0884:                    }
0885:
0886:                    int m = getMemoPosition(d, object);
0887:                    if (m >= 0) {
0888:                        get(m);
0889:                        return;
0890:                    }
0891:
0892:                    if (save_type(object, t))
0893:                        return;
0894:
0895:                    if (inst_persistent_id != null) {
0896:                        PyObject pid = inst_persistent_id.__call__(object);
0897:                        if (pid != Py.None) {
0898:                            save_pers(pid);
0899:                            return;
0900:                        }
0901:                    }
0902:
0903:                    PyObject tup = null;
0904:                    PyObject reduce = dispatch_table.__finditem__(t);
0905:                    if (reduce == null) {
0906:                        reduce = object.__findattr__("__reduce__");
0907:                        if (reduce == null)
0908:                            throw new PyException(UnpickleableError, object);
0909:                        tup = reduce.__call__();
0910:                    } else {
0911:                        tup = reduce.__call__(object);
0912:                    }
0913:
0914:                    if (tup instanceof  PyString) {
0915:                        save_global(object, tup);
0916:                        return;
0917:                    }
0918:
0919:                    if (!(tup instanceof  PyTuple)) {
0920:                        throw new PyException(PicklingError,
0921:                                "Value returned by " + reduce.__repr__()
0922:                                        + " must be a tuple");
0923:                    }
0924:
0925:                    int l = tup.__len__();
0926:                    if (l != 2 && l != 3) {
0927:                        throw new PyException(
0928:                                PicklingError,
0929:                                "tuple returned by "
0930:                                        + reduce.__repr__()
0931:                                        + " must contain only two or three elements");
0932:                    }
0933:
0934:                    PyObject callable = tup.__finditem__(0);
0935:                    PyObject arg_tup = tup.__finditem__(1);
0936:                    PyObject state = (l > 2) ? tup.__finditem__(2) : Py.None;
0937:
0938:                    if (!(arg_tup instanceof  PyTuple) && arg_tup != Py.None) {
0939:                        throw new PyException(PicklingError,
0940:                                "Second element of tupe returned by "
0941:                                        + reduce.__repr__()
0942:                                        + " must be a tuple");
0943:                    }
0944:
0945:                    save_reduce(callable, arg_tup, state);
0946:
0947:                    put(putMemo(d, object));
0948:                }
0949:
0950:                final private void save_pers(PyObject pid) {
0951:                    if (!bin) {
0952:                        file.write(PERSID);
0953:                        file.write(pid.toString());
0954:                        file.write("\n");
0955:                    } else {
0956:                        save(pid, true);
0957:                        file.write(BINPERSID);
0958:                    }
0959:                }
0960:
0961:                final private void save_reduce(PyObject callable,
0962:                        PyObject arg_tup, PyObject state) {
0963:                    save(callable);
0964:                    save(arg_tup);
0965:                    file.write(REDUCE);
0966:                    if (state != Py.None) {
0967:                        save(state);
0968:                        file.write(BUILD);
0969:                    }
0970:                }
0971:
0972:                final private boolean save_type(PyObject object, PyType type) {
0973:                    //System.out.println("save_type " + object + " " + cls);
0974:                    if (type == NoneType)
0975:                        save_none(object);
0976:                    else if (type == StringType)
0977:                        save_string(object);
0978:                    else if (type == IntType)
0979:                        save_int(object);
0980:                    else if (type == LongType)
0981:                        save_long(object);
0982:                    else if (type == FloatType)
0983:                        save_float(object);
0984:                    else if (type == TupleType)
0985:                        save_tuple(object);
0986:                    else if (type == ListType)
0987:                        save_list(object);
0988:                    else if (type == DictionaryType || type == StringMapType)
0989:                        save_dict(object);
0990:                    else if (type == InstanceType)
0991:                        save_inst((PyInstance) object);
0992:                    else if (type == ClassType)
0993:                        save_global(object);
0994:                    else if (type == TypeType)
0995:                        save_global(object);
0996:                    else if (type == FunctionType)
0997:                        save_global(object);
0998:                    else if (type == BuiltinFunctionType)
0999:                        save_global(object);
1000:                    else
1001:                        return false;
1002:                    return true;
1003:                }
1004:
1005:                final private void save_none(PyObject object) {
1006:                    file.write(NONE);
1007:                }
1008:
1009:                final private void save_int(PyObject object) {
1010:                    if (bin) {
1011:                        int l = ((PyInteger) object).getValue();
1012:                        char i1 = (char) (l & 0xFF);
1013:                        char i2 = (char) ((l >>> 8) & 0xFF);
1014:                        char i3 = (char) ((l >>> 16) & 0xFF);
1015:                        char i4 = (char) ((l >>> 24) & 0xFF);
1016:
1017:                        if (i3 == '\0' && i4 == '\0') {
1018:                            if (i2 == '\0') {
1019:                                file.write(BININT1);
1020:                                file.write(i1);
1021:                                return;
1022:                            }
1023:                            file.write(BININT2);
1024:                            file.write(i1);
1025:                            file.write(i2);
1026:                            return;
1027:                        }
1028:                        file.write(BININT);
1029:                        file.write(i1);
1030:                        file.write(i2);
1031:                        file.write(i3);
1032:                        file.write(i4);
1033:                    } else {
1034:                        file.write(INT);
1035:                        file.write(object.toString());
1036:                        file.write("\n");
1037:                    }
1038:                }
1039:
1040:                final private void save_long(PyObject object) {
1041:                    file.write(LONG);
1042:                    file.write(object.toString());
1043:                    file.write("\n");
1044:                }
1045:
1046:                final private void save_float(PyObject object) {
1047:                    if (bin) {
1048:                        file.write(BINFLOAT);
1049:                        double value = ((PyFloat) object).getValue();
1050:                        // It seems that struct.pack('>d', ..) and doubleToLongBits
1051:                        // are the same. Good for me :-)
1052:                        long bits = Double.doubleToLongBits(value);
1053:                        file.write((char) ((bits >>> 56) & 0xFF));
1054:                        file.write((char) ((bits >>> 48) & 0xFF));
1055:                        file.write((char) ((bits >>> 40) & 0xFF));
1056:                        file.write((char) ((bits >>> 32) & 0xFF));
1057:                        file.write((char) ((bits >>> 24) & 0xFF));
1058:                        file.write((char) ((bits >>> 16) & 0xFF));
1059:                        file.write((char) ((bits >>> 8) & 0xFF));
1060:                        file.write((char) ((bits >>> 0) & 0xFF));
1061:                    } else {
1062:                        file.write(FLOAT);
1063:                        file.write(object.toString());
1064:                        file.write("\n");
1065:                    }
1066:                }
1067:
1068:                final private void save_string(PyObject object) {
1069:                    boolean unicode = ((PyString) object).isunicode();
1070:                    String str = object.toString();
1071:
1072:                    if (bin) {
1073:                        if (unicode)
1074:                            str = codecs.PyUnicode_EncodeUTF8(str, "struct");
1075:                        int l = str.length();
1076:                        if (l < 256 && !unicode) {
1077:                            file.write(SHORT_BINSTRING);
1078:                            file.write((char) l);
1079:                        } else {
1080:                            if (unicode)
1081:                                file.write(BINUNICODE);
1082:                            else
1083:                                file.write(BINSTRING);
1084:                            file.write((char) (l & 0xFF));
1085:                            file.write((char) ((l >>> 8) & 0xFF));
1086:                            file.write((char) ((l >>> 16) & 0xFF));
1087:                            file.write((char) ((l >>> 24) & 0xFF));
1088:                        }
1089:                        file.write(str);
1090:                    } else {
1091:                        if (unicode) {
1092:                            file.write(UNICODE);
1093:                            file.write(codecs.PyUnicode_EncodeRawUnicodeEscape(
1094:                                    str, "strict", true));
1095:                        } else {
1096:                            file.write(STRING);
1097:                            file.write(object.__repr__().toString());
1098:                        }
1099:                        file.write("\n");
1100:                    }
1101:                    put(putMemo(get_id(object), object));
1102:                }
1103:
1104:                final private void save_tuple(PyObject object) {
1105:                    int d = get_id(object);
1106:
1107:                    file.write(MARK);
1108:
1109:                    int len = object.__len__();
1110:
1111:                    for (int i = 0; i < len; i++)
1112:                        save(object.__finditem__(i));
1113:
1114:                    if (len > 0) {
1115:                        int m = getMemoPosition(d, object);
1116:                        if (m >= 0) {
1117:                            if (bin) {
1118:                                file.write(POP_MARK);
1119:                                get(m);
1120:                                return;
1121:                            }
1122:                            for (int i = 0; i < len + 1; i++)
1123:                                file.write(POP);
1124:                            get(m);
1125:                            return;
1126:                        }
1127:                    }
1128:                    file.write(TUPLE);
1129:                    put(putMemo(d, object));
1130:                }
1131:
1132:                final private void save_empty_tuple(PyObject object) {
1133:                    file.write(EMPTY_TUPLE);
1134:                }
1135:
1136:                final private void save_list(PyObject object) {
1137:                    if (bin)
1138:                        file.write(EMPTY_LIST);
1139:                    else {
1140:                        file.write(MARK);
1141:                        file.write(LIST);
1142:                    }
1143:
1144:                    put(putMemo(get_id(object), object));
1145:
1146:                    int len = object.__len__();
1147:                    boolean using_appends = bin && len > 1;
1148:
1149:                    if (using_appends)
1150:                        file.write(MARK);
1151:
1152:                    for (int i = 0; i < len; i++) {
1153:                        save(object.__finditem__(i));
1154:                        if (!using_appends)
1155:                            file.write(APPEND);
1156:                    }
1157:                    if (using_appends)
1158:                        file.write(APPENDS);
1159:                }
1160:
1161:                final private void save_dict(PyObject object) {
1162:                    if (bin)
1163:                        file.write(EMPTY_DICT);
1164:                    else {
1165:                        file.write(MARK);
1166:                        file.write(DICT);
1167:                    }
1168:
1169:                    put(putMemo(get_id(object), object));
1170:
1171:                    PyObject list = object.invoke("keys");
1172:                    int len = list.__len__();
1173:
1174:                    boolean using_setitems = (bin && len > 1);
1175:
1176:                    if (using_setitems)
1177:                        file.write(MARK);
1178:
1179:                    for (int i = 0; i < len; i++) {
1180:                        PyObject key = list.__finditem__(i);
1181:                        PyObject value = object.__finditem__(key);
1182:                        save(key);
1183:                        save(value);
1184:
1185:                        if (!using_setitems)
1186:                            file.write(SETITEM);
1187:                    }
1188:                    if (using_setitems)
1189:                        file.write(SETITEMS);
1190:                }
1191:
1192:                final private void save_inst(PyInstance object) {
1193:                    if (object instanceof  PyJavaInstance)
1194:                        throw new PyException(PicklingError,
1195:                                "Unable to pickle java objects.");
1196:
1197:                    PyClass cls = object.instclass;
1198:
1199:                    PySequence args = null;
1200:                    PyObject getinitargs = object
1201:                            .__findattr__("__getinitargs__");
1202:                    if (getinitargs != null) {
1203:                        args = (PySequence) getinitargs.__call__();
1204:                        // XXX Assert it's a sequence
1205:                        keep_alive(args);
1206:                    }
1207:
1208:                    file.write(MARK);
1209:                    if (bin)
1210:                        save(cls);
1211:
1212:                    if (args != null) {
1213:                        int len = args.__len__();
1214:                        for (int i = 0; i < len; i++)
1215:                            save(args.__finditem__(i));
1216:                    }
1217:
1218:                    int mid = putMemo(get_id(object), object);
1219:                    if (bin) {
1220:                        file.write(OBJ);
1221:                        put(mid);
1222:                    } else {
1223:                        file.write(INST);
1224:                        file.write(cls.__findattr__("__module__").toString());
1225:                        file.write("\n");
1226:                        file.write(cls.__name__);
1227:                        file.write("\n");
1228:                        put(mid);
1229:                    }
1230:
1231:                    PyObject stuff = null;
1232:                    PyObject getstate = object.__findattr__("__getstate__");
1233:                    if (getstate == null) {
1234:                        stuff = object.__dict__;
1235:                    } else {
1236:                        stuff = getstate.__call__();
1237:                        keep_alive(stuff);
1238:                    }
1239:                    save(stuff);
1240:                    file.write(BUILD);
1241:                }
1242:
1243:                final private void save_global(PyObject object) {
1244:                    save_global(object, null);
1245:                }
1246:
1247:                final private void save_global(PyObject object, PyObject name) {
1248:                    if (name == null)
1249:                        name = object.__findattr__("__name__");
1250:
1251:                    PyObject module = object.__findattr__("__module__");
1252:                    if (module == null || module == Py.None)
1253:                        module = whichmodule(object, name);
1254:
1255:                    file.write(GLOBAL);
1256:                    file.write(module.toString());
1257:                    file.write("\n");
1258:                    file.write(name.toString());
1259:                    file.write("\n");
1260:                    put(putMemo(get_id(object), object));
1261:                }
1262:
1263:                final private int getMemoPosition(int id, Object o) {
1264:                    return memo.findPosition(id, o);
1265:                }
1266:
1267:                final private int putMemo(int id, PyObject object) {
1268:                    int memo_len = memo.size() + 1;
1269:                    memo.put(id, memo_len, object);
1270:                    return memo_len;
1271:                }
1272:
1273:                /**
1274:                 * Keeps a reference to the object x in the memo.
1275:                 *
1276:                 * Because we remember objects by their id, we have
1277:                 * to assure that possibly temporary objects are kept
1278:                 * alive by referencing them.
1279:                 * We store a reference at the id of the memo, which should
1280:                 * normally not be used unless someone tries to deepcopy
1281:                 * the memo itself...
1282:                 */
1283:                final private void keep_alive(PyObject obj) {
1284:                    int id = System.identityHashCode(memo);
1285:                    PyList list = (PyList) memo.findValue(id, memo);
1286:                    if (list == null) {
1287:                        list = new PyList();
1288:                        memo.put(id, -1, list);
1289:                    }
1290:                    list.append(obj);
1291:                }
1292:
1293:            }
1294:
1295:            private static Hashtable classmap = new Hashtable();
1296:
1297:            final private static PyObject whichmodule(PyObject cls,
1298:                    PyObject clsname) {
1299:                PyObject name = (PyObject) classmap.get(cls);
1300:                if (name != null)
1301:                    return name;
1302:
1303:                name = new PyString("__main__");
1304:
1305:                // For use with JPython1.0.x
1306:                //PyObject modules = sys.modules;
1307:
1308:                // For use with JPython1.1.x
1309:                //PyObject modules = Py.getSystemState().modules;
1310:
1311:                PyObject sys = imp.importName("sys", true);
1312:                PyObject modules = sys.__findattr__("modules");
1313:                PyObject keylist = modules.invoke("keys");
1314:
1315:                int len = keylist.__len__();
1316:                for (int i = 0; i < len; i++) {
1317:                    PyObject key = keylist.__finditem__(i);
1318:                    PyObject value = modules.__finditem__(key);
1319:
1320:                    if (!key.equals("__main__")
1321:                            && value.__findattr__(clsname.toString().intern()) == cls) {
1322:                        name = key;
1323:                        break;
1324:                    }
1325:                }
1326:
1327:                classmap.put(cls, name);
1328:                //System.out.println(name);
1329:                return name;
1330:            }
1331:
1332:            /*
1333:             * A very specialized and simplified version of PyStringMap. It can
1334:             * only use integers as keys and stores both an integer and an object
1335:             * as value. It is very private!
1336:             */
1337:            static private class PickleMemo {
1338:                //Table of primes to cycle through
1339:                private final int[] primes = { 13, 61, 251, 1021, 4093, 5987,
1340:                        9551, 15683, 19609, 31397, 65521, 131071, 262139,
1341:                        524287, 1048573, 2097143, 4194301, 8388593, 16777213,
1342:                        33554393, 67108859, 134217689, 268435399, 536870909,
1343:                        1073741789, };
1344:
1345:                private transient int[] keys;
1346:                private transient int[] position;
1347:                private transient Object[] values;
1348:
1349:                private int size;
1350:                private transient int filled;
1351:                private transient int prime;
1352:
1353:                public PickleMemo(int capacity) {
1354:                    prime = 0;
1355:                    keys = null;
1356:                    values = null;
1357:                    resize(capacity);
1358:                }
1359:
1360:                public PickleMemo() {
1361:                    this (4);
1362:                }
1363:
1364:                public synchronized int size() {
1365:                    return size;
1366:                }
1367:
1368:                private int findIndex(int key, Object value) {
1369:                    int[] table = keys;
1370:                    int maxindex = table.length;
1371:                    int index = (key & 0x7fffffff) % maxindex;
1372:
1373:                    // Fairly aribtrary choice for stepsize...
1374:                    int stepsize = maxindex / 5;
1375:
1376:                    // Cycle through possible positions for the key;
1377:                    //int collisions = 0;
1378:                    while (true) {
1379:                        int tkey = table[index];
1380:                        if (tkey == key && value == values[index]) {
1381:                            return index;
1382:                        }
1383:                        if (values[index] == null)
1384:                            return -1;
1385:                        index = (index + stepsize) % maxindex;
1386:                    }
1387:                }
1388:
1389:                public int findPosition(int key, Object value) {
1390:                    int idx = findIndex(key, value);
1391:                    if (idx < 0)
1392:                        return -1;
1393:                    return position[idx];
1394:                }
1395:
1396:                public Object findValue(int key, Object value) {
1397:                    int idx = findIndex(key, value);
1398:                    if (idx < 0)
1399:                        return null;
1400:                    return values[idx];
1401:                }
1402:
1403:                private final void insertkey(int key, int pos, Object value) {
1404:                    int[] table = keys;
1405:                    int maxindex = table.length;
1406:                    int index = (key & 0x7fffffff) % maxindex;
1407:
1408:                    // Fairly aribtrary choice for stepsize...
1409:                    int stepsize = maxindex / 5;
1410:
1411:                    // Cycle through possible positions for the key;
1412:                    while (true) {
1413:                        int tkey = table[index];
1414:                        if (values[index] == null) {
1415:                            table[index] = key;
1416:                            position[index] = pos;
1417:                            values[index] = value;
1418:                            filled++;
1419:                            size++;
1420:                            break;
1421:                        } else if (tkey == key && values[index] == value) {
1422:                            position[index] = pos;
1423:                            break;
1424:                        }
1425:                        index = (index + stepsize) % maxindex;
1426:                    }
1427:                }
1428:
1429:                private synchronized final void resize(int capacity) {
1430:                    int p = prime;
1431:                    for (; p < primes.length; p++) {
1432:                        if (primes[p] >= capacity)
1433:                            break;
1434:                    }
1435:                    if (primes[p] < capacity) {
1436:                        throw Py.ValueError("can't make hashtable of size: "
1437:                                + capacity);
1438:                    }
1439:                    capacity = primes[p];
1440:                    prime = p;
1441:
1442:                    int[] oldKeys = keys;
1443:                    int[] oldPositions = position;
1444:                    Object[] oldValues = values;
1445:
1446:                    keys = new int[capacity];
1447:                    position = new int[capacity];
1448:                    values = new Object[capacity];
1449:                    size = 0;
1450:                    filled = 0;
1451:
1452:                    if (oldValues != null) {
1453:                        int n = oldValues.length;
1454:
1455:                        for (int i = 0; i < n; i++) {
1456:                            Object value = oldValues[i];
1457:                            if (value == null)
1458:                                continue;
1459:                            insertkey(oldKeys[i], oldPositions[i], value);
1460:                        }
1461:                    }
1462:                }
1463:
1464:                public void put(int key, int pos, Object value) {
1465:                    if (2 * filled > keys.length)
1466:                        resize(keys.length + 1);
1467:                    insertkey(key, pos, value);
1468:                }
1469:            }
1470:
1471:            /**
1472:             * The Unpickler object. Unpickler instances are create by the factory
1473:             * methods Unpickler.
1474:             * @see cPickle#Unpickler(PyObject)
1475:             */
1476:            static public class Unpickler {
1477:
1478:                private IOFile file;
1479:
1480:                public Hashtable memo = new Hashtable();
1481:
1482:                /**
1483:                 * For the benefit of persistency modules written using pickle,
1484:                 * it supports the notion of a reference to an object outside
1485:                 * the pickled data stream.
1486:                 * Such objects are referenced by a name, which is an arbitrary
1487:                 * string of printable ASCII characters.
1488:                 * The resolution of such names is not defined by the pickle module
1489:                 * -- the persistent object module will have to add a method
1490:                 * persistent_load().
1491:                 */
1492:                public PyObject persistent_load = null;
1493:
1494:                private PyObject mark = new PyString("spam");
1495:
1496:                private int stackTop;
1497:                private PyObject[] stack;
1498:
1499:                Unpickler(PyObject file) {
1500:                    this .file = createIOFile(file);
1501:                }
1502:
1503:                /**
1504:                 * Unpickle and return an instance of the object represented by
1505:                 * the file.
1506:                 */
1507:                public PyObject load() {
1508:                    stackTop = 0;
1509:                    stack = new PyObject[10];
1510:
1511:                    while (true) {
1512:                        String s = file.read(1);
1513:                        //              System.out.println("load:" + s);
1514:                        //              for (int i = 0; i < stackTop; i++)
1515:                        //                  System.out.println("   " + stack[i]);
1516:                        if (s.length() < 1)
1517:                            load_eof();
1518:                        char key = s.charAt(0);
1519:                        switch (key) {
1520:                        case PERSID:
1521:                            load_persid();
1522:                            break;
1523:                        case BINPERSID:
1524:                            load_binpersid();
1525:                            break;
1526:                        case NONE:
1527:                            load_none();
1528:                            break;
1529:                        case INT:
1530:                            load_int();
1531:                            break;
1532:                        case BININT:
1533:                            load_binint();
1534:                            break;
1535:                        case BININT1:
1536:                            load_binint1();
1537:                            break;
1538:                        case BININT2:
1539:                            load_binint2();
1540:                            break;
1541:                        case LONG:
1542:                            load_long();
1543:                            break;
1544:                        case FLOAT:
1545:                            load_float();
1546:                            break;
1547:                        case BINFLOAT:
1548:                            load_binfloat();
1549:                            break;
1550:                        case STRING:
1551:                            load_string();
1552:                            break;
1553:                        case BINSTRING:
1554:                            load_binstring();
1555:                            break;
1556:                        case SHORT_BINSTRING:
1557:                            load_short_binstring();
1558:                            break;
1559:                        case UNICODE:
1560:                            load_unicode();
1561:                            break;
1562:                        case BINUNICODE:
1563:                            load_binunicode();
1564:                            break;
1565:                        case TUPLE:
1566:                            load_tuple();
1567:                            break;
1568:                        case EMPTY_TUPLE:
1569:                            load_empty_tuple();
1570:                            break;
1571:                        case EMPTY_LIST:
1572:                            load_empty_list();
1573:                            break;
1574:                        case EMPTY_DICT:
1575:                            load_empty_dictionary();
1576:                            break;
1577:                        case LIST:
1578:                            load_list();
1579:                            break;
1580:                        case DICT:
1581:                            load_dict();
1582:                            break;
1583:                        case INST:
1584:                            load_inst();
1585:                            break;
1586:                        case OBJ:
1587:                            load_obj();
1588:                            break;
1589:                        case GLOBAL:
1590:                            load_global();
1591:                            break;
1592:                        case REDUCE:
1593:                            load_reduce();
1594:                            break;
1595:                        case POP:
1596:                            load_pop();
1597:                            break;
1598:                        case POP_MARK:
1599:                            load_pop_mark();
1600:                            break;
1601:                        case DUP:
1602:                            load_dup();
1603:                            break;
1604:                        case GET:
1605:                            load_get();
1606:                            break;
1607:                        case BINGET:
1608:                            load_binget();
1609:                            break;
1610:                        case LONG_BINGET:
1611:                            load_long_binget();
1612:                            break;
1613:                        case PUT:
1614:                            load_put();
1615:                            break;
1616:                        case BINPUT:
1617:                            load_binput();
1618:                            break;
1619:                        case LONG_BINPUT:
1620:                            load_long_binput();
1621:                            break;
1622:                        case APPEND:
1623:                            load_append();
1624:                            break;
1625:                        case APPENDS:
1626:                            load_appends();
1627:                            break;
1628:                        case SETITEM:
1629:                            load_setitem();
1630:                            break;
1631:                        case SETITEMS:
1632:                            load_setitems();
1633:                            break;
1634:                        case BUILD:
1635:                            load_build();
1636:                            break;
1637:                        case MARK:
1638:                            load_mark();
1639:                            break;
1640:                        case STOP:
1641:                            return load_stop();
1642:                        }
1643:                    }
1644:                }
1645:
1646:                final private int marker() {
1647:                    for (int k = stackTop - 1; k >= 0; k--)
1648:                        if (stack[k] == mark)
1649:                            return stackTop - k - 1;
1650:                    throw new PyException(UnpicklingError,
1651:                            "Inputstream corrupt, marker not found");
1652:                }
1653:
1654:                final private void load_eof() {
1655:                    throw new PyException(Py.EOFError);
1656:                }
1657:
1658:                final private void load_persid() {
1659:                    String pid = file.readlineNoNl();
1660:                    push(persistent_load.__call__(new PyString(pid)));
1661:                }
1662:
1663:                final private void load_binpersid() {
1664:                    PyObject pid = pop();
1665:                    push(persistent_load.__call__(pid));
1666:                }
1667:
1668:                final private void load_none() {
1669:                    push(Py.None);
1670:                }
1671:
1672:                final private void load_int() {
1673:                    String line = file.readlineNoNl();
1674:                    PyObject value;
1675:                    // The following could be abstracted into a common string
1676:                    // -> int/long method.
1677:                    try {
1678:                        value = Py.newInteger(Integer.parseInt(line));
1679:                    } catch (NumberFormatException e) {
1680:                        try {
1681:                            value = Py.newLong(line);
1682:                        } catch (NumberFormatException e2) {
1683:                            throw Py
1684:                                    .ValueError("could not convert string to int");
1685:                        }
1686:                    }
1687:                    push(value);
1688:                }
1689:
1690:                final private void load_binint() {
1691:                    String s = file.read(4);
1692:                    int x = s.charAt(0) | (s.charAt(1) << 8)
1693:                            | (s.charAt(2) << 16) | (s.charAt(3) << 24);
1694:                    push(new PyInteger(x));
1695:                }
1696:
1697:                final private void load_binint1() {
1698:                    int val = (int) file.read(1).charAt(0);
1699:                    push(new PyInteger(val));
1700:                }
1701:
1702:                final private void load_binint2() {
1703:                    String s = file.read(2);
1704:                    int val = ((int) s.charAt(1)) << 8 | ((int) s.charAt(0));
1705:                    push(new PyInteger(val));
1706:                }
1707:
1708:                final private void load_long() {
1709:                    String line = file.readlineNoNl();
1710:                    push(new PyLong(line.substring(0, line.length() - 1)));
1711:                }
1712:
1713:                final private void load_float() {
1714:                    String line = file.readlineNoNl();
1715:                    push(new PyFloat(Double.valueOf(line).doubleValue()));
1716:                }
1717:
1718:                final private void load_binfloat() {
1719:                    String s = file.read(8);
1720:                    long bits = (long) s.charAt(7) | ((long) s.charAt(6) << 8)
1721:                            | ((long) s.charAt(5) << 16)
1722:                            | ((long) s.charAt(4) << 24)
1723:                            | ((long) s.charAt(3) << 32)
1724:                            | ((long) s.charAt(2) << 40)
1725:                            | ((long) s.charAt(1) << 48)
1726:                            | ((long) s.charAt(0) << 56);
1727:                    push(new PyFloat(Double.longBitsToDouble(bits)));
1728:                }
1729:
1730:                final private void load_string() {
1731:                    String line = file.readlineNoNl();
1732:
1733:                    String value;
1734:                    char quote = line.charAt(0);
1735:                    if (quote != '"' && quote != '\'')
1736:                        throw Py.ValueError("insecure string pickle");
1737:
1738:                    int nslash = 0;
1739:                    int i;
1740:                    char ch = '\0';
1741:                    int n = line.length();
1742:                    for (i = 1; i < n; i++) {
1743:                        ch = line.charAt(i);
1744:                        if (ch == quote && nslash % 2 == 0)
1745:                            break;
1746:                        if (ch == '\\')
1747:                            nslash++;
1748:                        else
1749:                            nslash = 0;
1750:                    }
1751:                    if (ch != quote)
1752:                        throw Py.ValueError("insecure string pickle");
1753:
1754:                    for (i++; i < line.length(); i++) {
1755:                        if (line.charAt(i) > ' ')
1756:                            throw Py.ValueError("insecure string pickle " + i);
1757:                    }
1758:                    value = PyString.decode_UnicodeEscape(line, 1, n - 1,
1759:                            "strict", false);
1760:
1761:                    push(new PyString(value));
1762:                }
1763:
1764:                final private void load_binstring() {
1765:                    String d = file.read(4);
1766:                    int len = d.charAt(0) | (d.charAt(1) << 8)
1767:                            | (d.charAt(2) << 16) | (d.charAt(3) << 24);
1768:                    push(new PyString(file.read(len)));
1769:                }
1770:
1771:                final private void load_short_binstring() {
1772:                    int len = (int) file.read(1).charAt(0);
1773:                    push(new PyString(file.read(len)));
1774:                }
1775:
1776:                final private void load_unicode() {
1777:                    String line = file.readlineNoNl();
1778:                    int n = line.length();
1779:                    String value = codecs.PyUnicode_DecodeRawUnicodeEscape(
1780:                            line, "strict");
1781:                    push(new PyString(value));
1782:                }
1783:
1784:                final private void load_binunicode() {
1785:                    String d = file.read(4);
1786:                    int len = d.charAt(0) | (d.charAt(1) << 8)
1787:                            | (d.charAt(2) << 16) | (d.charAt(3) << 24);
1788:                    String line = file.read(len);
1789:                    push(new PyString(codecs.PyUnicode_DecodeUTF8(line,
1790:                            "strict")));
1791:                }
1792:
1793:                final private void load_tuple() {
1794:                    PyObject[] arr = new PyObject[marker()];
1795:                    pop(arr);
1796:                    pop();
1797:                    push(new PyTuple(arr));
1798:                }
1799:
1800:                final private void load_empty_tuple() {
1801:                    push(new PyTuple(Py.EmptyObjects));
1802:                }
1803:
1804:                final private void load_empty_list() {
1805:                    push(new PyList(Py.EmptyObjects));
1806:                }
1807:
1808:                final private void load_empty_dictionary() {
1809:                    push(new PyDictionary());
1810:                }
1811:
1812:                final private void load_list() {
1813:                    PyObject[] arr = new PyObject[marker()];
1814:                    pop(arr);
1815:                    pop();
1816:                    push(new PyList(arr));
1817:                }
1818:
1819:                final private void load_dict() {
1820:                    int k = marker();
1821:                    PyDictionary d = new PyDictionary();
1822:                    for (int i = 0; i < k; i += 2) {
1823:                        PyObject value = pop();
1824:                        PyObject key = pop();
1825:                        d.__setitem__(key, value);
1826:                    }
1827:                    pop();
1828:                    push(d);
1829:                }
1830:
1831:                final private void load_inst() {
1832:                    PyObject[] args = new PyObject[marker()];
1833:                    pop(args);
1834:                    pop();
1835:
1836:                    String module = file.readlineNoNl();
1837:                    String name = file.readlineNoNl();
1838:                    PyObject klass = find_class(module, name);
1839:
1840:                    PyObject value = null;
1841:                    if (args.length == 0 && klass instanceof  PyClass
1842:                            && klass.__findattr__("__getinitargs__") == null) {
1843:                        value = new PyInstance((PyClass) klass);
1844:                    } else {
1845:                        value = klass.__call__(args);
1846:                    }
1847:                    push(value);
1848:                }
1849:
1850:                final private void load_obj() {
1851:                    PyObject[] args = new PyObject[marker() - 1];
1852:                    pop(args);
1853:                    PyObject klass = pop();
1854:                    pop();
1855:
1856:                    PyObject value = null;
1857:                    if (args.length == 0 && klass instanceof  PyClass
1858:                            && klass.__findattr__("__getinitargs__") == null) {
1859:                        value = new PyInstance((PyClass) klass);
1860:                    } else {
1861:                        value = klass.__call__(args);
1862:                    }
1863:                    push(value);
1864:                }
1865:
1866:                final private void load_global() {
1867:                    String module = file.readlineNoNl();
1868:                    String name = file.readlineNoNl();
1869:                    PyObject klass = find_class(module, name);
1870:                    push(klass);
1871:                }
1872:
1873:                final private PyObject find_class(String module, String name) {
1874:                    PyObject fc = dict.__finditem__("find_global");
1875:                    if (fc != null) {
1876:                        if (fc == Py.None)
1877:                            throw new PyException(UnpicklingError,
1878:                                    "Global and instance pickles are not supported.");
1879:                        return fc.__call__(new PyString(module), new PyString(
1880:                                name));
1881:                    }
1882:
1883:                    PyObject modules = Py.getSystemState().modules;
1884:                    PyObject mod = modules.__finditem__(module.intern());
1885:                    if (mod == null) {
1886:                        mod = importModule(module);
1887:                    }
1888:                    PyObject global = mod.__findattr__(name.intern());
1889:                    if (global == null) {
1890:                        throw new PyException(Py.SystemError,
1891:                                "Failed to import class " + name
1892:                                        + " from module " + module);
1893:                    }
1894:                    return global;
1895:                }
1896:
1897:                final private void load_reduce() {
1898:                    PyObject arg_tup = pop();
1899:                    PyObject callable = pop();
1900:                    if (!((callable instanceof  PyClass) || (callable instanceof  PyType))) {
1901:                        if (safe_constructors.__finditem__(callable) == null) {
1902:                            if (callable
1903:                                    .__findattr__("__safe_for_unpickling__") == null)
1904:                                throw new PyException(UnpicklingError, callable
1905:                                        + " is not safe for unpickling");
1906:                        }
1907:                    }
1908:
1909:                    PyObject value = null;
1910:                    if (arg_tup == Py.None) {
1911:                        // XXX __basicnew__ ?
1912:                        value = callable.__findattr__("__basicnew__")
1913:                                .__call__();
1914:                    } else {
1915:                        value = callable.__call__(make_array(arg_tup));
1916:                    }
1917:                    push(value);
1918:                }
1919:
1920:                final private PyObject[] make_array(PyObject seq) {
1921:                    int n = seq.__len__();
1922:                    PyObject[] objs = new PyObject[n];
1923:
1924:                    for (int i = 0; i < n; i++)
1925:                        objs[i] = seq.__finditem__(i);
1926:                    return objs;
1927:                }
1928:
1929:                final private void load_pop() {
1930:                    pop();
1931:                }
1932:
1933:                final private void load_pop_mark() {
1934:                    pop(marker());
1935:                }
1936:
1937:                final private void load_dup() {
1938:                    push(peek());
1939:                }
1940:
1941:                final private void load_get() {
1942:                    String py_str = file.readlineNoNl();
1943:                    PyObject value = (PyObject) memo.get(py_str);
1944:                    if (value == null)
1945:                        throw new PyException(BadPickleGet, py_str);
1946:                    push(value);
1947:                }
1948:
1949:                final private void load_binget() {
1950:                    String py_key = String
1951:                            .valueOf((int) file.read(1).charAt(0));
1952:                    PyObject value = (PyObject) memo.get(py_key);
1953:                    if (value == null)
1954:                        throw new PyException(BadPickleGet, py_key);
1955:                    push(value);
1956:                }
1957:
1958:                final private void load_long_binget() {
1959:                    String d = file.read(4);
1960:                    int i = d.charAt(0) | (d.charAt(1) << 8)
1961:                            | (d.charAt(2) << 16) | (d.charAt(3) << 24);
1962:                    String py_key = String.valueOf(i);
1963:                    PyObject value = (PyObject) memo.get(py_key);
1964:                    if (value == null)
1965:                        throw new PyException(BadPickleGet, py_key);
1966:                    push(value);
1967:                }
1968:
1969:                final private void load_put() {
1970:                    memo.put(file.readlineNoNl(), peek());
1971:                }
1972:
1973:                final private void load_binput() {
1974:                    int i = (int) file.read(1).charAt(0);
1975:                    memo.put(String.valueOf(i), peek());
1976:                }
1977:
1978:                final private void load_long_binput() {
1979:                    String d = file.read(4);
1980:                    int i = d.charAt(0) | (d.charAt(1) << 8)
1981:                            | (d.charAt(2) << 16) | (d.charAt(3) << 24);
1982:                    memo.put(String.valueOf(i), peek());
1983:                }
1984:
1985:                final private void load_append() {
1986:                    PyObject value = pop();
1987:                    PyList list = (PyList) peek();
1988:                    list.append(value);
1989:                }
1990:
1991:                final private void load_appends() {
1992:                    int mark = marker();
1993:                    PyList list = (PyList) peek(mark + 1);
1994:                    for (int i = mark - 1; i >= 0; i--)
1995:                        list.append(peek(i));
1996:                    pop(mark + 1);
1997:                }
1998:
1999:                final private void load_setitem() {
2000:                    PyObject value = pop();
2001:                    PyObject key = pop();
2002:                    PyDictionary dict = (PyDictionary) peek();
2003:                    dict.__setitem__(key, value);
2004:                }
2005:
2006:                final private void load_setitems() {
2007:                    int mark = marker();
2008:                    PyDictionary dict = (PyDictionary) peek(mark + 1);
2009:                    for (int i = 0; i < mark; i += 2) {
2010:                        PyObject key = peek(i + 1);
2011:                        PyObject value = peek(i);
2012:                        dict.__setitem__(key, value);
2013:                    }
2014:                    pop(mark + 1);
2015:                }
2016:
2017:                final private void load_build() {
2018:                    PyObject value = pop();
2019:                    PyInstance inst = (PyInstance) peek();
2020:                    PyObject setstate = inst.__findattr__("__setstate__");
2021:                    if (setstate == null) {
2022:                        inst.__dict__.__findattr__("update").__call__(value);
2023:                    } else {
2024:                        setstate.__call__(value);
2025:                    }
2026:                }
2027:
2028:                final private void load_mark() {
2029:                    push(mark);
2030:                }
2031:
2032:                final private PyObject load_stop() {
2033:                    return pop();
2034:                }
2035:
2036:                final private PyObject peek() {
2037:                    return stack[stackTop - 1];
2038:                }
2039:
2040:                final private PyObject peek(int count) {
2041:                    return stack[stackTop - count - 1];
2042:                }
2043:
2044:                final private PyObject pop() {
2045:                    PyObject val = stack[--stackTop];
2046:                    stack[stackTop] = null;
2047:                    return val;
2048:                }
2049:
2050:                final private void pop(int count) {
2051:                    for (int i = 0; i < count; i++)
2052:                        stack[--stackTop] = null;
2053:                }
2054:
2055:                final private void pop(PyObject[] arr) {
2056:                    int len = arr.length;
2057:                    System.arraycopy(stack, stackTop - len, arr, 0, len);
2058:                    stackTop -= len;
2059:                }
2060:
2061:                final private void push(PyObject val) {
2062:                    if (stackTop >= stack.length) {
2063:                        PyObject[] newStack = new PyObject[(stackTop + 1) * 2];
2064:                        System.arraycopy(stack, 0, newStack, 0, stack.length);
2065:                        stack = newStack;
2066:                    }
2067:                    stack[stackTop++] = val;
2068:                }
2069:            }
2070:
2071:            private static PyObject importModule(String name) {
2072:                PyObject silly_list = new PyTuple(new PyString[] { Py
2073:                        .newString("__doc__"), });
2074:                return __builtin__.__import__(name, null, null, silly_list);
2075:            }
2076:
2077:            private static PyObject getJavaFunc(String name) {
2078:                return Py.newJavaFunc(cPickle.class, name);
2079:            }
2080:
2081:            private static PyObject buildClass(String classname,
2082:                    PyObject super class, String classCodeName, String doc) {
2083:                PyObject[] sclass = Py.EmptyObjects;
2084:                if (super class != null)
2085:                    sclass = new PyObject[] { super class };
2086:                PyObject cls = Py.makeClass(classname, sclass, Py.newJavaCode(
2087:                        cPickle.class, classCodeName), new PyString(doc));
2088:                return cls;
2089:            }
2090:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.