private IEnumerable <byte> PackValue(DbfField field, object value) { Debug.WriteLine($"* V {field.Name} {_recordOffset + field.Displacement:X4}"); switch (field.Type) { case DbfFieldType.Character: { if (!(value is string s)) { throw new InvalidCastException(field.Name); } if (s.Length > field.Length) { throw new InvalidCastException(field.Name); } return(ToBytes(s, field.Length)); } case DbfFieldType.Date: { var d = (DateTime)value; var s = $"{d.Year:0000}{d.Month:00}{d.Day:00}"; var bytes = Encoding.Default.GetBytes(s); return(bytes); } case DbfFieldType.Numeric: case DbfFieldType.Float: { var d = (decimal)Convert.ChangeType(value, typeof(decimal)); var s = d.ToString("F" + field.Precision, CultureInfo.InvariantCulture.NumberFormat); if (s.Length > field.Length) { throw new InvalidCastException(field.Name); } s = new string(' ', field.Length - s.Length) + s; // justify right return(ToBytes(s, field.Length)); } case DbfFieldType.Logical: return(new[] { (bool)value ? (byte)'T' : (byte)'F' }); case DbfFieldType.Integer: { var v = (int)value; return(BitConverter.GetBytes(Helper.SwapEndianness(v))); } default: throw new ArgumentOutOfRangeException(field.Type.ToString()); } IEnumerable <byte> ToBytes(string s, int length) { var bytes = Encoding.Default.GetBytes(s); foreach (var b in bytes) { yield return(b); } // fill with blanks var n = field.Length - bytes.Length; while (n-- > 0) { yield return((byte)' '); } } }
public void AddField(DbfField field) { field.Displacement = CurrentRecordSize(); _fields.Add(field); }