Exemplo n.º 1
0
        public static void GetObjectData(DObject/*!*/ instance, SerializationInfo/*!*/ info, StreamingContext strctx)
		{
			info.SetType(typeof(Deserializer));

			SerializationContext context = SerializationContext.CreateFromStreamingContext(strctx);

			bool sleep_called;
			PhpArray sleep_result;

			// try to get the caches __sleep result
			if (context.SleepResults.TryGetValue(instance, out sleep_result))
			{
				if (Object.ReferenceEquals(sleep_result, SerializationContext.NoSleepResultSingleton))
				{
					sleep_called = false;
					sleep_result = null;
				}
				else sleep_called = true;
			}
			else
			{
				sleep_result = instance.Sleep(context.ClassContext, context.ScriptContext, out sleep_called);
				context.SleepResults.Add(instance, (sleep_called ? sleep_result : SerializationContext.NoSleepResultSingleton));
			}

			if (sleep_called && sleep_result == null)
			{
				// __sleep did not return an array -> this instance will deserialize as NULL
				info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, String.Empty);
			}
			else
			{
				// if we have a sleep result, serialize fields according to it, otherwise serialize all fields

				IEnumerable<KeyValuePair<string, object>> serializable_properties;
				object real_object = null;

				if (sleep_result == null)
				{
					serializable_properties = Serialization.EnumerateSerializableProperties(
						instance,
						true); // get PHP fields only

					// serialize CLR real object in the "CLR way"
					if (!(instance is PhpObject)) real_object = instance.RealObject;
				}
				else
				{
					serializable_properties = Serialization.EnumerateSerializableProperties(
						instance,
						sleep_result,
						context.ScriptContext);
				}

				bool type_name_serialized = false;
				bool real_object_serialized = false;

				foreach (KeyValuePair<string, object> pair in serializable_properties)
				{
					if (pair.Key == __PHP_Incomplete_Class.ClassNameFieldName) type_name_serialized = true;

					if (pair.Key == ClrRealObjectSerializationInfoKey)
					{
						// unwrap the possibly wrapped CLR real object
						info.AddValue(pair.Key, PhpVariable.Unwrap(pair.Value));

						real_object_serialized = true;
					}
					else
					{
						PhpReference reference = pair.Value as PhpReference;
						info.AddValue(pair.Key, WrapPropertyValue(pair.Value));
					}
				}

				// if the type name has not been serialized, do it now
				if (!type_name_serialized) info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, instance.TypeName);

				// if the real object has not been serialized, do it now
				if (!real_object_serialized) info.AddValue(ClrRealObjectSerializationInfoKey, real_object);
			}
		}
Exemplo n.º 2
0
            /// <summary>
            /// Serializes <see cref="DObject"/> using PHP serialization.
            /// </summary>
            /// <param name="value">The object.</param>
            private void WritePhpObjectInternal(DObject/*!*/value)
            {
                byte[] binaryClassName;

                // determine class name
                bool avoid_pic_name = false;
                string class_name = null;
                __PHP_Incomplete_Class pic = value as __PHP_Incomplete_Class;
                if (pic != null)
                {
                    if (pic.__PHP_Incomplete_Class_Name.IsSet)
                    {
                        avoid_pic_name = true;
                        class_name = pic.__PHP_Incomplete_Class_Name.Value as string;
                    }
                }
                if (value is stdClass) class_name = stdClass.ClassName;
                if (class_name == null) class_name = value.TypeName;

                // is the instance PHP5.1 Serializable?
                if (value.RealObject is Library.SPL.Serializable)
                {
                    context.Stack.AddFrame();
                    object res = PhpVariable.Dereference(value.InvokeMethod("serialize", null, context));
                    if (res == null)
                    {
                        // serialize returned NULL -> serialize the instance as NULL
                        WriteNull();
                        return;
                    }

                    byte[] resdata = null;

                    if (res is PhpString)
                    {
                        res = res.ToString();
                    }

                    if (res is string)
                    {
                        resdata = writer.Encoding.GetBytes((string)res);
                    }
                    else if (res is PhpBytes)
                    {
                        resdata = ((PhpBytes)res).ReadonlyData;
                    }

                    if (resdata == null)
                    {
                        // serialize did not return NULL nor a string -> throw an exception
                        SPL.Exception.ThrowSplException(
                            _ctx => new SPL.Exception(_ctx, true),
                            context,
                            string.Format(CoreResources.serialize_must_return_null_or_string, value.TypeName), 0, null);
                    }

                    writer.Write(Tokens.ObjectSer);
                    writer.Write(Tokens.Colon);

                    binaryClassName = writer.Encoding.GetBytes(class_name);

                    // write out class name
                    writer.Write(binaryClassName.Length);
                    writer.Write(Tokens.Colon);
                    writer.Write(Tokens.Quote);

                    // flush the StreamWriter before accessing its underlying stream
                    writer.Flush();

                    writer.BaseStream.Write(binaryClassName, 0, binaryClassName.Length);
                    writer.Write(Tokens.Quote);
                    writer.Write(Tokens.Colon);

                    // write out the result of serialize
                    writer.Write(resdata.Length);
                    writer.Write(Tokens.Colon);
                    writer.Write(Tokens.BraceOpen);

                    // flush the StreamWriter before accessing its underlying stream
                    writer.Flush();

                    writer.BaseStream.Write(resdata, 0, resdata.Length);
                    writer.Write(Tokens.BraceClose);
                    return;
                }

                // try to call the __sleep method
                bool sleep_called;
                PhpArray ser_props = value.Sleep(ClassContext, context, out sleep_called);

                if (sleep_called && ser_props == null)
                {
                    // __sleep did not return an array -> serialize the instance as NULL
                    WriteNull();
                    return;
                }

                writer.Write(Tokens.Object);
                writer.Write(Tokens.Colon);

                // write out class name
                binaryClassName = writer.Encoding.GetBytes(class_name);

                // write out class name
                writer.Write(binaryClassName.Length);
                writer.Write(Tokens.Colon);
                writer.Write(Tokens.Quote);

                // flush the StreamWriter before accessing its underlying stream
                writer.Flush();

                writer.BaseStream.Write(binaryClassName, 0, binaryClassName.Length);
                writer.Write(Tokens.Quote);
                writer.Write(Tokens.Colon);

                // write out property count
                if (ser_props != null) writer.Write(ser_props.Count);
                else writer.Write(value.Count - (avoid_pic_name ? 1 : 0));
                writer.Write(Tokens.Colon);
                writer.Write(Tokens.BraceOpen);

                // write out properties
                if (ser_props != null) WriteSleepResult(value, ser_props);
                else WriteAllProperties(value, avoid_pic_name);

                writer.Write(Tokens.BraceClose);
            }
Exemplo n.º 3
0
        public static void GetObjectData(DObject /*!*/ instance, SerializationInfo /*!*/ info, StreamingContext strctx)
        {
            info.SetType(typeof(Deserializer));

            SerializationContext context = SerializationContext.CreateFromStreamingContext(strctx);

            bool     sleep_called;
            PhpArray sleep_result;

            // try to get the caches __sleep result
            if (context.SleepResults.TryGetValue(instance, out sleep_result))
            {
                if (Object.ReferenceEquals(sleep_result, SerializationContext.NoSleepResultSingleton))
                {
                    sleep_called = false;
                    sleep_result = null;
                }
                else
                {
                    sleep_called = true;
                }
            }
            else
            {
                sleep_result = instance.Sleep(context.ClassContext, context.ScriptContext, out sleep_called);
                context.SleepResults.Add(instance, (sleep_called ? sleep_result : SerializationContext.NoSleepResultSingleton));
            }

            if (sleep_called && sleep_result == null)
            {
                // __sleep did not return an array -> this instance will deserialize as NULL
                info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, String.Empty);
            }
            else
            {
                // if we have a sleep result, serialize fields according to it, otherwise serialize all fields

                IEnumerable <KeyValuePair <string, object> > serializable_properties;
                object real_object = null;

                if (sleep_result == null)
                {
                    serializable_properties = Serialization.EnumerateSerializableProperties(
                        instance,
                        true);                         // get PHP fields only

                    // serialize CLR real object in the "CLR way"
                    if (!(instance is PhpObject))
                    {
                        real_object = instance.RealObject;
                    }
                }
                else
                {
                    serializable_properties = Serialization.EnumerateSerializableProperties(
                        instance,
                        sleep_result,
                        context.ScriptContext);
                }

                bool type_name_serialized   = false;
                bool real_object_serialized = false;

                foreach (KeyValuePair <string, object> pair in serializable_properties)
                {
                    if (pair.Key == __PHP_Incomplete_Class.ClassNameFieldName)
                    {
                        type_name_serialized = true;
                    }

                    if (pair.Key == ClrRealObjectSerializationInfoKey)
                    {
                        // unwrap the possibly wrapped CLR real object
                        info.AddValue(pair.Key, PhpVariable.Unwrap(pair.Value));

                        real_object_serialized = true;
                    }
                    else
                    {
                        PhpReference reference = pair.Value as PhpReference;
                        info.AddValue(pair.Key, WrapPropertyValue(pair.Value));
                    }
                }

                // if the type name has not been serialized, do it now
                if (!type_name_serialized)
                {
                    info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, instance.TypeName);
                }

                // if the real object has not been serialized, do it now
                if (!real_object_serialized)
                {
                    info.AddValue(ClrRealObjectSerializationInfoKey, real_object);
                }
            }
        }