Esempio n. 1
0
        /// <summary>
        /// Asynchronously reads XML data into the current <see cref="AtomEntry"/>.
        /// </summary>
        /// <exception cref="InvalidDataException">
        /// Thrown when an Invalid Data error condition occurs.
        /// </exception>
        /// <param name="reader">
        /// The reader from which to read.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> representing the operation.
        /// </returns>
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires<ArgumentNullException>(reader != null, "reader");

            this.Author = null;
            this.Content = null;
            this.Id = null;
            this.Links = null;
            this.Published = DateTime.MinValue;
            this.Title = null;
            this.Updated = DateTime.MinValue;

            reader.Requires(await reader.MoveToDocumentElementAsync("entry"));

            Dictionary<string, Uri> links = null;
            await reader.ReadAsync();

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                    case "title":

                        this.Title = await reader.ReadElementContentAsync(StringConverter.Instance);
                        break;

                    case "id":

                        this.Id = await reader.ReadElementContentAsync(UriConverter.Instance);
                        break;

                    case "author":
                        
                        await reader.ReadAsync();
                        reader.EnsureMarkup(XmlNodeType.Element, "name");
                        this.Author = await reader.ReadElementContentAsync(StringConverter.Instance);
                        reader.EnsureMarkup(XmlNodeType.EndElement, "author");
                        await reader.ReadAsync();
                        break;

                    case "published":

                        this.Published = await reader.ReadElementContentAsync(DateTimeConverter.Instance);
                        break;

                    case "updated":

                        this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance);
                        break;

                    case "link":

                        if (links == null)
                        {
                            links = new Dictionary<string, Uri>();
                        }

                        var href = reader.GetRequiredAttribute("href");
                        var rel = reader.GetRequiredAttribute("rel");
                        links[rel] = UriConverter.Instance.Convert(href);
                        await reader.ReadAsync();
                        break;

                    case "content":

                        this.Content = await ParsePropertyValueAsync(reader, 0);
                        break;

                    default: throw new InvalidDataException(); // TODO: Diagnostics : unexpected start tag
                }
            }

            reader.EnsureMarkup(XmlNodeType.EndElement, "entry");
            await reader.ReadAsync();

            if (links != null)
            {
                this.Links = new ReadOnlyDictionary<string, Uri>(links);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Asynchronously reads XML data into the current <see cref="AtomEntry"/>.
        /// </summary>
        /// <exception cref="InvalidDataException">
        /// Thrown when an Invalid Data error condition occurs.
        /// </exception>
        /// <param name="reader">
        /// The reader from which to read.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> representing the operation.
        /// </returns>
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires <ArgumentNullException>(reader != null, "reader");

            this.Author    = null;
            this.Content   = null;
            this.Id        = null;
            this.Links     = null;
            this.Published = DateTime.MinValue;
            this.Title     = null;
            this.Updated   = DateTime.MinValue;

            reader.Requires(await reader.MoveToDocumentElementAsync("entry").ConfigureAwait(false));

            Dictionary <string, Uri> links = null;
            await reader.ReadAsync().ConfigureAwait(false);

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                case "title":

                    this.Title = await reader.ReadElementContentAsync(StringConverter.Instance).ConfigureAwait(false);

                    break;

                case "id":

                    this.Id = await reader.ReadElementContentAsync(UriConverter.Instance).ConfigureAwait(false);

                    break;

                case "author":

                    await reader.ReadAsync().ConfigureAwait(false);

                    reader.EnsureMarkup(XmlNodeType.Element, "name");
                    this.Author = await reader.ReadElementContentAsync(StringConverter.Instance).ConfigureAwait(false);

                    reader.EnsureMarkup(XmlNodeType.EndElement, "author");
                    await reader.ReadAsync().ConfigureAwait(false);

                    break;

                case "published":

                    this.Published = await reader.ReadElementContentAsync(DateTimeConverter.Instance).ConfigureAwait(false);

                    break;

                case "updated":

                    this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance).ConfigureAwait(false);

                    break;

                case "link":

                    if (links == null)
                    {
                        links = new Dictionary <string, Uri>();
                    }

                    var href = reader.GetRequiredAttribute("href");
                    var rel  = reader.GetRequiredAttribute("rel");
                    links[rel] = UriConverter.Instance.Convert(href);
                    await reader.ReadAsync().ConfigureAwait(false);

                    break;

                case "content":

                    this.Content = await ParsePropertyValueAsync(reader, 0).ConfigureAwait(false);

                    break;

                default: throw new InvalidDataException();     // TODO: Diagnostics : unexpected start tag
                }
            }

            reader.EnsureMarkup(XmlNodeType.EndElement, "entry");
            await reader.ReadAsync().ConfigureAwait(false);

            if (links != null)
            {
                this.Links = new ReadOnlyDictionary <string, Uri>(links);
            }
        }
Esempio n. 3
0
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires <ArgumentNullException>(reader != null, "reader");

            if (reader.ReadState == ReadState.Initial)
            {
                await reader.ReadAsync();

                if (reader.NodeType == XmlNodeType.XmlDeclaration)
                {
                    await reader.ReadAsync();
                }
            }
            else
            {
                reader.MoveToElement();
            }

            if (!(reader.NodeType == XmlNodeType.Element && (reader.Name == "feed" || reader.Name == "entry")))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            string rootElementName = reader.Name;

            var entries = new List <AtomEntry>();

            this.Entries = entries;

            var links = new Dictionary <string, Uri>();

            this.Links = links;

            var messages = new List <Message>();

            this.Messages = messages;

            await reader.ReadAsync();

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                case "title":

                    this.Title = await reader.ReadElementContentAsync(StringConverter.Instance);

                    break;

                case "id":

                    this.Id = await reader.ReadElementContentAsync(UriConverter.Instance);

                    break;

                case "author":

                    await reader.ReadAsync();

                    if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "name"))
                    {
                        throw new InvalidDataException();     // TODO: Diagnostics
                    }

                    this.Author = await reader.ReadElementContentAsync(StringConverter.Instance);

                    if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == "author"))
                    {
                        throw new InvalidDataException();     // TODO: Diagnostics
                    }

                    await reader.ReadAsync();

                    break;

                case "generator":

                    string build = reader.GetAttribute("build");

                    if (build == null)
                    {
                        throw new InvalidDataException();     // TODO: Diagnostics
                    }

                    string version = reader.GetAttribute("version");

                    if (version == null)
                    {
                        throw new InvalidDataException();     // TODO: Diagnostics
                    }

                    this.GeneratorVersion = VersionConverter.Instance.Convert(string.Join(".", version, build));
                    await reader.ReadAsync();

                    break;

                case "updated":

                    this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance);

                    break;

                case "entry":

                    var entry = new AtomEntry();

                    await entry.ReadXmlAsync(reader);

                    entries.Add(entry);
                    break;

                case "link":

                    string href = reader.GetAttribute("href");

                    if (string.IsNullOrWhiteSpace(href))
                    {
                        throw new InvalidDataException();      // TODO: Diagnostics
                    }

                    string rel = reader.GetAttribute("rel");

                    if (string.IsNullOrWhiteSpace(rel))
                    {
                        throw new InvalidDataException();      // TODO: Diagnostics
                    }

                    links[rel] = UriConverter.Instance.Convert(href);
                    await reader.ReadAsync();

                    break;

                case "s:messages":

                    bool isEmptyElement = reader.IsEmptyElement;
                    await reader.ReadAsync();

                    if (isEmptyElement)
                    {
                        continue;
                    }

                    while (reader.NodeType == XmlNodeType.Element && reader.Name == "s:msg")
                    {
                        string value = reader.GetAttribute("type");

                        if (value == null)
                        {
                            throw new InvalidDataException();     // TODO: Diagnostics
                        }

                        MessageType type = EnumConverter <MessageType> .Instance.Convert(value);

                        string text = await reader.ReadElementContentAsStringAsync();

                        messages.Add(new Message(type, text));
                    }

                    if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        if (reader.Name != "s:messages")
                        {
                            throw new InvalidDataException();     // TODO: Diagnostics
                        }
                        await reader.ReadAsync();
                    }

                    break;

                case "opensearch:itemsPerPage":

                    int itemsPerPage = await reader.ReadElementContentAsync(Int32Converter.Instance);

                    this.Pagination = new Pagination(itemsPerPage, this.Pagination.StartIndex, this.Pagination.TotalResults);
                    break;

                case "opensearch:startIndex":

                    int startIndex = await reader.ReadElementContentAsync(Int32Converter.Instance);

                    this.Pagination = new Pagination(this.Pagination.ItemsPerPage, startIndex, this.Pagination.TotalResults);
                    break;

                case "opensearch:totalResults":

                    int totalResults = await reader.ReadElementContentAsync(Int32Converter.Instance);

                    this.Pagination = new Pagination(this.Pagination.ItemsPerPage, this.Pagination.StartIndex, totalResults);
                    break;

                default: throw new InvalidDataException(string.Format("Found invalid data while decoding: {0}", reader));
                }
            }

            if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == rootElementName))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            await reader.ReadAsync();
        }
Esempio n. 4
0
        /// <summary>
        /// Asynchronously reads XML data into the current <see cref="AtomFeed"/>.
        /// </summary>
        /// <exception cref="InvalidDataException">
        /// Thrown when an Invalid Data error condition occurs.
        /// </exception>
        /// <param name="reader">
        /// The reader from which to read.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> representing the operation.
        /// </returns>
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires <ArgumentNullException>(reader != null, "reader");

            this.Author           = null;
            this.Entries          = null;
            this.GeneratorVersion = null;
            this.Id         = null;
            this.Links      = null;
            this.Messages   = null;
            this.Pagination = Pagination.None;
            this.Title      = null;
            this.Updated    = DateTime.MinValue;

            reader.Requires(await reader.MoveToDocumentElementAsync("feed").ConfigureAwait(false));
            var documentElementName = reader.Name;

            List <AtomEntry>         entries  = null;
            Dictionary <string, Uri> links    = null;
            List <Message>           messages = null;


            await reader.ReadAsync().ConfigureAwait(false);

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                case "title":

                    this.Title = await reader.ReadElementContentAsync(StringConverter.Instance).ConfigureAwait(false);

                    break;

                case "id":

                    this.Id = await reader.ReadElementContentAsync(UriConverter.Instance).ConfigureAwait(false);

                    break;

                case "author":

                    await reader.ReadAsync().ConfigureAwait(false);

                    reader.EnsureMarkup(XmlNodeType.Element, "name");
                    this.Author = await reader.ReadElementContentAsync(StringConverter.Instance).ConfigureAwait(false);

                    reader.EnsureMarkup(XmlNodeType.EndElement, "author");
                    await reader.ReadAsync().ConfigureAwait(false);

                    break;

                case "generator":

                    // string build = reader.GetRequiredAttribute("build"); // TODO: Incorporate build number? Build number sometimes adds a fifth digit.
                    string version = reader.GetRequiredAttribute("version");
                    this.GeneratorVersion = VersionConverter.Instance.Convert(string.Join(".", version));
                    await reader.ReadAsync().ConfigureAwait(false);

                    break;

                case "updated":

                    this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance).ConfigureAwait(false);

                    break;

                case "entry":

                    var entry = new AtomEntry();

                    if (entries == null)
                    {
                        entries = new List <AtomEntry>();
                    }

                    entries.Add(entry);

                    await entry.ReadXmlAsync(reader).ConfigureAwait(false);

                    break;

                case "link":

                    var href = reader.GetRequiredAttribute("href");
                    var rel  = reader.GetRequiredAttribute("rel");

                    if (links == null)
                    {
                        links = new Dictionary <string, Uri>();
                    }

                    links[rel] = UriConverter.Instance.Convert(href);
                    await reader.ReadAsync().ConfigureAwait(false);

                    break;

                case "s:messages":

                    bool isEmptyElement = reader.IsEmptyElement;
                    await reader.ReadAsync().ConfigureAwait(false);

                    if (messages == null)
                    {
                        messages = new List <Message>();
                    }

                    if (isEmptyElement)
                    {
                        continue;
                    }

                    while (reader.NodeType == XmlNodeType.Element && reader.Name == "s:msg")
                    {
                        var value = reader.GetRequiredAttribute("type");
                        var type  = EnumConverter <MessageType> .Instance.Convert(value);

                        var text = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                        messages.Add(new Message(type, text));
                    }

                    if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        reader.EnsureMarkup(XmlNodeType.EndElement, "s:messages");
                        await reader.ReadAsync().ConfigureAwait(false);
                    }

                    break;

                case "opensearch:itemsPerPage":

                    int itemsPerPage = await reader.ReadElementContentAsync(Int32Converter.Instance).ConfigureAwait(false);

                    this.Pagination = new Pagination(itemsPerPage, this.Pagination.StartIndex, this.Pagination.TotalResults);
                    break;

                case "opensearch:startIndex":

                    int startIndex = await reader.ReadElementContentAsync(Int32Converter.Instance).ConfigureAwait(false);

                    this.Pagination = new Pagination(this.Pagination.ItemsPerPage, startIndex, this.Pagination.TotalResults);
                    break;

                case "opensearch:totalResults":

                    int totalResults = await reader.ReadElementContentAsync(Int32Converter.Instance).ConfigureAwait(false);

                    this.Pagination = new Pagination(this.Pagination.ItemsPerPage, this.Pagination.StartIndex, totalResults);
                    break;

                default: throw new InvalidDataException(string.Format("Unexpected start tag: {0}", reader.Name));     // TODO: Improved diagnostics
                }
            }

            reader.EnsureMarkup(XmlNodeType.EndElement, documentElementName);
            await reader.ReadAsync().ConfigureAwait(false);

            this.Entries  = entries == null ? emptyAtomEntryCollection : new ReadOnlyCollection <AtomEntry>(entries);
            this.Links    = links == null ? emptyLinksDictionary : new ReadOnlyDictionary <string, Uri>(links);
            this.Messages = messages == null ? emptyMessageCollection : new ReadOnlyCollection <Message>(messages);
        }
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires<ArgumentNullException>(reader != null, "reader");

            if (reader.ReadState == ReadState.Initial)
            {
                await reader.ReadAsync();

                if (reader.NodeType == XmlNodeType.XmlDeclaration)
                {
                    await reader.ReadAsync();
                }
            }
            else
            {
                reader.MoveToElement();
            }

            if (!(reader.NodeType == XmlNodeType.Element && (reader.Name == "feed" || reader.Name == "entry")))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            string rootElementName = reader.Name;

            var entries = new List<AtomEntry>();
            this.Entries = entries;

            var links = new Dictionary<string, Uri>();
            this.Links = links;

            var messages = new List<Message>();
            this.Messages = messages;

            await reader.ReadAsync();

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                    case "title":

                        this.Title = await reader.ReadElementContentAsync(StringConverter.Instance);
                        break;

                    case "id":

                        this.Id = await reader.ReadElementContentAsync(UriConverter.Instance);
                        break;

                    case "author":

                        await reader.ReadAsync();

                        if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "name"))
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        this.Author = await reader.ReadElementContentAsync(StringConverter.Instance);

                        if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == "author"))
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        await reader.ReadAsync();
                        break;

                    case "generator":

                        string build = reader.GetAttribute("build");

                        if (build == null)
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        string version = reader.GetAttribute("version");

                        if (version == null)
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        this.GeneratorVersion = VersionConverter.Instance.Convert(string.Join(".", version, build));
                        await reader.ReadAsync();
                        break;

                    case "updated":

                        this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance);
                        break;

                    case "entry":

                        var entry = new AtomEntry();

                        await entry.ReadXmlAsync(reader);
                        entries.Add(entry);
                        break;

                    case "link":

                        string href = reader.GetAttribute("href");

                        if (string.IsNullOrWhiteSpace(href))
                        {
                            throw new InvalidDataException();  // TODO: Diagnostics
                        }

                        string rel = reader.GetAttribute("rel");

                        if (string.IsNullOrWhiteSpace(rel))
                        {
                            throw new InvalidDataException();  // TODO: Diagnostics
                        }

                        links[rel] = UriConverter.Instance.Convert(href);
                        await reader.ReadAsync();
                        break;

                    case "s:messages":

                        bool isEmptyElement = reader.IsEmptyElement;
                        await reader.ReadAsync();

                        if (isEmptyElement)
                        {
                            continue;
                        }

                        while (reader.NodeType == XmlNodeType.Element && reader.Name == "s:msg")
                        {
                            string value = reader.GetAttribute("type");

                            if (value == null)
                            {
                                throw new InvalidDataException(); // TODO: Diagnostics
                            }

                            MessageType type = EnumConverter<MessageType>.Instance.Convert(value);
                            string text = await reader.ReadElementContentAsStringAsync();

                            messages.Add(new Message(type, text));
                        }

                        if (reader.NodeType == XmlNodeType.EndElement)
                        {
                            if (reader.Name != "s:messages")
                            {
                                throw new InvalidDataException(); // TODO: Diagnostics
                            }
                            await reader.ReadAsync();
                        }

                        break;

                    case "opensearch:itemsPerPage":

                        int itemsPerPage = await reader.ReadElementContentAsync(Int32Converter.Instance);
                        this.Pagination = new Pagination(itemsPerPage, this.Pagination.StartIndex, this.Pagination.TotalResults);
                        break;

                    case "opensearch:startIndex":

                        int startIndex = await reader.ReadElementContentAsync(Int32Converter.Instance);
                        this.Pagination = new Pagination(this.Pagination.ItemsPerPage, startIndex, this.Pagination.TotalResults);
                        break;

                    case "opensearch:totalResults":

                        int totalResults = await reader.ReadElementContentAsync(Int32Converter.Instance);
                        this.Pagination = new Pagination(this.Pagination.ItemsPerPage, this.Pagination.StartIndex, totalResults);
                        break;

                    default: throw new InvalidDataException(string.Format("Found invalid data while decoding: {0}", reader));
                }
            }

            if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == rootElementName))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            await reader.ReadAsync();
        }
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires <ArgumentNullException>(reader != null, "reader");

            if (reader.ReadState == ReadState.Initial)
            {
                await reader.ReadAsync();

                if (reader.NodeType == XmlNodeType.XmlDeclaration)
                {
                    await reader.ReadAsync();
                }
            }
            else
            {
                reader.MoveToElement();
            }

            if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "entry"))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            var links = new Dictionary <string, Uri>();

            this.Links = links;

            await reader.ReadAsync();

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                case "title":

                    this.Title = await reader.ReadElementContentAsync(StringConverter.Instance);

                    break;

                case "id":

                    this.Id = await reader.ReadElementContentAsync(UriConverter.Instance);

                    break;

                case "author":

                    await reader.ReadAsync();

                    if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "name"))
                    {
                        throw new InvalidDataException();     // TODO: Diagnostics
                    }

                    this.Author = await reader.ReadElementContentAsync(StringConverter.Instance);

                    if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == "author"))
                    {
                        throw new InvalidDataException();     // TODO: Diagnostics
                    }

                    await reader.ReadAsync();

                    break;

                case "published":

                    this.Published = await reader.ReadElementContentAsync(DateTimeConverter.Instance);

                    break;

                case "updated":

                    this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance);

                    break;

                case "link":

                    string href = reader.GetAttribute("href");

                    if (string.IsNullOrWhiteSpace(href))
                    {
                        throw new InvalidDataException();      // TODO: Diagnostics
                    }

                    string rel = reader.GetAttribute("rel");

                    if (string.IsNullOrWhiteSpace(rel))
                    {
                        throw new InvalidDataException();      // TODO: Diagnostics
                    }

                    links[rel] = UriConverter.Instance.Convert(href);
                    await reader.ReadAsync();

                    break;

                case "content":

                    this.Content = await ParsePropertyValueAsync(reader);

                    break;

                default: throw new InvalidDataException();     // TODO: Diagnostics
                }
            }

            if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == "entry"))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            await reader.ReadAsync();
        }
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires<ArgumentNullException>(reader != null, "reader");

            if (reader.ReadState == ReadState.Initial)
            {
                await reader.ReadAsync();

                if (reader.NodeType == XmlNodeType.XmlDeclaration)
                {
                    await reader.ReadAsync();
                }
            }
            else
            {
                reader.MoveToElement();
            }

            if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "entry"))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            var links = new Dictionary<string, Uri>();
            this.Links = links;

            await reader.ReadAsync();

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                    case "title":

                        this.Title = await reader.ReadElementContentAsync(StringConverter.Instance);
                        break;

                    case "id":

                        this.Id = await reader.ReadElementContentAsync(UriConverter.Instance);
                        break;

                    case "author":

                        await reader.ReadAsync();

                        if (!(reader.NodeType == XmlNodeType.Element && reader.Name == "name"))
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        this.Author = await reader.ReadElementContentAsync(StringConverter.Instance);

                        if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == "author"))
                        {
                            throw new InvalidDataException(); // TODO: Diagnostics
                        }

                        await reader.ReadAsync();
                        break;

                    case "published":

                        this.Published = await reader.ReadElementContentAsync(DateTimeConverter.Instance);
                        break;

                    case "updated":

                        this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance);
                        break;

                    case "link":

                        string href = reader.GetAttribute("href");

                        if (string.IsNullOrWhiteSpace(href))
                        {
                            throw new InvalidDataException();  // TODO: Diagnostics
                        }

                        string rel = reader.GetAttribute("rel");

                        if (string.IsNullOrWhiteSpace(rel))
                        {
                            throw new InvalidDataException();  // TODO: Diagnostics
                        }

                        links[rel] = UriConverter.Instance.Convert(href);
                        await reader.ReadAsync();
                        break;

                    case "content":

                        this.Content = await ParsePropertyValueAsync(reader);
                        break;

                    default: throw new InvalidDataException(); // TODO: Diagnostics
                }
            }

            if (!(reader.NodeType == XmlNodeType.EndElement && reader.Name == "entry"))
            {
                throw new InvalidDataException(); // TODO: Diagnostics
            }

            await reader.ReadAsync();
        }
Esempio n. 8
0
        /// <summary>
        /// Asynchronously reads XML data into the current <see cref="AtomFeed"/>.
        /// </summary>
        /// <exception cref="InvalidDataException">
        /// Thrown when an Invalid Data error condition occurs.
        /// </exception>
        /// <param name="reader">
        /// The reader from which to read.
        /// </param>
        /// <returns>
        /// A <see cref="Task"/> representing the operation.
        /// </returns>
        public async Task ReadXmlAsync(XmlReader reader)
        {
            Contract.Requires<ArgumentNullException>(reader != null, "reader");

            this.Author = null;
            this.Entries = null;
            this.GeneratorVersion = null;
            this.Id = null;
            this.Links = null;
            this.Messages = null;
            this.Pagination = Pagination.None;
            this.Title = null;
            this.Updated = DateTime.MinValue;

            reader.Requires(await reader.MoveToDocumentElementAsync("feed"));
            var documentElementName = reader.Name;

            List<AtomEntry> entries = null;
            Dictionary<string, Uri> links = null;
            List<Message> messages = null;

            await reader.ReadAsync();

            while (reader.NodeType == XmlNodeType.Element)
            {
                string name = reader.Name;

                switch (name)
                {
                    case "title":

                        this.Title = await reader.ReadElementContentAsync(StringConverter.Instance);
                        break;

                    case "id":

                        this.Id = await reader.ReadElementContentAsync(UriConverter.Instance);
                        break;

                    case "author":

                        await reader.ReadAsync();
                        reader.EnsureMarkup(XmlNodeType.Element, "name");
                        this.Author = await reader.ReadElementContentAsync(StringConverter.Instance);
                        reader.EnsureMarkup(XmlNodeType.EndElement, "author");
                        await reader.ReadAsync();
                        break;

                    case "generator":

                        // string build = reader.GetRequiredAttribute("build"); // TODO: Incorporate build number? Build number sometimes adds a fifth digit.
                        string version = reader.GetRequiredAttribute("version");
                        this.GeneratorVersion = VersionConverter.Instance.Convert(string.Join(".", version));
                        await reader.ReadAsync();
                        break;

                    case "updated":

                        this.Updated = await reader.ReadElementContentAsync(DateTimeConverter.Instance);
                        break;

                    case "entry":

                        var entry = new AtomEntry();

                        if (entries == null)
                        {
                            entries = new List<AtomEntry>();
                        }

                        entries.Add(entry);

                        await entry.ReadXmlAsync(reader);
                        break;

                    case "link":

                        var href = reader.GetRequiredAttribute("href");
                        var rel = reader.GetRequiredAttribute("rel");

                        if (links == null)
                        {
                            links = new Dictionary<string, Uri>();
                        }

                        links[rel] = UriConverter.Instance.Convert(href);
                        await reader.ReadAsync();
                        break;

                    case "s:messages":

                        bool isEmptyElement = reader.IsEmptyElement;
                        await reader.ReadAsync();

                        if (messages == null)
                        {
                            messages = new List<Message>();
                        }

                        if (isEmptyElement)
                        {
                            continue;
                        }

                        while (reader.NodeType == XmlNodeType.Element && reader.Name == "s:msg")
                        {
                            var value = reader.GetRequiredAttribute("type");
                            var type = EnumConverter<MessageType>.Instance.Convert(value);
                            var text = await reader.ReadElementContentAsStringAsync();
                            
                            messages.Add(new Message(type, text));
                        }

                        if (reader.NodeType == XmlNodeType.EndElement)
                        {
                            reader.EnsureMarkup(XmlNodeType.EndElement, "s:messages");
                            await reader.ReadAsync();
                        }

                        break;

                    case "opensearch:itemsPerPage":

                        int itemsPerPage = await reader.ReadElementContentAsync(Int32Converter.Instance);
                        this.Pagination = new Pagination(itemsPerPage, this.Pagination.StartIndex, this.Pagination.TotalResults);
                        break;

                    case "opensearch:startIndex":

                        int startIndex = await reader.ReadElementContentAsync(Int32Converter.Instance);
                        this.Pagination = new Pagination(this.Pagination.ItemsPerPage, startIndex, this.Pagination.TotalResults);
                        break;

                    case "opensearch:totalResults":

                        int totalResults = await reader.ReadElementContentAsync(Int32Converter.Instance);
                        this.Pagination = new Pagination(this.Pagination.ItemsPerPage, this.Pagination.StartIndex, totalResults);
                        break;

                    default: throw new InvalidDataException(string.Format("Unexpected start tag: {0}", reader.Name)); // TODO: Improved diagnostics
                }
            }

            reader.EnsureMarkup(XmlNodeType.EndElement, documentElementName);
            await reader.ReadAsync();

            if (entries != null)
            {
                this.Entries = new ReadOnlyCollection<AtomEntry>(entries);
            }

            if (links != null)
            {
                this.Links = new ReadOnlyDictionary<string, Uri>(links);
            }

            if (messages != null)
            {
                this.Messages = new ReadOnlyCollection<Message>(messages);
            }
        }