Need some help with Streams

BlitzMax Forums/BlitzMax Programming/Need some help with Streams

I need to create a stream that is able to read from an 'area' of an existing stream, a sort of sub stream that can be used as a regular stream (so extended from it).

That is, for example, If I'm reading from a file using a stream, I should be able to define another stream that gets de data from the byte number X of the existing stream, and has a lenth Y.

Something like:


Any help or solution in this direction would be very apreciated.

Can't you just use the same stream and seek to the locations you need, read then seek back?

No, becouse I need to pass this streams to functions like LoadImage and the like, so I need them to be real streams.

Create a Sub-stream type, which takes a TStream, and a start/length.

Then have it perform operations offset on the real stream by start.

eg. Seek(0) would actually translate to Seek(start).

and Eof() is true when _pos = start+length...

etc.

:o)

Yes, that's exactly the idea. I was asking for some help to do this. Any starting point or something. will it work extending the base Stream class or do I have to do something spetial. I mean, there's no 'implements¡ on BlitzMax and I am wondering wich kind of things do I have to keep in mind before proceeding.

[EDIT]
I've seen all base stream is performing operations using a byte ptr over a data buffer. How can I create a new sub-buffer from an existing stream (using the offset and the data size) and use a regular stream from there? Any idea?

Ok I've found it and it was easier than I suspected:
Function CreateSubStream:TStream(Stream:TStream, Pos:Int, Length:Int, MovePos:Int = False) 
	Local OldPos:Int = stream.Pos() 
	?debug
		If Stream = Null Then
			Throw "Stream was null."
		End If
		If pos < 0 Or pos > stream.Size() Then
			Throw "Byte position out of bounds."
		End If
	?
	Try
		stream.Seek(pos) 
	Catch Err:String
		Throw "Stream has to be seekable."
	End Try
	Local B:TBank = CreateBank(Length) 
	ReadBank(b, stream, 0, length) 
	Local NewStream:TStream = OpenStream(B) 
	If MovePos = False Then Stream.Seek(oldpos) 
	Return newstream
End Function

the best thing is that there's no need to create a new class, as I suspected initially, so this way I think it would be much more easy to mantain if there's any bug there.

hmm... maybe something like this :
Type TSubStream Extends TStreamWrapper

	Field start:Int
	Field length:Int
	
	Function Create:TSubStream(stream:TStream, start:Int, length:Int)
		Local this:TSubStream = New TSubStream
		this.SetStream stream
		this.start = start
		this.length = length
		Return this
	End Function
	
	Method Eof:Int()
		Return _stream.Eof() Or (Pos() >= length)
	End Method

	Method Pos:Int()
		Return _stream.Pos() - start
	End Method

	Method Size:Int()
		Return length
	End Method
	
	Method Seek:Int( pos:Int )
		Return _stream.Seek( pos + start )
	End Method

End Type

Untested...

That's a good approach, as my solution my be duplicating data... I'm not sure how I will implement this... thanks!

Do you know if there's any way to create a static bank from a internal stream data bank? that would be the best solution but I haven't find a way to do it.