📄 cpickle.java
字号:
* @see cPickle#Pickler(PyObject) * @see cPickle#Pickler(PyObject,boolean) */ static public class Pickler { private IOFile file; private boolean bin; /** * Hmm, not documented, perhaps it shouldn't be public? XXX: fixme. */ private PickleMemo memo = new PickleMemo(); /** * To write references to persistent objects, the persistent module * must assign a method to persistent_id which returns either None * or the persistent ID of the object. * For the benefit of persistency modules written using pickle, * it supports the notion of a reference to an object outside * the pickled data stream. * Such objects are referenced by a name, which is an arbitrary * string of printable ASCII characters. */ public PyObject persistent_id = null; /** * Hmm, not documented, perhaps it shouldn't be public? XXX: fixme. */ public PyObject inst_persistent_id = null; public Pickler(PyObject file, boolean bin) { this.file = createIOFile(file); this.bin = bin; } /** * Write a pickled representation of the object. * @param object The object which will be pickled. */ public void dump(PyObject object) { save(object); file.write(STOP); file.flush(); } private static final int get_id(PyObject o) { // we don't pickle Java instances so we don't have to consider that case return System.identityHashCode(o); } // Save name as in pickle.py but semantics are slightly changed. private void put(int i) { if (bin) { if (i < 256) { file.write(BINPUT); file.write((char)i); return; } file.write(LONG_BINPUT); file.write((char)( i & 0xFF)); file.write((char)((i >>> 8) & 0xFF)); file.write((char)((i >>> 16) & 0xFF)); file.write((char)((i >>> 24) & 0xFF)); return; } file.write(PUT); file.write(String.valueOf(i)); file.write("\n"); } // Same name as in pickle.py but semantics are slightly changed. private void get(int i) { if (bin) { if (i < 256) { file.write(BINGET); file.write((char)i); return; } file.write(LONG_BINGET); file.write((char)( i & 0xFF)); file.write((char)((i >>> 8) & 0xFF)); file.write((char)((i >>> 16) & 0xFF)); file.write((char)((i >>> 24) & 0xFF)); return; } file.write(GET); file.write(String.valueOf(i)); file.write("\n"); } private void save(PyObject object) { save(object, false); } private void save(PyObject object, boolean pers_save) { if (!pers_save) { if (persistent_id != null) { PyObject pid = persistent_id.__call__(object); if (pid != Py.None) { save_pers(pid); return; } } } int d = get_id(object); PyClass t = __builtin__.type(object); if (t == TupleType && object.__len__() == 0) { if (bin) save_empty_tuple(object); else save_tuple(object); return; } int m = getMemoPosition(d, object); if (m >= 0) { get(m); return; } if (save_type(object, t)) return; if (inst_persistent_id != null) { PyObject pid = inst_persistent_id.__call__(object); if (pid != Py.None) { save_pers(pid); return; } } PyObject tup = null; PyObject reduce = dispatch_table.__finditem__(t); if (reduce == null) { reduce = object.__findattr__("__reduce__"); if (reduce == null) throw new PyException(UnpickleableError, object); tup = reduce.__call__(); } else { tup = reduce.__call__(object); } if (tup instanceof PyString) { save_global(object, tup); return; } if (!(tup instanceof PyTuple)) { throw new PyException(PicklingError, "Value returned by " + reduce.__repr__() + " must be a tuple"); } int l = tup.__len__(); if (l != 2 && l != 3) { throw new PyException(PicklingError, "tuple returned by " + reduce.__repr__() + " must contain only two or three elements"); } PyObject callable = tup.__finditem__(0); PyObject arg_tup = tup.__finditem__(1); PyObject state = (l > 2) ? tup.__finditem__(2) : Py.None; if (!(arg_tup instanceof PyTuple) && arg_tup != Py.None) { throw new PyException(PicklingError, "Second element of tupe returned by " + reduce.__repr__() + " must be a tuple"); } save_reduce(callable, arg_tup, state); put(putMemo(d, object)); } final private void save_pers(PyObject pid) { if (!bin) { file.write(PERSID); file.write(pid.toString()); file.write("\n"); } else { save(pid, true); file.write(BINPERSID); } } final private void save_reduce(PyObject callable, PyObject arg_tup, PyObject state) { save(callable); save(arg_tup); file.write(REDUCE); if (state != Py.None) { save(state); file.write(BUILD); } } final private boolean save_type(PyObject object, PyClass cls) { //System.out.println("save_type " + object + " " + cls); if (cls == NoneType) save_none(object); else if (cls == StringType) save_string(object); else if (cls == IntType) save_int(object); else if (cls == LongType) save_long(object); else if (cls == FloatType) save_float(object); else if (cls == TupleType) save_tuple(object); else if (cls == ListType) save_list(object); else if (cls == DictionaryType || cls == StringMapType) save_dict(object); else if (cls == InstanceType) save_inst((PyInstance)object); else if (cls == ClassType) save_global(object); else if (cls == FunctionType) save_global(object); else if (cls == BuiltinFunctionType) save_global(object); else return false; return true; } final private void save_none(PyObject object) { file.write(NONE); } final private void save_int(PyObject object) { if (bin) { int l = ((PyInteger)object).getValue(); char i1 = (char)( l & 0xFF); char i2 = (char)((l >>> 8 ) & 0xFF); char i3 = (char)((l >>> 16) & 0xFF); char i4 = (char)((l >>> 24) & 0xFF); if (i3 == '\0' && i4 == '\0') { if (i2 == '\0') { file.write(BININT1); file.write(i1); return; } file.write(BININT2); file.write(i1); file.write(i2); return; } file.write(BININT); file.write(i1); file.write(i2); file.write(i3); file.write(i4); } else { file.write(INT); file.write(object.toString()); file.write("\n"); } } final private void save_long(PyObject object) { file.write(LONG); file.write(object.toString()); file.write("\n"); } final private void save_float(PyObject object) { if (bin) { file.write(BINFLOAT); double value= ((PyFloat) object).getValue(); // It seems that struct.pack('>d', ..) and doubleToLongBits // are the same. Good for me :-) long bits = Double.doubleToLongBits(value); file.write((char)((bits >>> 56) & 0xFF)); file.write((char)((bits >>> 48) & 0xFF)); file.write((char)((bits >>> 40) & 0xFF)); file.write((char)((bits >>> 32) & 0xFF)); file.write((char)((bits >>> 24) & 0xFF)); file.write((char)((bits >>> 16) & 0xFF)); file.write((char)((bits >>> 8) & 0xFF)); file.write((char)((bits >>> 0) & 0xFF)); } else { file.write(FLOAT); file.write(object.toString()); file.write("\n"); } } final private void save_string(PyObject object) { boolean unicode = ((PyString) object).isunicode(); String str = object.toString(); if (bin) { if (unicode) str = codecs.PyUnicode_EncodeUTF8(str, "struct"); int l = str.length(); if (l < 256 && !unicode) { file.write(SHORT_BINSTRING); file.write((char)l); } else { if (unicode) file.write(BINUNICODE); else file.write(BINSTRING); file.write((char)( l & 0xFF)); file.write((char)((l >>> 8 ) & 0xFF)); file.write((char)((l >>> 16) & 0xFF)); file.write((char)((l >>> 24) & 0xFF)); } file.write(str); } else { if (unicode) { file.write(UNICODE); file.write(codecs.PyUnicode_EncodeRawUnicodeEscape(str, "strict", true)); } else { file.write(STRING); file.write(object.__repr__().toString()); } file.write("\n"); } put(putMemo(get_id(object), object)); } final private void save_tuple(PyObject object) { int d = get_id(object); file.write(MARK); int len = object.__len__(); for (int i = 0; i < len; i++) save(object.__finditem__(i)); if (len > 0) { int m = getMemoPosition(d, object); if (m >= 0) { if (bin) { file.write(POP_MARK); get(m); return; } for (int i = 0; i < len+1; i++) file.write(POP); get(m); return; } } file.write(TUPLE); put(putMemo(d, object)); } final private void save_empty_tuple(PyObject object) { file.write(EMPTY_TUPLE); } final private void save_list(PyObject object) { if (bin) file.write(EMPTY_LIST); else { file.write(MARK); file.write(LIST); } put(putMemo(get_id(object), object)); int len = object.__len__(); boolean using_appends = bin && len > 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -