#region License // // Copyright 2015-2013 Giacomo Stelluti Scala // // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #endregion #region Using Directives using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using CommandLine.Infrastructure; #endregion namespace CommandLine.Parsing { [DebuggerDisplay("ShortName = {ShortName}, LongName = {LongName}")] internal sealed class OptionInfo { private readonly CultureInfo _parsingCulture; private readonly BaseOptionAttribute _attribute; private readonly PropertyInfo _property; private readonly PropertyWriter _propertyWriter; private readonly bool _required; private readonly char? _shortName; private readonly string _longName; private readonly string _mutuallyExclusiveSet; private readonly object _defaultValue; private readonly bool _hasDefaultValue; public OptionInfo(BaseOptionAttribute attribute, PropertyInfo property, CultureInfo parsingCulture) { if (attribute == null) { throw new ArgumentNullException("attribute", SR.ArgumentNullException_AttributeCannotBeNull); } if (property == null) { throw new ArgumentNullException("property", SR.ArgumentNullException_PropertyCannotBeNull); } _required = attribute.Required; _shortName = attribute.ShortName; _longName = attribute.LongName; _mutuallyExclusiveSet = attribute.MutuallyExclusiveSet; _defaultValue = attribute.DefaultValue; _hasDefaultValue = attribute.HasDefaultValue; _attribute = attribute; _property = property; _parsingCulture = parsingCulture; _propertyWriter = new PropertyWriter(_property, _parsingCulture); } /// /// Initializes a new instance of the class. Used for unit testing purpose. /// /// Option short name. /// Option long name. internal OptionInfo(char? shortName, string longName) { _shortName = shortName; _longName = longName; } public char? ShortName { get { return _shortName; } } public string LongName { get { return _longName; } } public string MutuallyExclusiveSet { get { return _mutuallyExclusiveSet; } } public bool Required { get { return _required; } } public bool IsBoolean { get { return _property.PropertyType == typeof(bool); } } public bool IsArray { get { return _property.PropertyType.IsArray; } } public bool IsAttributeArrayCompatible { get { return _attribute is OptionArrayAttribute; } } public bool IsDefined { get; set; } public bool ReceivedValue { get; private set; } public bool HasBothNames { get { return _shortName != null && _longName != null; } } public bool HasParameterLessCtor { get; set; } public object GetValue(object target) { return _property.GetValue(target, null); } public object CreateInstance(object target) { object instance = null; try { instance = Activator.CreateInstance(_property.PropertyType); _property.SetValue(target, instance, null); } catch (Exception e) { throw new ParserException(SR.CommandLineParserException_CannotCreateInstanceForVerbCommand, e); } return instance; } public bool SetValue(string value, object options) { if (_attribute is OptionListAttribute) { return SetValueList(value, options); } if (ReflectionHelper.IsNullableType(_property.PropertyType)) { return ReceivedValue = _propertyWriter.WriteNullable(value, options); } return ReceivedValue = _propertyWriter.WriteScalar(value, options); } public bool SetValue(IList values, object options) { var elementType = _property.PropertyType.GetElementType(); var array = Array.CreateInstance(elementType, values.Count); for (int i = 0; i < array.Length; i++) { try { array.SetValue(Convert.ChangeType(values[i], elementType, _parsingCulture), i); _property.SetValue(options, array, null); } catch (FormatException) { return false; } } return ReceivedValue = true; } public bool SetValue(bool value, object options) { _property.SetValue(options, value, null); return ReceivedValue = true; } public void SetDefault(object options) { if (_hasDefaultValue) { try { _property.SetValue(options, _defaultValue, null); } catch (Exception e) { throw new ParserException("Bad default value.", e); } } } private bool SetValueList(string value, object options) { _property.SetValue(options, new List(), null); var fieldRef = (IList)_property.GetValue(options, null); var values = value.Split(((OptionListAttribute)_attribute).Separator); foreach (var item in values) { fieldRef.Add(item); } return ReceivedValue = true; } } }