///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Xml;
using wasDAVClient.Model;
namespace wasDAVClient.Helpers
{
///
/// Represents the parser for response's results.
///
internal static class ResponseParser
{
internal static XmlReaderSettings XmlReaderSettings = new XmlReaderSettings
{
IgnoreComments = true,
IgnoreProcessingInstructions = true,
IgnoreWhitespace = true
};
///
/// Parses the disk item.
///
/// The response text.
/// The parsed item.
public static Item ParseItem(Stream stream)
{
return ParseItems(stream).FirstOrDefault();
}
///
/// Parses the disk items.
///
/// The response text.
/// The list of parsed items.
public static IEnumerable- ParseItems(Stream stream)
{
var items = new List
- ();
using (var reader = XmlReader.Create(stream, XmlReaderSettings))
{
Item itemInfo = null;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.LocalName.ToLower())
{
case "response":
itemInfo = new Item();
break;
case "href":
if (!reader.IsEmptyElement)
{
reader.Read();
var value = reader.Value;
value = value.Replace("#", "%23");
itemInfo.Href = value;
}
break;
case "creationdate":
if (!reader.IsEmptyElement)
{
reader.Read();
DateTime creationdate;
if (DateTime.TryParse(reader.Value, out creationdate))
itemInfo.CreationDate = creationdate;
}
break;
case "getlastmodified":
if (!reader.IsEmptyElement)
{
reader.Read();
DateTime lastmodified;
if (DateTime.TryParse(reader.Value, out lastmodified))
itemInfo.LastModified = lastmodified;
}
break;
case "displayname":
if (!reader.IsEmptyElement)
{
reader.Read();
itemInfo.DisplayName = reader.Value;
}
break;
case "getcontentlength":
if (!reader.IsEmptyElement)
{
reader.Read();
long contentLength;
if (long.TryParse(reader.Value, out contentLength))
itemInfo.ContentLength = contentLength;
}
break;
case "getcontenttype":
if (!reader.IsEmptyElement)
{
reader.Read();
itemInfo.ContentType = reader.Value;
}
break;
case "getetag":
if (!reader.IsEmptyElement)
{
reader.Read();
itemInfo.Etag = reader.Value;
}
break;
case "iscollection":
if (!reader.IsEmptyElement)
{
reader.Read();
bool isCollection;
if (bool.TryParse(reader.Value, out isCollection))
itemInfo.IsCollection = isCollection;
int isCollectionInt;
if (int.TryParse(reader.Value, out isCollectionInt))
itemInfo.IsCollection = isCollectionInt == 1;
}
break;
case "resourcetype":
if (!reader.IsEmptyElement)
{
reader.Read();
var resourceType = reader.LocalName.ToLower();
if (string.Equals(resourceType, "collection",
StringComparison.InvariantCultureIgnoreCase))
itemInfo.IsCollection = true;
}
break;
case "hidden":
case "ishidden":
itemInfo.IsHidden = true;
break;
case "checked-in":
case "version-controlled-configuration":
reader.Skip();
break;
}
}
else if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName.ToLower() == "response")
{
// Remove trailing / if the item is not a collection
var href = itemInfo.Href.TrimEnd('/');
if (!itemInfo.IsCollection)
{
itemInfo.Href = href;
}
if (string.IsNullOrEmpty(itemInfo.DisplayName))
{
var name = href.Substring(href.LastIndexOf('/') + 1);
itemInfo.DisplayName = WebUtility.UrlDecode(name);
}
items.Add(itemInfo);
}
}
}
return items;
}
}
}