Datei wird kopiert und gepatcht

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
mpz
Beiträge: 505
Registriert: 14.06.2005 15:53
Computerausstattung: Win 11 Pro, 48 GB Ram, Intel I7 CPU und RX4070 Grafikkarte, PB (4/5) 6.12LT
Wohnort: Berlin, Tempelhof

Datei wird kopiert und gepatcht

Beitrag von mpz »

Hallo Leute,

anbei ein kleine Anregung um eine Datei zu kopieren und dabei Platzhalter zu ersetzen, oder (böse böse böse) an einer bestimmten Stelle einen String zu schreiben. Ich benutze diese Funktion als Serienbrieffunktion für Worddateien.

Gruß Michael

Code: Alles auswählen


    ;-TOP 
; Kommentar : Patchroutine um Dateien zu kopieren und Daten zu verändern
;           : Wird von mir quasi als Serienbrieffunktion für Worddateien
;           : benutzt
; Version   : v 1.01, v1.00 
; Author    : Michael Paulwitz
;              
; Datei     : Patchen und Schreiben.pb 
; Erstellt  : 18.07.2007 
; Sprache   : Purebasic 4.10 Beta 2 Windows
; *************************************************************************************** 

Procedure.s WriteStringmem (*Speicher,Text$,Startposition.l=0)
  ; Schreiben ohne abschließende Null 
  
  Laenge = Len (Text$)-1
  For n = Startposition To Startposition + Laenge
      Nummer.b = Asc (Mid(Text$, n - Startposition + 1,1) )      
      PokeB(*Speicher + n, Nummer.b)
  Next n

EndProcedure

Procedure.l SearchStringmem (*Speicher,Suchstring$)
  ; Suche im *Speicherpuffer einen Suchstring$ und gib die Position an
  
  Laenge = Len (Suchstring$)
  *Findstring = AllocateMemory(Laenge)
  For m = 0 To Laenge -1
      Nummer.b = Asc (Mid(Suchstring$, m + 1,1) )      
      PokeB(*Findstring + m, Nummer.b)
  Next m  

  For n = 0 To MemorySize(*Speicher) - Laenge
      If CompareMemory(*Speicher + n, *Findstring , Laenge)
        Gefunden = 1
        Break
      EndIf
  Next n

  FreeMemory(*Findstring) 

  If Gefunden = 1
     ProcedureReturn  n
  Else
     ProcedureReturn  -1
  EndIf
  
EndProcedure

Procedure.l ReplaceStringmem (*Speicher,SuchString$, ErsatzString$, StartPosition=0)
    
  If Len(SuchString$) <> Len (ErsatzString$)
     ProcedureReturn  -1     
  EndIf
 
  If StartPosition > MemorySize(*Speicher) - Laenge
     ProcedureReturn  -2     
  EndIf

  Laenge = Len (SuchString$)
  *Findstring = AllocateMemory(Laenge)
  For m = 0 To Laenge -1
      Nummer.b = Asc (Mid(SuchString$, m + 1,1) )      
      PokeB(*Findstring + m, Nummer.b)
  Next m  
 
  For n = 0 To MemorySize(*Speicher) - Laenge
      If CompareMemory(*Speicher + n, *Findstring , Laenge)
        Gefunden = 1
        Break
      EndIf
  Next n

  FreeMemory(*Findstring) 

  If Gefunden = 1
     For m = n To n + Laenge -1
        Nummer.b = Asc (Mid(ErsatzString$, m - n + 1,1) )      
        PokeB(*Speicher + m, Nummer.b)
     Next m
     ProcedureReturn  n
  Else 
     ProcedureReturn  0
  EndIf

EndProcedure


; Hier beginnts


Filename.s = "Testdatei.doc"
fileLen = FileSize(Filename)  

If fileLen > 0 
   ; Jetzt wird die Datei in den Speicher gelesen
   If OpenFile(0,Filename.s) 
      *tempmem = AllocateMemory(fileLen) 
      ReadData(0,*tempmem, fileLen) 
      CloseFile(0)
      
      ;String in der Datei wird gesucht und ersetzt
      gefunden = SearchStringmem (*tempmem,"[Platzhalter1]")
      If gefunden <> -1 
         ; Daten werden an eine bestimmten Stelle geschrieben
         WriteStringmem (*tempmem,"Wird ersetzt1!",gefunden)
      EndIf

      ; Daten Ersetzen mit vielen schönen Abfragen
      test = ReplaceStringmem (*tempmem,"[Platzhalter2]", "Wird ersetzt2!",300)
      If test = -1
         MessageRequester("Fehler:" , "SuchString$ und ErsatzString$ haben unterschiedliche Grösse!", 0)
      ElseIf test = -2
         MessageRequester("Fehler:" , "Startposition zu gross!", 0)
      ElseIf test = 0
         MessageRequester("Fehler:" , "Keinen SuchString$ gefunden!", 0)
      Else
         MessageRequester("Okay:" , "Suchstring wurde an Position "+Str(test)+" gefunden und ersetzt!", 0)
      EndIf

      ; Neue Datei erstellt mit gepatchten Inhalt
      Fileneuname.s = "Testdatei_Neu.doc"      
      If CreateFile(0,Fileneuname) 
         WriteData (0,*tempmem, fileLen)
         CloseFile(0)
      Else
         MessageRequester("Fehler:" , "Ergebnis "+Fileneuname+" kann nicht geschrieben werden!", 0)
      EndIf 
   Else  
      MessageRequester("Fehler:" , "Vorlage "+Filename+" kann nicht gelesen werden!", 0)
      End  
   EndIf
Else   
   MessageRequester("Fehler:" , "Vorlage "+Filename+" nicht vorhanden!", 0)
EndIf
   
Zuletzt geändert von mpz am 18.07.2007 22:55, insgesamt 1-mal geändert.
Working on :lol: - LibSGD - MP3D Engine - 8)
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Datei wird kopiert und gepatcht

Beitrag von Kiffi »

mpz hat geschrieben:anbei ein kleine Anregung um eine Datei zu kopieren und dabei Platzhalter zu ersetzen
... wobei erwähnt werden muss, dass der zu ersetzende Text genauso lang
sein muss wie der Platzhalter. Ansonsten bleiben entweder
Platzhalterfragmente in der Datei übrig (Ersetzungstextlänge kleiner als
Platzhalterlänge) oder es werden Speicherbereiche überschrieben
(Ersetzungstextlänge größer als Platzhalterlänge).

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
mpz
Beiträge: 505
Registriert: 14.06.2005 15:53
Computerausstattung: Win 11 Pro, 48 GB Ram, Intel I7 CPU und RX4070 Grafikkarte, PB (4/5) 6.12LT
Wohnort: Berlin, Tempelhof

Beitrag von mpz »

Hey Kiffi,

das habe ich mir wirklich zu Herzen genommen und habe gleich die "Replacestringmem" Procedure eingebaut. Die möglichen Fehlerabfragen sollten hoffendlich genug sein :mrgreen:

Zwei drei Fehlermöglichkeiten fehlen noch, aber man soll nicht gleich übertreiben >:)

Gruß Michael
Working on :lol: - LibSGD - MP3D Engine - 8)
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

mpz hat geschrieben:das habe ich mir wirklich zu Herzen genommen und habe gleich die "Replacestringmem" Procedure eingebaut.
wenn ich das richtig sehe, dann prüfst Du jetzt, ob Search- und Replacestring
die selbe Länge haben, korrekt?

So richtig cool wäre es allerdings, wenn man beliebig lange Platzhalter durch
beliebig lange Replacestrings ersetzen könnte. :mrgreen:

Hierfür müsste nur der Speicherbereich hinter dem Platzhalter entweder nach
vorne gezogen (Platzhalter ist länger als Ersetzungstext) oder nach hinten
geschoben werden (Platzhalter ist kürzer als Ersetzungstext).

Grüße ... Kiffi
a²+b²=mc²
Antworten