This version adds support for zip packages. So you can retrieve a zipped file anywhere in the subdirectory by just specifying the file name and extension. Perfect for loading media:
Import koriolis.zipstream
Import gman.zipengine
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 Null
Return ReadStream(filename)
EndMethod
EndType
New TAbstractStreamFactory
Function RegisterAbstractPath(filepath$)
Local name$,filename$
Local d
Local zrObject:ZipReader
Local packagefile$
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)
If filename="" Exit
Select FileType(filepath+"/"+filename)
Case 0 Exit
Case 1
name=Lower(StripDir(filename))
If MapValueForKey(AbstractFileMap,name) Continue
MapInsert AbstractFileMap,name,RealPath(filepath+"/"+filename)
'Zip stream support
Select Lower(ExtractExt(filename))
Case "zip","pk3"
packagefile=filename
zrObject=New ZipReader
If zrObject.OpenZip(filename)
For Local i:Int=0 To zrObject.getFileCount()-1
filename$=zrObject.getFileInfo(i).zipFileName
If ExtractExt(filename)<>""
name=Lower(StripDir(filename))
filename="zip::"+packagefile+"//"+filename
If MapValueForKey(AbstractFileMap,name) Continue
MapInsert AbstractFileMap,name,filename
EndIf
Next
zrObject.CloseZip()
EndIf
EndSelect
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~q.",1
End
EndIf
While Not stream.eof()
Notify stream.readline()
Wend
End
|