2014-04-20 16:57:38 -04:00
|
|
|
|
using System;
|
2014-04-09 21:30:07 -04:00
|
|
|
|
using System.Collections.Generic;
|
2014-04-20 18:42:51 -04:00
|
|
|
|
using System.Globalization;
|
2014-04-09 21:30:07 -04:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
2014-04-20 16:57:38 -04:00
|
|
|
|
namespace NTwain.Data
|
2014-04-09 21:30:07 -04:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Utility on converting (possibly bad) integer values to enum values.
|
|
|
|
|
|
/// </summary>
|
2014-04-22 06:50:58 -04:00
|
|
|
|
public static class ValueExtensions
|
2014-04-09 21:30:07 -04:00
|
|
|
|
{
|
2014-04-22 06:50:58 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Casts a list of objects to a list of specified enum.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
|
|
|
|
|
/// <param name="list">The list.</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static IList<TEnum> CastToEnum<TEnum>(this IEnumerable<object> list) where TEnum : struct,IConvertible
|
2014-04-09 21:30:07 -04:00
|
|
|
|
{
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return list.CastToEnum<TEnum>(true);
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
2014-04-22 06:50:58 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Casts a list of objects to a list of specified enum.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
|
|
|
|
|
/// <param name="list">The list.</param>
|
|
|
|
|
|
/// <param name="tryUpperWord">set to <c>true</c> for working with bad values.</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static IList<TEnum> CastToEnum<TEnum>(this IEnumerable<object> list, bool tryUpperWord) where TEnum : struct,IConvertible
|
2014-04-09 21:30:07 -04:00
|
|
|
|
{
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return list.Select(o => o.ConvertToEnum<TEnum>(tryUpperWord)).ToList();
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-22 06:50:58 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Casts an objects to the specified enum.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
|
|
|
|
|
/// <param name="value">The value.</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static TEnum ConvertToEnum<TEnum>(this object value) where TEnum : struct,IConvertible
|
2014-04-09 21:30:07 -04:00
|
|
|
|
{
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return ConvertToEnum<TEnum>(value, true);
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
2014-04-22 06:50:58 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Casts an objects to the specified enum.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
|
|
|
|
|
/// <param name="value">The value.</param>
|
|
|
|
|
|
/// <param name="tryUpperWord">if set to <c>true</c> [try upper word].</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static TEnum ConvertToEnum<TEnum>(this object value, bool tryUpperWord) where TEnum : struct,IConvertible
|
2014-04-09 21:30:07 -04:00
|
|
|
|
{
|
2014-04-22 06:50:58 -04:00
|
|
|
|
var returnType = typeof(TEnum);
|
2014-04-09 21:30:07 -04:00
|
|
|
|
|
|
|
|
|
|
// standard int values
|
|
|
|
|
|
if (returnType.IsEnum)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (tryUpperWord)
|
|
|
|
|
|
{
|
|
|
|
|
|
// small routine to work with bad sources that may put
|
|
|
|
|
|
// 16bit value in the upper word instead of lower word (as per the twain spec).
|
|
|
|
|
|
var rawType = Enum.GetUnderlyingType(returnType);
|
|
|
|
|
|
if (typeof(ushort).IsAssignableFrom(rawType))
|
|
|
|
|
|
{
|
2014-04-20 18:42:51 -04:00
|
|
|
|
var intVal = Convert.ToUInt32(value, CultureInfo.InvariantCulture);
|
2014-04-09 21:30:07 -04:00
|
|
|
|
var enumVal = GetLowerWord(intVal);
|
|
|
|
|
|
if (!Enum.IsDefined(returnType, enumVal))
|
|
|
|
|
|
{
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return (TEnum)Enum.ToObject(returnType, GetUpperWord(intVal));
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// this may work better?
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return (TEnum)Enum.ToObject(returnType, value);
|
2014-04-09 21:30:07 -04:00
|
|
|
|
//// cast to underlying type first then to the enum
|
|
|
|
|
|
//return (T)Convert.ChangeType(value, rawType);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (typeof(IConvertible).IsAssignableFrom(returnType))
|
|
|
|
|
|
{
|
|
|
|
|
|
// for regular integers and whatnot
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return (TEnum)Convert.ChangeType(value, returnType, CultureInfo.InvariantCulture);
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
|
|
|
|
|
// return as-is from cap. if caller made a mistake then there should be exceptions
|
2014-04-22 06:50:58 -04:00
|
|
|
|
return (TEnum)value;
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ushort GetLowerWord(uint value)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (ushort)(value & 0xffff);
|
|
|
|
|
|
}
|
|
|
|
|
|
static uint GetUpperWord(uint value)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (ushort)(value >> 16);
|
|
|
|
|
|
}
|
2014-04-15 18:45:41 -04:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Tries to convert to a value to <see cref="TWFix32"/> if possible.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="value">The value.</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static TWFix32 ConvertToFix32(this object value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value is TWFix32)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (TWFix32)value;
|
|
|
|
|
|
}
|
2014-04-20 18:42:51 -04:00
|
|
|
|
return (TWFix32)Convert.ToSingle(value, CultureInfo.InvariantCulture);
|
2014-04-15 18:45:41 -04:00
|
|
|
|
}
|
2014-04-09 21:30:07 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|