AbstractStream update
BlitzMax Forums/BlitzMax Programming/AbstractStream update
| ||
| This modification will allow you to either specify just the file name to load: ReadFile("abstract::test.md3") Or you can also just specify the name with no extension: ReadFile("abstract::test") Obviously you can only have one file named "test.xxx" if you only use the name with no extension. This is useful for loading media when you don't know or care exactly where it may be located. It will automatically detect and read files within zip packages (requires gman.zipengine and koriolis.zipstream). Private
Global AbstractFileMap:TMap[2]
AbstractFileMap[0]=New TMap
AbstractFileMap[1]=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
If ExtractExt(filename)=""
filename=String(MapValueForKey(AbstractFileMap[1],filename))
Else
filename=String(MapValueForKey(AbstractFileMap[0],filename))
EndIf
If filename="" Return Null
Return ReadStream(filename)
EndMethod
EndType
New TAbstractStreamFactory
Function AbstractFileExists:Int(name$)
If ExtractExt(name)=""
If String(MapValueForKey(AbstractFileMap[1],Lower(name)))<>"" Return 1
Else
If String(MapValueForKey(AbstractFileMap[0],Lower(name)))<>"" Return 1
EndIf
EndFunction
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[0],name) Continue
MapInsert AbstractFileMap[0],name,RealPath(filepath+"/"+filename)
If Not MapValueForKey(AbstractFileMap[1],StripExt(name))
MapInsert AbstractFileMap[1],StripExt(name),RealPath(filepath+"/"+filename)
EndIf
'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[0],name) Continue
MapInsert AbstractFileMap[0],name,filename
If Not MapValueForKey(AbstractFileMap[1],StripExt(name))
MapInsert AbstractFileMap[1],StripExt(name),filename
EndIf
EndIf
Next
zrObject.CloseZip()
EndIf
EndSelect
Case 2
If filename<>"." And filename<>".."
RegisterAbstractPath(filepath+"/"+filename)
EndIf
EndSelect
Forever
CloseDir d
EndFunction
Rem
'-----------------------------------------------
' 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
endrem |