public bool Create(string filename, List <ColumnInfo> fields) { FileMode mode = FileMode.Create; FileAccess access = FileAccess.ReadWrite; // exclusive string filename_memo = string.Empty; bool memo = false; foreach (ColumnInfo item in fields) { memo = memo || (Convert.Type(item.DataType, item.Length) == DataType.Memo); } FileStream stream = new FileStream(filename, mode, access); FileStream stream_memo = null; bool ok = (stream != null); if (ok && memo) { filename_memo = MemoFile.CreateFileName(filename); stream_memo = new FileStream(filename_memo, mode, access); ok = (stream_memo != null); } if (ok) { byte[] bytes; ok = Attach(stream, filename, false); if (ok) { HeaderLength = Const.DefaultHeaderLen + Const.FieldTerminatorLen + Const.DefaultFieldLen * fields.Count; IsDirty = true; stream.SetLength(HeaderLength); StreamSeek(stream, Const.DefaultHeaderLen); Columns = fields; RecordLength = Const.RECORD_POS_DATA; foreach (ColumnInfo item in fields) { DBF_FILEFIELD_3 field = new DBF_FILEFIELD_3(); if (item.Name.Length > Const.FieldNameLen) { throw new Exception("Name too long"); } field.title = item.Name; field.type = Const.DataTypes[(int)Convert.Type(item.DataType, item.Length)]; field.length = (byte)item.Length; field.deccount = (byte)item.DecCount; bytes = Utility.StructureToPtr <DBF_FILEFIELD_3>(field); StreamWrite(stream, bytes); RecordLength += item.Length; } bytes = new byte[] { (byte)Const.FieldTerminator }; StreamWrite(stream, bytes); } if (stream_memo != null) { AttachMemo(stream_memo, filename_memo); } } return(ok); }
public bool Attach(Stream stream, string filename, bool read_header) { bool ok = (stream != null); if (ok && read_header) { byte[] bytes = new byte[Marshal.SizeOf(typeof(Byte))]; ok = (bytes.Length == StreamRead(stream, bytes)); if (ok) { Byte version = bytes[0]; int len_header; int len_field; switch (version) { case Const.MAGIC_DBASE4: case Const.MAGIC_DBASE4_MEMO: len_header = Marshal.SizeOf(typeof(DBF_FILEHEADER_4)); len_field = Marshal.SizeOf(typeof(DBF_FILEFIELD_4)); break; case Const.MAGIC_DBASE3: case Const.MAGIC_DBASE3_MEMO: case Const.MAGIC_DBASE3_MEMO_2: case Const.MAGIC_FOXPRO: default: len_header = Marshal.SizeOf(typeof(DBF_FILEHEADER_3)); len_field = Marshal.SizeOf(typeof(DBF_FILEFIELD_3)); break; } bytes = new byte[len_header]; StreamSeek(stream, 0); ok = (len_header == StreamRead(stream, bytes)); if (ok) { switch (version) { case Const.MAGIC_DBASE4: case Const.MAGIC_DBASE4_MEMO: { DBF_FILEHEADER_4 header = Utility.PtrToStructure <DBF_FILEHEADER_4>(bytes); _RecordCount = header.recordcount; RecordLength = header.recordlength; HeaderLength = header.headerlength; ok = sanity_check(header); break; } case Const.MAGIC_DBASE3: case Const.MAGIC_DBASE3_MEMO: case Const.MAGIC_DBASE3_MEMO_2: case Const.MAGIC_FOXPRO: default: { DBF_FILEHEADER_3 header = Utility.PtrToStructure <DBF_FILEHEADER_3>(bytes); _RecordCount = header.recordcount; RecordLength = header.recordlength; HeaderLength = header.headerlength; ok = sanity_check(header); break; } } if (ok) { if ((RecordCount == 0) && (RecordLength != 0)) { _RecordCount = (stream.Length - HeaderLength) / RecordLength; } int fieldcount = (HeaderLength - (len_header + 1)) / len_field; bytes = new byte[len_field]; for (int i = 0; i < fieldcount; i++) { ColumnInfo field; StreamRead(stream, bytes); if ((bytes[0] >= 0) && (bytes[0] <= (byte)' ')) { break; } switch (version) { case Const.MAGIC_DBASE4: case Const.MAGIC_DBASE4_MEMO: { DBF_FILEFIELD_4 item = Utility.PtrToStructure <DBF_FILEFIELD_4>(bytes); DataType type = (DataType)Const.DataTypes.IndexOf(item.type); field = new ColumnInfo() { Name = item.title, DataType = Convert.Type(type), Length = item.length, DecCount = item.deccount }; break; } case Const.MAGIC_DBASE3: case Const.MAGIC_DBASE3_MEMO: case Const.MAGIC_DBASE3_MEMO_2: case Const.MAGIC_FOXPRO: default: { DBF_FILEFIELD_3 item = Utility.PtrToStructure <DBF_FILEFIELD_3>(bytes); DataType type = (DataType)Const.DataTypes.IndexOf(item.type); field = new ColumnInfo() { Name = item.title, DataType = Convert.Type(type), Length = item.length, DecCount = item.deccount }; break; } } Columns.Add(field); } } } } } if (ok) { _Stream = stream; Filename = filename; } return(ok); }