Пример #1
0
        /// <summary>
        /// Gets the feature at the specified Object ID
        /// </summary>
        /// <param name="oid">the object Id</param>
        /// <param name="table">the table to add the feature to</param>
        /// <returns></returns>
        internal FeatureDataRow GetFeature(uint oid, FeatureDataTable table)
        {
            if (!_isOpen)
            {
                throw (new ApplicationException("An attempt was made to read from a closed DBF file"));
            }
            if (oid >= _NumberOfRecords)
            {
                throw (new ArgumentException("Invalid DataRow requested at index " + oid));
            }
            fs.Seek(_HeaderLength + oid * _RecordLength, 0);

            FeatureDataRow dr = table.NewRow();

            if (br.ReadChar() == '*') //is record marked deleted?
            {
                return(null);
            }

            for (int i = 0; i < DbaseColumns.Length; i++)
            {
                DbaseField dbf = DbaseColumns[i];
                dr[dbf.ColumnName] = ReadDbfValue(dbf);
            }
            return(dr);
        }
Пример #2
0
        internal static DbaseField[] GetFields(System.Data.DataTable schema)
        {
            if (schema == null)
            {
                throw new ArgumentNullException("schema");
            }

            List <DbaseField> fields = new List <DbaseField>();

            foreach (DataRow row in schema.Rows)
            {
                if (row[DbaseSchema.ColumnNameColumn].Equals(DbaseSchema.OidColumnName))
                {
                    continue;
                }

                DbaseField field = new DbaseField();
                field.ColumnName = row[DbaseSchema.ColumnNameColumn] as string;
                field.DataType   = (Type)row[DbaseSchema.DataTypeColumn];
                field.Length     = Convert.ToInt16(row[DbaseSchema.ColumnSizeColumn]);
                field.Decimals   = Convert.ToByte(row[DbaseSchema.NumericPrecisionColumn]);
                fields.Add(field);
            }

            return(fields.ToArray());
        }
Пример #3
0
        /// <summary>
        /// Gets the feature at the specified Object ID
        /// </summary>
        /// <param name="oid"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        internal FeatureDataRow GetFeature(int oid, FeatureDataTable table)
        {
            if (!_isOpen)
            {
                Open();
            }

            if (oid >= _NumberOfRecords)
            {
                throw (new ArgumentException("Invalid DataRow requested at index " + oid.ToString()));
            }
            fs.Seek(_HeaderLength + oid * _RecordLength, 0);

            SharpMap.Data.FeatureDataRow dr = table.NewRow();

            if (br.ReadChar() == '*')             //is record marked deleted?
            {
                return(null);
            }

            for (int i = 0; i < DbaseColumns.Length; i++)
            {
                DbaseField dbf = DbaseColumns[i];
                dr[dbf.ColumnName] = ReadDbfValue(dbf);
            }
            return(dr);
        }
Пример #4
0
        private void ParseDbfHeader(string filename)
        {
            var buffer32 = new byte[32];

            _dbfStream.Seek(0, SeekOrigin.Begin);
            _dbfStream.Read(buffer32, 0, 32);

            if (buffer32[0] != 0x03)
            {
                throw new NotSupportedException("Unsupported DBF Type");
            }

            //Get last modified date
            _lastUpdate = new DateTime(buffer32[1] + 1900, buffer32[2], buffer32[3]);

            //Get number of records
            _numberOfRecords = BitConverter.ToInt32(buffer32, 4);

            //Get the header length
            _headerLength = BitConverter.ToInt16(buffer32, 8);

            //Get the record length
            _recordLength = BitConverter.ToInt16(buffer32, 10);

            //Get and parse the language driver code
            _fileEncoding = GetDbaseLanguageDriver(buffer32[29], filename);

            var numberOfColumns = (_headerLength - 31) / 32; // calculate the number of DataColumns in the header

            _dbaseColumns = new DbaseField[numberOfColumns];
            for (var i = 0; i < numberOfColumns; i++)
            {
                _dbfStream.Read(buffer32, 0, 32);
                using (var br = new BinaryReader(new MemoryStream(buffer32)))
                {
                    _dbaseColumns[i]            = new DbaseField();
                    _dbaseColumns[i].ColumnName = Encoding.UTF7.GetString((br.ReadBytes(11))).Replace("\0", "").Trim();
                    var fieldtype = br.ReadChar();
                    switch (fieldtype)
                    {
                    case 'L':
                        //_dbaseColumns[i].DataType = typeof (bool);
                        _dbaseColumns[i].DataTypeCode = TypeCode.Boolean;
                        break;

                    case 'C':
                        //_dbaseColumns[i].DataType = typeof (string);
                        _dbaseColumns[i].DataTypeCode = TypeCode.String;
                        break;

                    case 'D':
                        //_dbaseColumns[i].DataType = typeof (DateTime);
                        _dbaseColumns[i].DataTypeCode = TypeCode.DateTime;
                        break;

                    case 'N':
                        //_dbaseColumns[i].DataType = typeof (double);
                        _dbaseColumns[i].DataTypeCode = TypeCode.Double;
                        break;

                    case 'F':
                        //_dbaseColumns[i].DataType = typeof (float);
                        _dbaseColumns[i].DataTypeCode = TypeCode.Single;
                        break;

                    case 'B':
                        //_dbaseColumns[i].DataType = typeof (byte[]);
                        _dbaseColumns[i].DataTypeCode = TypeCode.Object;     //Hack for
                        break;

                    default:
                        throw (new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype +
                                                         "' in column '" + _dbaseColumns[i].ColumnName + "'"));
                    }
                    _dbaseColumns[i].Address = br.ReadInt32();
                    if (i == 0) //Set it to 0 for first column and calculate it for the rest
                    {
                        _dbaseColumns[i].Address = 0;
                    }
                    else
                    {
                        _dbaseColumns[i].Address = _dbaseColumns[i - 1].Address + _dbaseColumns[i - 1].Length;
                    }

                    var length = (int)br.ReadByte();
                    if (length < 0)
                    {
                        length = length + 256;
                    }
                    _dbaseColumns[i].Length   = length;
                    _dbaseColumns[i].Decimals = br.ReadByte();


                    //If the double-type doesn't have any decimals, make the type an integer
                    //if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataType == typeof (double))
                    //    if (_dbaseColumns[i].Length <= 2)
                    //        _dbaseColumns[i].DataType = typeof (Int16);
                    //    else if (_dbaseColumns[i].Length <= 4)
                    //        _dbaseColumns[i].DataType = typeof (Int32);
                    //    else
                    //        _dbaseColumns[i].DataType = typeof (Int64);
                    if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataTypeCode == TypeCode.Double)
                    {
                        if (_dbaseColumns[i].Length < 3) //Range [-9, 99]
                        {
                            _dbaseColumns[i].DataTypeCode = TypeCode.Byte;
                        }
                        else if (_dbaseColumns[i].Length < 5) //Range [-999, 9999]
                        {
                            _dbaseColumns[i].DataTypeCode = TypeCode.Int16;
                        }
                        else if (_dbaseColumns[i].Length < 10)
                        {
                            _dbaseColumns[i].DataTypeCode = TypeCode.Int32;
                        }
                        else if (_dbaseColumns[i].Length < 19)
                        {
                            _dbaseColumns[i].DataTypeCode = TypeCode.Int64;
                        }
                        else
                        {
                            _dbaseColumns[i].DataTypeCode = TypeCode.Double;
                        }
                    }
                }
            }

            //using (var s = GetStream())
            //using(var br = new BinaryReader(s))
            //{
            //    if (br.ReadByte() != 0x03)
            //        throw new NotSupportedException("Unsupported DBF Type");

            //    _lastUpdate = new DateTime(br.ReadByte() + 1900, br.ReadByte(), br.ReadByte());
            //    //Read the last update date
            //    _numberOfRecords = br.ReadInt32(); // read number of records.
            //    _headerLength = br.ReadInt16(); // read length of header structure.
            //    _recordLength = br.ReadInt16(); // read length of a record
            //    s.Seek(29, SeekOrigin.Begin); //Seek to encoding flag
            //    _fileEncoding = GetDbaseLanguageDriver(br.ReadByte(), filename); //Read and parse Language driver
            //    s.Seek(32, SeekOrigin.Begin); //Move past the reserved bytes

            //    var numberOfColumns = (_headerLength - 31)/32; // calculate the number of DataColumns in the header
            //    _dbaseColumns = new DbaseField[numberOfColumns];
            //    for (var i = 0; i < _dbaseColumns.Length; i++)
            //    {
            //        _dbaseColumns[i] = new DbaseField();
            //        _dbaseColumns[i].ColumnName = Encoding.UTF7.GetString((br.ReadBytes(11))).Replace("\0", "").Trim();
            //        var fieldtype = br.ReadChar();
            //        switch (fieldtype)
            //        {
            //            case 'L':
            //                //_dbaseColumns[i].DataType = typeof (bool);
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Boolean;
            //                break;
            //            case 'C':
            //                //_dbaseColumns[i].DataType = typeof (string);
            //                _dbaseColumns[i].DataTypeCode = TypeCode.String;
            //                break;
            //            case 'D':
            //                //_dbaseColumns[i].DataType = typeof (DateTime);
            //                _dbaseColumns[i].DataTypeCode = TypeCode.DateTime;
            //                break;
            //            case 'N':
            //                //_dbaseColumns[i].DataType = typeof (double);
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Double;
            //                break;
            //            case 'F':
            //                //_dbaseColumns[i].DataType = typeof (float);
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Single;
            //                break;
            //            case 'B':
            //                //_dbaseColumns[i].DataType = typeof (byte[]);
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Object; //Hack for
            //                break;
            //            default:
            //                throw (new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype +
            //                                                 "' in column '" + _dbaseColumns[i].ColumnName + "'"));
            //        }
            //        _dbaseColumns[i].Address = br.ReadInt32();
            //        if (i > 0) _dbaseColumns[i].Address = _dbaseColumns[i - 1].Address + _dbaseColumns[i - 1].Length;

            //        var length = (int) br.ReadByte();
            //        if (length < 0) length = length + 256;
            //        _dbaseColumns[i].Length = length;
            //        _dbaseColumns[i].Decimals = br.ReadByte();


            //        //If the double-type doesn't have any decimals, make the type an integer
            //        //if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataType == typeof (double))
            //        //    if (_dbaseColumns[i].Length <= 2)
            //        //        _dbaseColumns[i].DataType = typeof (Int16);
            //        //    else if (_dbaseColumns[i].Length <= 4)
            //        //        _dbaseColumns[i].DataType = typeof (Int32);
            //        //    else
            //        //        _dbaseColumns[i].DataType = typeof (Int64);
            //        if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataTypeCode == TypeCode.Double)
            //        {
            //            if (_dbaseColumns[i].Length < 3) //Range [-9, 99]
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Byte;
            //            else if (_dbaseColumns[i].Length < 5) //Range [-999, 9999]
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Int16;
            //            else if (_dbaseColumns[i].Length < 10)
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Int32;
            //            else if (_dbaseColumns[i].Length < 19)
            //                _dbaseColumns[i].DataTypeCode = TypeCode.Int64;
            //            else
            //                _dbaseColumns[i].DataTypeCode = TypeCode.double;
            //        }

            //        br.BaseStream.Seek(s.Position + 14, 0);
            //    }
            //}

            _currentRecordBuffer = new byte[_recordLength];
            _headerIsParsed      = true;

            CreateBaseTable();
        }
Пример #5
0
        private object ReadDbfValue(DbaseField dbf)
        {
            var tmpBuffer = new byte[dbf.Length];

            Buffer.BlockCopy(_currentRecordBuffer, dbf.Address + 1, tmpBuffer, 0, dbf.Length);

            string temp;

            switch (dbf.DataTypeCode)
            {
            case TypeCode.String:
                return(_encoding == null
                        ? _fileEncoding.GetString(tmpBuffer).Replace("\0", "").Trim()
                        : _encoding.GetString(tmpBuffer).Replace("\0", "").Trim());

            case TypeCode.Double:
                temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim();
                double dbl;
                if (double.TryParse(temp, NumberStyles.Float, Nfi, out dbl))
                {
                    return(dbl);
                }
                return(DBNull.Value);

            case TypeCode.Byte:
                temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim();
                Byte i8;
                if (Byte.TryParse(temp, NumberStyles.Integer, Nfi, out i8))
                {
                    return(i8);
                }
                return(DBNull.Value);

            case TypeCode.Int16:
                temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim();
                Int16 i16;
                if (Int16.TryParse(temp, NumberStyles.Integer, Nfi, out i16))
                {
                    return(i16);
                }
                return(DBNull.Value);

            case TypeCode.Int32:
                temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim();
                Int32 i32;
                if (Int32.TryParse(temp, NumberStyles.Integer, Nfi, out i32))
                {
                    return(i32);
                }
                return(DBNull.Value);

            case TypeCode.Int64:
                temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim();
                Int64 i64;
                if (Int64.TryParse(temp, NumberStyles.Integer, Nfi, out i64))
                {
                    return(i64);
                }
                return(DBNull.Value);

            //case "System.Single":
            case TypeCode.Single:
                temp = Encoding.UTF8.GetString(tmpBuffer);
                float f;
                if (float.TryParse(temp, NumberStyles.Float, Nfi, out f))
                {
                    return(f);
                }
                return(DBNull.Value);

            //case "System.Boolean":
            case TypeCode.Boolean:
                var tempChar = BitConverter.ToChar(tmpBuffer, 0);
                return((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y'));

            //case "System.DateTime":
            case TypeCode.DateTime:
                DateTime date;
                // Mono has not yet implemented DateTime.TryParseExact
#if !MONO
                if (DateTime.TryParseExact(Encoding.UTF7.GetString(tmpBuffer),
                                           "yyyyMMdd", Nfi, DateTimeStyles.None, out date))
                {
                    return(date);
                }
                return(DBNull.Value);
#else
                try
                {
                    return(date = DateTime.ParseExact(System.Text.Encoding.UTF7.GetString(tmpBuffer),
                                                      "yyyyMMdd", Nfi, System.Globalization.DateTimeStyles.None));
                }
                catch (Exception e)
                {
                    return(DBNull.Value);
                }
#endif
            default:
                throw (new NotSupportedException("Cannot parse DBase field '" + dbf.ColumnName + "' of type '" +
//                                                     dbf.DataType + "'"));
                                                 TypeByTypeCode(dbf.DataTypeCode) + "'"));
            }

//            switch (dbf.DataTypeCode)
//            {
//                case TypeCode.String:
//                    return _encoding == null
//                        ? _fileEncoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim()
//                        : _encoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim();
//                case TypeCode.Double:
//                    temp = Encoding.UTF7.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim();
//                    double dbl;
//                    if (double.TryParse(temp, NumberStyles.Float, Nfi, out dbl))
//                        return dbl;
//                    return DBNull.Value;
//                case TypeCode.Int16:
//                    temp = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim();
//                    Int16 i16;
//                    if (Int16.TryParse(temp, NumberStyles.Integer, Nfi, out i16))
//                        return i16;
//                    return DBNull.Value;
//                case TypeCode.Int32:
//                    temp = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim();
//                    Int32 i32;
//                    if (Int32.TryParse(temp, NumberStyles.Integer, Nfi, out i32))
//                        return i32;
//                    return DBNull.Value;
//                case TypeCode.Int64:
//                    temp = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim();
//                    Int64 i64;
//                    if (Int64.TryParse(temp, NumberStyles.Integer, Nfi, out i64))
//                        return i64;
//                    return DBNull.Value;
//                //case "System.Single":
//                case TypeCode.Single:
//                    temp = Encoding.UTF8.GetString((br.ReadBytes(dbf.Length)));
//                    float f;
//                    if (float.TryParse(temp, NumberStyles.Float, Nfi, out f))
//                        return f;
//                    return DBNull.Value;
//                //case "System.Boolean":
//                case TypeCode.Boolean:
//                    var tempChar = br.ReadChar();
//                    return ((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y'));
//                //case "System.DateTime":
//                case TypeCode.DateTime:
//                    DateTime date;
//                    // Mono has not yet implemented DateTime.TryParseExact
//#if !MONO
//                    if (DateTime.TryParseExact(Encoding.UTF7.GetString((br.ReadBytes(8))),
//                                               "yyyyMMdd", Nfi, DateTimeStyles.None, out date))
//                        return date;
//                    return DBNull.Value;
//#else
//                    try
//                    {
//                        return date = DateTime.ParseExact ( System.Text.Encoding.UTF7.GetString((br.ReadBytes(8))),
//                        "yyyyMMdd", SharpMap.Map.numberFormat_EnUS, System.Globalization.DateTimeStyles.None );
//                    }
//                    catch ( Exception e )
//                    {
//                        return DBNull.Value;
//                    }
//#endif
//                default:
//                    throw (new NotSupportedException("Cannot parse DBase field '" + dbf.ColumnName + "' of type '" +
//                        //                                                     dbf.DataType + "'"));
//                                                     TypeByTypeCode(dbf.DataTypeCode) + "'"));
//            }
        }
Пример #6
0
        private object ReadDbfValue(DbaseField dbf)
        {
            switch (dbf.DataType.ToString())
            {
            case "System.String":
                if (_Encoding == null)
                {
                    return(_FileEncoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim());
                }
                return(_Encoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim());

            case "System.Double":
                string temp = Encoding.UTF7.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim();
                double dbl  = 0;
                if (double.TryParse(temp, NumberStyles.Float, Map.NumberFormatEnUs, out dbl))
                {
                    return(dbl);
                }
                return(DBNull.Value);

            case "System.Int16":
                string temp16 = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim();
                Int16  i16    = 0;
                if (Int16.TryParse(temp16, NumberStyles.Float, Map.NumberFormatEnUs, out i16))
                {
                    return(i16);
                }
                return(DBNull.Value);

            case "System.Int32":
                string temp32 = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim();
                Int32  i32    = 0;
                if (Int32.TryParse(temp32, NumberStyles.Float, Map.NumberFormatEnUs, out i32))
                {
                    return(i32);
                }
                return(DBNull.Value);

            case "System.Int64":
                string temp64 = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim();
                Int64  i64    = 0;
                if (Int64.TryParse(temp64, NumberStyles.Float, Map.NumberFormatEnUs, out i64))
                {
                    return(i64);
                }
                return(DBNull.Value);

            case "System.Single":
                string temp4 = Encoding.UTF8.GetString((br.ReadBytes(dbf.Length)));
                float  f     = 0;
                if (float.TryParse(temp4, NumberStyles.Float, Map.NumberFormatEnUs, out f))
                {
                    return(f);
                }
                return(DBNull.Value);

            case "System.Boolean":
                char tempChar = br.ReadChar();
                return((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y'));

            case "System.DateTime":
                DateTime date;
                // Mono has not yet implemented DateTime.TryParseExact
#if !MONO
                if (DateTime.TryParseExact(Encoding.UTF7.GetString((br.ReadBytes(8))),
                                           "yyyyMMdd", Map.NumberFormatEnUs, DateTimeStyles.None, out date))
                {
                    return(date);
                }
                return(DBNull.Value);
#else
                try
                {
                    return(date = DateTime.ParseExact(System.Text.Encoding.UTF7.GetString((br.ReadBytes(8))),
                                                      "yyyyMMdd", SharpMap.Map.numberFormat_EnUS, System.Globalization.DateTimeStyles.None));
                }
                catch (Exception e)
                {
                    return(DBNull.Value);
                }
#endif
            default:
                throw (new NotSupportedException("Cannot parse DBase field '" + dbf.ColumnName + "' of type '" +
                                                 dbf.DataType.ToString() + "'"));
            }
        }
Пример #7
0
        private void ParseDbfHeader(string filename)
        {
            if (br.ReadByte() != 0x03)
            {
                throw new NotSupportedException("Unsupported DBF Type");
            }

            _lastUpdate = new DateTime((int)br.ReadByte() + 1900, (int)br.ReadByte(), (int)br.ReadByte());
            //Read the last update date
            _NumberOfRecords = br.ReadInt32();                     // read number of records.
            _HeaderLength    = br.ReadInt16();                     // read length of header structure.
            _RecordLength    = br.ReadInt16();                     // read length of a record
            fs.Seek(29, SeekOrigin.Begin);                         //Seek to encoding flag
            _FileEncoding = GetDbaseLanguageDriver(br.ReadByte()); //Read and parse Language driver
            fs.Seek(32, SeekOrigin.Begin);                         //Move past the reserved bytes

            int NumberOfColumns = (_HeaderLength - 31) / 32;       // calculate the number of DataColumns in the header

            DbaseColumns = new DbaseField[NumberOfColumns];
            for (int i = 0; i < DbaseColumns.Length; i++)
            {
                DbaseColumns[i]            = new DbaseField();
                DbaseColumns[i].ColumnName = Encoding.UTF7.GetString((br.ReadBytes(11))).Replace("\0", "").Trim();
                char fieldtype = br.ReadChar();
                switch (fieldtype)
                {
                case 'L':
                    DbaseColumns[i].DataType = typeof(bool);
                    break;

                case 'C':
                    DbaseColumns[i].DataType = typeof(string);
                    break;

                case 'D':
                    DbaseColumns[i].DataType = typeof(DateTime);
                    break;

                case 'N':
                    DbaseColumns[i].DataType = typeof(double);
                    break;

                case 'F':
                    DbaseColumns[i].DataType = typeof(float);
                    break;

                case 'B':
                    DbaseColumns[i].DataType = typeof(byte[]);
                    break;

                default:
                    throw (new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype +
                                                     "' in column '" + DbaseColumns[i].ColumnName + "'"));
                }
                DbaseColumns[i].Address = br.ReadInt32();

                int Length = (int)br.ReadByte();
                if (Length < 0)
                {
                    Length = Length + 256;
                }
                DbaseColumns[i].Length   = Length;
                DbaseColumns[i].Decimals = (int)br.ReadByte();
                //If the double-type doesn't have any decimals, make the type an integer
                if (DbaseColumns[i].Decimals == 0 && DbaseColumns[i].DataType == typeof(double))
                {
                    if (DbaseColumns[i].Length <= 2)
                    {
                        DbaseColumns[i].DataType = typeof(Int16);
                    }
                    else if (DbaseColumns[i].Length <= 4)
                    {
                        DbaseColumns[i].DataType = typeof(Int32);
                    }
                    else
                    {
                        DbaseColumns[i].DataType = typeof(Int64);
                    }
                }
                fs.Seek(fs.Position + 14, 0);
            }
            HeaderIsParsed = true;
            CreateBaseTable();
        }
Пример #8
0
        internal static DbaseHeader ParseDbfHeader(BinaryReader reader)
        {
            DbaseHeader header = new DbaseHeader();

            if (reader.ReadByte() != DbaseConstants.DbfVersionCode)
            {
                throw new NotSupportedException("Unsupported DBF Type");
            }

            header.LastUpdate  = new DateTime((int)reader.ReadByte() + 1900, (int)reader.ReadByte(), (int)reader.ReadByte());             //Read the last update date
            header.RecordCount = reader.ReadUInt32();                                                                                     // read number of records.
            short storedHeaderLength = reader.ReadInt16();                                                                                // read length of header structure.
            short storedRecordLength = reader.ReadInt16();                                                                                // read length of a record

            reader.BaseStream.Seek(DbaseConstants.EncodingOffset, SeekOrigin.Begin);                                                      //Seek to encoding flag
            header.LanguageDriver = reader.ReadByte();                                                                                    //Read and parse Language driver
            reader.BaseStream.Seek(DbaseConstants.ColumnDescriptionOffset, SeekOrigin.Begin);                                             //Move past the reserved bytes

            int numberOfColumns = (storedHeaderLength - DbaseConstants.ColumnDescriptionOffset) / DbaseConstants.ColumnDescriptionLength; // calculate the number of DataColumns in the header

            DbaseField[] columns = new DbaseField[numberOfColumns];
            for (int i = 0; i < columns.Length; i++)
            {
                columns[i]            = new DbaseField();
                columns[i].ColumnName = System.Text.Encoding.UTF7.GetString((reader.ReadBytes(11))).Replace("\0", "").Trim();
                char fieldtype = reader.ReadChar();

                columns[i].Address = reader.ReadInt32();

                short fieldLength = reader.ReadByte();
                if (fieldtype == 'N' || fieldtype == 'F')
                {
                    columns[i].Decimals = reader.ReadByte();
                }
                else
                {
                    fieldLength += (short)((short)reader.ReadByte() << 8);
                }

                columns[i].Length = fieldLength;

                switch (fieldtype)
                {
                case 'L':
                    columns[i].DataType = typeof(bool);
                    break;

                case 'C':
                    columns[i].DataType = typeof(string);
                    break;

                case 'D':
                    columns[i].DataType = typeof(DateTime);
                    break;

                case 'N':
                    //If the number doesn't have any decimals, make the type an integer, if possible
                    if (columns[i].Decimals == 0)
                    {
                        if (columns[i].Length <= 4)
                        {
                            columns[i].DataType = typeof(Int16);
                        }
                        else if (columns[i].Length <= 9)
                        {
                            columns[i].DataType = typeof(Int32);
                        }
                        else if (columns[i].Length <= 18)
                        {
                            columns[i].DataType = typeof(Int64);
                        }
                        else
                        {
                            columns[i].DataType = typeof(double);
                        }
                    }
                    else
                    {
                        columns[i].DataType = typeof(double);
                    }
                    break;

                case 'F':
                    columns[i].DataType = typeof(float);
                    break;

                case 'B':
                    columns[i].DataType = typeof(byte[]);
                    break;

                default:
                    throw new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype +
                                                    "' in column '" + columns[i].ColumnName + "'");
                }

                // Move stream to next field record
                reader.BaseStream.Seek(DbaseConstants.BytesFromEndOfDecimalInFieldRecord, SeekOrigin.Current);
            }

            header.Columns = columns;
            if (storedHeaderLength != header.HeaderLength)
            {
                throw new Exception("Recorded header length doesn't equal computed header length");
            }
            if (storedRecordLength != header.RecordLength)
            {
                throw new Exception("Recorded record length doesn't equal computed record length");
            }

            return(header);
        }