///// <summary> ///// Получает или устанавливает кодировку используемую для интерпретации записей dbf-файла ///// </summary> ///// <remarks> ///// если не задана, будет предпринята попытка определить корректную кодировку по языковому драйверу ///// </remarks> //public Encoding Encoding //{ // get { return _encoding; } // set { _encoding = value; } //} /// <summary> /// Gets a dBase row. /// </summary> /// <param name="oid">A row id value</param> /// <param name="table">A System.Data.DataTable instance containing dBase data</param> /// <returns>A data row</returns> internal DataRow GetRow(uint oid, DataTable table) { if (!_isOpen) { throw new ApplicationException("Unable to read the closed dbf-file"); } if (oid >= _dbaseHeader.NumRecords) { throw new ArgumentOutOfRangeException("Incorrect record identity", "oid"); } _fs.Seek(_dbaseHeader.HeaderLength + oid * _dbaseHeader.RecordLength, 0); DataRow dr = table.NewRow(); if (_br.ReadChar() == '*') //is record marked as deleted? { return(null); } for (int i = 0; i < _dbaseHeader.DBaseColumns.Length; i++) { DbaseFieldDescriptor dbf = _dbaseHeader.DBaseColumns[i]; dr[dbf.Name] = readDbfValue(dbf); } return(dr); }
/// <summary> /// Converts a CLR type to corresponding dBase type. /// </summary> /// <param name="type">A CLR type</param> /// <returns>A corresponding dBase type</returns> public static char GetDbaseType(Type type) { DbaseFieldDescriptor dbaseColumn = new DbaseFieldDescriptor(); if (type == typeof(Char)) return 'C'; if (type == typeof(string)) return 'C'; else if (type == typeof(Double)) return 'N'; else if (type == typeof(Single)) return 'N'; else if (type == typeof(Int16)) return 'N'; else if (type == typeof(Int32)) return 'N'; else if (type == typeof(Int64)) return 'N'; else if (type == typeof(UInt16)) return 'N'; else if (type == typeof(UInt32)) return 'N'; else if (type == typeof(UInt64)) return 'N'; else if (type == typeof(Decimal)) return 'N'; else if (type == typeof(Boolean)) return 'L'; else if (type == typeof(DateTime)) return 'D'; throw new NotSupportedException(String.Format("{0} does not have a corresponding dbase type.", type.Name)); }
/// <summary> /// Converts a CLR type to corresponding dBase type. /// </summary> /// <param name="type">A CLR type</param> /// <returns>A corresponding dBase type</returns> public static char GetDbaseType(Type type) { DbaseFieldDescriptor dbaseColumn = new DbaseFieldDescriptor(); if (type == typeof(Char)) { return('C'); } if (type == typeof(string)) { return('C'); } else if (type == typeof(Double)) { return('N'); } else if (type == typeof(Single)) { return('N'); } else if (type == typeof(Int16)) { return('N'); } else if (type == typeof(Int32)) { return('N'); } else if (type == typeof(Int64)) { return('N'); } else if (type == typeof(UInt16)) { return('N'); } else if (type == typeof(UInt32)) { return('N'); } else if (type == typeof(UInt64)) { return('N'); } else if (type == typeof(Decimal)) { return('N'); } else if (type == typeof(Boolean)) { return('L'); } else if (type == typeof(DateTime)) { return('D'); } throw new NotSupportedException(String.Format("{0} does not have a corresponding dbase type.", type.Name)); }
/// <summary> /// Removes a column. /// </summary> /// <param name="fieldName">A filed name</param> /// <returns>An index of the removed filed, -1 if filed is not found</returns> public int RemoveColumn(string fieldName) { int retCol = -1; int tempLength = 1; DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_dbaseColumns.Length - 1]; for (int i = 0, j = 0; i < _dbaseColumns.Length; i++) { if (fieldName.ToLower() != (_dbaseColumns[i].Name.Trim().ToLower())) { // if this is the last field and we still haven't found the // named field if (i == j && i == _dbaseColumns.Length - 1) { return(retCol); } tempFieldDescriptors[j] = _dbaseColumns[i]; tempFieldDescriptors[j].DataAddress = tempLength; tempLength += tempFieldDescriptors[j].Length; // only increment j on non-matching fields j++; } else { retCol = i; } } // set the new fields. _dbaseColumns = tempFieldDescriptors; _headerLength = 33 + 32 * _dbaseColumns.Length; _numFields = _dbaseColumns.Length; _recordLength = tempLength; return(retCol); }
private object readDbfValue(DbaseFieldDescriptor dbf) { byte[] bytes = _br.ReadBytes(dbf.Length); switch (dbf.DataType.ToString()) { case "System.String": //if (_encoding == null) // return _fileEncoding.GetString(bytes).Replace("\0", "").Trim(); //else return _dbaseHeader.Encoding.GetString(bytes).Replace("\0", "").Trim(); case "System.Double": string temp = System.Text.Encoding.UTF7.GetString(bytes).Replace("\0", "").Trim(); double dbl = 0; if (double.TryParse(temp, System.Globalization.NumberStyles.Float, _numberFormat, out dbl)) return dbl; else return DBNull.Value; case "System.Int16": string temp16 = System.Text.Encoding.UTF7.GetString((bytes)).Replace("\0", "").Trim(); Int16 i16 = 0; if (Int16.TryParse(temp16, System.Globalization.NumberStyles.Float, _numberFormat, out i16)) return i16; else return DBNull.Value; case "System.Int32": string temp32 = System.Text.Encoding.UTF7.GetString((bytes)).Replace("\0", "").Trim(); Int32 i32 = 0; if (Int32.TryParse(temp32, System.Globalization.NumberStyles.Float, _numberFormat, out i32)) return i32; else return DBNull.Value; case "System.Int64": string temp64 = System.Text.Encoding.UTF7.GetString((bytes)).Replace("\0", "").Trim(); Int64 i64 = 0; if (Int64.TryParse(temp64, System.Globalization.NumberStyles.Float, _numberFormat, out i64)) return i64; else return DBNull.Value; case "System.Single": string temp4 = System.Text.Encoding.UTF8.GetString((bytes)); float f = 0; if (float.TryParse(temp4, System.Globalization.NumberStyles.Float, _numberFormat, out f)) return f; else return DBNull.Value; case "System.Boolean": char tempChar = Convert.ToChar(bytes[0]);// BitConverter.ToChar(bytes, 0);// _br.ReadChar(); return ((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y')); case "System.DateTime": #if !MONO DateTime date; if (DateTime.TryParseExact(System.Text.Encoding.UTF7.GetString((bytes)), "yyyyMMdd", _numberFormat, System.Globalization.DateTimeStyles.None, out date)) return date; else return DBNull.Value; #else // в mono еще не реализован метод DateTime.TryParseExact try { return DateTime.ParseExact (System.Text.Encoding.UTF7.GetString((bytes)), "yyyyMMdd", _numberFormat, System.Globalization.DateTimeStyles.None ); } catch { return DBNull.Value; } #endif default: throw (new NotSupportedException("Unable to process field '" + dbf.Name + "' (data type '" + dbf.DataType.ToString() + "')")); } }
/// <summary> /// Writes a row. /// </summary> /// <param name="columnValues">A list containing the column values</param> /// <param name="RecNum">A number of record</param> public void Write(IList columnValues, int RecNum) { if (columnValues == null) { throw new ArgumentNullException("columnValues"); } if (!_headerWritten) { throw new InvalidOperationException("Header records need to be written first."); } int i = 0; _writer.BaseStream.Seek(this._header.HeaderLength + RecNum * this._header.RecordLength, SeekOrigin.Begin); _writer.Write((byte)0x20); // the deleted flag foreach (object columnValue in columnValues) { DbaseFieldDescriptor headerField = _header.DBaseColumns[i]; if (columnValue == null) { // Don't corrupt the file by not writing if the value is null. // Instead, treat it like an empty string. Write(string.Empty, headerField.Length); } else if (headerField.DataType == typeof(string)) { // If the column is a character column, the values in that // column should be treated as text, even if the column value // is not a string. Write(columnValue.ToString(), headerField.Length); } else if (IsRealType(columnValue.GetType())) { decimal decValue = Convert.ToDecimal(columnValue); Write(decValue, headerField.Length, headerField.DecimalCount); } else if (IsIntegerType(columnValue.GetType())) { Write(Convert.ToDecimal(columnValue), headerField.Length, headerField.DecimalCount); } else if (columnValue is Decimal) { Write((decimal)columnValue, headerField.Length, headerField.DecimalCount); } else if (columnValue is Boolean) { Write((bool)columnValue); } else if (columnValue is string) { Write((string)columnValue, headerField.Length); } else if (columnValue is DateTime) { Write((DateTime)columnValue); } else if (columnValue is Char) { Write((Char)columnValue, headerField.Length); } i++; } }
/// <summary> /// Generates a dBase file header. /// </summary> /// <param name="dbFields">An array containing the dBase filed descriptors</param> /// <param name="count">The record count</param> /// <returns>A stub of dBase file header</returns> public static DbaseFileHeader GetDbaseHeader(DbaseFieldDescriptor[] dbFields, int count) { DbaseFileHeader header = new DbaseFileHeader(); header.NumRecords = count; foreach (DbaseFieldDescriptor dbField in dbFields) header.AddColumn(dbField.Name, dbField.DbaseType, dbField.DataType, dbField.Length, dbField.DecimalCount); return header; }
/// <summary> /// Computes a maximum length of field taking into account all the values. /// </summary> /// <param name="field">A descriptor of field</param> /// <param name="columnValues">A field value enumerator</param> public void RecountColumnLength(DbaseFieldDescriptor field, IEnumerable columnValues) { int size = 0; int decimalCount = 0; System.Globalization.NumberFormatInfo numberFormatInfo = new System.Globalization.NumberFormatInfo(); numberFormatInfo.NumberDecimalSeparator = "."; foreach (object value in columnValues) { if (field.DataType == typeof(string)) { string svalue = Convert.ToString(value); int s = this.Encoding.GetBytes(svalue).Length; if (s > size) size = s; } //else if (field.DataType == typeof(Int16) || field.DataType == typeof(Int32) || field.DataType == typeof(Int64) // || field.DataType == typeof(UInt16) || field.DataType == typeof(UInt32) || field.DataType == typeof(UInt64)) //{ // size = System.Runtime.InteropServices.Marshal.SizeOf(field.DataType); // decimalCount = 0; //} else if (field.DataType == typeof(Double) ||field.DataType == typeof(Single) || field.DataType == typeof(Decimal) || field.DataType == typeof(Int16) || field.DataType == typeof(Int32) || field.DataType == typeof(Int64) || field.DataType == typeof(UInt16) || field.DataType == typeof(UInt32) || field.DataType == typeof(UInt64)) { string svalue = Convert.ToString(value, numberFormatInfo); if (svalue.Length > size) size = svalue.Length; int decimalSepIndex = svalue.IndexOf("."); if (decimalSepIndex != -1) { if (svalue.Length - decimalSepIndex - 1 > decimalCount) decimalCount = Math.Max(decimalCount, svalue.Length - decimalSepIndex - 1); } //else if (decimalCount == 0) //{ // size += 3; // с учетом разделителя // decimalCount = 2; //} } } if (field.DataType == typeof(Double) || field.DataType == typeof(Single) || field.DataType == typeof(Decimal)) { if (decimalCount == 0) { size += 3; // с учетом разделителя decimalCount = 2; } } if (size != 0) { this._recordLength = this._recordLength - field.Length + size; field.Length = size; if (decimalCount != 0) field.DecimalCount = decimalCount; } }
/// <summary> /// Reads a dBase header. /// </summary> /// <param name="reader">A System.IO.BinaryReader instance to read header</param> public void Read(BinaryReader reader) { // type of reader. _fileType = reader.ReadByte(); if (_fileType != 0x03) throw new NotSupportedException("Unsupported DBF Type " + _fileType); // parse the update date information. int year = (int)reader.ReadByte(); int month = (int)reader.ReadByte(); int day = (int)reader.ReadByte(); _updateDate = new DateTime(year + 1900, month, day); // read the number of records. _numRecords = reader.ReadInt32(); // read the length of the header structure. _headerLength = reader.ReadInt16(); // read the length of a record _recordLength = reader.ReadInt16(); // skip the reserved bytes in the header. //in.skipBytes(20); //reader.ReadBytes(20); reader.BaseStream.Seek(29, SeekOrigin.Begin); //языковой драйвер _encoding = getDbaseLanguageDriver(reader.ReadByte()); reader.BaseStream.Seek(32, SeekOrigin.Begin); // calculate the number of Fields in the header _numFields = (_headerLength - _fileDescriptorSize - 1) / _fileDescriptorSize; // read all of the header records _dbaseColumns = new DbaseFieldDescriptor[_numFields]; for (int i = 0; i < _numFields; i++) { _dbaseColumns[i] = new DbaseFieldDescriptor(); // read the field name byte[] buffer = reader.ReadBytes(11); string name = _encoding.GetString(buffer); if (name.Contains("\0")) name = name.Substring(0, name.IndexOf('\0')); name = name.Replace("\0", "").Trim(); int nullPoint = name.IndexOf((char)0); if (nullPoint != -1) name = name.Substring(0, nullPoint); _dbaseColumns[i].Name = name; // read the field type _dbaseColumns[i].DbaseType = (char)reader.ReadByte(); _dbaseColumns[i].DataType = DbaseFieldDescriptor.GetDataType(_dbaseColumns[i].DbaseType); // read the field data address, offset from the start of the record. _dbaseColumns[i].DataAddress = reader.ReadInt32(); // read the field length in bytes int tempLength = (int)reader.ReadByte(); if (tempLength < 0) tempLength = tempLength + 256; _dbaseColumns[i].Length = tempLength; // read the field decimal count in bytes _dbaseColumns[i].DecimalCount = (int)reader.ReadByte(); if (_dbaseColumns[i].DecimalCount == 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); // read the reserved bytes. //reader.skipBytes(14); reader.ReadBytes(14); } // Last byte is a marker for the end of the field definitions. reader.ReadBytes(1); }
/// <summary> /// Removes a column. /// </summary> /// <param name="fieldName">A filed name</param> /// <returns>An index of the removed filed, -1 if filed is not found</returns> public int RemoveColumn(string fieldName) { int retCol = -1; int tempLength = 1; DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_dbaseColumns.Length - 1]; for (int i = 0, j = 0; i < _dbaseColumns.Length; i++) { if (fieldName.ToLower() != (_dbaseColumns[i].Name.Trim().ToLower())) { // if this is the last field and we still haven't found the // named field if (i == j && i == _dbaseColumns.Length - 1) return retCol; tempFieldDescriptors[j] = _dbaseColumns[i]; tempFieldDescriptors[j].DataAddress = tempLength; tempLength += tempFieldDescriptors[j].Length; // only increment j on non-matching fields j++; } else retCol = i; } // set the new fields. _dbaseColumns = tempFieldDescriptors; _headerLength = 33 + 32 * _dbaseColumns.Length; _numFields = _dbaseColumns.Length; _recordLength = tempLength; return retCol; }
/// <summary> /// Adds a column. ///</summary> /// <param name="fieldName">A filed name</param> /// <param name="fieldType">A character defining a dBAse filed type (C N L or D)</param> /// <param name="fieldLength">A length of field in bytes</param> /// <param name="decimalCount">A number of decimal characters</param> /// <param name="DataType">A CLR data type</param> public void AddColumn(string fieldName, char fieldType, Type DataType, int fieldLength, int decimalCount) { if (fieldLength <= 0) fieldLength = 1; if (_dbaseColumns == null) _dbaseColumns = new DbaseFieldDescriptor[0]; int tempLength = 1; // the length is used for the offset, and there is a * for deleted as the first byte DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_dbaseColumns.Length + 1]; for (int i = 0; i < _dbaseColumns.Length; i++) { _dbaseColumns[i].DataAddress = tempLength; tempLength = tempLength + _dbaseColumns[i].Length; tempFieldDescriptors[i] = _dbaseColumns[i]; } tempFieldDescriptors[_dbaseColumns.Length] = new DbaseFieldDescriptor(); tempFieldDescriptors[_dbaseColumns.Length].Length = fieldLength; tempFieldDescriptors[_dbaseColumns.Length].DecimalCount = decimalCount; tempFieldDescriptors[_dbaseColumns.Length].DataAddress = tempLength; // set the field name string tempFieldName = fieldName; if (tempFieldName == null) tempFieldName = "NoName"; if (tempFieldName.Length > 11) { tempFieldName = tempFieldName.Substring(0, 11); //!!!Trace.Write("FieldName " + fieldName + " is longer than 11 characters, truncating to " + tempFieldName); } tempFieldDescriptors[_dbaseColumns.Length].Name = tempFieldName; // the field type tempFieldDescriptors[_dbaseColumns.Length].DataType = DataType; if ((fieldType == 'C') || (fieldType == 'c')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'C'; } else if ((fieldType == 'S') || (fieldType == 's')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'C'; tempFieldDescriptors[_dbaseColumns.Length].Length = 8; } else if ((fieldType == 'D') || (fieldType == 'd')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'D'; tempFieldDescriptors[_dbaseColumns.Length].Length = 8; } else if ((fieldType == 'F') || (fieldType == 'f')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'F'; } else if ((fieldType == 'N') || (fieldType == 'n')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'N'; if (decimalCount < 0) { tempFieldDescriptors[_dbaseColumns.Length].DecimalCount = 0; } if (decimalCount > fieldLength - 1) { tempFieldDescriptors[_dbaseColumns.Length].DecimalCount = fieldLength - 1; } } else if ((fieldType == 'L') || (fieldType == 'l')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'L'; tempFieldDescriptors[_dbaseColumns.Length].Length = 1; } else { throw new NotSupportedException("Unsupported field type " + fieldType + " For column " + fieldName); } // the length of a record tempLength = tempLength + tempFieldDescriptors[_dbaseColumns.Length].Length; // set the new fields. _dbaseColumns = tempFieldDescriptors; _headerLength = 33 + 32 * _dbaseColumns.Length; _numFields = _dbaseColumns.Length; _recordLength = tempLength; }
/// <summary> /// Computes a maximum length of field taking into account all the values. /// </summary> /// <param name="field">A descriptor of field</param> /// <param name="columnValues">A field value enumerator</param> public void RecountColumnLength(DbaseFieldDescriptor field, IEnumerable columnValues) { int size = 0; int decimalCount = 0; System.Globalization.NumberFormatInfo numberFormatInfo = new System.Globalization.NumberFormatInfo(); numberFormatInfo.NumberDecimalSeparator = "."; foreach (object value in columnValues) { if (field.DataType == typeof(string)) { string svalue = Convert.ToString(value); int s = this.Encoding.GetBytes(svalue).Length; if (s > size) { size = s; } } //else if (field.DataType == typeof(Int16) || field.DataType == typeof(Int32) || field.DataType == typeof(Int64) // || field.DataType == typeof(UInt16) || field.DataType == typeof(UInt32) || field.DataType == typeof(UInt64)) //{ // size = System.Runtime.InteropServices.Marshal.SizeOf(field.DataType); // decimalCount = 0; //} else if (field.DataType == typeof(Double) || field.DataType == typeof(Single) || field.DataType == typeof(Decimal) || field.DataType == typeof(Int16) || field.DataType == typeof(Int32) || field.DataType == typeof(Int64) || field.DataType == typeof(UInt16) || field.DataType == typeof(UInt32) || field.DataType == typeof(UInt64)) { string svalue = Convert.ToString(value, numberFormatInfo); if (svalue.Length > size) { size = svalue.Length; } int decimalSepIndex = svalue.IndexOf("."); if (decimalSepIndex != -1) { if (svalue.Length - decimalSepIndex - 1 > decimalCount) { decimalCount = Math.Max(decimalCount, svalue.Length - decimalSepIndex - 1); } } //else if (decimalCount == 0) //{ // size += 3; // с учетом разделителя // decimalCount = 2; //} } } if (field.DataType == typeof(Double) || field.DataType == typeof(Single) || field.DataType == typeof(Decimal)) { if (decimalCount == 0) { size += 3; // с учетом разделителя decimalCount = 2; } } if (size != 0) { this._recordLength = this._recordLength - field.Length + size; field.Length = size; if (decimalCount != 0) { field.DecimalCount = decimalCount; } } }
/// <summary> /// Reads a dBase header. /// </summary> /// <param name="reader">A System.IO.BinaryReader instance to read header</param> public void Read(BinaryReader reader) { // type of reader. _fileType = reader.ReadByte(); if (_fileType != 0x03) { throw new NotSupportedException("Unsupported DBF Type " + _fileType); } // parse the update date information. int year = (int)reader.ReadByte(); int month = (int)reader.ReadByte(); int day = (int)reader.ReadByte(); int yearShifted = year + 1900; try { _updateDate = new DateTime(yearShifted, month, day); } catch (ArgumentOutOfRangeException ex) { Debug.WriteLine("Data reading failed."); _updateDate = DateTime.MinValue; } // read the number of records. _numRecords = reader.ReadInt32(); // read the length of the header structure. _headerLength = reader.ReadInt16(); // read the length of a record _recordLength = reader.ReadInt16(); // skip the reserved bytes in the header. //in.skipBytes(20); //reader.ReadBytes(20); reader.BaseStream.Seek(29, SeekOrigin.Begin); //языковой драйвер _encoding = getDbaseLanguageDriver(reader.ReadByte()); reader.BaseStream.Seek(32, SeekOrigin.Begin); // calculate the number of Fields in the header _numFields = (_headerLength - _fileDescriptorSize - 1) / _fileDescriptorSize; // read all of the header records _dbaseColumns = new DbaseFieldDescriptor[_numFields]; for (int i = 0; i < _numFields; i++) { _dbaseColumns[i] = new DbaseFieldDescriptor(); // read the field name byte[] buffer = reader.ReadBytes(11); string name = _encoding.GetString(buffer); if (name.Contains("\0")) { name = name.Substring(0, name.IndexOf('\0')); } name = name.Replace("\0", "").Trim(); int nullPoint = name.IndexOf((char)0); if (nullPoint != -1) { name = name.Substring(0, nullPoint); } _dbaseColumns[i].Name = name; // read the field type _dbaseColumns[i].DbaseType = (char)reader.ReadByte(); _dbaseColumns[i].DataType = DbaseFieldDescriptor.GetDataType(_dbaseColumns[i].DbaseType); // read the field data address, offset from the start of the record. _dbaseColumns[i].DataAddress = reader.ReadInt32(); // read the field length in bytes int tempLength = (int)reader.ReadByte(); if (tempLength < 0) { tempLength = tempLength + 256; } _dbaseColumns[i].Length = tempLength; // read the field decimal count in bytes _dbaseColumns[i].DecimalCount = (int)reader.ReadByte(); if (_dbaseColumns[i].DecimalCount == 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); } } // read the reserved bytes. //reader.skipBytes(14); reader.ReadBytes(14); } // Last byte is a marker for the end of the field definitions. reader.ReadBytes(1); }
/// <summary> /// Adds a column. ///</summary> /// <param name="fieldName">A filed name</param> /// <param name="fieldType">A character defining a dBAse filed type (C N L or D)</param> /// <param name="fieldLength">A length of field in bytes</param> /// <param name="decimalCount">A number of decimal characters</param> /// <param name="DataType">A CLR data type</param> public void AddColumn(string fieldName, char fieldType, Type DataType, int fieldLength, int decimalCount) { if (fieldLength <= 0) { fieldLength = 1; } if (_dbaseColumns == null) { _dbaseColumns = new DbaseFieldDescriptor[0]; } int tempLength = 1; // the length is used for the offset, and there is a * for deleted as the first byte DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_dbaseColumns.Length + 1]; for (int i = 0; i < _dbaseColumns.Length; i++) { _dbaseColumns[i].DataAddress = tempLength; tempLength = tempLength + _dbaseColumns[i].Length; tempFieldDescriptors[i] = _dbaseColumns[i]; } tempFieldDescriptors[_dbaseColumns.Length] = new DbaseFieldDescriptor(); tempFieldDescriptors[_dbaseColumns.Length].Length = fieldLength; tempFieldDescriptors[_dbaseColumns.Length].DecimalCount = decimalCount; tempFieldDescriptors[_dbaseColumns.Length].DataAddress = tempLength; // set the field name string tempFieldName = fieldName; if (tempFieldName == null) { tempFieldName = "NoName"; } if (tempFieldName.Length > 11) { tempFieldName = tempFieldName.Substring(0, 11); //!!!Trace.Write("FieldName " + fieldName + " is longer than 11 characters, truncating to " + tempFieldName); } tempFieldDescriptors[_dbaseColumns.Length].Name = tempFieldName; // the field type tempFieldDescriptors[_dbaseColumns.Length].DataType = DataType; if ((fieldType == 'C') || (fieldType == 'c')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'C'; } else if ((fieldType == 'S') || (fieldType == 's')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'C'; tempFieldDescriptors[_dbaseColumns.Length].Length = 8; } else if ((fieldType == 'D') || (fieldType == 'd')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'D'; tempFieldDescriptors[_dbaseColumns.Length].Length = 8; } else if ((fieldType == 'F') || (fieldType == 'f')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'F'; } else if ((fieldType == 'N') || (fieldType == 'n')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'N'; if (decimalCount < 0) { tempFieldDescriptors[_dbaseColumns.Length].DecimalCount = 0; } if (decimalCount > fieldLength - 1) { tempFieldDescriptors[_dbaseColumns.Length].DecimalCount = fieldLength - 1; } } else if ((fieldType == 'L') || (fieldType == 'l')) { tempFieldDescriptors[_dbaseColumns.Length].DbaseType = 'L'; tempFieldDescriptors[_dbaseColumns.Length].Length = 1; } else { throw new NotSupportedException("Unsupported field type " + fieldType + " For column " + fieldName); } // the length of a record tempLength = tempLength + tempFieldDescriptors[_dbaseColumns.Length].Length; // set the new fields. _dbaseColumns = tempFieldDescriptors; _headerLength = 33 + 32 * _dbaseColumns.Length; _numFields = _dbaseColumns.Length; _recordLength = tempLength; }
private object readDbfValue(DbaseFieldDescriptor dbf) { byte[] bytes = _br.ReadBytes(dbf.Length); switch (dbf.DataType.ToString()) { case "System.String": //if (_encoding == null) // return _fileEncoding.GetString(bytes).Replace("\0", "").Trim(); //else return(_dbaseHeader.Encoding.GetString(bytes).Replace("\0", "").Trim()); case "System.Double": string temp = System.Text.Encoding.UTF7.GetString(bytes).Replace("\0", "").Trim(); double dbl = 0; if (double.TryParse(temp, System.Globalization.NumberStyles.Float, _numberFormat, out dbl)) { return(dbl); } else { return(DBNull.Value); } case "System.Int16": string temp16 = System.Text.Encoding.UTF7.GetString((bytes)).Replace("\0", "").Trim(); Int16 i16 = 0; if (Int16.TryParse(temp16, System.Globalization.NumberStyles.Float, _numberFormat, out i16)) { return(i16); } else { return(DBNull.Value); } case "System.Int32": string temp32 = System.Text.Encoding.UTF7.GetString((bytes)).Replace("\0", "").Trim(); Int32 i32 = 0; if (Int32.TryParse(temp32, System.Globalization.NumberStyles.Float, _numberFormat, out i32)) { return(i32); } else { return(DBNull.Value); } case "System.Int64": string temp64 = System.Text.Encoding.UTF7.GetString((bytes)).Replace("\0", "").Trim(); Int64 i64 = 0; if (Int64.TryParse(temp64, System.Globalization.NumberStyles.Float, _numberFormat, out i64)) { return(i64); } else { return(DBNull.Value); } case "System.Single": string temp4 = System.Text.Encoding.UTF8.GetString((bytes)); float f = 0; if (float.TryParse(temp4, System.Globalization.NumberStyles.Float, _numberFormat, out f)) { return(f); } else { return(DBNull.Value); } case "System.Boolean": char tempChar = Convert.ToChar(bytes[0]); // BitConverter.ToChar(bytes, 0);// _br.ReadChar(); return((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y')); case "System.DateTime": #if !MONO DateTime date; if (DateTime.TryParseExact(System.Text.Encoding.UTF7.GetString((bytes)), "yyyyMMdd", _numberFormat, System.Globalization.DateTimeStyles.None, out date)) { return(date); } else { return(DBNull.Value); } #else // в mono еще не реализован метод DateTime.TryParseExact try { return(DateTime.ParseExact(System.Text.Encoding.UTF7.GetString((bytes)), "yyyyMMdd", _numberFormat, System.Globalization.DateTimeStyles.None)); } catch { return(DBNull.Value); } #endif default: throw (new NotSupportedException("Unable to process field '" + dbf.Name + "' (data type '" + dbf.DataType.ToString() + "')")); } }