/// <summary> /// Writes the header to the specified stream. /// </summary> /// <param name="stream">The stream.</param> /// <param name="sampleRecord">The sample record.</param> public void Write(Stream stream, IDictionary <String, Object> sampleRecord) { _bytesInRecord = 1; _fields = new List <DBaseField>(); foreach (String key in sampleRecord.Keys) { DBaseField field = DBaseField.FromRecord(key, sampleRecord[key]); _fields.Add(field); _bytesInRecord += (Int16)field.FieldLength; } _numOfRecords = 0; _bytesInHeader = (Int16)(32 + (sampleRecord.Count * 32) + 1); Byte[] headerBytes = new Byte[_bytesInHeader]; headerBytes[0] = _identifier; // write dBase ID headerBytes[1] = (Byte)(_lastUpdate.Year - 1900); // write last update time headerBytes[2] = (Byte)_lastUpdate.Month; headerBytes[3] = (Byte)_lastUpdate.Day; headerBytes[headerBytes.Length - 1] = FieldTerminator; EndianBitConverter.CopyBytes(_numOfRecords, headerBytes, 4, ByteOrder.LittleEndian); EndianBitConverter.CopyBytes(_bytesInHeader, headerBytes, 8, ByteOrder.LittleEndian); EndianBitConverter.CopyBytes(_bytesInRecord, headerBytes, 10, ByteOrder.LittleEndian); Int32 headerIndex = 32; foreach (DBaseField field in _fields) { Array.Copy(field.ToByteArray(), 0, headerBytes, headerIndex, 32); headerIndex += 32; } stream.Write(headerBytes, 0, headerBytes.Length); }
/// <summary> /// Initializes a new instance of the <see cref="DBaseHeader"/> class. /// </summary> /// <param name="stream">The source stream.</param> /// <exception cref="System.ArgumentNullException">The stream is null.</exception> /// <exception cref="System.IO.InvalidDataException">The specified dBase format is not supported.</exception> public DBaseHeader(Stream stream) : this() { if (stream == null) { throw new ArgumentNullException("stream", "The stream is null."); } Byte[] headerBuffer = new Byte[32]; stream.Read(headerBuffer, 0, 32); _identifier = headerBuffer[0]; if (_identifier != DBaseIIIPlusIdentifier && _identifier != (Byte)0x04) { throw new InvalidDataException("The specified dBase format is not supported."); } _lastUpdate = new DateTime(1900 + headerBuffer[1], headerBuffer[2], headerBuffer[3]); _numOfRecords = EndianBitConverter.ToInt32(headerBuffer, 4, ByteOrder.LittleEndian); _bytesInHeader = EndianBitConverter.ToInt16(headerBuffer, 8, ByteOrder.LittleEndian); _bytesInRecord = EndianBitConverter.ToInt16(headerBuffer, 10, ByteOrder.LittleEndian); Byte b = headerBuffer[29]; DBaseField field = DBaseField.FromStream(stream); while (field != null) { _fields.Add(field); field = DBaseField.FromStream(stream); } }
/// <summary> /// Creates the field from a stream. /// </summary> /// <param name="stream">The stream.</param> /// <returns>The produced dBase field.</returns> /// <exception cref="System.ArgumentNullException">The stream is null.</exception> public static DBaseField FromStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream", "The stream is null."); } DBaseField result = new DBaseField(); Byte[] buffer = new Byte[14]; buffer[0] = (Byte)stream.ReadByte(); if (buffer[0] == FieldTerminator) // we reached the end of the field descriptor { return(null); } stream.Read(buffer, 1, 10); for (Int32 i = 0; i < 11; i++) { if (buffer[i] == (Byte)0) { result._nameLength = i; break; } } if (result._nameLength == 0) { result._nameLength = 11; } result._name = Encoding.ASCII.GetString(buffer, 0, result._nameLength); result._type = Convert.ToChar(stream.ReadByte()); stream.Read(buffer, 0, 4); result._dataAddress = EndianBitConverter.ToInt32(buffer, 0, ByteOrder.LittleEndian); result._length = stream.ReadByte(); result._decimalCount = stream.ReadByte(); stream.Read(buffer, 0, 14); return(result); }
/// <summary> /// Creates the field from a metadata record name and value. /// </summary> /// <param name="name">The record name.</param> /// <param name="value">The record value.</param> /// <returns>The produced dDbase field.</returns> /// <exception cref="System.ArgumentNullException"> /// The name is null. /// or /// The value is null. /// </exception> /// <exception cref="System.ArgumentException"> /// The name is empty or consists only of white-space characters. /// or /// The length of the name is more than the maximum supported by the field (10). /// or /// The value is null. /// </exception> public static DBaseField FromRecord(String name, Object value) { if (name == null) { throw new ArgumentNullException("name", "The name is null."); } if (String.IsNullOrWhiteSpace(name)) { throw new ArgumentException("The name is empty or consists only of white-space characters.", "name"); } if (name.Length > 10) { throw new ArgumentException("The length of the name is more than the maximum supported by the field (10).", "name"); } if (value == null) { throw new ArgumentNullException("value", "The value is null."); } DBaseField result = new DBaseField(); result._name = name; result._nameLength = name.Length; switch (Type.GetTypeCode(value.GetType())) { case TypeCode.Char: case TypeCode.String: result._type = 'C'; result._decimalCount = 0; result._length = 255; break; case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: result._type = 'N'; result._decimalCount = 0; result._length = 18; break; case TypeCode.Single: case TypeCode.Double: result._type = 'N'; result._decimalCount = 8; result._length = 18; break; case TypeCode.Boolean: result._type = 'L'; result._decimalCount = 0; result._length = 1; break; case TypeCode.DateTime: result._type = 'D'; result._decimalCount = 0; result._length = 8; break; } return(result); }