using System;
using System.Linq;
using System.Runtime.InteropServices;
using NvAPIWrapper.Native.Attributes;
using NvAPIWrapper.Native.General.Structures;
using NvAPIWrapper.Native.Helpers;
using NvAPIWrapper.Native.Interfaces;
namespace NvAPIWrapper.Native.DRS.Structures
{
///
/// Represents a NVIDIA driver setting
///
[StructLayout(LayoutKind.Sequential, Pack = 8)]
[StructureVersion(1)]
public struct DRSSettingV1 : IInitializable
{
internal StructureVersion _Version;
internal UnicodeString _SettingName;
internal uint _SettingId;
internal DRSSettingType _SettingType;
internal DRSSettingLocation _SettingLocation;
internal uint _IsCurrentPredefined;
internal uint _IsPredefinedValid;
internal DRSSettingValue _PredefinedValue;
internal DRSSettingValue _CurrentValue;
///
/// Creates a new instance of containing the passed value.
///
/// The setting identification number.
/// The type of the setting's value
/// The setting's value
public DRSSettingV1(uint id, DRSSettingType settingType, object value)
{
this = typeof(DRSSettingV1).Instantiate();
Id = id;
IsPredefinedValueValid = false;
_SettingType = settingType;
CurrentValue = value;
}
///
/// Creates a new instance of containing the passed value.
///
/// The setting identification number.
/// The setting's value
public DRSSettingV1(uint id, string value) : this(id, DRSSettingType.String, value)
{
}
///
/// Creates a new instance of containing the passed value.
///
/// The setting identification number.
/// The setting's value
public DRSSettingV1(uint id, uint value) : this(id, DRSSettingType.Integer, value)
{
}
///
/// Creates a new instance of containing the passed value.
///
/// The setting identification number.
/// The setting's value
public DRSSettingV1(uint id, byte[] value) : this(id, DRSSettingType.Binary, value)
{
}
///
/// Gets the name of the setting
///
public string Name
{
get => _SettingName.Value;
}
///
/// Gets the identification number of the setting
///
public uint Id
{
get => _SettingId;
private set => _SettingId = value;
}
///
/// Gets the setting's value type
///
public DRSSettingType SettingType
{
get => _SettingType;
private set => _SettingType = value;
}
///
/// Gets the setting location
///
public DRSSettingLocation SettingLocation
{
get => _SettingLocation;
}
///
/// Gets a boolean value indicating if the current value is the predefined value
///
public bool IsCurrentValuePredefined
{
get => _IsCurrentPredefined > 0;
private set => _IsCurrentPredefined = value ? 1u : 0u;
}
///
/// Gets a boolean value indicating if the predefined value is available and valid
///
public bool IsPredefinedValueValid
{
get => _IsPredefinedValid > 0;
private set => _IsPredefinedValid = value ? 1u : 0u;
}
///
/// Returns the predefined value as an integer
///
/// An integer representing the predefined value
public uint GetPredefinedValueAsInteger()
{
return _PredefinedValue.AsInteger();
}
///
/// Returns the predefined value as an array of bytes
///
/// An byte array representing the predefined value
public byte[] GetPredefinedValueAsBinary()
{
return _PredefinedValue.AsBinary();
}
///
/// Returns the predefined value as an unicode string
///
/// An unicode string representing the predefined value
public string GetPredefinedValueAsUnicodeString()
{
return _PredefinedValue.AsUnicodeString();
}
///
/// Gets the setting's predefined value
///
public object PredefinedValue
{
get
{
if (!IsPredefinedValueValid)
{
return null;
}
switch (_SettingType)
{
case DRSSettingType.Integer:
return GetPredefinedValueAsInteger();
case DRSSettingType.Binary:
return GetPredefinedValueAsBinary();
case DRSSettingType.String:
case DRSSettingType.UnicodeString:
return GetPredefinedValueAsUnicodeString();
default:
throw new ArgumentOutOfRangeException(nameof(SettingType));
}
}
}
///
/// Returns the current value as an integer
///
/// An integer representing the current value
public uint GetCurrentValueAsInteger()
{
return _CurrentValue.AsInteger();
}
///
/// Returns the current value as an array of bytes
///
/// An byte array representing the current value
public byte[] GetCurrentValueAsBinary()
{
return _CurrentValue.AsBinary();
}
///
/// Returns the current value as an unicode string
///
/// An unicode string representing the current value
public string GetCurrentValueAsUnicodeString()
{
return _CurrentValue.AsUnicodeString();
}
///
/// Sets the passed value as the current value
///
/// The new value for the setting
public void SetCurrentValueAsInteger(uint value)
{
if (SettingType != DRSSettingType.Integer)
{
throw new ArgumentOutOfRangeException(nameof(value), "Passed argument is invalid for this setting.");
}
_CurrentValue = new DRSSettingValue(value);
IsCurrentValuePredefined = IsPredefinedValueValid && (uint) CurrentValue == (uint) PredefinedValue;
}
///
/// Sets the passed value as the current value
///
/// The new value for the setting
public void SetCurrentValueAsBinary(byte[] value)
{
if (SettingType != DRSSettingType.Binary)
{
throw new ArgumentOutOfRangeException(nameof(value), "Passed argument is invalid for this setting.");
}
_CurrentValue = new DRSSettingValue(value);
IsCurrentValuePredefined =
IsPredefinedValueValid &&
((byte[]) CurrentValue)?.SequenceEqual((byte[]) PredefinedValue ?? new byte[0]) == true;
}
///
/// Sets the passed value as the current value
///
/// The new value for the setting
public void SetCurrentValueAsUnicodeString(string value)
{
if (SettingType != DRSSettingType.UnicodeString)
{
throw new ArgumentOutOfRangeException(nameof(value), "Passed argument is invalid for this setting.");
}
_CurrentValue = new DRSSettingValue(value);
IsCurrentValuePredefined =
IsPredefinedValueValid &&
string.Equals(
(string) CurrentValue,
(string) PredefinedValue,
StringComparison.InvariantCulture
);
}
///
/// Gets or sets the setting's current value
///
public object CurrentValue
{
get
{
switch (_SettingType)
{
case DRSSettingType.Integer:
return GetCurrentValueAsInteger();
case DRSSettingType.Binary:
return GetCurrentValueAsBinary();
case DRSSettingType.String:
case DRSSettingType.UnicodeString:
return GetCurrentValueAsUnicodeString();
default:
throw new ArgumentOutOfRangeException(nameof(SettingType));
}
}
private set
{
if (value is int intValue)
{
SetCurrentValueAsInteger((uint) intValue);
}
else if (value is uint unsignedIntValue)
{
SetCurrentValueAsInteger(unsignedIntValue);
}
else if (value is short shortValue)
{
SetCurrentValueAsInteger((uint) shortValue);
}
else if (value is ushort unsignedShortValue)
{
SetCurrentValueAsInteger(unsignedShortValue);
}
else if (value is long longValue)
{
SetCurrentValueAsInteger((uint) longValue);
}
else if (value is ulong unsignedLongValue)
{
SetCurrentValueAsInteger((uint) unsignedLongValue);
}
else if (value is byte byteValue)
{
SetCurrentValueAsInteger(byteValue);
}
else if (value is string stringValue)
{
SetCurrentValueAsUnicodeString(stringValue);
}
else if (value is byte[] binaryValue)
{
SetCurrentValueAsBinary(binaryValue);
}
else
{
throw new ArgumentException("Unacceptable argument type.", nameof(value));
}
}
}
}
}