Beispiel #1
0
        public static Func <object[], T> CreateMapper <T>(this Dbf dbf) where T : class, new()
        {
            var fields = dbf.GetHeader().Fields;
            var type   = typeof(T);
            var props  = type.GetProperties();

            var methodBody = new List <Expression>();

            var rowParam = Expression.Parameter(typeof(object[]), "row");

            var hoistedLocalVariable = Expression.Property(Expression.Constant(new ValueBag <T>()), "Value");

            methodBody.Add(Expression.Assign(hoistedLocalVariable, Expression.New(type)));

            for (int i = 0; i < fields.Count; i++)
            {
                var field = fields[i];
                var prop  = props.FirstOrDefault(x => x.Name.Equals(field.Name, StringComparison.OrdinalIgnoreCase));
                if (prop is null)
                {
                    continue;
                }
                var value = Expression.ArrayIndex(rowParam, Expression.Constant(field.Index));

                var access = Expression.MakeMemberAccess(hoistedLocalVariable, prop);
                var setter = Expression.Assign(access, Expression.Convert(value, prop.PropertyType));
                methodBody.Add(setter);
            }
            var returnTarget = Expression.Label(type);

            methodBody.Add(Expression.Return(returnTarget, hoistedLocalVariable, type));

            methodBody.Add(Expression.Label(returnTarget, hoistedLocalVariable));

            var lambda = Expression.Lambda <Func <object[], T> >(Expression.Block(methodBody), rowParam);

            return(lambda.Compile());
        }
Beispiel #2
0
        public DbfReader(Dbf dbf, Encoding textEncoding)
        {
            DbfTypeMap.Add('C', (i, b, f, e) =>
            {
                if (f.Length == 1)
                {
                    return(e.GetString(b)[0]);
                }
                return(e.GetString(b).TrimEnd('\0'));
            });
            DbfTypeMap.Add('M', (i, b, f, e) => BitConverter.ToInt32(b));
            DbfTypeMap.Add('W', (i, b, f, e) => BitConverter.ToInt32(b));
            DbfTypeMap.Add('G', (i, b, f, e) => BitConverter.ToInt32(b));
            DbfTypeMap.Add('Y', (i, b, f, e) => BitConverter.ToInt64(b) / 10000m); // Stored as int64 with 4 implicit decimal places
            DbfTypeMap.Add('D', (i, b, f, e) =>
            {
                var dateStr = e.GetString(b).Trim(); return(dateStr == "" ? DateTime.MinValue : DateTime.ParseExact(dateStr, "yyyyMMdd", null));
            });
            DbfTypeMap.Add('T', (i, b, f, e) => JulianDateHelper.FromULongBuffer(b));
            DbfTypeMap.Add('N', (i, b, f, e) =>
            {
                var numStr = e.GetString(b).Trim();

                if (f.DecimalCount == 0)
                {
                    if (f.Length < 3)
                    {
                        if (numStr == "")
                        {
                            return((byte)0);
                        }
                        return(byte.Parse(numStr));
                    }
                    else if (f.Length < 5)
                    {
                        if (numStr == "")
                        {
                            return((short)0);
                        }
                        return(short.Parse(numStr));
                    }
                    else if (f.Length < 10)
                    {
                        if (numStr == "")
                        {
                            return((int)0);
                        }
                        return(int.Parse(numStr));
                    }
                    else if (f.Length < 19)
                    {
                        if (numStr == "")
                        {
                            return((long)0);
                        }
                        return(long.Parse(numStr));
                    }
                }
                return(numStr == "" ? 0m : decimal.Parse(numStr));
            });
            DbfTypeMap.Add('B', (i, b, f, e) => BitConverter.ToInt32(b));
            DbfTypeMap.Add('O', (i, b, f, e) => BitConverter.ToDouble(b));
            DbfTypeMap.Add('F', (i, b, f, e) => { var numStr = e.GetString(b).Trim(); return(numStr == "" ? 0f : float.Parse(numStr)); });
            DbfTypeMap.Add('I', (i, b, f, e) => BitConverter.ToInt32(b));
            DbfTypeMap.Add('L', (i, b, f, e) => BitConverter.ToBoolean(b));
            DbfTypeMap.Add('Q', CopyFieldBuffer);
            DbfTypeMap.Add('P', CopyFieldBuffer);

            this.dbf     = dbf;
            TextEncoding = textEncoding;
            dbfHeader    = dbf.GetHeader();

            if (IsVisualFoxPro(dbfHeader))
            { // Special handling for VFP
                DbfTypeMap['B'] = (i, b, f, e) => BitConverter.ToDouble(b);

                // VarChar/VarBinary
                // SPECIAL CASE for VARCHAR/BINARY
                DbfTypeMap['V'] = (i, b, f, e) => f.Flags.HasFlag(DbfFieldFlags.Binary) ? CopyFieldBuffer(i, b, f, e) : e.GetString(b);

                // _NullFlags
                nullField            = dbfHeader.Fields.FirstOrDefault(x => x.Type == '0');
                nullFieldDataHandler = DbfTypeMap['0'] = CopyFieldBuffer;

                if (nullField != null)
                {
                    if (nullField.Length == 1)
                    {
                        nullFieldHandlerFactory = (i, b, f, e) => new UIntNullFieldHandler(b[0]);
                    }
                    else
                    {
                        nullFieldHandlerFactory = (i, b, f, e) => new BitArrayNullFieldHandler(b.ToArray());
                    }
                }
            }
        }