private object DecodeBytes(byte[] data, int fieldIndex) { var field = Fields[fieldIndex]; try { var type = field.DbfType; if (type == DbfType.Double || type == DbfType.Numeric) { return(DecodeFloatPoint(data, field, type)); } if (type == DbfType.Date) { return(DecodeDate(data)); } if (type == DbfType.Logical) { return(DecodeLogical(data)); } if (type == DbfType.Memo) { return(DecodeMemo(data, fieldIndex)); } return(CharEncoding.GetString(data, 0, field.FieldLength).TrimEnd()); } catch (Exception e) { var msg = String.Format("Unable to decode field [{0}], value <{1}>", field.Name, CharEncoding.GetString(data, 0, field.FieldLength)); throw new DbfReaderException(msg, e); } }
private object DecodeDate(byte[] data) { var strYear = CharEncoding.GetString(data, 0, 4); var strMonth = CharEncoding.GetString(data, 4, 2); var strDay = CharEncoding.GetString(data, 6, 2); object ret = null; int year, month, day; if (Int32.TryParse(strYear, out year) && Int32.TryParse(strMonth, out month) && Int32.TryParse(strDay, out day)) { ret = new DateTime(year, month, day); } return(ret); }
private object DecodeFloatPoint(byte[] data, DbfField field, DbfType type) { object ret = null; var str = CharEncoding.GetString(data, 0, field.FieldLength); if (str.Length != 0) { var last = str[str.Length - 1]; if (last != ' ' && last != '?') { var culture = CultureInfo.InvariantCulture; str = str.Replace(',', '.'); ret = type == DbfType.Double ? (object)Double.Parse(str, Styles, culture) : Decimal.Parse(str, Styles, culture); } } return(ret); }
private object DecodeMemo(byte[] data, int fieldIndex) { if (DbtReader == null) { throw new DbfReaderException("Unable to read memo file"); } var str = CharEncoding.GetString(data, 0, Fields[fieldIndex].FieldLength); if (string.IsNullOrWhiteSpace(str)) { return(null); } long index; if (!long.TryParse(str.Trim(), out index)) { return(null); } // reading memo file DbtReader.BaseStream.Seek((index + 1) << 9, SeekOrigin.Begin); var ms = new MemoryStream(); var xCnt = 0; // read until [0x1a, 0x1a] in file while (xCnt < 2) { var bt = DbtReader.ReadByte(); ms.WriteByte(bt); xCnt = bt == 0x1a ? xCnt + 1 : 0; } var memo = ms.ToArray(); var retString = CharEncoding.GetString(new byte[] { 0x8d, 0x0a }); return(CharEncoding.GetString(memo, 0, memo.Length - 2).Replace(retString, string.Empty)); }
internal Object[] NextRecord(IEnumerable <int> selectIndexes, IList <int> sortedIndexes) { if (isClosed) { throw new DBFException("Source is not open"); } IList <int> tOrderdSelectIndexes = sortedIndexes; var recordObjects = new Object[_header.FieldArray.Length]; try { bool isDeleted = false; do { if (isDeleted) { _dataInputStream.ReadBytes(_header.RecordLength - 1); } int t_byte = _dataInputStream.ReadByte(); if (t_byte == DBFFieldType.EndOfData) { return(null); } isDeleted = (t_byte == '*'); } while (isDeleted); int j = 0; int k = -1; for (int i = 0; i < _header.FieldArray.Length; i++) { if (tOrderdSelectIndexes.Count == j && j != 0 || (tOrderdSelectIndexes.Count > j && tOrderdSelectIndexes[j] > i && tOrderdSelectIndexes[j] != k)) { _dataInputStream.BaseStream.Seek(_header.FieldArray[i].FieldLength, SeekOrigin.Current); continue; } if (tOrderdSelectIndexes.Count > j) { k = tOrderdSelectIndexes[j]; } j++; switch (_header.FieldArray[i].DataType) { case NativeDbType.Char: var b_array = new byte[ _header.FieldArray[i].FieldLength ]; _dataInputStream.Read(b_array, 0, b_array.Length); //StringBuilder sb = new StringBuilder(); //for (int c = 0; c < b_array.Length && b_array[c] != 0; c++) //{ // sb.Append((char)b_array[c]); //} //recordObjects[i] = sb.ToString().TrimEnd(); recordObjects[i] = CharEncoding.GetString(b_array).TrimEnd(); //recordObjects[i] = Encoding.GetEncoding("ISO-8859-1").GetString(b_array).TrimEnd(); break; case NativeDbType.Date: byte[] t_byte_year = new byte[4]; _dataInputStream.Read(t_byte_year, 0, t_byte_year.Length); byte[] t_byte_month = new byte[2]; _dataInputStream.Read(t_byte_month, 0, t_byte_month.Length); byte[] t_byte_day = new byte[2]; _dataInputStream.Read(t_byte_day, 0, t_byte_day.Length); try { var tYear = CharEncoding.GetString(t_byte_year); var tMonth = CharEncoding.GetString(t_byte_month); var tDay = CharEncoding.GetString(t_byte_day); int tIntYear, tIntMonth, tIntDay; if (Int32.TryParse(tYear, out tIntYear) && Int32.TryParse(tMonth, out tIntMonth) && Int32.TryParse(tDay, out tIntDay)) { recordObjects[i] = new DateTime( tIntYear, tIntMonth, tIntDay); } else { recordObjects[i] = null; } } catch (ArgumentOutOfRangeException) { /* this field may be empty or may have improper value set */ recordObjects[i] = null; } break; case NativeDbType.Float: try { byte[] t_float = new byte[ _header.FieldArray[i].FieldLength ]; _dataInputStream.Read(t_float, 0, t_float.Length); String tParsed = CharEncoding.GetString(t_float); var tLast = tParsed.Substring(tParsed.Length - 1); if (tParsed.Length > 0 && tLast != " " && tLast != DBFFieldType.Unknown) { //recordObjects[i] = Double.Parse(tParsed, NumberStyles.Float | NumberStyles.AllowLeadingWhite); recordObjects[i] = GAPPSF.Utils.Conversion.StringToDouble(tParsed); } else { recordObjects[i] = null; } } catch (FormatException e) { throw new DBFException("Failed to parse Float", e); } break; case NativeDbType.Numeric: try { byte[] t_numeric = new byte[ _header.FieldArray[i].FieldLength ]; _dataInputStream.Read(t_numeric, 0, t_numeric.Length); string tParsed = CharEncoding.GetString(t_numeric); var tLast = tParsed.Substring(tParsed.Length - 1); if (tParsed.Length > 0 && tLast != " " && tLast != DBFFieldType.Unknown) { //recordObjects[i] = Decimal.Parse(tParsed, NumberStyles.Float | NumberStyles.AllowLeadingWhite); recordObjects[i] = GAPPSF.Utils.Conversion.StringToDouble(tParsed); } else { recordObjects[i] = null; } } catch (FormatException e) { throw new DBFException( "Failed to parse Number", e); } break; case NativeDbType.Logical: byte t_logical = _dataInputStream.ReadByte(); //todo find out whats really valid if (t_logical == 'Y' || t_logical == 't' || t_logical == 'T' || t_logical == 't') { recordObjects[i] = true; } else if (t_logical == DBFFieldType.UnknownByte) { recordObjects[i] = DBNull.Value; } else { recordObjects[i] = false; } break; case NativeDbType.Memo: if (string.IsNullOrEmpty(_dataMemoLoc)) { throw new Exception("Memo Location Not Set"); } var tRawMemoPointer = _dataInputStream.ReadBytes(_header.FieldArray[i].FieldLength); var tMemoPoiner = CharEncoding.GetString(tRawMemoPointer); if (string.IsNullOrEmpty(tMemoPoiner)) { recordObjects[i] = DBNull.Value; break; } long tBlock; if (!long.TryParse(tMemoPoiner, out tBlock)) { //Because Memo files can vary and are often the least importat data, //we will return null when it doesn't match our format. recordObjects[i] = DBNull.Value; break; } recordObjects[i] = new MemoValue(tBlock, this, _dataMemoLoc); break; default: _dataInputStream.ReadBytes(_header.FieldArray[i].FieldLength); recordObjects[i] = DBNull.Value; break; } } } catch (EndOfStreamException) { return(null); } catch (IOException e) { throw new DBFException("Problem Reading File", e); } return(selectIndexes.Any() ? selectIndexes.Select(it => recordObjects[it]).ToArray() : recordObjects); }
internal (Object[], long) NextRecord(IEnumerable <int> selectIndexes, IList <int> sortedIndexes) { if (_IsClosed) { throw new DBFException("Source is not open"); } var position = _BaseStream.Position; var tOrderdSelectIndexes = sortedIndexes; var recordObjects = new Object[_Header.FieldArray.Length]; try { var isDeleted = false; do { if (isDeleted) { position += _BinaryRead.ReadBytes(_Header.RecordLength - 1).Length; } int t_byte = _BinaryRead.ReadByte(); if (t_byte == DBFFieldType.EndOfData) { return(null, position); } position++; isDeleted = (t_byte == '*'); } while (isDeleted); position = position - 1; var j = 0; var k = -1; for (var i = 0; i < _Header.FieldArray.Length; i++) { if (tOrderdSelectIndexes.Count == j && j != 0 || (tOrderdSelectIndexes.Count > j && tOrderdSelectIndexes[j] > i && tOrderdSelectIndexes[j] != k)) { _BaseStream.Seek(_Header.FieldArray[i].FieldLength, SeekOrigin.Current); continue; } if (tOrderdSelectIndexes.Count > j) { k = tOrderdSelectIndexes[j]; } j++; switch (_Header.FieldArray[i].DataType) { case NativeDbType.UnicodeChar: var b_arrayU = new byte[ _Header.FieldArray[i].FieldLength ]; _BinaryRead.Read(b_arrayU, 0, b_arrayU.Length); recordObjects[i] = _UCharEncoding.GetString(b_arrayU).TrimEnd('\0', ' '); break; case NativeDbType.Char: var b_array = new byte[ _Header.FieldArray[i].FieldLength ]; _BinaryRead.Read(b_array, 0, b_array.Length); recordObjects[i] = CharEncoding.GetString(b_array).TrimEnd(); break; case NativeDbType.Date: var t_byte_year = new byte[4]; _BinaryRead.Read(t_byte_year, 0, t_byte_year.Length); var t_byte_month = new byte[2]; _BinaryRead.Read(t_byte_month, 0, t_byte_month.Length); var t_byte_day = new byte[2]; _BinaryRead.Read(t_byte_day, 0, t_byte_day.Length); try { var tYear = CharEncoding.GetString(t_byte_year); var tMonth = CharEncoding.GetString(t_byte_month); var tDay = CharEncoding.GetString(t_byte_day); int tIntYear, tIntMonth, tIntDay; if (int.TryParse(tYear, out tIntYear) && int.TryParse(tMonth, out tIntMonth) && int.TryParse(tDay, out tIntDay)) { recordObjects[i] = new DateTime( tIntYear, tIntMonth, tIntDay); } else { recordObjects[i] = null; } } catch (ArgumentOutOfRangeException) { /* this field may be empty or may have improper value set */ recordObjects[i] = null; } break; case NativeDbType.Float: try { var t_float = new byte[ _Header.FieldArray[i].FieldLength ]; _BinaryRead.Read(t_float, 0, t_float.Length); var tParsed = CharEncoding.GetString(t_float); var tLast = tParsed.Substring(tParsed.Length - 1); if (tParsed.Length > 0 && tLast != " " && tLast != NullSymbol) { recordObjects[i] = double.Parse(tParsed, NumberStyles.Float | NumberStyles.AllowLeadingWhite, NumberFormatInfo.InvariantInfo); } else { recordObjects[i] = null; } } catch (FormatException e) { throw new DBFException("Failed to parse Float", e); } break; case NativeDbType.Numeric: try { var t_numeric = new byte[ _Header.FieldArray[i].FieldLength ]; _BinaryRead.Read(t_numeric, 0, t_numeric.Length); var tParsed = CharEncoding.GetString(t_numeric); var tLast = tParsed.Substring(tParsed.Length - 1); if (tParsed.Length > 0 && tLast != " " && tLast != NullSymbol) { recordObjects[i] = Decimal.Parse(tParsed, NumberStyles.Float | NumberStyles.AllowLeadingWhite, NumberFormatInfo.InvariantInfo); } else { recordObjects[i] = null; } } catch (FormatException e) { throw new DBFException( "Failed to parse Number", e); } break; case NativeDbType.Logical: var t_logical = _BinaryRead.ReadByte(); //todo find out whats really valid if (t_logical == 'Y' || t_logical == 't' || t_logical == 'T' || t_logical == 't') { recordObjects[i] = true; } else if (t_logical == DBFFieldType.UnknownByte) { recordObjects[i] = DBNull.Value; } else { recordObjects[i] = false; } break; case NativeDbType.Memo: //if (String.IsNullOrEmpty(streamMemoLoc) && streamMemo == null) if (_StreamMemo == null) { throw new Exception("Memo Location Not Set"); } var tRawMemoPointer = _BinaryRead.ReadBytes(_Header.FieldArray[i].FieldLength); var tMemoPoiner = CharEncoding.GetString(tRawMemoPointer); if (string.IsNullOrEmpty(tMemoPoiner)) { recordObjects[i] = DBNull.Value; break; } long tBlock; if (!long.TryParse(tMemoPoiner, out tBlock)) { //Because Memo files can vary and are often the least importat data, //we will return null when it doesn't match our format. recordObjects[i] = DBNull.Value; break; } //recordObjects[i] = new MemoValue(tBlock, this, streamMemoLoc, GetLazyStreamFromLocation()); recordObjects[i] = new MemoValue(tBlock, this, _StreamMemo); break; default: _BinaryRead.ReadBytes(_Header.FieldArray[i].FieldLength); recordObjects[i] = DBNull.Value; break; } } } catch (EndOfStreamException) { return(null, position); } catch (IOException e) { throw new DBFException("Problem Reading File", e); } return(selectIndexes.Any() ? selectIndexes.Select(it => recordObjects[it]).ToArray() : recordObjects, position); }