public DbfReader(string path) { _readStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); var header = (Header)_readStream.ReadValue(typeof(Header)); Version = (DbfVersion)header.Version; RecordCount = (int)header.RecordCount; Date = header.LastUpdateDate; _dataOffset = header.HeaderBytes; _recordSize = header.RecordBytes; Fields = new ReadOnlyCollection <DbfField>(ReadFieldHeaders().ToList()); IEnumerable <DbfField> ReadFieldHeaders() { while (true) { var position = _readStream.Position; if (_readStream.ReadByte() == 0x0d) { break; } _readStream.Position = position; var f = (FieldDescriptor)_readStream.ReadValue(typeof(FieldDescriptor)); yield return(new DbfField(f.FieldName, (DbfFieldType)f.FieldType, f.FieldLength, f.DecimalCount)); } } }
/// <summary> /// Creates writes the current instance to the specified stream. /// </summary> /// <param name="stream">The output stream.</param> /// <param name="version">The version <see cref="DbfVersion" />. If unknown specified, use current header version.</param> public void Write(Stream stream, DbfVersion version = DbfVersion.Unknown) { if (version != DbfVersion.Unknown) { header.Version = version; header = DbfHeader.CreateHeader(header.Version); } Write(stream, true); }
private void ReadHeader(BinaryReader reader) { // Peek at version number, then try to read correct version header. byte versionByte = reader.ReadByte(); reader.BaseStream.Seek(0, SeekOrigin.Begin); DbfVersion version = (DbfVersion)versionByte; Header = DbfHeader.CreateHeader(version); Header.Read(reader); }
public static void GetDefaultColumnType(Type objectType, DbfVersion version, out ColumnType type, out int defaultWidth, out int defaultDecimals) { defaultDecimals = 0; if (objectType == typeof(byte[])) { type = ColumnType.BYTES; defaultWidth = 0; } else { throw new InvalidColumnException(objectType, null); } }
/// <summary> /// Creates a new file, writes the current instance to the file, and then closes the file. If the target file already exists, it is overwritten. /// </summary> /// <param name="path">The file to read.</param> /// <param name="version">The version <see cref="DbfVersion" />. If unknown specified, use current header version.</param> public void Write(string path, DbfVersion version = DbfVersion.Unknown) { if (version != DbfVersion.Unknown) { header.Version = version; header = DbfHeader.CreateHeader(header.Version); } using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write)) { Write(stream, false); } }
// called when created from existing DBF file public void Initialize(DbfVersion version, FieldInfo fieldinfo, ColumnAttribute columnAttribute) { this.mFieldInfo = fieldinfo; this.mVersion = version; if (columnAttribute == null) { columnAttribute = new ColumnAttribute(); } Type fieldType = mFieldInfo.FieldType; if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>)) { IsNullable = true; NativeTypeCode = Type.GetTypeCode(fieldType.GetGenericArguments()[0]); } else { this.NativeTypeCode = Type.GetTypeCode(fieldType); } mColumnName = (columnAttribute.ColumnName == null || columnAttribute.ColumnName.Length == 0 ? fieldinfo.Name : columnAttribute.ColumnName); mColumnType = columnAttribute.Type; mWidth = columnAttribute.Width; mDecimals = columnAttribute.Decimals; int defaultWidth, defaultDecimals; if (mColumnType == ColumnType.UNKNOWN) { if (NativeTypeCode == TypeCode.Object) { GetDefaultColumnType(fieldType, mVersion, out mColumnType, out defaultWidth, out defaultDecimals); } else { GetDefaultColumnType(NativeTypeCode, IsNullable, mVersion, out mColumnType, out defaultWidth, out defaultDecimals); } if (mWidth == -1) { mWidth = defaultWidth; } if (mDecimals == -1) { mDecimals = defaultDecimals; } } CheckWidthAndDecimals(); }
public void Write(String path, DbfVersion version = DbfVersion.Unknown) { // Use version specified. If unknown specified, use current header version. if (version != DbfVersion.Unknown) { header.Version = version; } header = DbfHeader.CreateHeader(header.Version); FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write); BinaryWriter writer = new BinaryWriter(stream); header.Write(writer, fields, records); WriteFields(writer); WriteRecords(writer); writer.Close(); stream.Close(); }
private void GetNewFileVersion() { if (rbtndBaseIII.Checked == true) { newFileVersion = DbfVersion.FoxBaseDBase3NoMemo; } else if (rbtndBaseIV.Checked == true) { newFileVersion = DbfVersion.dBase4SQLTableNoMemo; } else if (rbtnFoxpro2x.Checked == true) { newFileVersion = DbfVersion.FoxBase; } else if (rbtnVisualFoxpro.Checked == true) { newFileVersion = DbfVersion.VisualFoxPro; } else { newFileVersion = DbfVersion.VisualFoxProWithAutoIncrement; } }
public static DbfHeader CreateHeader(DbfVersion version) { DbfHeader header; switch (version) { case DbfVersion.FoxBaseDBase3NoMemo: header = new Dbf3Header(); break; case DbfVersion.VisualFoxPro: header = new Dbf3Header(); break; case DbfVersion.VisualFoxProWithAutoIncrement: header = new Dbf3Header(); break; case DbfVersion.FoxPro2WithMemo: header = new Dbf3Header(); break; case DbfVersion.FoxBaseDBase3WithMemo: header = new Dbf3Header(); break; case DbfVersion.dBase4WithMemo: header = new Dbf3Header(); break; default: throw new ArgumentException("Unsupported dBASE version: " + version); } header.Version = version; return(header); }
public static void GetDefaultColumnType(TypeCode nativeTypeCode, bool nullable, DbfVersion version, out ColumnType type, out int defaultWidth, out int defaultDecimals) { defaultDecimals = 0; // default if (version == DbfVersion.DbfDotNet) { switch (nativeTypeCode) { case TypeCode.Boolean: type = ColumnType.LOGICAL; defaultWidth = 1; break; case TypeCode.Byte: type = ColumnType.BYTE; defaultWidth = 1; break; case TypeCode.SByte: type = ColumnType.SBYTE; defaultWidth = 1; break; case TypeCode.Int16: type = ColumnType.INT16; defaultWidth = 2; break; case TypeCode.UInt16: type = ColumnType.UINT16; defaultWidth = 2; break; case TypeCode.Int32: type = ColumnType.INT32; defaultWidth = 4; break; case TypeCode.UInt32: type = ColumnType.UINT32; defaultWidth = 4; break; case TypeCode.Single: type = ColumnType.SINGLE; defaultWidth = 4; break; case TypeCode.Int64: type = ColumnType.INT64; defaultWidth = 8; break; case TypeCode.UInt64: type = ColumnType.UINT64; defaultWidth = 8; break; case TypeCode.Double: type = ColumnType.DOUBLE; defaultWidth = 8; break; case TypeCode.Decimal: type = ColumnType.DECIMAL; defaultWidth = 13; // 96 bits + 0..28 (4 bits exponent) + sign = 101 bits minimum break; case TypeCode.DateTime: type = ColumnType.DATETIME; defaultWidth = 8; // 64 bits break; case TypeCode.String: type = ColumnType.CHARACTER; defaultWidth = 20; // unknown break; case TypeCode.Char: // TODO depend on the encoding type = ColumnType.CHARW; defaultWidth = 2; break; default: throw new InvalidColumnException(nativeTypeCode.ToString(), null); } } else { switch (nativeTypeCode) { case TypeCode.Boolean: type = ColumnType.LOGICAL; defaultWidth = 1; // T or F break; case TypeCode.Byte: type = ColumnType.NUMERICAL; defaultWidth = 3; // 255 break; case TypeCode.SByte: type = ColumnType.NUMERICAL; defaultWidth = 4; // -128 break; case TypeCode.Int16: type = ColumnType.NUMERICAL; defaultWidth = 6; // -32768 break; case TypeCode.UInt16: type = ColumnType.NUMERICAL; defaultWidth = 5; // 65535 break; case TypeCode.Int32: type = ColumnType.NUMERICAL; defaultWidth = 11; // -2147483648 break; case TypeCode.UInt32: type = ColumnType.NUMERICAL; defaultWidth = 10; // 4294967295 break; case TypeCode.Single: type = ColumnType.NUMERICAL; defaultWidth = 9 + 1; // 7..9 decimals digits of decimals + the DOT defaultDecimals = 2; break; case TypeCode.Int64: type = ColumnType.NUMERICAL; defaultWidth = 20; // Int64.MinValue "-9223372036854775808" break; case TypeCode.UInt64: type = ColumnType.NUMERICAL; defaultWidth = 19; // UInt64.MaxValue "18446744073709551615" break; case TypeCode.Double: type = ColumnType.NUMERICAL; defaultWidth = 17 + 1; // 15..17 decimal digits of decimals + the DOT defaultDecimals = 2; break; case TypeCode.Decimal: type = ColumnType.NUMERICAL; defaultWidth = 30 + 1; // Decimal.MinValue "-79228162514264337593543950335" + the DOT defaultDecimals = 4; break; case TypeCode.DateTime: type = ColumnType.DATE_YYYYMMDD; defaultWidth = 8; break; case TypeCode.String: type = ColumnType.CHARACTER; defaultWidth = 20; // unknown really break; case TypeCode.Char: // TODO depend on the encoding type = ColumnType.CHARACTER; defaultWidth = 1; break; default: throw new InvalidColumnException(nativeTypeCode.ToString(), null); } } }
// Added On DT: 24/01/2019 public string Write(String path, List <DbfRecord> newrecords, List <DbfField> newfields, DbfVersion version = DbfVersion.Unknown) { // Use version specified. If unknown specified, use current header version. if (version != DbfVersion.Unknown) { header.Version = version; } header = DbfHeader.CreateHeader(header.Version); FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write); BinaryWriter writer = new BinaryWriter(stream); try { header.Write(writer, newfields, newrecords); WriteFields(writer, newfields); WriteRecords(writer, newrecords); writer.Close(); stream.Close(); return("File Updated Successfully !!!"); } catch (Exception ex) { writer.Close(); stream.Close(); return(ex.Message); } }
// called when created from existing DBF file public void Initialize(DbfVersion version, FieldInfo fieldinfo, ColumnAttribute columnAttribute) { this.mFieldInfo = fieldinfo; this.mVersion = version; if (columnAttribute == null) columnAttribute = new ColumnAttribute(); Type fieldType = mFieldInfo.FieldType; if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable<>)) { IsNullable=true; NativeTypeCode= Type.GetTypeCode(fieldType.GetGenericArguments()[0]); } else this.NativeTypeCode = Type.GetTypeCode(fieldType); mColumnName = (columnAttribute.ColumnName == null || columnAttribute.ColumnName.Length == 0 ? fieldinfo.Name : columnAttribute.ColumnName); mColumnType = columnAttribute.Type; mWidth = columnAttribute.Width; mDecimals = columnAttribute.Decimals; int defaultWidth, defaultDecimals; if (mColumnType == ColumnType.UNKNOWN) { if (NativeTypeCode == TypeCode.Object) { GetDefaultColumnType(fieldType, mVersion, out mColumnType, out defaultWidth, out defaultDecimals); } else { GetDefaultColumnType(NativeTypeCode, IsNullable, mVersion, out mColumnType, out defaultWidth, out defaultDecimals); } if (mWidth == -1) mWidth = defaultWidth; if (mDecimals == -1) mDecimals = defaultDecimals; } CheckWidthAndDecimals(); }
public DbfTable(string filePath, System.Text.Encoding encoding, DbfVersion version) { mDbfFile = Core.DbfFile <TRecord> .Get(filePath, encoding, version); }
public DbfWriter(string path, DbfVersion version) { Version = version; _writeStream = File.Open(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); Fields = new ReadOnlyCollection <DbfField>(_fields); }
public QuickSerializer( Type recordType, DbfVersion version, List <ColumnDefinition> columns, int recordWidth, bool ignoreMissingFields, bool setOffset) { mVersion = version; if (columns == null) { columns = new List <ColumnDefinition>(); mCreateColumns = true; } mColumns = columns; mIgnoreMissingFields = ignoreMissingFields; mRecordWidth = 0; // dbf use a character to specify deleted record mIsFixedRecordWidth = true; var readMethod = new DynamicMethod("__readRecord", null, new Type[] { typeof(IHasEncoding), typeof(Byte[]), typeof(object) }, recordType, true); mIlRead = readMethod.GetILGenerator(); var writeMethod = new DynamicMethod("__writeRecord", null, new Type[] { typeof(IHasEncoding), typeof(Byte[]), typeof(object) }, recordType, true); mIlWrite = writeMethod.GetILGenerator(); var compareMethod = new DynamicMethod("__compareRecord", typeof(int), new Type[] { typeof(IHasEncoding), typeof(object), typeof(object) }, recordType, true); mIlCompare = compareMethod.GetILGenerator(); EnumerateFields(recordType); int currentOffset = 0; int columnIndex = 0; foreach (var cd in mColumns) { if (setOffset) { cd.mOffset = currentOffset; currentOffset += cd.mWidth; } cd.ColumnIndex = columnIndex++; EmitColumnCode(cd); } mRecordWidth = currentOffset; mIlRead.Emit(OpCodes.Ret); mIlWrite.Emit(OpCodes.Ret); mIlCompare.Emit(OpCodes.Ldc_I4_0); // if not return yet, we can say that the records are equal mIlCompare.Emit(OpCodes.Ret); mQuickReadMethod = (QuickReadDelegate)readMethod.CreateDelegate(typeof(QuickReadDelegate)); mQuickWriteMethod = (QuickWriteDelegate)writeMethod.CreateDelegate(typeof(QuickWriteDelegate)); mQuickCompareMethod = (QuickCompareDelegate)compareMethod.CreateDelegate(typeof(QuickCompareDelegate)); if (recordWidth > 0) { mRecordWidth = recordWidth; } }
/// <summary> /// Creates empty dBASE table with default (ASCII) encoding. /// </summary> /// <param name="version"></param> public Dbf(DbfVersion version) { Header = DbfHeader.CreateHeader(version); }
/// <summary> /// Creates empty dBASE table with specified encoding. /// </summary> /// <param name="version"></param> public Dbf(DbfVersion version, Encoding encoding) { _encoding = encoding; Header = DbfHeader.CreateHeader(version); }
public QuickSerializer( Type recordType, DbfVersion version, List<ColumnDefinition> columns, int recordWidth, bool ignoreMissingFields, bool setOffset) { mVersion = version; if (columns == null) { columns = new List<ColumnDefinition>(); mCreateColumns = true; } mColumns = columns; mIgnoreMissingFields = ignoreMissingFields; mRecordWidth = 0; // dbf use a character to specify deleted record mIsFixedRecordWidth = true; var readMethod = new DynamicMethod("__readRecord", null, new Type[] { typeof(IHasEncoding), typeof(Byte[]), typeof(object) }, recordType, true); mIlRead = readMethod.GetILGenerator(); var writeMethod = new DynamicMethod("__writeRecord", null, new Type[] { typeof(IHasEncoding), typeof(Byte[]), typeof(object) }, recordType, true); mIlWrite = writeMethod.GetILGenerator(); var compareMethod = new DynamicMethod("__compareRecord", typeof(int), new Type[] { typeof(IHasEncoding), typeof(object), typeof(object) }, recordType, true); mIlCompare = compareMethod.GetILGenerator(); EnumerateFields(recordType); int currentOffset = 0; int columnIndex = 0; foreach(var cd in mColumns) { if (setOffset) { cd.mOffset = currentOffset; currentOffset += cd.mWidth; } cd.ColumnIndex = columnIndex++; EmitColumnCode(cd); } mRecordWidth = currentOffset; mIlRead.Emit(OpCodes.Ret); mIlWrite.Emit(OpCodes.Ret); mIlCompare.Emit(OpCodes.Ldc_I4_0); // if not return yet, we can say that the records are equal mIlCompare.Emit(OpCodes.Ret); mQuickReadMethod = (QuickReadDelegate)readMethod.CreateDelegate(typeof(QuickReadDelegate)); mQuickWriteMethod = (QuickWriteDelegate)writeMethod.CreateDelegate(typeof(QuickWriteDelegate)); mQuickCompareMethod = (QuickCompareDelegate)compareMethod.CreateDelegate(typeof(QuickCompareDelegate)); if (recordWidth > 0) mRecordWidth = recordWidth; }
public static void GetDefaultColumnType(Type objectType, DbfVersion version, out ColumnType type, out int defaultWidth, out int defaultDecimals) { defaultDecimals = 0; if (objectType == typeof(byte[])) { type = ColumnType.BYTES; defaultWidth = 0; } else throw new InvalidColumnException(objectType, null); }
public DbfTable(string filepath, System.Text.Encoding encoding, DbfVersion version) : base(filepath, encoding, version) { mExpression = Expression.Constant(this); }
public static void GetDefaultColumnType(TypeCode nativeTypeCode, bool nullable, DbfVersion version, out ColumnType type, out int defaultWidth, out int defaultDecimals) { defaultDecimals = 0; // default if (version == DbfVersion.DbfDotNet) { switch (nativeTypeCode) { case TypeCode.Boolean: type = ColumnType.LOGICAL; defaultWidth = 1; break; case TypeCode.Byte: type = ColumnType.BYTE; defaultWidth = 1; break; case TypeCode.SByte: type = ColumnType.SBYTE; defaultWidth = 1; break; case TypeCode.Int16: type = ColumnType.INT16; defaultWidth = 2; break; case TypeCode.UInt16: type = ColumnType.UINT16; defaultWidth = 2; break; case TypeCode.Int32: type = ColumnType.INT32; defaultWidth = 4; break; case TypeCode.UInt32: type = ColumnType.UINT32; defaultWidth = 4; break; case TypeCode.Single: type = ColumnType.SINGLE; defaultWidth = 4; break; case TypeCode.Int64: type = ColumnType.INT64; defaultWidth = 8; break; case TypeCode.UInt64: type = ColumnType.UINT64; defaultWidth = 8; break; case TypeCode.Double: type = ColumnType.DOUBLE; defaultWidth = 8; break; case TypeCode.Decimal: type = ColumnType.DECIMAL; defaultWidth = 13;// 96 bits + 0..28 (4 bits exponent) + sign = 101 bits minimum break; case TypeCode.DateTime: type = ColumnType.DATETIME; defaultWidth = 8; // 64 bits break; case TypeCode.String: type = ColumnType.CHARACTER; defaultWidth = 20; // unknown break; case TypeCode.Char: // TODO depend on the encoding type = ColumnType.CHARW; defaultWidth = 2; break; default: throw new InvalidColumnException(nativeTypeCode.ToString(), null); } } else { switch (nativeTypeCode) { case TypeCode.Boolean: type = ColumnType.LOGICAL; defaultWidth = 1; // T or F break; case TypeCode.Byte: type = ColumnType.NUMERICAL; defaultWidth = 3; // 255 break; case TypeCode.SByte: type = ColumnType.NUMERICAL; defaultWidth = 4; // -128 break; case TypeCode.Int16: type = ColumnType.NUMERICAL; defaultWidth = 6; // -32768 break; case TypeCode.UInt16: type = ColumnType.NUMERICAL; defaultWidth = 5; // 65535 break; case TypeCode.Int32: type = ColumnType.NUMERICAL; defaultWidth = 11; // -2147483648 break; case TypeCode.UInt32: type = ColumnType.NUMERICAL; defaultWidth = 10; // 4294967295 break; case TypeCode.Single: type = ColumnType.NUMERICAL; defaultWidth = 9 + 1; // 7..9 decimals digits of decimals + the DOT defaultDecimals = 2; break; case TypeCode.Int64: type = ColumnType.NUMERICAL; defaultWidth = 20; // Int64.MinValue "-9223372036854775808" break; case TypeCode.UInt64: type = ColumnType.NUMERICAL; defaultWidth = 19; // UInt64.MaxValue "18446744073709551615" break; case TypeCode.Double: type = ColumnType.NUMERICAL; defaultWidth = 17 + 1; // 15..17 decimal digits of decimals + the DOT defaultDecimals = 2; break; case TypeCode.Decimal: type = ColumnType.NUMERICAL; defaultWidth = 30 + 1; // Decimal.MinValue "-79228162514264337593543950335" + the DOT defaultDecimals = 4; break; case TypeCode.DateTime: type = ColumnType.DATE_YYYYMMDD; defaultWidth = 8; break; case TypeCode.String: type = ColumnType.CHARACTER; defaultWidth = 20; // unknown really break; case TypeCode.Char: // TODO depend on the encoding type = ColumnType.CHARACTER; defaultWidth = 1; break; default: throw new InvalidColumnException(nativeTypeCode.ToString(), null); } } }
internal static DbfFile <TRecord> Get(string filePath, System.Text.Encoding encoding, DbfVersion version) { var file = ClusteredFile.Get <DbfFile <TRecord> >(filePath, OpenFileMode.OpenOrCreate, 4096); if (file.ReaderCount == 1) { file.mEncoding = encoding; file.mVersion = version; file.Initialize(); } else { // perhaps check encoding and version match } return(file); }