object ReadInlineObjectStructured(ISubStructuredReader rSub, Type type, object o) { if (type == null && o == null) { throw new ArgumentException(R.AtLeastTypeOrObjectMustBeSpecified); } if (type == null) { type = o.GetType(); } Type serializerServiceType = typeof(IStructuredSerializer <>).MakeGenericType(type); object serializer = GetService(serializerServiceType); if (serializer != null) { o = serializerServiceType.InvokeMember("ReadInlineContent", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, serializer, new object[] { rSub, o }); } else { // If no serializer is found, the object must implement IStructuredSerializable interface. if (o == null) { o = Activator.CreateInstance(type); } ((IStructuredSerializable)o).ReadContent(rSub); } OnObjectRead(o, rSub); return(o); }
object IStructuredReader.ReadInlineObjectStructured(Type type, object o) { AssertCurrentReader(); using (ISubStructuredReader rSub = OpenSubReader()) { return(ReadInlineObjectStructured(rSub, type, o)); } }
object ReadInlineObjectStructured( ISubStructuredReader rSub, Type type, object o ) { if( type == null && o == null ) throw new ArgumentException( R.AtLeastTypeOrObjectMustBeSpecified ); if( type == null ) type = o.GetType(); Type serializerServiceType = typeof( IStructuredSerializer<> ).MakeGenericType( type ); object serializer = GetService( serializerServiceType ); if( serializer != null ) { o = serializerServiceType.InvokeMember( "ReadInlineContent", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, serializer, new object[] { rSub, o } ); } else { // If no serializer is found, the object must implement IStructuredSerializable interface. if( o == null ) o = Activator.CreateInstance( type ); ((IStructuredSerializable)o).ReadContent( rSub ); } OnObjectRead( o, rSub ); return o; }
object IStructuredReader.ReadInlineObject(out StandardReadStatus status) { AssertCurrentReader(); XmlReader r = Xml; object o = null; string type = r.GetAttribute("type"); if (type == null) { status = StandardReadStatus.ErrorTypeAttributeMissing; } else { status = StandardReadStatus.SimpleTypeData; switch (type) { case "null": status = StandardReadStatus.NullData; r.Skip(); break; case "Enum": { status = StandardReadStatus.XmlSerializable; try { Type t = GetType(r.GetAttribute("typeName")); if (t == null) { r.Skip(); } else { r.Read(); o = Enum.Parse(t, r.ReadContentAsString()); } } finally { // On error, we can be on the <data key="..." type="Enum" typeName="..." > element or after its content: // by skipping, we either skip the content and the end element or the end element. r.Skip(); } break; } case "String": o = r.ReadElementString(); break; case "Int32": o = r.ReadElementContentAsInt(); break; case "Bool": o = XmlConvert.ToBoolean(r.ReadElementContentAsString()); break; case "DateTimeOffset": o = XmlConvert.ToDateTimeOffset(r.ReadElementContentAsString()); break; case "DateTime": o = XmlConvert.ToDateTime(r.ReadElementContentAsString(), XmlDateTimeSerializationMode.RoundtripKind); break; case "TimeSpan": o = XmlConvert.ToTimeSpan(r.ReadElementContentAsString()); break; case "Guid": o = XmlConvert.ToGuid(r.ReadElementContentAsString()); break; case "Single": o = XmlConvert.ToSingle(r.ReadElementContentAsString()); break; case "Double": o = XmlConvert.ToDouble(r.ReadElementContentAsString()); break; case "Decimal": o = XmlConvert.ToDecimal(r.ReadElementContentAsString()); break; case "Char": o = XmlConvert.ToChar(r.ReadElementContentAsString()); break; case "UInt32": o = XmlConvert.ToUInt32(r.ReadElementContentAsString()); break; case "Int16": o = XmlConvert.ToInt16(r.ReadElementContentAsString()); break; case "UInt16": o = XmlConvert.ToUInt16(r.ReadElementContentAsString()); break; case "Int64": o = XmlConvert.ToInt64(r.ReadElementContentAsString()); break; case "UInt64": o = XmlConvert.ToUInt64(r.ReadElementContentAsString()); break; case "Byte": o = XmlConvert.ToByte(r.ReadElementContentAsString()); break; case "SByte": o = XmlConvert.ToSByte(r.ReadElementContentAsString()); break; case "Structured": { status = StandardReadStatus.Structured; using (ISubStructuredReader rSub = OpenSubReader()) { Type t = GetType(r.GetAttribute("typeName")); if (t != null) { o = ReadInlineObjectStructured(rSub, t, null); } } break; } case "XmlSerializable": { status = StandardReadStatus.XmlSerializable; using (Root.CreateJail()) { Type t = GetType(r.GetAttribute("typeName")); if (t != null) { o = Activator.CreateInstance(t); IXmlSerializable xmlSer = (IXmlSerializable)o; xmlSer.ReadXml(Xml); OnObjectRead(o, (IStructuredReader)this); } } break; } case "Object": { status = StandardReadStatus.BinaryObject; try { int size = int.Parse(r.GetAttribute("size")); // Adds 8 bytes to the size. It allows to detect when the content is bigger than we expect. // ReadContentAsBinHex moves the reader to the next non-content element: this is either // the start element of extra data or the end of the current element. byte[] buffer = new byte[size + 8]; int readBytes = 0; // If an error occur while reading content, the reader.ReadState is Error // and this is definitive... r.Read(); readBytes = r.ReadContentAsBinHex(buffer, readBytes, buffer.Length); if (readBytes != size) { throw new CKException(R.SizeDifferError, size, readBytes); } if (readBytes != -1) { BinaryFormatter f = new BinaryFormatter(); using (MemoryStream mem = new MemoryStream(buffer)) { try { o = f.Deserialize(mem); } catch (Exception ex) { throw new CKException(R.DeserializeError, ex); } } OnObjectRead(o, (IStructuredReader)this); } } catch (XmlException ex) { throw new CKException(R.InvalidXml, ex); } finally { // We are on the opening element OR on the closing tag. r.Skip(); } break; } default: { status = StandardReadStatus.ErrorUnknownTypeAttribute; break; } } } return(o); }