file to DataSection (w/ compression)

Share your advanced PureBasic knowledge/code with the community.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

file to DataSection (w/ compression)

Post by jassing »

Here's another bit I use in some applications. useful when file can be compressed a lot...
(Yes, there are a couple other variants of this idea here, this is just another)

Code: Select all

UseLZMAPacker()
EnableExplicit
Declare fileToDataSection( cFile.s, bCompress=#False )


;- --[ DEMO ]---
; will create a file "c:\pbfiles\josh\DS_searchsvgico.pbi"
Debug fileToDataSection( "c:\pbfiles\josh\search.svg.ico", #True )
;
; regardless of if you use compression or not, you can leave code "as is"
;
; ie:
; Define *mem=searchsvgicoToMemory()
; CreateFile( 0, "c:\temp\search.ico" )
; WriteData( 0,*mem,MemorySize(*mem))
; CloseFile(0)
;
; you can readily "xincudefile" as many ds_*.pbi" as you want w/o issues, 
;    provided the filenames are all unique.
;
; You can exclude the macro & declare/procedure if you don't use macro.
;- --[ End DEMO ]---



Procedure fileToDataSection( cFile.s, bCompress=#False )
  Protected nFileSize, cTag.s,
            l, i, h,
            s.s, w.w, 
            *p, *o
  
  h = ReadFile( -1, cFile)
  If h
    nFileSize=Lof(h)
    *p = AllocateMemory( nFileSize )
    ReadData( h, *p, nFileSize )
    CloseFile( h )
    
    If bCompress
      *o = AllocateMemory( nFileSize*2 )
      l  = CompressMemory( *p, nFileSize, *o, nFileSize*2, #PB_PackerPlugin_Lzma, 9)
      If l = 0
        Debug "compression failed"
        bCompress=#False
        FreeMemory(*o)
        l=nFileSize
      Else 
        Debug "Compressed "+Str(nFileSize)+" to "+Str(l)
        FreeMemory(*p) : *p=*o
      EndIf 
    Else
      l =nFileSize
    EndIf 
    
    s = ~"\tData.w"
    cTag="_"+GetFilePart(cfile,#PB_FileSystem_NoExtension)+GetExtensionPart(cfile)
    While FindString(ctag," " )
      ctag = ReplaceString(ctag," ","",#PB_String_CaseSensitive)
    Wend
    While FindString(ctag,"." )
      ctag = ReplaceString(ctag,".","",#PB_String_CaseSensitive)
    Wend
    
    If CreateFile( 0,    GetPathPart(cfile)+"DS"+ctag+".pbi" )
      Debug "Created " + GetPathPart(cfile)+"DS"+ctag+".pbi" 
      
      If bCompress
        WriteStringN( 0, ";-***** You want to move these lines up in code" )
        WriteStringN( 0, "UseLZMAPacker()" )
      Else
        WriteStringN( 0, ";-***** The stuff is optional!")
        WriteStringN( 0, ";-*****    If you use the data directly, you can skip including this.")
        WriteStringN( 0, ";-***** You want to move these lines up in code (DON'T FORGET TO FreeMemory())" )
      EndIf 
      WriteStringN( 0, "CompilerIf Not Defined( dataSectionToMemory, #PB_Procedure)" )
      WriteStringN( 0, ~"\tDeclare dataSectionToMemory( bCompressed, *size, *begin, *end )" )
      WriteStringN( 0, ~"CompilerEndIf\n" )
      WriteStringN( 0, ";-***** DON'T FORGET TO FreeMemory()!!!!")
      WriteStringN( 0, "Macro "+Mid(cTag,2)+"ToMemory() : dataSectionToMemory( "+Str(bCompress)+", ?Size"+ctag+", ?begin"+ctag+", ?end"+ctag+" ) : EndMacro" )
      If bCompress
        WriteStringN( 0, ";-***** end move" )
      Else
        WriteStringN( 0, ";-***** end optional/move" )
      EndIf
      
      WriteStringN( 0, ~"\nDataSection" )
      WriteStringN( 0, ~"\tSize"+cTag+":" )
      WriteStringN( 0, ~"\tData.q "+Str(nFileSize)); file size
      WriteStringN( 0, ~"\tbegin"+cTag+":" ) 
      
      While i < l
        If i <> 0 And i% 32 = 0
          WriteStringN( 0, Left( s, Len(s)-1 ) )
          s = ~"\tData.w "
        ElseIf i % 16 = 0
          s+" "
        EndIf
        w = PeekW(*p+i)
        s+"$"+RSet( Hex(w,#PB_Word), 4, "0" ) + ","
        i+2
      Wend
      If s <> ~"\tData.w "
        WriteStringN( 0, Left(s, Len(s)-1 ) )
      EndIf
      
      WriteStringN( 0, ~"\tend"+ctag+":" )
      WriteStringN( 0, ~"EndDataSection\n" )
      
      If Not bCompress
        WriteStringN( 0, ";-***** The stuff is optional!")
        WriteStringN( 0, ";-*****    If you use the data directly, you can skip including this.")
      EndIf 
      WriteStringN( 0, "CompilerIf Not Defined( dataSectionToMemory, #PB_Procedure )" )
      WriteStringN( 0, ~"\tProcedure dataSectionToMemory( bCompressed, *size, *begin, *end )" )
      WriteStringN( 0, ~"\t  Protected cSize," )
      WriteStringN( 0, ~"\t            fSize = PeekQ(*size)," )
      WriteStringN( 0, ~"\t            *mem  = AllocateMemory(fSize)" )
      WriteStringN( 0, ~"\t  If bCompressed" )
      WriteStringN( 0, ~"\t    If UncompressMemory(*begin, cSize, *mem, fSize, #PB_PackerPlugin_Lzma) <> fSize" )
      WriteStringN( 0, ~"\t      FreeMemory(*mem) : *mem=#Null" )
      WriteStringN( 0, ~"\t    EndIf" )
      WriteStringN( 0, ~"\t  Else" )
      WriteStringN( 0, ~"\t    CopyMemory( *begin, *mem, fSize )" )
      WriteStringN( 0, ~"\t  EndIf" )
      WriteStringN( 0, ~"\t  ProcedureReturn *mem" )
      WriteStringN( 0, ~"\tEndProcedure" )
      WriteStringN( 0, "CompilerEndif" )
      If Not bCompress
        WriteStringN( 0, ";-***** End of optional")
      EndIf 
      CloseFile(0)
    Else
      Debug "Failed to create "+GetPathPart(cfile)+"DS"+ctag+".pbi" 
    EndIf
  EndIf
  ProcedureReturn l
EndProcedure