Files
win8phoneApp/CampusAppWP8/CampusAppWP8/Utility/ICSClasses.cs
Christian Fiedler 53fb8599d1 ics classes
2013-09-02 18:09:19 +02:00

1773 lines
52 KiB
C#

//-----------------------------------------------------------------------------
// <copyright file="ICSClasses.cs" company="BTU/IIT">
// Company copyright tag.
// </copyright>
// <author>fiedlchr</author>
// <sience>29.08.2013</sience>
//-----------------------------------------------------------------------------
namespace CampusAppWP8.Utility
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Shapes;
using System.Xml.Serialization;
public class ICSClasses
{
private abstract class Interface
{
public void Set(string valueStr, string paramStr);
public void Set(string valueStr, string[] paramStrList);
public byte[] Get();
public string Get();
}
public class Attachment : Interface
{
// 3.8.1.1.
public const string Name = ICSTag.ATTACHMENT;
public readonly List<string> ParamList = null;
private string valueType = string.Empty;
private string encodingType = string.Empty;
private string formatType = string.Empty;
private byte[] value;
public Attachment()
{
this.ParamList = new List<string>();
this.ParamList.AddRange(new string[] {
ICSParam.NONE,
ICSParam.FORMAT_TYPE,
ICSParam.ENCODING,
ICSParam.VALUE_TYPE
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList)
{
foreach (string p in paramStrList)
{
string[] pSplit = p.Split('=');
if (pSplit.Length != 2)
{
throw new NotSupportedException("the number of '=' in the parameter (" + p + ") is less or greater then 1");
}
switch (pSplit[0])
{
case ICSParam.FORMAT_TYPE:
this.formatType = pSplit[1];
break;
case ICSParam.ENCODING:
this.encodingType = pSplit[1];
break;
case ICSParam.VALUE_TYPE:
this.valueType = pSplit[1];
break;
default:
throw new NotSupportedException("Parameter with tag (" + pSplit[0] + ") is not supported");
}
}
if (this.encodingType.Equals(ICSParamValue.BASE64))
{
this.value = Convert.FromBase64String(valueStr);
}
else //if (this.encodingType.Equals(ICSParamValue.BIT8))
{
this.value = Encoding.UTF8.GetBytes(valueStr);
}
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.ATTACHMENT;
if (this.formatType.Equals(string.Empty) == false)
{
retValue += ";" + ICSParam.FORMAT_TYPE + "=" + this.formatType;
}
if (this.encodingType.Equals(string.Empty) == false)
{
retValue += ";" + ICSParam.ENCODING + "=" + this.encodingType;
}
if (this.valueType.Equals(string.Empty) == false)
{
retValue += ";" + ICSParam.VALUE_TYPE + "=" + this.valueType;
}
retValue += ":" + Encoding.UTF8.GetString(this.value, 0, this.value.Length);
return retValue;
}
public byte[] Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public string Value
{
get
{
return Encoding.UTF8.GetString(this.value, 0, this.value.Length);
}
set
{
this.value = Encoding.UTF8.GetBytes(value);
}
}
public string EncodingType
{
get
{
return this.encodingType;
}
set
{
if (value.Equals(ICSParamValue.BIT8) || value.Equals(ICSParamValue.BASE64))
{
this.encodingType = value;
}
}
}
public string ValueType
{
get
{
return this.valueType;
}
set
{
if (value.Equals(ICSParamValue.BINARY))
{
this.valueType = value;
}
}
}
public string FormatType
{
get
{
return this.formatType;
}
set
{
this.formatType = value;
}
}
}
public class Categories : Interface
{
// 3.8.1.2
public const string Name = ICSTag.CATEGORIES;
public readonly List<string> ParamList = null;
private List<string> valueList = null;
private string languageType = string.Empty;
public Categories()
{
this.ParamList = new List<string>();
this.ParamList.AddRange(new string[] {
ICSParam.NONE,
ICSParam.LANGUAGE
});
this.valueList = new List<string>();
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList)
{
if (paramStrList.Count() > 1)
{
throw new NotSupportedException("in (" + ICSTag.CATEGORIES + ") is only the (" + ICSParam.LANGUAGE + ") param supported");
}
else if (paramStrList.Count() == 1)
{
string[] pSplit = paramStrList[0].Split('=');
if (pSplit.Length != 2)
{
throw new NotSupportedException("the number of '=' in the parameter (" + paramStrList[0] + ") is less or greater then 1");
}
switch (pSplit[0])
{
case ICSParam.LANGUAGE:
this.languageType = pSplit[1];
break;
default:
throw new NotSupportedException("Parameter with tag (" + pSplit[0] + ") is not supported");
}
}
this.valueList.AddRange(valueStr.Split(','));
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.CATEGORIES;
if (this.languageType.Equals(string.Empty) == false)
{
retValue += ";" + ICSParam.LANGUAGE + "=" + this.languageType;
}
retValue += ":" + this.valueList.First();
for(int i = 1; i < this.valueList.Count(); i++)
{
retValue += "," + this.valueList[i];
}
return retValue;
}
public List<string> Value
{
get
{
return this.valueList;
}
set
{
this.valueList = value;
}
}
public void AddCategory(string categoryName)
{
if (this.valueList.IndexOf(categoryName) < 0)
{
this.valueList.Add(categoryName);
}
}
public void RemoveCategory(string categoryName)
{
this.valueList.Remove(categoryName);
}
public string Language
{
get
{
return this.languageType;
}
set
{
this.languageType = value;
}
}
}
public class AccessClass : Interface
{
// 3.8.1.3
public const string Name = ICSTag.ACCESS_CLASS;
public readonly List<string> ValueList = null;
private string value = string.Empty;
public AccessClass()
{
this.ValueList = new List<string>();
this.ValueList.AddRange(new string[] {
ICSValue.PUBLIC,
ICSValue.PRIVATE,
ICSValue.CONFIDENTIAL
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList)
{
if (paramStrList.Count() > 0)
{
throw new NotSupportedException("in (" + ICSTag.ACCESS_CLASS + ") is no param supported");
}
if (this.ValueList.IndexOf(valueStr) >= 0)
{
this.value = valueStr;
}
else
{
throw new NotSupportedException("value (" + valueStr + ") is not supported");
}
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
return (ICSTag.ACCESS_CLASS + ":" + this.value);
}
public string Value
{
get
{
return this.value;
}
set
{
if (this.ValueList.IndexOf(value) >= 0)
{
this.value = value;
}
else
{
throw new NotSupportedException("value (" + value + ") is not supported");
}
}
}
}
public class Comment : Interface
{
// 3.8.1.4
public const string Name = ICSTag.COMMENT;
public readonly List<string> ParamList = null;
private string altrep = string.Empty;
private string languageType = string.Empty;
private string value = string.Empty;
public Comment()
{
this.ParamList = new List<string>();
this.ParamList.AddRange(new string[] {
ICSParam.NONE,
ICSParam.ALT_REPRESENTATION,
ICSParam.LANGUAGE
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList)
{
foreach (string p in paramStrList)
{
string[] pSplit = p.Split('=');
if (pSplit.Count() != 2)
{
throw new NotSupportedException("the number of '=' in the parameter (" + p + ") is less or greater then 1");
}
switch (pSplit[0])
{
case ICSParam.LANGUAGE:
this.languageType = pSplit[1];
break;
case ICSParam.ALT_REPRESENTATION:
// TODO: test, remove DQUOTES "
this.altrep = pSplit[1];
break;
default:
throw new NotSupportedException("Parameter with tag (" + pSplit[0] + ") is not supported");
}
}
this.value = valueStr;
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.COMMENT;
if (this.altrep.Equals(string.Empty) == false)
{
// TODO: add DQUOTES "
retValue += ";" + ICSParam.ALT_REPRESENTATION + "=" + this.altrep;
}
if (this.languageType.Equals(string.Empty) == false)
{
retValue += ";" + ICSParam.LANGUAGE + "=" + this.languageType;
}
retValue += ":" + this.value;
return retValue;
}
public string Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public string AltRepresentation
{
get
{
return this.altrep;
}
set
{
this.altrep = value;
}
}
public string Langauge
{
get
{
return this.languageType;
}
set
{
this.languageType = value;
}
}
}
public class Description : Comment // because the structure is the same
{
// 3.8.1.5
public const string Name = ICSTag.DESCRIPTION;
public Description() : base()
{
}
}
public class Geo : Interface
{
// 3.8.1.6
public const string Name = ICSTag.GEO;
private Tuple<float, float> value = null;
public Geo()
{
}
public void Set(string valueStr, string paramStr)
{
if ((paramStr == null) || (paramStr.Equals(string.Empty)))
{
this.Set(valueStr);
}
else
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.GEO + ")");
}
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.GEO + ")");
}
string[] valSplit = valueStr.Split(';');
if (valSplit.Count() != 2)
{
throw new FormatException("there are not 2 float values, seperated by ';', in the value string");
}
this.value = new Tuple<float, float>(float.Parse(valSplit[0]), float.Parse(valSplit[1]));
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.GEO;
if (this.value == null)
{
throw new NotSupportedException("there is no value set for (" + ICSTag.GEO + ")");
}
retValue += ":" + this.value.Item1.ToString() + ";" + this.value.Item2.ToString();
return retValue;
}
public Tuple<float,float> Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
}
public class Location : Comment // because the structure is the same
{
// 3.8.1.7.
public const string Name = ICSTag.LOCATION;
public Location() : base()
{
}
}
public class PercentComplete : Interface
{
// 3.8.1.8
public const string Name = ICSTag.PERCENT;
private int value = -1;
public PercentComplete()
{
}
public void Set(string valueStr, string paramStr)
{
if ((paramStr == null) || (paramStr.Equals(string.Empty)))
{
this.Set(valueStr);
}
else
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.PERCENT + ")");
}
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.PERCENT + ")");
}
this.value = int.Parse(valueStr);
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.PERCENT;
if (this.value < 0)
{
throw new NotSupportedException("there is no value set for (" + ICSTag.PERCENT + ")");
}
retValue += ":" + this.value.ToString();
return retValue;
}
public int Value
{
get
{
return this.value;
}
set
{
if ((value >= 0) && (value <= 100))
{
this.value = value;
}
else
{
throw new ArgumentOutOfRangeException("value must be in rang of [0..100] in (" + ICSTag.PERCENT + ")");
}
}
}
}
public class Priority : Interface
{
// 3.8.1.9.
public const string Name = ICSTag.PRIORITY;
private int value = -1;
public Priority()
{
}
public void Set(string valueStr, string paramStr)
{
if ((paramStr == null) || (paramStr.Equals(string.Empty)))
{
this.Set(valueStr);
}
else
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.PRIORITY + ")");
}
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.PRIORITY + ")");
}
this.value = int.Parse(valueStr);
if ((this.value < 0) || (this.value > 9))
{
throw new ArgumentOutOfRangeException("value must be in the range of [0..9] in (" + ICSTag.PRIORITY + ")");
}
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.PERCENT;
if (this.value < 0 || this.value > 9)
{
throw new NotSupportedException("there is no value set for (" + ICSTag.PRIORITY + ")");
}
retValue += ":" + this.value.ToString();
return retValue;
}
public int Value
{
get
{
return this.value;
}
set
{
if (value >= 0 && value <= 9)
{
this.value = value;
}
else
{
throw new ArgumentOutOfRangeException("value must be in rage of [0..9] in (" + ICSTag.PRIORITY + ")");
}
}
}
}
public class Resources : Comment // because the structure is the same
{
// 3.8.1.10.
public const string Name = ICSTag.RESOURCES;
public Resources() : base()
{
}
}
public class Status : Interface
{
// 3.8.1.11.
public const string Name = ICSTag.STATUS;
public readonly List<string> ValueListEvent = null;
public readonly List<string> ValueListToDo = null;
public readonly List<string> ValueListJournal = null;
private string value = string.Empty;
public Status()
{
this.ValueListEvent = new List<string>();
this.ValueListEvent.AddRange(new string[] {
ICSValue.TENTATIVE,
ICSValue.CONFIRMED,
ICSValue.CANCELLED
});
this.ValueListToDo = new List<string>();
this.ValueListToDo.AddRange(new string[] {
ICSValue.NEEDS_ACTION,
ICSValue.COMPLETED,
ICSValue.IN_PROCESS,
ICSValue.CANCELLED
});
this.ValueListJournal = new List<string>();
this.ValueListJournal.AddRange(new string[] {
ICSValue.DRAFT,
ICSValue.FINAL,
ICSValue.CANCELLED
});
}
public void Set(string valueStr, string paramStr)
{
if ((paramStr == null) || (paramStr.Equals(string.Empty)))
{
this.Set(valueStr);
}
else
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.STATUS + ")");
}
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("parameter are not supported in (" + ICSTag.PRIORITY + ")");
}
if ((this.ValueListEvent.IndexOf(valueStr) < 0)
&& (this.ValueListToDo.IndexOf(valueStr) < 0)
&& (this.ValueListJournal.IndexOf(valueStr) < 0))
{
throw new NotSupportedException("value (" + valueStr + ") is not supported in (" + ICSTag.STATUS + ")");
}
this.value = valueStr;
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += ICSTag.STATUS + ":" + this.value;
return retValue;
}
public string Value
{
get
{
return this.value;
}
set
{
if ((this.ValueListEvent.IndexOf(value) >= 0)
|| (this.ValueListToDo.IndexOf(value) >= 0)
|| (this.ValueListJournal.IndexOf(value) >= 0))
{
this.value = value;
}
else
{
throw new NotSupportedException("value (" + value + ") is not supported in (" + ICSTag.STATUS + ")");
}
}
}
}
public class Summary : Comment // because the structure is the same
{
// 3.8.1.12.
public const string Name = ICSTag.SUMMARY;
public Summary()
: base()
{
}
}
public class DTCompleted : Interface
{
// 3.8.2.1.
public readonly string Name = ICSTag.COMPLETED;
private DateTime value = DateTime.MinValue;
public DTCompleted()
{
}
public void Set(string valueStr, string paramStr)
{
if ((paramStr == null) || (paramStr.Equals(string.Empty)))
{
this.Set(valueStr);
}
else
{
throw new NotSupportedException("parameter are not supported in (" + this.Name + ")");
}
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("parameter are not supported in (" + this.Name + ")");
}
this.value = UTCStringToDateTime(valueStr);
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name + ":" + string.Format("{0:yyyyMMdd}T{0:HHmmss}Z", this.value.ToUniversalTime());
return retValue;
}
public DateTime Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
}
public class DTEnd : Interface
{
// 3.8.2.2.
public readonly string Name = ICSTag.DT_END;
public readonly List<string> ParamList = null;
public readonly List<string> ParamValueList = null;
private DateTime value = DateTime.MinValue;
private string timeZone = string.Empty;
private bool isDate = false;
public DTEnd()
{
this.ParamList = new List<string>();
this.ParamList.AddRange(new string[] {
ICSParam.NONE,
ICSParam.VALUE_TYPE,
ICSParam.TIME_ZONE_ID
});
this.ParamValueList = new List<string>();
this.ParamValueList.AddRange(new string[] {
ICSParamValue.DATE_TIME,
ICSParamValue.DATE
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
if (paramStrList.Count() > 2)
{
throw new NotSupportedException("too many params in (" + this.Name + ")");
}
for(int i = 0; i < paramStrList.Count(); i++)
{
string[] p = paramStrList[i].Split('=');
if (p.Count() != 2)
{
throw new NotSupportedException("incorrect param string (" + paramStrList[0] + ")");
}
if (p[0].Equals(ICSParam.VALUE_TYPE))
{
if (p[1].Equals(ICSParamValue.DATE))
{
this.isDate = true;
}
else if (p[1].Equals(ICSParamValue.DATE_TIME))
{
this.isDate = false;
}
else
{
throw new NotSupportedException("param value (" + p[1] + ") is not supported in (" + this.Name + ")");
}
}
else if(p[0].Equals(ICSParam.TIME_ZONE_ID))
{
this.timeZone = p[1];
}
else
{
throw new NotSupportedException("param (" + p[0] + ") is not supported in (" + this.Name + ")");
}
}
}
bool tempIsDate = IsDate(valueStr);
if (this.isDate != tempIsDate)
{
throw new NotSupportedException("time value has not the same type as declared in param in(" + this.Name + ")");
}
this.value = UTCStringToDateTime(valueStr);
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name;
if(!this.timeZone.Equals(string.Empty))
{
retValue += ";" + this.timeZone;
}
if (this.isDate)
{
retValue += ";" + ICSParam.VALUE_TYPE + "=" + ICSParamValue.DATE;
}
retValue += ":";
if (this.isDate)
{
retValue += string.Format("{0:yyyyMMdd}", this.value.ToUniversalTime());
}
else
{
retValue += string.Format("{0:yyyyMMdd}T{0:HHmmss}Z", this.value.ToUniversalTime());
}
return retValue;
}
public DateTime Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public bool IsDate
{
get
{
return this.isDate;
}
set
{
this.isDate = value;
}
}
public string TimeZone
{
get
{
return this.timeZone;
}
set
{
this.timeZone = value;
}
}
}
public class DTDue : DTEnd // because the structure is the same
{
// 3.8.2.3.
public readonly string Name = ICSTag.DUE;
public DTDue()
: base()
{
}
}
public class DTStart : DTEnd // because the structure is the same
{
// 3.8.2.4.
public readonly string Name = ICSTag.DT_START;
public DTStart()
: base()
{
}
}
public class Duration : Interface
{
// 3.8.2.5.
public readonly string Name = ICSTag.DURATION;
private TimeSpan value = TimeSpan.Zero;
private bool isNegative = false;
public Duration()
{
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr);
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("params are not supported in (" + this.Name + ")");
}
this.value = StringToTimeSpan(valueStr);
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name + ":" + TimeSpanToString(this.value, this.isNegative);
return retValue;
}
public TimeSpan Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public bool IsNegative
{
get
{
return this.isNegative;
}
set
{
this.isNegative = value;
}
}
}
public class FreeBusyTime : Interface
{
// 3.8.2.6.
public readonly string Name = ICSTag.FREEBUSY;
public readonly List<string> ParamList = null;
public readonly List<string> ParamValueList = null;
private string freebusyType = string.Empty;
private List<Tuple<DateTime, TimeSpan, DateTime>> valueList = null;
public FreeBusyTime()
{
this.valueList = new List<Tuple<DateTime, TimeSpan, DateTime>>();
this.ParamList = new List<string>();
this.ParamList.AddRange(new string[] {
ICSParam.NONE,
ICSParam.FREE_BUSY_TIME_TYPE
});
this.ParamValueList = new List<string>();
this.ParamValueList.AddRange(new string[] {
ICSParamValue.FREE,
ICSParamValue.BUSY,
ICSParamValue.BUSY_UNAVAILABLE,
ICSParamValue.BUSY_TENTATIVE
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null && paramStrList.Count() > 0)
{
if (paramStrList.Count() > 1)
{
throw new NotSupportedException("there is only 1 param in (" + this.Name + ") supported");
}
string[] pSplit = paramStrList[0].Split('=');
if (pSplit.Count() != 2)
{
throw new FormatException("parameter string (" + paramStrList[0] + ") is wrong");
}
if (pSplit[0].Equals(ICSParam.FREE_BUSY_TIME_TYPE))
{
if (this.ParamValueList.IndexOf(pSplit[1]) < 0)
{
throw new NotSupportedException("unsupported param value (" + pSplit[1] + ")");
}
else
{
this.freebusyType = pSplit[1];
}
}
else
{
throw new NotSupportedException("unsupported param (" + pSplit[0] + ")");
}
}
string[] valSplit = valueStr.Split(',');
for (int i = 0; i < valueStr.Count(); i++)
{
string[] subSplit = valSplit[i].Split('/');
if (subSplit.Count() != 2)
{
throw new FormatException("value has a unsupported format (" + valSplit[i] + ")");
}
DateTime partDTStart = UTCStringToDateTime(subSplit[0]);
TimeSpan partTSDur = TimeSpan.Zero;
DateTime partDTEnd = DateTime.MinValue;
if ((subSplit[1][subSplit[1].Length - 1].Equals('Z'))
|| (subSplit[1][subSplit[1].Length - 1] >= '0' && subSplit[1][subSplit[1].Length - 1] <= '9'))
{
partDTEnd = UTCStringToDateTime(subSplit[1]);
}
else
{
partTSDur = StringToTimeSpan(subSplit[1]);
}
this.valueList.Add(new Tuple<DateTime, TimeSpan, DateTime>(partDTStart, partTSDur, partDTEnd));
}
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name;
if (!this.freebusyType.Equals(string.Empty))
{
retValue += ICSParam.FREE_BUSY_TIME_TYPE + "=" + this.freebusyType;
}
retValue += ":";
for (int i = 0; i < this.valueList.Count(); i++)
{
if(i > 0)
{
retValue += ",";
}
retValue += string.Format("{0:yyyyMMdd}T{0:HHmmss}Z", this.valueList[i].Item1.ToUniversalTime()) + "/";
if (this.valueList[i].Item2.Equals(TimeSpan.Zero))
{
retValue += string.Format("{0:yyyyMMdd}T{0:HHmmss}Z", this.valueList[i].Item3.ToUniversalTime());
}
else
{
retValue += TimeSpanToString(this.valueList[i].Item2);
}
}
return retValue;
}
public List<Tuple<DateTime, TimeSpan, DateTime>> ValueList
{
get
{
return this.valueList;
}
set
{
this.valueList = value;
}
}
public string FreeBusyType
{
get
{
return this.freebusyType;
}
set
{
if (this.ParamValueList.IndexOf(value) < 0)
{
throw new NotSupportedException("param value (" + value + ") is not supported");
}
else
{
this.freebusyType = value;
}
}
}
public void AddValue(DateTime dtStart, TimeSpan tsDur)
{
this.valueList.Add(new Tuple<DateTime, TimeSpan, DateTime>(dtStart, tsDur, DateTime.MinValue));
}
public void AddValue(DateTime dtStart, DateTime dtEnd)
{
this.ValueList.Add(new Tuple<DateTime, TimeSpan, DateTime>(dtStart, TimeSpan.Zero, dtEnd));
}
}
public class TimeTransparency : Interface
{
// 3.8.2.7.
public readonly string Name = ICSTag.TRANSP;
public readonly List<string> ValueList = null;
private string value = ICSValue.OPAQUE;
public TimeTransparency()
{
this.ValueList = new List<string>();
this.ValueList.AddRange(new string[] {
ICSValue.OPAQUE,
ICSValue.TRANSPARENT
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr);
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("params are not supported in (" + this.Name + ")");
}
if (this.ValueList.IndexOf(valueStr) < 0)
{
throw new NotSupportedException("value (" + valueStr + ") is not supported");
}
this.value = valueStr;
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name + ":" + this.value;
return retValue;
}
public string Value
{
get
{
return this.value;
}
set
{
if (this.ValueList.IndexOf(value) < 0)
{
throw new NotSupportedException("value (" + value + ") is not supported");
}
else
{
this.value = value;
}
}
}
}
public class TimeZoneIdentifier : Interface
{
// 3.8.3.1.
public readonly string Name = ICSTag.TIME_ZONE_ID;
private string value = string.Empty;
public TimeZoneIdentifier()
{
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr);
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("params are not supported in (" + this.Name + ")");
}
this.value = valueStr;
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name + ":" + this.value;
return retValue;
}
public string Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
}
public class TimeZoneName : Interface
{
// 3.8.3.2.
public readonly string Name = ICSTag.TIME_ZONE_NAME;
public readonly List<string> ParamList = null;
private string language = string.Empty;
private string value = string.Empty;
public TimeZoneName()
{
this.ParamList = new List<string>();
this.ParamList.AddRange(new string[] {
ICSParam.NONE,
ICSParam.LANGUAGE
});
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr, paramStr.Split(';'));
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
if (paramStrList.Count() > 1)
{
throw new NotSupportedException("ther is only 1 param supported in (" + this.Name + ")");
}
if (paramStrList.Count() == 1)
{
string[] pSplit = paramStrList[0].Split('=');
if (pSplit.Count() != 2)
{
throw new FormatException("unsupported format in param (" + paramStrList[0] + ")");
}
if (pSplit[0].Equals(ICSParam.LANGUAGE))
{
this.language = pSplit[1];
}
else
{
throw new NotSupportedException("unsupported param (" + pSplit[0] + ")");
}
}
}
this.value = valueStr;
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name;
if (!this.language.Equals(string.Empty))
{
retValue += ";" + ICSParam.LANGUAGE + "=" + this.language;
}
retValue += ":" + this.value;
return retValue;
}
public string Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public string Language
{
get
{
return this.language;
}
set
{
this.language = value;
}
}
}
public class TimeZoneOffsetFrom : Interface
{
// 3.8.3.3.
public readonly string Name = ICSTag.TIME_ZONE_OFFSET_FROM;
private bool isNegative = false;
private TimeSpan value = TimeSpan.Zero;
public TimeZoneOffsetFrom()
{
}
public void Set(string valueStr, string paramStr)
{
this.Set(valueStr);
}
public void Set(string valueStr, string[] paramStrList = null)
{
if (paramStrList != null)
{
throw new NotSupportedException("no param supported in (" + this.Name + ")");
}
if(valueStr[0].Equals('+'))
{
this.isNegative = false;
}
else if(valueStr[0].Equals('-'))
{
this.isNegative = true;
}
else
{
throw new NotImplementedException("unhandled starting char (" + valueStr + ")");
}
this.value = new TimeSpan(int.Parse(valueStr.Substring(1, 2)), int.Parse(valueStr.Substring(3, 2)), ((valueStr.Length > 5) ? int.Parse(valueStr.Substring(5, 2)) : 0));
}
public byte[] GetBytes()
{
return Encoding.UTF8.GetBytes(this.GetString());
}
public string GetString()
{
string retValue = string.Empty;
retValue += this.Name + ":" + ((this.isNegative) ? "-" : "+") + string.Format("{0:HHmm}", this.value);
return retValue;
}
public TimeSpan Value
{
get
{
return this.value;
}
set
{
this.value = value;
}
}
public bool IsNegative
{
get
{
return this.isNegative;
}
set
{
this.isNegative = value;
}
}
}
// functions
private static DateTime UTCStringToDateTime(string timeStr)
{
// see http://tools.ietf.org/html/rfc5545 3.3.5.
timeStr = timeStr.Insert(4, "-");
timeStr = timeStr.Insert(7, "-");
if (!IsDate(timeStr))
{
timeStr = timeStr.Insert(13, ":");
timeStr = timeStr.Insert(16, ":");
}
return DateTime.Parse(timeStr);
}
private static bool IsDate(string timeStr)
{
if (timeStr[timeStr.Length - 1].Equals('Z'))
return false;
else
return true;
}
private static TimeSpan StringToTimeSpan(string timeStr)
{
TimeSpan retValue = TimeSpan.Zero;
Tuple<int, char>[] valList = DurSplit(timeStr);
int days = 0;
int hours = 0;
int mins = 0;
int secs = 0;
for (int i = 0; i < valList.Count(); i++)
{
switch (valList[i].Item2)
{
case 'D':
days = valList[i].Item1;
break;
case 'W':
days = valList[i].Item1 * 7;
break;
case 'H':
hours = valList[i].Item1;
break;
case 'M':
mins = valList[i].Item1;
break;
case 'S':
secs = valList[i].Item1;
break;
default:
throw new NotSupportedException("duration tag (" + valList[i].Item2 + ") not supported");
}
}
retValue = new TimeSpan(days, hours, mins, secs);
return retValue;
}
private static Tuple<int, char>[] DurSplit(string durStr)
{
List<Tuple<int, char>> retValue = new List<Tuple<int,char>>();
string str = durStr.Replace("P", "").Replace("T", "").Replace("+", "").Replace("-", "");
int val = 0;
char typeChar;
for (int i = 0; i < durStr.Length; i++)
{
if (durStr[i] >= '0' && durStr[i] <= '9')
{
val *= 10;
val += (durStr[0] - '0');
}
else
{
typeChar = durStr[i];
retValue.Add(new Tuple<int, char>(val, typeChar));
val = 0;
}
}
return retValue.ToArray();
}
private static string TimeSpanToString(TimeSpan timeSpan, bool isNegative = false)
{
string retValue = string.Empty;
if (isNegative)
{
retValue += "-";
}
retValue += "P";
if (timeSpan.Days > 0)
{
retValue += timeSpan.Days.ToString() + "D";
}
if ((timeSpan.Hours > 0) || (timeSpan.Minutes > 0) || (timeSpan.Seconds > 0))
{
retValue += "T" + timeSpan.Hours.ToString() + "H" + timeSpan.Minutes.ToString() + "M" + timeSpan.Seconds.ToString() + "S";
}
return retValue;
}
}
}