1 (edited by ninjarat 2007-07-26 19:40:38)

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
The only thing I like better than coffee and gaming is coding!  smile

Re: TIrrStream and TIrrStreamReader

Whee!  I just made some massive changes, but for the better.  I'm almost done with the stream writer too.  Stick around.  :-3

The only thing I like better than coffee and gaming is coding!  smile