Source

pyobjc / pyobjc-core / Modules / objc / OC_PythonData.m

Diff from to

pyobjc-core/Modules/objc/OC_PythonData.m

 	return res;
 }
 
+
 - (id)initWithPythonObject:(PyObject*)v
 {
 	self = [super init];
 	return rval;
 }
 
+-(Class)classForCoder
+{
+	return [OC_PythonData class];
+}
+
+
+-(void)encodeWithCoder:(NSCoder*)coder
+{
+
+	PyObjC_BEGIN_WITH_GIL
+		if (PyBytes_CheckExact(value)) {
+			if (unlikely(PyObject_AsReadBuffer(value, &buffer, &buffer_len) == -1)) {
+				PyObjC_GIL_FORWARD_EXC();
+			}
+
+
+			if ([coder allowsKeyedCoding]) {
+				[coder encodeInt32:1 forKey:@"pytype"];
+				[coder encodeBytes:buffer length:buffer_len forKey: @"pybytes"];
+
+			} else {
+				int v = 1;
+				[coder encodeValueOfObjCType:@encode(int) at:&v];
+				[coder encodeBytes:buffer length:buffer_len];
+			}
+			
+		} else {
+			if ([coder allowsKeyedCoding]) {
+				[coder encodeInt32:2 forKey:@"pytype"];
+			} else {
+				int v = 2;
+				[coder encodeValueOfObjCType:@encode(int) at:&v];
+			}
+
+			PyObjC_encodeWithCoder(value, coder);
+		}
+	PyObjC_END_WITH_GIL
+}
+
+/* 
+ * Helper method for initWithCoder, needed to deal with
+ * recursive objects (e.g. o.value = o)
+ */
+-(void)pyobjcSetValue:(NSObject*)other
+{
+	PyObjC_BEGIN_WITH_GIL
+		PyObject* v = PyObjC_IdToPython(other);
+		Py_XDECREF(value);
+		value = v;
+	PyObjC_END_WITH_GIL
+}
+
+- (id)initWithCoder:(NSCoder*)coder
+{
+	int v;
+	
+	if ([coder allowsKeyedCoding]) {
+
+		v = [coder decodeInt32ForKey:@"pytype"];
+	} else {
+		[coder decodeValueOfObjCType:@encode(int) at:&v];
+	}
+	if (v == 1) {
+		self = [super init];
+		if (unlikely(self == nil)) return nil;
+
+		void *bytes;
+		NSUInteger length;
+
+		if ([coder allowsKeyedCoding]) {
+			bytes = [coder decodeBytesForKey:@"pybytes" returnedLength:&length];
+		} else {
+			bytes = [coder decodeBytesWithReturnedLength:&length];
+		}
+		PyObjC_BEGIN_WITH_GIL
+			value = PyBytes_FromStringAndSize(bytes, length);
+			if (value == NULL) {
+				[super dealloc];
+				PyObjC_GIL_FORWARD_EXC();
+			}
+		PyObjC_END_WITH_GIL;
+		return self;
+
+	} else if (v == 2) {
+
+		if (PyObjC_Decoder != NULL) {
+			PyObjC_BEGIN_WITH_GIL
+				PyObject* cdr = PyObjC_IdToPython(coder);
+				if (cdr == NULL) {
+					PyObjC_GIL_FORWARD_EXC();
+				}
+
+				PyObject* setValue;
+				PyObject* selfAsPython = PyObjCObject_New(self, 0, YES);
+				setValue = PyObject_GetAttrString(selfAsPython, "pyobjcSetValue_");
+
+				PyObject* v2 = PyObject_CallFunction(PyObjC_Decoder, "OO", cdr, setValue);
+				Py_DECREF(cdr);
+				Py_DECREF(setValue);
+				Py_DECREF(selfAsPython);
+
+				if (v2 == NULL) {
+					PyObjC_GIL_FORWARD_EXC();
+				}
+
+				Py_XDECREF(value);
+				value = v2;
+
+				NSObject* proxy = PyObjC_FindObjCProxy(value);
+				if (proxy == NULL) {
+					PyObjC_RegisterObjCProxy(value, self);
+				} else {
+					[self release];
+					[proxy retain];
+					self = (OC_PythonData*)proxy;
+				}
+
+
+			PyObjC_END_WITH_GIL
+
+			return self;
+
+		} else {
+			[NSException raise:NSInvalidArgumentException
+					format:@"decoding Python objects is not supported"];
+			return nil;
+
+		}
+
+	} else {
+		[NSException raise:NSInvalidArgumentException
+				format:@"encoding Python objects is not supported"];
+	}
+	return self;
+}
+
+
 @end /* implementation OC_PythonData */