File Wrapper: Mehrere Files in eins packen

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

BtbN

Betreff: File Wrapper: Mehrere Files in eins packen

BeitragDi, Nov 22, 2005 20:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
Strict

Rem
bbdoc: File Wrapper
End Rem
Module BtbN.FileWrapper

ModuleInfo "Version: 1.20"
ModuleInfo "Author: BtbN"
ModuleInfo "License: Public"
ModuleInfo "Modserver: BtbN"
ModuleInfo "Thx to: Henry für die hilfe bei der ZLib"

ModuleInfo "History: 1.20 Release"
ModuleInfo "History: ZLib-Funktionalität hinzugefügt"
ModuleInfo "History: Kleinere Unschönheiten geglättet"

Import Brl.System
Import Brl.Bank
Import Brl.Retro
Import Brl.Basic
Import Brl.BankStream
Import Brl.FileSystem
Import Brl.linkedlist
Import Brl.Math
Import Pub.ZLib

Rem
bbdoc: Läd ein existierendes Wrapped-File
End Rem
Function LoadWrappedFile:TWrapFile(fpath:String)
 Return TWrapFile.Load(fpath)
EndFunction

Rem
bbdoc: Erstellt ein Leeres Wrapped-File
about: Achtung! Das File wird noch nicht gespeichert, nur in den RAM geladen.
End Rem
Function NewWrappedFile:TWrapFile(fpath:String)
 Return TWrapFile.Create(fpath)
EndFunction

Rem
bbdoc: Speichert das angegebene Wrapped-File am im Wrapped-File angegebenen Ort.
End Rem
Function SaveWrappedFile(wrfile:TWrapFile)
 Return wrfile.Save()
EndFunction

Rem
bbdoc: Zip't sämtliche Virutelle Files eines Wrapped Files
End Rem
Function ZipWrappedFile(wrfile:TWrapFile)
 Return wrfile.Zip()
EndFunction

Rem
bbdoc: EntZip't sämtliche Virutelle Files eines Wrapped Files
End Rem
Function UnZipWrappedFile(wrfile:TWrapFile)
 Return wrfile.UnZip()
EndFunction

Rem
bbdoc: Fügt ein existierendes Virtuelles-File zum Wrapped-File hinzu.
End Rem
Function AddVirtualFile(wrfile:TWrapFile,vfile:TVirtualFile)
 Return wrfile.AddVFile(vfile)
EndFunction

Rem
bbdoc: Fügt ein File zum Wrapped-File hinzu.
about: Diese Funktion erstellt zunächst ein Virtuelles File, und hängt dieses dann an das Wrapped-File an.
End Rem
Function AddFile(wrfile:TWrapFile,fpath:String,fname:String)
 If Not wrfile Then Return 0
 If FileType(fpath) <> 1 Then Return 0
 If Trim(fname) = "" Then Return
 Local tempv:TVirtualFile = TVirtualFile.Open(fpath:String,fname:String)
 Return wrfile.AddVFile(tempv)
End Function

Rem
bbdoc: Löscht ein angefügtes Virutelles File anhand dessen Namen.
End Rem
Function RemoveVirtualFile(wrfile:TWrapFile,seeked:String)
 Return wrfile.RemoveVFile(seeked)
EndFunction

Rem
bbdoc: Setzt den Pfad, wo das Wrapped-File gespeichert wird.
End Rem
Function SetPath(wrfile:TWrapFile,fpath:String)
 wrfile.path = fpath
EndFunction


Rem
bbdoc: Setz das aktivierte Virtuelle File anhand dessen Namen.
End Rem
Function SetAktiveFile(wrfile:TWrapFile,seeked:String)
 Return wrfile.SetAktFile(seeked)
EndFunction

Rem
bbdoc: Speichert das angegebene Wrapped-File am im Wrapped-File angegebenen Ort.
End Rem
Function SaveAktiveFile(wrfile:TWrapFile,fpath:String)
 Return wrfile.SaveAktFile(fpath)
EndFunction

Rem
bbdoc: Zip't das aktivierte Virutlle File.
End Rem
Function ZipAktiveFile(wrfile:TWrapFile)
 Return wrfile.aktfile.Zip()
EndFunction

Rem
bbdoc: EntZip't das aktivierte Virutlle File.
End Rem
Function UnZipAktiveFile(wrfile:TWrapFile)
 Return wrfile.aktfile.UnZip()
EndFunction

Global TWrapFileTempBank:TBank = CreateBank()
Rem
bbdoc: Wrapped-File
about: Man kann mit den Standart-Stream-Funktionen aus diesem Type lesen.<br>Dabei wird immer aus dem aktuell aktivierten Virtullen File gelesen.
End Rem
Type TWrapFile Extends TStream

   Field path:String
   Field filesin:Long
   Field files:TList
   Field aktfile:TVirtualFile

   Rem
   bbdoc: Läd ein existierendes Wrapped-File
   End Rem
   Function Load:TWrapFile(fpath:String)
      If FileType(fpath) <> 1 Then Return Null
      Local ifile:TStream = ReadFile(fpath)
      If Not ifile Then Return Null
      Local filesin:Long = ReadLong(ifile)
      Local filearray:TVirtualFile[filesin]
      Local k:Long,iSize:Long,iName:String,iPath:String,vtf:TVirtualFile,iZip:Byte
      Local tmp:TWrapFile = New TWrapFile
      tmp.path = fpath
      tmp.filesin = filesin
      tmp.files = New TList
      For k = 0 To filesin-1
         iName = ReadLine(ifile)
         iPath = "/"+iName
         iZip = ReadByte(ifile)
         iSize = ReadLong(ifile)
         ResizeBank(TWrapFileTempBank,iSize)
         ReadBank(TWrapFileTempBank,ifile,0,iSize)
         vtf = TVirtualFile.Add(iName,iPath,TWrapFileTempBank)
         vtf.iszip = iZip
         ResizeBank(TWrapFileTempBank,0)
         tmp.files.AddLast(vtf)
         tmp.aktfile = vtf
         vtf = Null
      Next
      CloseFile(ifile)
      Return tmp
   End Function

   Rem
   bbdoc: Erstellt ein Leeres Wrapped-File
   about: Achtung! Das File wird noch nicht gespeichert, nur in den RAM geladen.
   End Rem
   Function Create:TWrapFile(fpath:String)
      Local tmp:TWrapFile = New TWrapFile
      tmp.path = fpath
      tmp.filesin = 0
      tmp.files = New TList
      Return tmp
   EndFunction
   
   Rem
   bbdoc: Speichert ein Wrapped-File am im Type angegebenen(self.path) angegebenen Ort
   End Rem
   Method Save()
      Local k:TVirtualFile
      Local ifile:TStream = WriteFile(self.path)
      If Not ifile Return False
      ifile.WriteLong(CountList(self.files))
      For k = EachIn self.files
         ifile.WriteLine(k.name)
         ifile.WriteByte(k.iszip)
         ifile.WriteLong(k.fsize)
         WriteBank(k.bank,ifile,0,k.fsize)
      Next
      CloseFile(ifile)
      Return True
   EndMethod

   Rem
   bbdoc: Zip't sämtliche Virtuelle Files
   End Rem
   Method Zip()
      For Local k:TVirtualFile = EachIn self.files
         k.Zip()
      Next
   End Method
   
   Rem
   bbdoc: EntZip't sämtliche Virtuelle Files
   End Rem
   Method UnZip()
      For Local k:TVirtualFile = EachIn self.files
         k.UnZip()
      Next   
   EndMethod

   Rem
   bbdoc: Fügt ein existierendes Virtuelles-File zum Wrapped-File hinzu
   End Rem
   Method AddVFile(k:TVirtualFile)
      If k Then
         self.files.AddLast(k)
         self.filesin :+ 1
      EndIf
   EndMethod

   Rem
   bbdoc: Löscht ein angefügtes Virutelles File anhand dessen Namen
   End Rem
   Method RemoveVFile(seeked:String)
      Local k:TVirtualFile
      For k = EachIn self.files
         If k.name = seeked Then
            self.files.Remove(k)
            k.Remove()
            self.filesin :- 1
            Exit
         EndIf
      Next
   EndMethod

   Rem
   bbdoc: Setz das aktivierte Virtuelle File anhand dessen Namen
   End Rem
   Method SetAktFile(seeked:String)
      Local k:TVirtualFile
      For k = EachIn self.files
         If k.name = seeked Then
            self.aktfile = k
            Return True
         EndIf
      Next
      Return False
   EndMethod

   Rem
   bbdoc: Speichert das aktivierte Virtuelle File im Angegebnen Pfad
   End Rem
   Method SaveAktFile(ipath:String)
      self.aktfile.Save(ipath)
   EndMethod
   
   'Stream-Funktions
   Method Pos:Int()
      If self.aktfile Then
         Return self.aktfile.bankstrm.Pos()
      EndIf
   End Method

   Method Size:Int()
      If self.aktfile Then
         Return self.aktfile.bankstrm.Size()
      EndIf
   End Method

   Method Seek:Int(pos:Int)
      If self.aktfile Then
         Return self.aktfile.bankstrm.Seek(pos)
      EndIf
   End Method
   
   Method Read:Int(Buffer:Byte Ptr,gSize:Int)
      If self.aktfile Then
         Return self.aktfile.bankstrm.Read(Buffer,gSize)
      EndIf
   EndMethod

   Method Write:Int(Buffer:Byte Ptr,gSize:Int)
      If self.aktfile Then
         Return self.aktfile.bankstrm.Write(Buffer,gSize)
      EndIf
   EndMethod
   'End Stream-Funktions

End Type

Global TVirtualFileList:TList = New TList
Rem
bbdoc: Virutelles File
about: Ein Stream, der mit SeekStream durchsucht werden kann.
End Rem
Type TVirtualFile Extends TStream

   Field path:String
   Field name:String
   Field fsize:Int
   Field bank:TBank
   Field bankstrm:TBankStream
   Field iszip:Byte
   
   Method New()

      TVirtualFileList.AddLast(Self)

      

   EndMethod
   
   Method Remove()

      TVirtualFileList.Remove(Self)

      

   End Method

   Rem
   bbdoc: Fügt ein Virtuelles File hinzu
   about: Das File wird aus der angegebenen Bank gelesen.<br>Dabei wird die gesamte bank übrnommen.
   End Rem
   Function Add:TVirtualFile(fname:String,fpath:String,BankToRead:TBank)

      

      Local temp:TVirtualFile = New TVirtualFile
      temp.path = fpath
      temp.name = fname
      temp.fsize = BankSize(BankToRead)

      temp.bank = CreateBank(temp.fsize)

      CopyBank(BankToRead,0,temp.bank,0,temp.fsize)

      temp.bankstrm = CreateBankStream(temp.bank)
      SeekStream(temp.bankstrm,0)
      
      Return temp

   End Function

   Rem
   bbdoc: Läd ein Virtuelles File mit dem Namen @fname aus dem Pfad @fpath.
   End Rem
   Function Open:TVirtualFile(fpath:String,fname:String)

      

      If FileType(fpath) <> 1 Then Return Null

      Local temp:TVirtualFile = New TVirtualFile
      temp.path = fpath
      temp.name = fname
      temp.fsize = FileSize(fpath)

      temp.bank = LoadBank(fpath)

      temp.bankstrm = CreateBankStream(temp.bank)
      SeekStream(temp.bankstrm,0)

      Return temp

   EndFunction

   Rem
   bbdoc: Schließt das Virutelle File
   End Rem
   Method Close()

      CloseStream(self.bankstrm)
      ResizeBank(self.bank,0)

      self.Remove()
      
      

   EndMethod

   Rem
   bbdoc: Speichert das Virutelle File im angegebenen Pfad
   End Rem
   Method Save(pathto:String)

      SaveBank(self.bank,pathto)

   EndMethod

   Rem
   bbdoc: Zip't das virtuelle File
   about: Vielen dank an Henry, der mir hierbei sehr geholfen hat.
   End Rem
   Method Zip(rate:Int=9)

      If self.iszip = 1 Then Return False

      Local srzsz:Int = self.bank.Size()
      Local destsz:Int = (srzsz + srzsz / 10 + 32)
      Local destbank:TBank = CreateBank(destsz)

      Local toret:Int = compress2(destbank.Buf()+4,destsz,self.bank.Buf(),srzsz,rate)

      If toret <> 0 Then Return toret

      destbank.PokeByte(0,srzsz )
      destbank.PokeByte(1,srzsz Shr 8)
      destbank.PokeByte(2,srzsz Shr 16)
      destbank.PokeByte(3,srzsz Shr 24)

      destbank.Resize(destsz+4)

      self.bank = destbank

      self.bankstrm = CreateBankStream(self.bank)

      

      Return toret

   End Method

   Rem
   bbdoc: Entzip't das virtuelle File
   about: Vielen dank an Henry, der mir hierbei sehr geholfen hat.
   EndRem
   Method UnZip()

      If self.iszip = 0 Then Return False

      Local srzsz:Int = self.bank.Size()

      Local destsz:Int
      destsz:|self.bank.PeekByte(0)
      destsz:|self.bank.PeekByte(1) Shl 8
      destsz:|self.bank.PeekByte(2) Shl 16
      destsz:|self.bank.PeekByte(3) Shl 24

      Local destbank:TBank = CreateBank(destsz)
      
      Local toret:Int = uncompress(destbank.Buf(),destsz,self.bank.Buf()+4,srzsz-4)
      
      If toret <> 0 Then Return toret
      
      self.bank = destbank
      
      self.bankstrm = CreateBankStream(self.bank)
      
      

      Return toret

   EndMethod

   'Stream-Funktions
   Method Pos:Int()
      If self.bankstrm Then
         Return self.bankstrm.Pos()
      EndIf
   End Method

   Method Size:Int()
      If self.bankstrm Then
         Return self.bankstrm.Size()
      EndIf
   End Method

   Method Seek:Int(pos:Int)
      If self.bankstrm Then
         Return self.bankstrm.Seek(pos)
      EndIf
   End Method
   
   Method Read:Int(Buffer:Byte Ptr,gSize:Int)
      If self.bankstrm Then
         Return self.bankstrm.Read(Buffer,gSize)
      EndIf
   EndMethod

   Method Write:Int(Buffer:Byte Ptr,gSize:Int)
      If self.bankstrm Then
         Return self.bankstrm.Write(Buffer,gSize)
      EndIf
   EndMethod
   'End Stream-Funktions

EndType


Ist im code komplett beschreiben.
Man kann halt einfach von BMK doe Dokus machen lassen, dann is das auch ausdokumentiert.
Ich habs getestet, geht einwandfrei!
Das ganze ist komplett OOP, ich hab lediglich zum Funktionsweisen Nutzen die paar Funktionen oben gemacht.
Bitte bewerten!

Edit: Update auf V1.20
Edit: Hab ma das FlushMem() rausgenommen.
  • Zuletzt bearbeitet von BtbN am Sa, Dez 03, 2005 19:37, insgesamt einmal bearbeitet

BtbN

BeitragMo, Nov 28, 2005 15:57
Antworten mit Zitat
Benutzer-Profile anzeigen
So, hab nun die V1.20 herrausgebracht!
Man kann die Files jetzt Zippen.

Ps.: Nochma vielen dank an Henry

Henry

BeitragMo, Nov 28, 2005 16:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Schön handlich! Very Happy

Allerdings hast Du FlushMem() da noch überall drin...das verträgt sich afaik nicht mit der aktuellen Version von BMax...oder ist das in Modulen anders, I wonder?! Shocked
Aiya Eärendil Elenion Ancalima!

All you have to decide is what to do with the time that is given to you.

Robsite.de ist eine Anlaufstelle für Tutorials und Tools, die Noobs das Leben leichter machen!
Forensuche ist nicht nur als Lückenfüller in den oberen Links gedacht!

BtbN

BeitragMo, Nov 28, 2005 17:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Bis jetzt hatte ich ma keine Probleme damit.
Wenn das bei wem rumbockt, soll ers einfach per Replace rausnehmen!

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group