Esempio n. 1
0
        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;
        }
Esempio n. 2
0
        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);
        }