Skip to content

Commit d4e2921

Browse files
committed
Merge SocialExplorer#9 SlightlyMadGargoyle
1 parent a3f3ce9 commit d4e2921

1 file changed

Lines changed: 52 additions & 6 deletions

File tree

FastDBF/DbfFile.cs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ namespace SocialExplorer.IO.FastDBF
2424
/// This class represents a DBF file. You can create new, open, update and save DBF files using this class and supporting classes.
2525
/// Also, this class supports reading/writing from/to an internet forward only type of stream!
2626
/// </summary>
27-
/// <remarks>
28-
/// TODO: add end of file byte '0x1A' !!!
29-
/// We don't relly on that byte at all, and everything works with or without that byte, but it should be there by spec.
30-
/// </remarks>
3127
public class DbfFile
3228
{
3329

@@ -42,6 +38,10 @@ public class DbfFile
4238
/// </summary>
4339
protected bool _headerWritten = false;
4440

41+
/// <summary>
42+
/// flag that indicates whether a footer update is required
43+
/// </summary>
44+
protected bool _footerUpdateNeeded = false;
4545

4646
/// <summary>
4747
/// Streams to read and write to the DBF file.
@@ -204,13 +204,19 @@ public void Close()
204204
if (_header.IsDirty)
205205
WriteHeader();
206206

207-
207+
//try to update the footer if the file has been udpated
208+
//------------------------------------------
209+
if (_footerUpdateNeeded)
210+
WriteFooter();
208211

209212
//Empty header...
210213
//--------------------------------
211214
_header = new DbfHeader(encoding);
212215
_headerWritten = false;
213216

217+
//Clear the footer required flag
218+
//------------------------------------------
219+
_footerUpdateNeeded = false;
214220

215221
//reset current record index
216222
//--------------------------------
@@ -548,6 +554,7 @@ public void Update(DbfRecord orec)
548554
//write
549555
orec.Write(_dbfFile);
550556

557+
_footerUpdateNeeded = true;
551558

552559
}
553560

@@ -569,6 +576,7 @@ public bool WriteHeader()
569576
_dbfFileWriter.Seek(0, SeekOrigin.Begin);
570577
_header.Write(_dbfFileWriter);
571578
_headerWritten = true;
579+
_footerUpdateNeeded = true;
572580
return true;
573581
}
574582
else
@@ -578,15 +586,53 @@ public bool WriteHeader()
578586
_header.Write(_dbfFileWriter);
579587

580588
_headerWritten = true;
581-
589+
_footerUpdateNeeded = true;
582590
}
583591
}
584592

585593
return false;
586594

587595
}
588596

597+
public bool WriteFooter()
598+
{
599+
// return false if it's not possible to write.
600+
if (_dbfFileWriter == null)
601+
{
602+
return false;
603+
}
604+
605+
606+
//if stream can not seek, then just write it out and that's it.
607+
if (!_dbfFileWriter.BaseStream.CanSeek)
608+
{
609+
_dbfFileWriter.Write((byte)0x1A);
610+
return true;
611+
}
612+
613+
var streamLength = _dbfFileWriter.BaseStream.Length;
614+
var expectedLength = Header.HeaderLength + Header.RecordCount * Header.RecordLength + 1;
615+
616+
// If the length of the stream is the same as the expected length, seek ready to re-write the last byte.
617+
if (streamLength == expectedLength)
618+
{
619+
_dbfFileWriter.BaseStream.Seek(-1, SeekOrigin.End);
620+
}
621+
// If the length of the stream is one less than expected length, seek ready to append the last byte.
622+
else if (streamLength == expectedLength - 1)
623+
{
624+
_dbfFileWriter.BaseStream.Seek(0, SeekOrigin.End);
625+
}
626+
// Otherwise, something isn't right. return false.
627+
else
628+
{
629+
return false;
630+
}
589631

632+
// Write the last byte and return true
633+
_dbfFileWriter.Write((byte)0x1A);
634+
return true;
635+
}
590636

591637
/// <summary>
592638
/// Access DBF header with information on columns. Use this object for faster access to header.

0 commit comments

Comments
 (0)