Topic: TIrrStream and TIrrStreamReader
Check it out! More excerpts from my engine. This particular class doesn't use any other objects in my engine, so you can use it as is. Oh, except it does get the file system manager from my TIrrContainer object. You can get around that by replacing 'IrrContainer.IrrFileSys' with 'device.getFileSystem()'. It basically creates an advanced blitz-like stream reader based in the Irrlicht file system manager.
Special thanks to Mark and Simon. I could never have made this if I hadn't had a good look at their stream module first.
EDIT: Fixed an issue with ReadLine. When reading last line of text from the read target, an attempt to access null memory error occurred. I found a spot where I was freeing some memory when I shouldn't have. All cleared up now. I had to fix it the hard way, because the debug build worked for some reason. Probably a difference in garbage collection.
EDIT: Restructured for the addition of a stream writer object. Yay! Same basic use, mostly just stuff behind the scenes changed. You'll find that with the new version you'll have to use TIrrStreamReader(irrstreamobject) to get access to the functions, but these changes will make it more efficient in the long run. I swear.
'RCD Software (TM)
'by ninjarat
'This is part of the RCD Irrlicht Addons
Const STREAM_TARGET_UNDEFINED=-1
Const STREAM_TARGET_FILE=0
Const STREAM_TARGET_RAM=1
'irrlicht stream base class
Type TIrrStreamBase
Field irrstream:TIrr_IUnknown
Field pos,size,fname$
Field endoffile=False
Field irrstreamtype=-1
Function create:TIrrStreamBase(file$)
Return New TIrrStreamBase
End Function
Function createFromRAM:TIrrStreamBase(name$,buffer:Byte Ptr,buflength)
Return New TIrrStreamBase
End Function
Method _reader:IReadFile()
Return IReadFile(irrstream)
End Method
Method _writer:IWriteFile()
Return IWriteFile(irrstream)
End Method
Method _setreader(r:IReadFile)
irrstream=r
End Method
Method _setwriter(w:IWriteFile)
irrstream=w
End Method
Method GetType()
Return irrstreamtype
End Method
Method Eof()
Return endoffile
End Method
Method GetSize()
Return size
End Method
Method GetPos()
Return pos
End Method
Method GetFName$()
Return fname
End Method
Method Destroy()
If irrstream Then irrstream.drop
End Method
Method ToString$()
str$="Stream Object~n~r"
If IReadFile(irrstream) Then
str:+"type:STREAM_TYPE_READ~n~r"
Else If IWriteFile(irrstream) Then
str:+"type:STREAM_TYPE_WRITE~n~r"
Else
str:+"type:STREAM_TYPE_NULLOBJECT~n~r"
End If
str:+"pos:"+pos+"~n~rsize:"+size+"~n~rname:"+..
fname+"~n~reof:"+TrFs(endoffile)+"~n~rtarget:"
If irrstreamtype=0 Then
str:+"STREAM_TARGET_FILE~n~r"
Else If irrstreamtype=1 Then
str:+"STREAM_TARGET_RAM~n~r"
Else
str:+"STREAM_TARGET_UNDEFINED~n~r"
End If
Return str
End Method
End Type
'extends irrlicht stream base in to a stream reader
Type TIrrStreamReader Extends TIrrStreamBase
Function create:TIrrStreamBase(file$)
read:TIrrStreamReader=New TIrrStreamReader
read._init1(file,0)
Return read
End Function
Function createFromRAM:TIrrStreamBase(name$,buffer:Byte Ptr,buflength)
read:TIrrStreamReader=New TIrrStreamReader
read._init2(name,buffer,buflength,1)
Return read
End Function
Method _init1(file$,mode)
_setreader TIrrContainer.IrrFileSys.createAndOpenFile(file)
fname=_reader().getFileName()
pos=_reader().getPos()
size=_reader().getSize()
irrstreamtype=mode
End Method
Method _init2(name$,buffer:Byte Ptr,buflength,mode)
_setreader TIrrContainer.IrrFileSys.createMemoryReadFile(buffer,buflength,name)
fname=_reader().getFileName()
pos=_reader().getPos()
size=_reader().getSize()
irrstreamtype=mode
End Method
Method Read(buffer:Byte Ptr,numbytes)
bytesread=_reader().read(buffer,numbytes)
pos=_reader().getPos()
If bytesread<numbytes Or pos>=size Then
endoffile=True
Return False
End If
Return True
End Method
Method Seek(pos,relativemove=False)
If Not _reader().seek(pos,relativemove) Then Return False
Return True
End Method
Method Eof()
Return endoffile
End Method
Method GetSize()
size=_reader().getSize()
Return size
End Method
Method GetPos()
pos=_reader().getPos()
Return pos
End Method
Method ReadByte:Byte()
If endoffile Then Return Null
n:Byte=0
If Not Read(Varptr n,1) Then n=Null
Return n
End Method
Method ReadShort:Short()
If endoffile Then Return Null
n:Short=0
If Not Read(Varptr n,2) Then n=Null
Return n
End Method
Method ReadInt()
If endoffile Then Return Null
n=0
If Not Read(Varptr n,4) Then n=Null
Return n
End Method
Method ReadLong:Long()
If endoffile Then Return Null
n:Long=0
If Not Read(Varptr n,4) Then n=Null
Return n
End Method
Method ReadString$(numbytes)
Assert numbytes>0, "Byte length must be greater than 0"
If endoffile Then Return Null
Local buffer:Byte[numbytes]
If Not Read(buffer,numbytes) Then n=Null
Return String.FromBytes(buffer,numbytes)
End Method
Method ReadLine$()
If endoffile Then Return Null
Local buffer:Byte[1024],str$,char:Byte
Repeat
If Not Read(Varptr char,1) Then Exit
If char=0 Then Exit
If char=10 Then Exit
If char=13 Then Continue
buffer[posi]=char
posi:+1
If p<>buffer.length Then Continue
str:+String.FromBytes(buffer,posi)
posi=0
Forever
If posi Then str:+String.FromBytes(buffer,posi)
Return str
End Method
End Type
'extends irrlicht stream base in to a stream writer
'not yet added, as you can see.
'Type TIrrStreamWriter Extends TIrrStreamBase
' Function create:TIrrStreamWriter()
' End Function
'End Type
Const STREAM_TYPE_READ=0
Const STREAM_TYPE_WRITE=1
Function CreateIrrStream:TIrrStreamBase(file$,mode=STREAM_TYPE_READ)
Select mode
Case STREAM_TYPE_READ Return TIrrStreamReader.Create(file)
Case STREAM_TYPE_WRITE Return Null 'not yet supported
End Select
End Function
Function CreateIrrRAMStream:TIrrStreamBase(name$,buffer:Byte Ptr,buflength,mode=STREAM_TYPE_READ)
Select mode
Case STREAM_TYPE_READ Return TIrrStreamReader.CreateFromRAM(name,buffer,buflength)
Case STREAM_TYPE_WRITE Return Null 'not yet supported
End Select
End Function