Index: src/Common/NetTopologySuite/IO/GeoTools/Dbase/DbaseFileReader.cs
===================================================================
diff -u -r8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9 -r5fc71a385897af92ccb092f2f969b5709afab85a
--- src/Common/NetTopologySuite/IO/GeoTools/Dbase/DbaseFileReader.cs (.../DbaseFileReader.cs) (revision 8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9)
+++ src/Common/NetTopologySuite/IO/GeoTools/Dbase/DbaseFileReader.cs (.../DbaseFileReader.cs) (revision 5fc71a385897af92ccb092f2f969b5709afab85a)
@@ -6,51 +6,130 @@
namespace GisSharpBlog.NetTopologySuite.IO
{
- ///
- /// Class that allows records in a dbase file to be enumerated.
- ///
- public class DbaseFileReader : IEnumerable
- {
+ ///
+ /// Class that allows records in a dbase file to be enumerated.
+ ///
+ public class DbaseFileReader : IEnumerable
+ {
+ private DbaseFileHeader _header = null;
+ private readonly string _filename;
+
+ #region Constructors
+
///
+ /// Initializes a new instance of the DbaseFileReader class.
+ ///
+ ///
+ public DbaseFileReader(string filename)
+ {
+ if (filename == null)
+ {
+ throw new ArgumentNullException(filename);
+ }
+ // check for the file existing here, otherwise we will not get an error
+ //until we read the first record or read the header.
+ if (!File.Exists(filename))
+ {
+ throw new FileNotFoundException(String.Format("Could not find file \"{0}\"", filename));
+ }
+ _filename = filename;
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Gets the header information for the dbase file.
+ ///
+ /// DbaseFileHeader contain header and field information.
+ public DbaseFileHeader GetHeader()
+ {
+ if (_header == null)
+ {
+ FileStream stream = new FileStream(_filename, FileMode.Open, FileAccess.Read);
+ BinaryReader dbfStream = new BinaryReader(stream);
+
+ _header = new DbaseFileHeader();
+ // read the header
+ _header.ReadHeader(dbfStream);
+
+ dbfStream.Close();
+ stream.Close();
+ }
+ return _header;
+ }
+
+ #endregion
+
+ #region Implementation of IEnumerable
+
+ ///
+ /// Gets the object that allows iterating through the members of the collection.
+ ///
+ ///
+ /// An object that implements the IEnumerator interface.
+ ///
+ public IEnumerator GetEnumerator()
+ {
+ return new DbaseFileEnumerator(this);
+ }
+
+ #endregion
+
+ ///
///
///
- private class DbaseFileEnumerator : IEnumerator, IDisposable
- {
- DbaseFileReader _parent;
- ArrayList _arrayList;
- int _iCurrentRecord=0;
- private BinaryReader _dbfStream = null;
- private int _readPosition = 0;
- private DbaseFileHeader _header = null;
- protected string[] _fieldNames = null;
+ private class DbaseFileEnumerator : IEnumerator, IDisposable
+ {
+ protected string[] _fieldNames = null;
+ private DbaseFileReader _parent;
+ private ArrayList _arrayList;
+ private int _iCurrentRecord = 0;
+ private readonly BinaryReader _dbfStream = null;
+ private int _readPosition = 0;
+ private DbaseFileHeader _header = null;
///
/// Initializes a new instance of the class.
///
///
public DbaseFileEnumerator(DbaseFileReader parent)
- {
- _parent = parent;
- FileStream stream = new FileStream(parent._filename, FileMode.Open, FileAccess.Read, FileShare.Read);
- _dbfStream = new BinaryReader(stream, Encoding.Default);
- ReadHeader();
- }
+ {
+ _parent = parent;
+ FileStream stream = new FileStream(parent._filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+ _dbfStream = new BinaryReader(stream, Encoding.Default);
+ ReadHeader();
+ }
- #region Implementation of IEnumerator
+ #region IDisposable Members
///
+ /// Performs application-defined tasks associated with freeing, releasing,
+ /// or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ _dbfStream.Close();
+ }
+
+ #endregion
+
+ #region Implementation of IEnumerator
+
+ ///
/// Sets the enumerator to its initial position, which is
/// before the first element in the collection.
///
///
/// The collection was modified after the enumerator was created.
///
- public void Reset()
- {
+ public void Reset()
+ {
_dbfStream.BaseStream.Seek(_header.HeaderLength, SeekOrigin.Begin);
_iCurrentRecord = 0;
- //throw new InvalidOperationException();
- }
+ //throw new InvalidOperationException();
+ }
///
/// Advances the enumerator to the next element of the collection.
@@ -62,19 +141,21 @@
///
/// The collection was modified after the enumerator was created.
///
- public bool MoveNext()
- {
- _iCurrentRecord++;
- if (_iCurrentRecord <= _header.NumRecords)
- _arrayList = this.Read();
- bool more= true;
- if (_iCurrentRecord > _header.NumRecords)
- {
- //this._dbfStream.Close();
- more = false;
- }
- return more;
- }
+ public bool MoveNext()
+ {
+ _iCurrentRecord++;
+ if (_iCurrentRecord <= _header.NumRecords)
+ {
+ _arrayList = Read();
+ }
+ bool more = true;
+ if (_iCurrentRecord > _header.NumRecords)
+ {
+ //this._dbfStream.Close();
+ more = false;
+ }
+ return more;
+ }
///
/// Gets the current element in the collection.
@@ -85,226 +166,156 @@
/// The enumerator is positioned before the first element of the collection
/// or after the last element.
///
- public object Current
- {
- get
- {
- return _arrayList;
- }
- }
+ public object Current
+ {
+ get
+ {
+ return _arrayList;
+ }
+ }
///
///
///
- protected void ReadHeader()
- {
- _header = new DbaseFileHeader();
- // read the header
- _header.ReadHeader(_dbfStream);
+ protected void ReadHeader()
+ {
+ _header = new DbaseFileHeader();
+ // read the header
+ _header.ReadHeader(_dbfStream);
- // how many records remain
- _readPosition = _header.HeaderLength;
- }
+ // how many records remain
+ _readPosition = _header.HeaderLength;
+ }
- ///
- /// Read a single dbase record
- ///
- ///
- /// The read shapefile record,
- /// or null if there are no more records.
- ///
- private ArrayList Read()
- {
- ArrayList attrs = null;
-
- bool foundRecord = false;
- while (!foundRecord)
- {
- // retrieve the record length
- int tempNumFields = _header.NumFields;
-
- // storage for the actual values
- attrs = new ArrayList(tempNumFields);
-
- // read the deleted flag
- char tempDeleted = (char)_dbfStream.ReadChar();
-
- // read the record length
- int tempRecordLength = 1; // for the deleted character just read.
-
- // read the Fields
- for (int j = 0; j < tempNumFields; j++)
- {
- // find the length of the field.
- int tempFieldLength = _header.Fields[j].Length;
- tempRecordLength = tempRecordLength + tempFieldLength;
-
- // find the field type
- char tempFieldType = _header.Fields[j].DbaseType;
-
- // read the data.
- object tempObject = null;
- switch (tempFieldType)
- {
- case 'L': // logical data type, one character (T,t,F,f,Y,y,N,n)
- char tempChar = (char)_dbfStream.ReadByte();
- if ((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y'))
- tempObject = true;
- else tempObject = false;
- break;
+ ///
+ /// Read a single dbase record
+ ///
+ ///
+ /// The read shapefile record,
+ /// or null if there are no more records.
+ ///
+ private ArrayList Read()
+ {
+ ArrayList attrs = null;
- case 'C': // character record.
- char[] sbuffer = new char[tempFieldLength];
- sbuffer = _dbfStream.ReadChars(tempFieldLength);
- // use an encoding to ensure all 8 bits are loaded
- // tempObject = new string(sbuffer, "ISO-8859-1").Trim();
+ bool foundRecord = false;
+ while (!foundRecord)
+ {
+ // retrieve the record length
+ int tempNumFields = _header.NumFields;
- //HACK: this can be made more efficient
- tempObject = new string(sbuffer).Trim().Replace("\0",String.Empty); //.ToCharArray();
- break;
-
- case 'D': // date data type.
- char[] ebuffer = new char[8];
- ebuffer = _dbfStream.ReadChars(8);
- string tempString = new string(ebuffer, 0, 4);
+ // storage for the actual values
+ attrs = new ArrayList(tempNumFields);
- int year;
- if (!Int32.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out year))
- break;
- tempString = new string(ebuffer, 4, 2);
+ // read the deleted flag
+ char tempDeleted = (char) _dbfStream.ReadChar();
- int month;
- if (!Int32.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out month))
- break;
- tempString = new string(ebuffer, 6, 2);
-
- int day;
- if (!Int32.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out day))
- break;
+ // read the record length
+ int tempRecordLength = 1; // for the deleted character just read.
- tempObject = new DateTime(year, month, day);
- break;
-
- case 'N': // number
- case 'F': // floating point number
- char[] fbuffer = new char[tempFieldLength];
- fbuffer = _dbfStream.ReadChars(tempFieldLength);
- tempString = new string(fbuffer);
- try
- {
- tempObject = Double.Parse(tempString.Trim(), CultureInfo.InvariantCulture);
- }
- catch (FormatException)
- {
- // if we can't format the number, just save it as a string
- tempObject = tempString;
- }
- break;
-
- default:
- throw new NotSupportedException("Do not know how to parse Field type "+tempFieldType);
- }
- attrs.Add(tempObject);
- }
-
- // ensure that the full record has been read.
- if (tempRecordLength < _header.RecordLength)
- {
- byte[] tempbuff = new byte[_header.RecordLength-tempRecordLength];
- tempbuff = _dbfStream.ReadBytes(_header.RecordLength-tempRecordLength);
- }
-
- // add the row if it is not deleted.
- if (tempDeleted != '*')
- {
- foundRecord = true;
- }
- }
- return attrs;
- }
+ // read the Fields
+ for (int j = 0; j < tempNumFields; j++)
+ {
+ // find the length of the field.
+ int tempFieldLength = _header.Fields[j].Length;
+ tempRecordLength = tempRecordLength + tempFieldLength;
- #endregion
+ // find the field type
+ char tempFieldType = _header.Fields[j].DbaseType;
- #region IDisposable Members
+ // read the data.
+ object tempObject = null;
+ switch (tempFieldType)
+ {
+ case 'L': // logical data type, one character (T,t,F,f,Y,y,N,n)
+ char tempChar = (char) _dbfStream.ReadByte();
+ if ((tempChar == 'T') || (tempChar == 't') || (tempChar == 'Y') || (tempChar == 'y'))
+ {
+ tempObject = true;
+ }
+ else
+ {
+ tempObject = false;
+ }
+ break;
- ///
- /// Performs application-defined tasks associated with freeing, releasing,
- /// or resetting unmanaged resources.
- ///
- public void Dispose()
- {
- _dbfStream.Close();
- }
+ case 'C': // character record.
+ char[] sbuffer = new char[tempFieldLength];
+ sbuffer = _dbfStream.ReadChars(tempFieldLength);
+ // use an encoding to ensure all 8 bits are loaded
+ // tempObject = new string(sbuffer, "ISO-8859-1").Trim();
- #endregion
- }
+ //HACK: this can be made more efficient
+ tempObject = new string(sbuffer).Trim().Replace("\0", String.Empty); //.ToCharArray();
+ break;
- private DbaseFileHeader _header = null;
- private string _filename;
+ case 'D': // date data type.
+ char[] ebuffer = new char[8];
+ ebuffer = _dbfStream.ReadChars(8);
+ string tempString = new string(ebuffer, 0, 4);
- #region Constructors
+ int year;
+ if (!Int32.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out year))
+ {
+ break;
+ }
+ tempString = new string(ebuffer, 4, 2);
- ///
- /// Initializes a new instance of the DbaseFileReader class.
- ///
- ///
- public DbaseFileReader(string filename)
- {
- if (filename==null)
- {
- throw new ArgumentNullException(filename);
- }
- // check for the file existing here, otherwise we will not get an error
- //until we read the first record or read the header.
- if (!File.Exists(filename))
- {
- throw new FileNotFoundException(String.Format("Could not find file \"{0}\"",filename));
- }
- _filename = filename;
-
- }
-
- #endregion
+ int month;
+ if (!Int32.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out month))
+ {
+ break;
+ }
+ tempString = new string(ebuffer, 6, 2);
- #region Methods
+ int day;
+ if (!Int32.TryParse(tempString, NumberStyles.Integer, CultureInfo.InvariantCulture, out day))
+ {
+ break;
+ }
- ///
- /// Gets the header information for the dbase file.
- ///
- /// DbaseFileHeader contain header and field information.
- public DbaseFileHeader GetHeader()
- {
- if (_header==null)
- {
- FileStream stream = new FileStream(_filename, FileMode.Open, FileAccess.Read);
- BinaryReader dbfStream = new BinaryReader(stream);
+ tempObject = new DateTime(year, month, day);
+ break;
- _header = new DbaseFileHeader();
- // read the header
- _header.ReadHeader(dbfStream);
+ case 'N': // number
+ case 'F': // floating point number
+ char[] fbuffer = new char[tempFieldLength];
+ fbuffer = _dbfStream.ReadChars(tempFieldLength);
+ tempString = new string(fbuffer);
+ try
+ {
+ tempObject = Double.Parse(tempString.Trim(), CultureInfo.InvariantCulture);
+ }
+ catch (FormatException)
+ {
+ // if we can't format the number, just save it as a string
+ tempObject = tempString;
+ }
+ break;
- dbfStream.Close();
- stream.Close();
+ default:
+ throw new NotSupportedException("Do not know how to parse Field type " + tempFieldType);
+ }
+ attrs.Add(tempObject);
+ }
- }
- return _header;
- }
-
- #endregion
+ // ensure that the full record has been read.
+ if (tempRecordLength < _header.RecordLength)
+ {
+ byte[] tempbuff = new byte[_header.RecordLength - tempRecordLength];
+ tempbuff = _dbfStream.ReadBytes(_header.RecordLength - tempRecordLength);
+ }
- #region Implementation of IEnumerable
+ // add the row if it is not deleted.
+ if (tempDeleted != '*')
+ {
+ foundRecord = true;
+ }
+ }
+ return attrs;
+ }
- ///
- /// Gets the object that allows iterating through the members of the collection.
- ///
- ///
- /// An object that implements the IEnumerator interface.
- ///
- public IEnumerator GetEnumerator()
- {
- return new DbaseFileEnumerator(this);
- }
-
- #endregion
- }
-}
+ #endregion
+ }
+ }
+}
\ No newline at end of file