Simple abstract stream

BlitzMax Forums/BlitzMax Programming/Simple abstract stream

Here is a very simple abstract stream type. You can simply go ReadFile("abstract::readme.txt") and the stream will return any file in any subfolder called "readme.txt".

This allows you to load media and other files without knowing exactly where they are in your directories.

The initialization uses a TMap, so it should be very fast to startup and retrieve files.

Implementing a package file system in the RegisterAbstractPath() routine would make this much more powerful.

Strict

Private
Global AbstractFileMap:TMap=New TMap
Public

Type TAbstractStreamFactory Extends TStreamFactory
	
	Method CreateStream:TStream( url:Object,proto$,path$,readable,writeable )
		If proto<>"abstract" Return Null
		Local filename$
		Local p
		filename=Lower(StripDir(String(url)))
		p=Instr(filename,"::")
		If p filename=Right(filename,Len(filename)-p-1)
		If filename="" Return Null
		filename=String(MapValueForKey(AbstractFileMap,filename))
		If filename<>"" Return ReadStream(filename)
	EndMethod
	
EndType

New TAbstractStreamFactory

Function RegisterAbstractPath(filepath$)	
	Local name$,filename$
	Local d
	d=ReadDir(filepath)
	If Not d Return
	If Right(filepath,1)="/" filepath=Left(filepath,Len(filepath)-1)
	If Right(filepath,1)="" filepath=Left(filepath,Len(filepath)-1)
	Repeat
		filename$=NextFile(d)		
		Select FileType(filepath+"/"+filename)
			Case 0 Exit
			Case 1
				name=Lower(StripDir(filename))
				If MapValueForKey(AbstractFileMap,name) Continue
				MapInsert AbstractFileMap,name,RealPath(filepath+"/"+filename)
			Case 2
				If filename<>"." And filename<>".."
					RegisterAbstractPath(filepath+"/"+filename)
				EndIf
		EndSelect
	Forever
	CloseDir d
EndFunction


'-----------------------------------------------
' Test Program
'-----------------------------------------------

Local stream:TStream

RegisterAbstractPath(AppDir)

stream=ReadFile("abstract::readme.txt")
If Not stream
	Notify "Failed to open abstract stream ~qreadme.txt~q.",1
	End
EndIf

While Not stream.eof()
	Notify stream.readline()
Wend

End