示例#1
0
 public _MemberAccessingFailure(
     Schema.Field field, _MemberAccessor ma,
     string nextMemberName, string cause)
 {
     this.field          = field;
     this.memberAccessor = ma;
     this.nextMemberName = nextMemberName;
     this.cause          = cause;
 }
示例#2
0
        private string _GetMemberValue(
            _MemberAccessor ma, object obj, out object value)
        {
            var pi = ma.info as PropertyInfo;
            var fi = ma.info as FieldInfo;

            value = (pi != null) ? pi.GetValue(obj, null) : fi.GetValue(obj);
            if (value == null)
            {
                if (!ma.canWrite)
                {
                    return("Member is null but is not writable.");
                }
                if (ma.valueConstructor == null)
                {
                    return("Default constructor not found.");
                }
                value = ma.valueConstructor.Invoke(null);
                if (pi != null)
                {
                    pi.SetValue(obj, value, null);
                }
                else
                {
                    fi.SetValue(obj, value);
                }
            }
            if (ma.arrayIndex < 0)
            {
                return(null);
            }
            var list = value;

            value = null;
            var count = _FillList(ma, list);

            if (count == 0)
            {
                return("List is 'ReadOnly' or 'FixedSize' but empty.");
            }
            if (ma.arrayIndex >= count)
            {
                return("Index is out of range. (IList<>.Count: " + count + ")");
            }
            value = ma.listItemGetter
                    .Invoke(list, new object[] { ma.arrayIndex });
            if (value == null)
            {
                if (ma.listItemConstructor != null)
                {
                    return("Member must be writable 'IList<>'.");
                }
                return("List item default constructor not found.");
            }
            return(null);
        }
示例#3
0
        private int _FillList(_MemberAccessor ma, object list)
        {
            var isArray    = list.GetType().IsArray;
            var isReadOnly = (bool)ma.listReadOnlyGetter.Invoke(list, null);
            var count      = (int)ma.listItemCountGetter.Invoke(list, null);

            if (!isArray && isReadOnly)
            {
                return(count);
            }
            if (ma.listItemConstructor != null)
            {
                for (var n = 0; n < count; ++n)
                {
                    var item = ma.listItemGetter
                               .Invoke(list, new object[] { n });
                    if (item != null)
                    {
                        continue;
                    }
                    item = ma.listItemConstructor.Invoke(null);
                    ma.listItemSetter.Invoke(list, new object[] { item });
                }
            }
            if (isArray)
            {
                return(count);
            }
            if (ma.listItemConstructor != null)
            {
                while (count <= ma.arrayIndex)
                {
                    var item = ma.listItemConstructor.Invoke(null);
                    ma.listItemAdder.Invoke(list, new object[] { item });
                    count = (int)ma.listItemCountGetter.Invoke(list, null);
                }
            }
            else
            {
                while (count <= ma.arrayIndex)
                {
                    var item = default(object);
                    if (ma.listItemType.IsValueType)
                    {
                        item = System.Activator.CreateInstance(ma.listItemType);
                    }
                    ma.listItemAdder.Invoke(list, new object[] { item });
                    count = (int)ma.listItemCountGetter.Invoke(list, null);
                }
            }
            return(count);
        }
示例#4
0
        private string _SetMemberValue(
            _MemberAccessor ma, object obj, object value)
        {
            var pi = ma.info as PropertyInfo;
            var fi = ma.info as FieldInfo;

            if (ma.arrayIndex < 0)
            {
                if (pi != null)
                {
                    pi.SetValue(obj, value, null);
                }
                else
                {
                    fi.SetValue(obj, value);
                }
                return(null);
            }
            var list = (pi != null) ? pi.GetValue(obj, null) : fi.GetValue(obj);

            if (list == null)
            {
                if (ma.valueConstructor == null)
                {
                    return("Default constructor not found.");
                }
                list = ma.valueConstructor.Invoke(null);
            }
            var isReadOnly = (bool)ma.listReadOnlyGetter.Invoke(list, null);

            if (isReadOnly && !list.GetType().IsArray)
            {
                return("Member must be writable 'IList<>'.");
            }
            var count = _FillList(ma, list);

            if (ma.arrayIndex >= count)
            {
                return("Index is out of range. (IList<>.Count: " + count + ")");
            }
            ma.listItemSetter
            .Invoke(list, new object[] { ma.arrayIndex, value });
            return(null);
        }
示例#5
0
        private string _GetFullWarning(
            string message, _MemberAccessor ma = null, int rowIndex = -1)
        {
            var table = (DataTable)tableRef.Target;
            var name  = table.name + "=>" + typeof(T).FullName;

            if (ma == null)
            {
                return(string.Format("{0}: {1}", name, message));
            }
            else if (rowIndex < 0)
            {
                return(string.Format("{0}({2}=>{3}): {1}",
                                     name, message, ma.sourcePath, ma.targetPath
                                     ));
            }
            return(string.Format("{0}({4}, {2}=>{3}): {1}",
                                 name, message, ma.sourcePath, ma.targetPath, rowIndex
                                 ));
        }
示例#6
0
        private void _InitMemberAccessors()
        {
            var propMap           = _CreatePropertyMap();
            var accessors         = new List <_MemberAccessor>();
            var failures          = new List <_MemberAccessingFailure>();
            var fields            = ((DataTable)tableRef.Target).schema.fieldsForWriter;
            var d                 = 0;
            var n                 = -1;
            var declarerStart     = 0;
            var lastAccessorCount = 0;

            System.Func <string> getSourcePath = () => {
                var dotCount = 0;
                for (var m = 0; m < fields[n].name.Length; ++m)
                {
                    if (fields[n].name[m] == '.')
                    {
                        if (++dotCount > d)
                        {
                            return(fields[n].name.Substring(0, m));
                        }
                    }
                }
                return(fields[n].name);
            };
            System.Func <string, string> getTargetName = (sourcePath) => {
                var sb = new StringBuilder();
                foreach (var token in sourcePath.Split('.', '['))
                {
                    if (!char.IsNumber(token[0]))
                    {
                        sb.Append(token + ".");
                    }
                }
                if (sb.Length > 0)
                {
                    sb.Remove(sb.Length - 1, 1);
                }
                string v = null;
                if (propMap.TryGetValue(sb.ToString(), out v))
                {
                    return(v);
                }
                return(fields[n].nameNodes[d].name);
            };
            System.Func <string, int> getDeclarerIndex = (sourcePath) => {
                for (var m = declarerStart; m < lastAccessorCount; ++m)
                {
                    if (sourcePath.StartsWith(accessors[m].sourcePath))
                    {
                        return(m);
                    }
                }
                return(-1);
            };
            System.Func <int, System.Type>
            getMemberValueType = (declarerIndex) => {
                if (declarerIndex < 0)
                {
                    return(typeof(T));
                }
                var ma = accessors[declarerIndex];
                return((ma.arrayIndex < 0) ? ma.valueType : ma.listItemType);
            };
            System.Func <MemberInfo, string>
            verifyMemberInfo = (mi) => {
                if (mi == null)
                {
                    return("target '{0}' not found.");
                }
                else if (!_IsReadableMember(mi))
                {
                    return("target '{0}' is not readable.");
                }
                else if (_IsIndexedMember(mi))
                {
                    return("target '{0}' is indexer.");
                }
                var ai  = fields[n].nameNodes[d].arrayIndex;
                var vt  = _GetMemberValueType(mi);
                var lit = _GetListItemType(vt);
                vt = (ai < 0) ? vt : lit;
                if (ai >= 0 && lit == typeof(_NonListItem))
                {
                    return("target '{0}' is not 'IList<>' implementation.");
                }
                if (ai < 0 && !_IsWritableMember(mi))
                {
                    if (d == fields[n].depth)
                    {
                        return("target '{0}' must be writable.");
                    }
                    else if (vt.IsValueType)
                    {
                        return(""
                               + "If target '{0}' is 'ValueType', "
                               + "must be writable.");
                    }
                }
                if (d < fields[n].depth)
                {
                    return(null);
                }
                if (!vt.IsValueType && vt != typeof(string))
                {
                    return("target '{0}' is not 'ValueType' or 'string'.");
                }
                return(null);
            };
            System.Func <int, string, string>
            getTargetPath = (declarerIndex, targetName) => {
                var sb = new StringBuilder();
                if (declarerIndex >= 0)
                {
                    sb.Append(accessors[declarerIndex].targetPath + ".");
                }
                var nd = fields[n].nameNodes[d];
                sb.Append(targetName);
                if (nd.isArrayElement)
                {
                    sb.Append("[" + nd.arrayIndex + "]");
                }
                return(sb.ToString());
            };
            string lastSourcePath = null;

            while (true)
            {
                if (++n >= fields.Count)
                {
                    ++d;
                    n = -1;
                    if (lastAccessorCount == accessors.Count)
                    {
                        break;
                    }
                    else
                    {
                        declarerStart     = lastAccessorCount;
                        lastAccessorCount = accessors.Count;
                        continue;
                    }
                }
                if (d > fields[n].depth)
                {
                    continue;
                }
                var ai = fields[n].nameNodes[d].arrayIndex;
                var sp = getSourcePath();
                if (sp == lastSourcePath)
                {
                    continue;
                }
                lastSourcePath = sp;
                var tn = getTargetName(sp);
                var di = getDeclarerIndex(sp);
                if (di < 0 && d > 0)
                {
                    continue;
                }
                var ma  = (di < 0) ? null : accessors[di];
                var mvt = getMemberValueType(di);
                var mi  = _GetMemberInfo(mvt, tn);
                var err = verifyMemberInfo(mi);
                if (!string.IsNullOrEmpty(err))
                {
                    err = string.Format(err, tn);
                    failures.Add(
                        new _MemberAccessingFailure(fields[n], ma, tn, err)
                        );
                    continue;
                }
                var tp  = getTargetPath(di, tn);
                var mfi = (d < fields[n].depth) ? -1 : fields[n].index;
                ma = new _MemberAccessor(mi, ai, sp, tp, di, mfi);
                accessors.Add(ma);
            }
            _memberAccessors         = accessors;
            _memberAccessingFailures = failures;
        }