'
' File Stream
' version 0.1
' (c) 2011 Stefan Wurzinger
'

Type FileStream
	
	Public:
	
	FileName As String
	
	Declare Function ReadData(Buffer As ZString Ptr, MaxLen As UInteger) As UInteger
	Declare Function ReadByte() As UByte
	Declare Function atEOF() As Integer
	Declare Sub CloseStream()
	
	Declare Property Position() As UInteger
	Declare Property Length() As UInteger
	
	Declare Constructor(FileName As String)
	Declare Destructor()
	
	Private:
	
	Declare Sub fillBuffer(filePos As UInteger)
	
	Const bufLen As Integer = 1024*4
	fileBuf As String * (bufLen+1)
	filePos As UInteger = 0
	fileLength As UInteger = 0
	fileNo As UInteger = FreeFile()
	bufPos As UInteger = 0
	isOpen As Integer = -1
	
End Type

Property FileStream.Position() As UInteger
	Return this.filePos
End Property

Property FileStream.Length() As UInteger
	Return this.fileLength
End Property

Constructor FileStream (FileName As String)
  this.FileName = FileName
  Open FileName For Binary As #this.fileNo
  fileLength = Lof(fileNo)
End Constructor

Destructor FileStream ()
	this.CloseStream()
End Destructor

Function FileStream.ReadByte() As UByte
	If fileLength = 0 Then Return 0
	If atEOF Then Return 0
	If bufPos = 0 Or filePos >= bufPos+bufLen Then fillBuffer(filePos+1)
	filePos += 1
	Return fileBuf[filePos-bufPos]
End Function

Function FileStream.ReadData(Buffer As ZString Ptr, MaxLen As UInteger) As UInteger
	Dim cntBytes As UInteger = 0
	For q As UInteger = 0 To MaxLen-1
		If atEOF Then Exit For
		Buffer[q] = this.ReadByte()
		cntBytes += 1
	Next
	Return cntBytes
End Function



Function FileStream.atEOF() As Integer
	Return filePos = fileLength
End Function

Sub FileStream.CloseStream()
	If isOpen then
	  Close #this.fileNo
	  fileLength = 0
	  filePos = 0
	  this.isOpen = 0
	End If
End Sub

Private Sub FileStream.fillBuffer(filePos As UInteger)
	Get #fileNo,filePos,fileBuf
	bufPos = filePos
End Sub
