Seite 2 von 2

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 03.06.2019 11:15
von mk-soft
Erst die Daten im Memory zusammenstellen (AllocateMemory)
Dann die Daten komplett schreiben (WriteData)

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 03.06.2019 13:09
von matbal
8 MB Byte für Byte zu schreiben ist nicht das Problem.

Die Stringfunktion Mid() ist zu langsam!
(PureBasic weiß nicht, wie lang ein String ist und liest deshalb bei jedem Aufruf von Mid() den String von Anfang an bis zur Startposition. Könnte ja sein, daß der String kürzer ist als die angegebene Startposition)

Tausche ich Mid() gegen PeekS(), geht es flott.

Eine andere Alternative wäre ein Pointer mit Struktur, mit dem man durch den String läuft.

Geschwindigkeitstest:

Code: Alles auswählen

OpenConsole()
a$ = "001122AABBCCDDEEFF"   ; Teststring 

Repeat
   a$ + a$                 ; Teststring verlängern
Until Len(a$) > 8000000    ; bis über 8 MB

lenght = Len(a$)




t = ElapsedMilliseconds()
For i = 1 To lenght Step 2
   
   ;b$ = Mid(a$, i, 2)      ; < - Langsam
   
   b$ = PeekS(@a$ + (i - 1) * SizeOf(character), 2)  ; < - Schneller
   
   ;byte = Val("$" +b$)
   
   ; Kontrollausgabe, wie schnell die Schleife läuft
   If i % 10000 = 1
      PrintN("Fortschritt: " + Str(i))
   EndIf
   
Next i
PrintN("Zeit: " + Str(ElapsedMilliseconds() - t))
Input()

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 03.06.2019 14:27
von NicTheQuick
Ich hätte hier noch eine Funktion, die aus einem Unicode-String, der aus Hexzeichen besteht einen Speicherbereich erzeugt mit dem dekodierten Inhalt. Allerdings überprüft er nicht, ob gültige Hexzeichen benutzt werden. Der Prototyp ist nur dazu da, damit man Strings ohne @ übergeben kann, er aber trotzdem nicht kopiert, sondern nur per Referenz weitergegeben wird.
Der Speicherpuffer beginnt mit einer festgelegten Größe (1024) und wird immer wieder verdoppelt, falls nicht mehr alles reinpasst. Das ist ein übliches Verfahren für dynamische zusammenhängende Speicherbereiche.
Am Ende sollte man daran denken den Speicherbereich wieder mit FreeMemory() freizugeben.

Code: Alles auswählen

Prototype.i hex2bin(input.p-unicode)

Procedure.i __hex2bin(*input)
	Protected *i.Character = *input
	Protected bufSize.i = 1024
	Protected *buf = AllocateMemory(bufSize)
	Protected *bufEnd = *buf + bufSize
	Protected *bufTmp
	Protected *o.Ascii = *buf
	Protected state.i = 0
	Protected digit.i
	
	While *i\c
		If *i\c <= '9'
			digit = *i\c - '0'
		Else
			digit = (*i\c & $1f) + 9
		EndIf
		If state = 0
			*o\a = digit << 4
			state = 1
		Else
			*o\a | digit
			state = 0
			*o + 1
			If *o = *bufEnd
				*bufTmp = ReAllocateMemory(*buf, bufSize * 2)
				If Not *bufTmp
					FreeMemory(*buf)
					ProcedureReturn #False
				EndIf
				*buf = *bufTmp
				*o = *buf + bufSize
				bufSize * 2
				*bufEnd = *buf + bufSize
			EndIf
		EndIf
		*i + SizeOf(Character)
	Wend
	
	If *o - *buf = 0
		ProcedureReturn #False
	EndIf
	
	*bufTmp = ReAllocateMemory(*buf, *o - *buf)
	If Not *bufTmp
		FreeMemory(*buf)
		ProcedureReturn #False
	EndIf
	
	ProcedureReturn *bufTmp
EndProcedure

Global hex2bin.hex2bin = @__hex2bin()

s.s = "57696c6c6b6f6d6d656e20696d20507572652d426f61726400"

*a = hex2bin(s)

Debug PeekS(*a, -1, #PB_Ascii)
FreeMemory(*a)

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 03.06.2019 21:10
von Mijikai
Hab mal ne lib in fasm gebastelt eventuell besteht ja Interesse :)
Der Code funktioniert nur wenn der Hex-String intakt ist also keine ungültigen Zeichen enthält
und es müssen immer 2 Character Paare (Groß) pro Byte vorliegen.

Code: Alles auswählen

EnableExplicit

;Windows x64 Unicode (uppercase) only!

Import "h2b.lib"
  h2bConvert.i(*Str)
  h2bSize.i(*Buffer)
  h2bFree.i(*Buffer)
EndImport

Global teststring.s
Global *buffer

teststring = "FF00FF"

*buffer = h2bConvert(@teststring)

ShowMemoryViewer(*buffer,3)

Debug h2bSize(*buffer)

Debug h2bFree(*buffer)

End
Download:
https://www.dropbox.com/s/5242otg3qtg3o ... 4.zip?dl=0

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 04.06.2019 18:44
von NicTheQuick
Wieso eigentlich als Library? Wäre es nicht einfacher das direkt in Inline-ASM zu machen?

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 04.06.2019 19:05
von Mijikai
NicTheQuick hat geschrieben:Wieso eigentlich als Library? Wäre es nicht einfacher das direkt in Inline-ASM zu machen?
Ginge schon aber umständlicher und mit mehr Code.
Keine Freiheiten/Krontrolle im Funktionsaufbau -> man muss dann mit dem Setup von Procedure arbeiten/leben...
Wenn es nur eine ProcedureASM.i () geben würde wo man volle Kontrolle hätte.

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 07.06.2019 08:40
von Jörg Burdorf
Hallo Gemeinde!

Vielen Dank für eure Arbeit, Tips und Anregungen. Hab das Problem jetzt relativ einfach lösen können,
in dem ich mit der Funktion getdatabaseblob die Binärdaten aus der DB2 DB direkt in den Speicher lese
und von da in eine Datei schreiben kann. Geht auch vertretbar schnell. Je nachdem wie groß (Movie) so ein
Blob halt ist.

Hier der Code:

Code: Alles auswählen

  
           If DatabaseQuery(0, insql$, #PB_Database_StaticCursor)
             NextDatabaseRow(0)
             collen = DatabaseColumnSize(0,0)
             *MemoryID = AllocateMemory(collen)
             GetDatabaseBlob(0,0,*MemoryID,collen)
             If *MemoryID
               OpenFile(0,dsname$)
               WriteData(0,*MemoryID,collen)
               CloseFile(0)
               FreeMemory(*MemoryID)
             EndIf
           EndIf

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 07.06.2019 10:13
von NicTheQuick
Und wir denken die ganze Zeit dieser Blob besteht aus Hexadezimaldaten. Wieso hast du nicht gleich gesagt, dass das ein binärer Blob ist?

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 17.06.2019 14:47
von Jörg Burdorf
Sorry! Hatte zuerst mit GetDatabaseString probiert,da kamen die Daten in Hex zurück. Erst bei
größeren BLOBs gab es dann Probleme.

Jetzt tut.

Sorry nochmal. War da auf dem Holzweg.

Habe aber wieder was dazu gelernt.

LG
Jörg

Re: Chr(0) in String verketten und in File schreiben

Verfasst: 17.06.2019 15:40
von NicTheQuick
:allright: