/// <summary> /// Gets the feature at the specified Object ID /// </summary> /// <param name="oid">the object Id</param> /// <param name="table">the table to add the feature to</param> /// <returns></returns> internal FeatureDataRow GetFeature(uint oid, FeatureDataTable table) { if (!_isOpen) { throw (new ApplicationException("An attempt was made to read from a closed DBF file")); } if (oid >= _NumberOfRecords) { throw (new ArgumentException("Invalid DataRow requested at index " + oid)); } fs.Seek(_HeaderLength + oid * _RecordLength, 0); FeatureDataRow dr = table.NewRow(); if (br.ReadChar() == '*') //is record marked deleted? { return(null); } for (int i = 0; i < DbaseColumns.Length; i++) { DbaseField dbf = DbaseColumns[i]; dr[dbf.ColumnName] = ReadDbfValue(dbf); } return(dr); }
internal static DbaseField[] GetFields(System.Data.DataTable schema) { if (schema == null) { throw new ArgumentNullException("schema"); } List <DbaseField> fields = new List <DbaseField>(); foreach (DataRow row in schema.Rows) { if (row[DbaseSchema.ColumnNameColumn].Equals(DbaseSchema.OidColumnName)) { continue; } DbaseField field = new DbaseField(); field.ColumnName = row[DbaseSchema.ColumnNameColumn] as string; field.DataType = (Type)row[DbaseSchema.DataTypeColumn]; field.Length = Convert.ToInt16(row[DbaseSchema.ColumnSizeColumn]); field.Decimals = Convert.ToByte(row[DbaseSchema.NumericPrecisionColumn]); fields.Add(field); } return(fields.ToArray()); }
/// <summary> /// Gets the feature at the specified Object ID /// </summary> /// <param name="oid"></param> /// <param name="table"></param> /// <returns></returns> internal FeatureDataRow GetFeature(int oid, FeatureDataTable table) { if (!_isOpen) { Open(); } if (oid >= _NumberOfRecords) { throw (new ArgumentException("Invalid DataRow requested at index " + oid.ToString())); } fs.Seek(_HeaderLength + oid * _RecordLength, 0); SharpMap.Data.FeatureDataRow dr = table.NewRow(); if (br.ReadChar() == '*') //is record marked deleted? { return(null); } for (int i = 0; i < DbaseColumns.Length; i++) { DbaseField dbf = DbaseColumns[i]; dr[dbf.ColumnName] = ReadDbfValue(dbf); } return(dr); }
private void ParseDbfHeader(string filename) { var buffer32 = new byte[32]; _dbfStream.Seek(0, SeekOrigin.Begin); _dbfStream.Read(buffer32, 0, 32); if (buffer32[0] != 0x03) { throw new NotSupportedException("Unsupported DBF Type"); } //Get last modified date _lastUpdate = new DateTime(buffer32[1] + 1900, buffer32[2], buffer32[3]); //Get number of records _numberOfRecords = BitConverter.ToInt32(buffer32, 4); //Get the header length _headerLength = BitConverter.ToInt16(buffer32, 8); //Get the record length _recordLength = BitConverter.ToInt16(buffer32, 10); //Get and parse the language driver code _fileEncoding = GetDbaseLanguageDriver(buffer32[29], filename); var numberOfColumns = (_headerLength - 31) / 32; // calculate the number of DataColumns in the header _dbaseColumns = new DbaseField[numberOfColumns]; for (var i = 0; i < numberOfColumns; i++) { _dbfStream.Read(buffer32, 0, 32); using (var br = new BinaryReader(new MemoryStream(buffer32))) { _dbaseColumns[i] = new DbaseField(); _dbaseColumns[i].ColumnName = Encoding.UTF7.GetString((br.ReadBytes(11))).Replace("\0", "").Trim(); var fieldtype = br.ReadChar(); switch (fieldtype) { case 'L': //_dbaseColumns[i].DataType = typeof (bool); _dbaseColumns[i].DataTypeCode = TypeCode.Boolean; break; case 'C': //_dbaseColumns[i].DataType = typeof (string); _dbaseColumns[i].DataTypeCode = TypeCode.String; break; case 'D': //_dbaseColumns[i].DataType = typeof (DateTime); _dbaseColumns[i].DataTypeCode = TypeCode.DateTime; break; case 'N': //_dbaseColumns[i].DataType = typeof (double); _dbaseColumns[i].DataTypeCode = TypeCode.Double; break; case 'F': //_dbaseColumns[i].DataType = typeof (float); _dbaseColumns[i].DataTypeCode = TypeCode.Single; break; case 'B': //_dbaseColumns[i].DataType = typeof (byte[]); _dbaseColumns[i].DataTypeCode = TypeCode.Object; //Hack for break; default: throw (new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype + "' in column '" + _dbaseColumns[i].ColumnName + "'")); } _dbaseColumns[i].Address = br.ReadInt32(); if (i == 0) //Set it to 0 for first column and calculate it for the rest { _dbaseColumns[i].Address = 0; } else { _dbaseColumns[i].Address = _dbaseColumns[i - 1].Address + _dbaseColumns[i - 1].Length; } var length = (int)br.ReadByte(); if (length < 0) { length = length + 256; } _dbaseColumns[i].Length = length; _dbaseColumns[i].Decimals = br.ReadByte(); //If the double-type doesn't have any decimals, make the type an integer //if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataType == typeof (double)) // if (_dbaseColumns[i].Length <= 2) // _dbaseColumns[i].DataType = typeof (Int16); // else if (_dbaseColumns[i].Length <= 4) // _dbaseColumns[i].DataType = typeof (Int32); // else // _dbaseColumns[i].DataType = typeof (Int64); if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataTypeCode == TypeCode.Double) { if (_dbaseColumns[i].Length < 3) //Range [-9, 99] { _dbaseColumns[i].DataTypeCode = TypeCode.Byte; } else if (_dbaseColumns[i].Length < 5) //Range [-999, 9999] { _dbaseColumns[i].DataTypeCode = TypeCode.Int16; } else if (_dbaseColumns[i].Length < 10) { _dbaseColumns[i].DataTypeCode = TypeCode.Int32; } else if (_dbaseColumns[i].Length < 19) { _dbaseColumns[i].DataTypeCode = TypeCode.Int64; } else { _dbaseColumns[i].DataTypeCode = TypeCode.Double; } } } } //using (var s = GetStream()) //using(var br = new BinaryReader(s)) //{ // if (br.ReadByte() != 0x03) // throw new NotSupportedException("Unsupported DBF Type"); // _lastUpdate = new DateTime(br.ReadByte() + 1900, br.ReadByte(), br.ReadByte()); // //Read the last update date // _numberOfRecords = br.ReadInt32(); // read number of records. // _headerLength = br.ReadInt16(); // read length of header structure. // _recordLength = br.ReadInt16(); // read length of a record // s.Seek(29, SeekOrigin.Begin); //Seek to encoding flag // _fileEncoding = GetDbaseLanguageDriver(br.ReadByte(), filename); //Read and parse Language driver // s.Seek(32, SeekOrigin.Begin); //Move past the reserved bytes // var numberOfColumns = (_headerLength - 31)/32; // calculate the number of DataColumns in the header // _dbaseColumns = new DbaseField[numberOfColumns]; // for (var i = 0; i < _dbaseColumns.Length; i++) // { // _dbaseColumns[i] = new DbaseField(); // _dbaseColumns[i].ColumnName = Encoding.UTF7.GetString((br.ReadBytes(11))).Replace("\0", "").Trim(); // var fieldtype = br.ReadChar(); // switch (fieldtype) // { // case 'L': // //_dbaseColumns[i].DataType = typeof (bool); // _dbaseColumns[i].DataTypeCode = TypeCode.Boolean; // break; // case 'C': // //_dbaseColumns[i].DataType = typeof (string); // _dbaseColumns[i].DataTypeCode = TypeCode.String; // break; // case 'D': // //_dbaseColumns[i].DataType = typeof (DateTime); // _dbaseColumns[i].DataTypeCode = TypeCode.DateTime; // break; // case 'N': // //_dbaseColumns[i].DataType = typeof (double); // _dbaseColumns[i].DataTypeCode = TypeCode.Double; // break; // case 'F': // //_dbaseColumns[i].DataType = typeof (float); // _dbaseColumns[i].DataTypeCode = TypeCode.Single; // break; // case 'B': // //_dbaseColumns[i].DataType = typeof (byte[]); // _dbaseColumns[i].DataTypeCode = TypeCode.Object; //Hack for // break; // default: // throw (new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype + // "' in column '" + _dbaseColumns[i].ColumnName + "'")); // } // _dbaseColumns[i].Address = br.ReadInt32(); // if (i > 0) _dbaseColumns[i].Address = _dbaseColumns[i - 1].Address + _dbaseColumns[i - 1].Length; // var length = (int) br.ReadByte(); // if (length < 0) length = length + 256; // _dbaseColumns[i].Length = length; // _dbaseColumns[i].Decimals = br.ReadByte(); // //If the double-type doesn't have any decimals, make the type an integer // //if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataType == typeof (double)) // // if (_dbaseColumns[i].Length <= 2) // // _dbaseColumns[i].DataType = typeof (Int16); // // else if (_dbaseColumns[i].Length <= 4) // // _dbaseColumns[i].DataType = typeof (Int32); // // else // // _dbaseColumns[i].DataType = typeof (Int64); // if (_dbaseColumns[i].Decimals == 0 && _dbaseColumns[i].DataTypeCode == TypeCode.Double) // { // if (_dbaseColumns[i].Length < 3) //Range [-9, 99] // _dbaseColumns[i].DataTypeCode = TypeCode.Byte; // else if (_dbaseColumns[i].Length < 5) //Range [-999, 9999] // _dbaseColumns[i].DataTypeCode = TypeCode.Int16; // else if (_dbaseColumns[i].Length < 10) // _dbaseColumns[i].DataTypeCode = TypeCode.Int32; // else if (_dbaseColumns[i].Length < 19) // _dbaseColumns[i].DataTypeCode = TypeCode.Int64; // else // _dbaseColumns[i].DataTypeCode = TypeCode.double; // } // br.BaseStream.Seek(s.Position + 14, 0); // } //} _currentRecordBuffer = new byte[_recordLength]; _headerIsParsed = true; CreateBaseTable(); }
private object ReadDbfValue(DbaseField dbf) { var tmpBuffer = new byte[dbf.Length]; Buffer.BlockCopy(_currentRecordBuffer, dbf.Address + 1, tmpBuffer, 0, dbf.Length); string temp; switch (dbf.DataTypeCode) { case TypeCode.String: return(_encoding == null ? _fileEncoding.GetString(tmpBuffer).Replace("\0", "").Trim() : _encoding.GetString(tmpBuffer).Replace("\0", "").Trim()); case TypeCode.Double: temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim(); double dbl; if (double.TryParse(temp, NumberStyles.Float, Nfi, out dbl)) { return(dbl); } return(DBNull.Value); case TypeCode.Byte: temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim(); Byte i8; if (Byte.TryParse(temp, NumberStyles.Integer, Nfi, out i8)) { return(i8); } return(DBNull.Value); case TypeCode.Int16: temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim(); Int16 i16; if (Int16.TryParse(temp, NumberStyles.Integer, Nfi, out i16)) { return(i16); } return(DBNull.Value); case TypeCode.Int32: temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim(); Int32 i32; if (Int32.TryParse(temp, NumberStyles.Integer, Nfi, out i32)) { return(i32); } return(DBNull.Value); case TypeCode.Int64: temp = Encoding.UTF7.GetString(tmpBuffer).Replace("\0", "").Trim(); Int64 i64; if (Int64.TryParse(temp, NumberStyles.Integer, Nfi, out i64)) { return(i64); } return(DBNull.Value); //case "System.Single": case TypeCode.Single: temp = Encoding.UTF8.GetString(tmpBuffer); float f; if (float.TryParse(temp, NumberStyles.Float, Nfi, out f)) { return(f); } return(DBNull.Value); //case "System.Boolean": case TypeCode.Boolean: var tempChar = BitConverter.ToChar(tmpBuffer, 0); return((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y')); //case "System.DateTime": case TypeCode.DateTime: DateTime date; // Mono has not yet implemented DateTime.TryParseExact #if !MONO if (DateTime.TryParseExact(Encoding.UTF7.GetString(tmpBuffer), "yyyyMMdd", Nfi, DateTimeStyles.None, out date)) { return(date); } return(DBNull.Value); #else try { return(date = DateTime.ParseExact(System.Text.Encoding.UTF7.GetString(tmpBuffer), "yyyyMMdd", Nfi, System.Globalization.DateTimeStyles.None)); } catch (Exception e) { return(DBNull.Value); } #endif default: throw (new NotSupportedException("Cannot parse DBase field '" + dbf.ColumnName + "' of type '" + // dbf.DataType + "'")); TypeByTypeCode(dbf.DataTypeCode) + "'")); } // switch (dbf.DataTypeCode) // { // case TypeCode.String: // return _encoding == null // ? _fileEncoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim() // : _encoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim(); // case TypeCode.Double: // temp = Encoding.UTF7.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim(); // double dbl; // if (double.TryParse(temp, NumberStyles.Float, Nfi, out dbl)) // return dbl; // return DBNull.Value; // case TypeCode.Int16: // temp = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim(); // Int16 i16; // if (Int16.TryParse(temp, NumberStyles.Integer, Nfi, out i16)) // return i16; // return DBNull.Value; // case TypeCode.Int32: // temp = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim(); // Int32 i32; // if (Int32.TryParse(temp, NumberStyles.Integer, Nfi, out i32)) // return i32; // return DBNull.Value; // case TypeCode.Int64: // temp = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim(); // Int64 i64; // if (Int64.TryParse(temp, NumberStyles.Integer, Nfi, out i64)) // return i64; // return DBNull.Value; // //case "System.Single": // case TypeCode.Single: // temp = Encoding.UTF8.GetString((br.ReadBytes(dbf.Length))); // float f; // if (float.TryParse(temp, NumberStyles.Float, Nfi, out f)) // return f; // return DBNull.Value; // //case "System.Boolean": // case TypeCode.Boolean: // var tempChar = br.ReadChar(); // return ((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y')); // //case "System.DateTime": // case TypeCode.DateTime: // DateTime date; // // Mono has not yet implemented DateTime.TryParseExact //#if !MONO // if (DateTime.TryParseExact(Encoding.UTF7.GetString((br.ReadBytes(8))), // "yyyyMMdd", Nfi, DateTimeStyles.None, out date)) // return date; // return DBNull.Value; //#else // try // { // return date = DateTime.ParseExact ( System.Text.Encoding.UTF7.GetString((br.ReadBytes(8))), // "yyyyMMdd", SharpMap.Map.numberFormat_EnUS, System.Globalization.DateTimeStyles.None ); // } // catch ( Exception e ) // { // return DBNull.Value; // } //#endif // default: // throw (new NotSupportedException("Cannot parse DBase field '" + dbf.ColumnName + "' of type '" + // // dbf.DataType + "'")); // TypeByTypeCode(dbf.DataTypeCode) + "'")); // } }
private object ReadDbfValue(DbaseField dbf) { switch (dbf.DataType.ToString()) { case "System.String": if (_Encoding == null) { return(_FileEncoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim()); } return(_Encoding.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim()); case "System.Double": string temp = Encoding.UTF7.GetString(br.ReadBytes(dbf.Length)).Replace("\0", "").Trim(); double dbl = 0; if (double.TryParse(temp, NumberStyles.Float, Map.NumberFormatEnUs, out dbl)) { return(dbl); } return(DBNull.Value); case "System.Int16": string temp16 = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim(); Int16 i16 = 0; if (Int16.TryParse(temp16, NumberStyles.Float, Map.NumberFormatEnUs, out i16)) { return(i16); } return(DBNull.Value); case "System.Int32": string temp32 = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim(); Int32 i32 = 0; if (Int32.TryParse(temp32, NumberStyles.Float, Map.NumberFormatEnUs, out i32)) { return(i32); } return(DBNull.Value); case "System.Int64": string temp64 = Encoding.UTF7.GetString((br.ReadBytes(dbf.Length))).Replace("\0", "").Trim(); Int64 i64 = 0; if (Int64.TryParse(temp64, NumberStyles.Float, Map.NumberFormatEnUs, out i64)) { return(i64); } return(DBNull.Value); case "System.Single": string temp4 = Encoding.UTF8.GetString((br.ReadBytes(dbf.Length))); float f = 0; if (float.TryParse(temp4, NumberStyles.Float, Map.NumberFormatEnUs, out f)) { return(f); } return(DBNull.Value); case "System.Boolean": char tempChar = br.ReadChar(); return((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y')); case "System.DateTime": DateTime date; // Mono has not yet implemented DateTime.TryParseExact #if !MONO if (DateTime.TryParseExact(Encoding.UTF7.GetString((br.ReadBytes(8))), "yyyyMMdd", Map.NumberFormatEnUs, DateTimeStyles.None, out date)) { return(date); } return(DBNull.Value); #else try { return(date = DateTime.ParseExact(System.Text.Encoding.UTF7.GetString((br.ReadBytes(8))), "yyyyMMdd", SharpMap.Map.numberFormat_EnUS, System.Globalization.DateTimeStyles.None)); } catch (Exception e) { return(DBNull.Value); } #endif default: throw (new NotSupportedException("Cannot parse DBase field '" + dbf.ColumnName + "' of type '" + dbf.DataType.ToString() + "'")); } }
private void ParseDbfHeader(string filename) { if (br.ReadByte() != 0x03) { throw new NotSupportedException("Unsupported DBF Type"); } _lastUpdate = new DateTime((int)br.ReadByte() + 1900, (int)br.ReadByte(), (int)br.ReadByte()); //Read the last update date _NumberOfRecords = br.ReadInt32(); // read number of records. _HeaderLength = br.ReadInt16(); // read length of header structure. _RecordLength = br.ReadInt16(); // read length of a record fs.Seek(29, SeekOrigin.Begin); //Seek to encoding flag _FileEncoding = GetDbaseLanguageDriver(br.ReadByte()); //Read and parse Language driver fs.Seek(32, SeekOrigin.Begin); //Move past the reserved bytes int NumberOfColumns = (_HeaderLength - 31) / 32; // calculate the number of DataColumns in the header DbaseColumns = new DbaseField[NumberOfColumns]; for (int i = 0; i < DbaseColumns.Length; i++) { DbaseColumns[i] = new DbaseField(); DbaseColumns[i].ColumnName = Encoding.UTF7.GetString((br.ReadBytes(11))).Replace("\0", "").Trim(); char fieldtype = br.ReadChar(); switch (fieldtype) { case 'L': DbaseColumns[i].DataType = typeof(bool); break; case 'C': DbaseColumns[i].DataType = typeof(string); break; case 'D': DbaseColumns[i].DataType = typeof(DateTime); break; case 'N': DbaseColumns[i].DataType = typeof(double); break; case 'F': DbaseColumns[i].DataType = typeof(float); break; case 'B': DbaseColumns[i].DataType = typeof(byte[]); break; default: throw (new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype + "' in column '" + DbaseColumns[i].ColumnName + "'")); } DbaseColumns[i].Address = br.ReadInt32(); int Length = (int)br.ReadByte(); if (Length < 0) { Length = Length + 256; } DbaseColumns[i].Length = Length; DbaseColumns[i].Decimals = (int)br.ReadByte(); //If the double-type doesn't have any decimals, make the type an integer if (DbaseColumns[i].Decimals == 0 && DbaseColumns[i].DataType == typeof(double)) { if (DbaseColumns[i].Length <= 2) { DbaseColumns[i].DataType = typeof(Int16); } else if (DbaseColumns[i].Length <= 4) { DbaseColumns[i].DataType = typeof(Int32); } else { DbaseColumns[i].DataType = typeof(Int64); } } fs.Seek(fs.Position + 14, 0); } HeaderIsParsed = true; CreateBaseTable(); }
internal static DbaseHeader ParseDbfHeader(BinaryReader reader) { DbaseHeader header = new DbaseHeader(); if (reader.ReadByte() != DbaseConstants.DbfVersionCode) { throw new NotSupportedException("Unsupported DBF Type"); } header.LastUpdate = new DateTime((int)reader.ReadByte() + 1900, (int)reader.ReadByte(), (int)reader.ReadByte()); //Read the last update date header.RecordCount = reader.ReadUInt32(); // read number of records. short storedHeaderLength = reader.ReadInt16(); // read length of header structure. short storedRecordLength = reader.ReadInt16(); // read length of a record reader.BaseStream.Seek(DbaseConstants.EncodingOffset, SeekOrigin.Begin); //Seek to encoding flag header.LanguageDriver = reader.ReadByte(); //Read and parse Language driver reader.BaseStream.Seek(DbaseConstants.ColumnDescriptionOffset, SeekOrigin.Begin); //Move past the reserved bytes int numberOfColumns = (storedHeaderLength - DbaseConstants.ColumnDescriptionOffset) / DbaseConstants.ColumnDescriptionLength; // calculate the number of DataColumns in the header DbaseField[] columns = new DbaseField[numberOfColumns]; for (int i = 0; i < columns.Length; i++) { columns[i] = new DbaseField(); columns[i].ColumnName = System.Text.Encoding.UTF7.GetString((reader.ReadBytes(11))).Replace("\0", "").Trim(); char fieldtype = reader.ReadChar(); columns[i].Address = reader.ReadInt32(); short fieldLength = reader.ReadByte(); if (fieldtype == 'N' || fieldtype == 'F') { columns[i].Decimals = reader.ReadByte(); } else { fieldLength += (short)((short)reader.ReadByte() << 8); } columns[i].Length = fieldLength; switch (fieldtype) { case 'L': columns[i].DataType = typeof(bool); break; case 'C': columns[i].DataType = typeof(string); break; case 'D': columns[i].DataType = typeof(DateTime); break; case 'N': //If the number doesn't have any decimals, make the type an integer, if possible if (columns[i].Decimals == 0) { if (columns[i].Length <= 4) { columns[i].DataType = typeof(Int16); } else if (columns[i].Length <= 9) { columns[i].DataType = typeof(Int32); } else if (columns[i].Length <= 18) { columns[i].DataType = typeof(Int64); } else { columns[i].DataType = typeof(double); } } else { columns[i].DataType = typeof(double); } break; case 'F': columns[i].DataType = typeof(float); break; case 'B': columns[i].DataType = typeof(byte[]); break; default: throw new NotSupportedException("Invalid or unknown DBase field type '" + fieldtype + "' in column '" + columns[i].ColumnName + "'"); } // Move stream to next field record reader.BaseStream.Seek(DbaseConstants.BytesFromEndOfDecimalInFieldRecord, SeekOrigin.Current); } header.Columns = columns; if (storedHeaderLength != header.HeaderLength) { throw new Exception("Recorded header length doesn't equal computed header length"); } if (storedRecordLength != header.RecordLength) { throw new Exception("Recorded record length doesn't equal computed record length"); } return(header); }