using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Collections;
using System.Runtime.Serialization;
namespace Apolyton.FastJson.Serialization
{
/// <summary>
/// This class contains deserialization helpers
/// </summary>
internal static class Deserialization
{
/// <summary>
/// Changes the value type to the expected one.
/// </summary>
/// <param name="value"></param>
/// <param name="convertTo"></param>
/// <returns></returns>
internal static object ChangeType(object value, Type convertTo)
{
if (convertTo == typeof(int))
return (int)((long)value);
else if (convertTo == typeof(long))
return (long)value;
else if (convertTo == typeof(string))
return (string)value;
else if (convertTo == typeof(Guid))
return CreateGuid((string)value);
else if (convertTo == typeof(TimeSpan))
return CreateTimeSpan((String)value);
else if (convertTo.IsEnum)
return CreateEnum(convertTo, (string)value);
return Convert.ChangeType(value, convertTo, CultureInfo.InvariantCulture);
}
/// <summary>
/// Returns an enum value for the given type.
/// </summary>
/// <param name="enumType"></param>
/// <param name="enumString"></param>
/// <returns></returns>
internal static object CreateEnum(Type enumType, string enumString)
{
// TODO : optimize create enum
return Enum.Parse(enumType, enumString);
}
/// <summary>
/// Returns a guid for the given string.
/// </summary>
/// <param name="base64OrGuidString"></param>
/// <returns></returns>
internal static Guid CreateGuid(string base64OrGuidString)
{
if (base64OrGuidString.Length > 30)
{
return new Guid(base64OrGuidString);
}
else
{
return new Guid(Convert.FromBase64String(base64OrGuidString));
}
}
/// <summary>
/// Returns a time span for the given string.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
internal static TimeSpan CreateTimeSpan(String s)
{
return TimeSpan.Parse(s);
}
/// <summary>
/// Returns the parsed date time.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
internal static DateTime CreateDateTime(string value)
{
// 0123456789012345678
// datetime format = yyyy-MM-dd HH:mm:ss
int year = (int)CreateLong(value.Substring(0, 4));
int month = (int)CreateLong(value.Substring(5, 2));
int day = (int)CreateLong(value.Substring(8, 2));
int hour = (int)CreateLong(value.Substring(11, 2));
int min = (int)CreateLong(value.Substring(14, 2));
int sec = (int)CreateLong(value.Substring(17, 2));
if (!value.EndsWith("Z"))
{
return new DateTime(year, month, day, hour, min, sec);
}
else
{
return new DateTime(year, month, day, hour, min, sec, DateTimeKind.Utc).ToLocalTime();
}
}
/// <summary>
/// Returns a long value for the given string.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
internal static long CreateLong(string s)
{
long num = 0;
bool neg = false;
foreach (char cc in s)
{
if (cc == '-')
{
neg = true;
}
else if (cc == '+')
{
neg = false;
}
else
{
num *= 10;
num += (int)(cc - '0');
}
}
return neg ? -num : num;
}
internal static IEnumerable<Byte> CreateByteArray(string base64ByteString, Type targetType)
{
if (targetType.IsArray || typeof(IEnumerable).IsAssignableFrom(targetType))
{
return Convert.FromBase64String(base64ByteString);
}
throw new SerializationException("Cannot create instance for type " + targetType);
}
}
}