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. |