![]() |
Delphi-Version: 2006
[nicht-Profi] Datentyp auf bestimmte Weise darstellen
Hallo,
ich möchte gerne einen bestimmten Datentyp aus einer Datei einlesen und entsprechend einer vorliegenden Spezifikation sichtbar machen: Hier der Teil der Spezifikation, der mir Rätsel aufgibt: Zitat:
also etwa so:
Delphi-Quellcode:
was mir nicht klar ist, wie ich das jetzt mal auf den bildschirm bekomme damit es so aussieht:
procedure TForm1.Button6Click(Sender: TObject);
var fs: TFilestream; EntryCount:integer; w32:longword; w16a,w16b:word; w8a,w8b,w8c,w8d,w8e,w8f,w8g,w8h:byte; begin fs:=TFilestream.Create(edit1.Text,fmopenread); fs.Position:=89; fs.ReadBuffer(w32,4); fs.ReadBuffer(w16a,2); fs.ReadBuffer(w16b,2); fs.ReadBuffer(w8a,1); fs.ReadBuffer(w8b,1); fs.ReadBuffer(w8c,1); fs.ReadBuffer(w8d,1); fs.ReadBuffer(w8e,1); fs.ReadBuffer(w8f,1); fs.ReadBuffer(w8g,1); fs.ReadBuffer(w8h,1); fs.free; end; Zitat:
|
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Guten Abend,
schau Dir mal die Routine IntToHex an. added: Für das Daten auslesen eventuell einen Record definieren.
Delphi-Quellcode:
type
TData = record firstSegment : LongWord; next2Segments : Array[0..1] of Word; leftOver : Array[0..7] of Byte; end; Grüße Klaus |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
zur Anzeige:
![]() Einfach einen Formatstring definieren, welcher der Vorgabe entspricht und dann alle Zahlen/Variablen übergeben. Ist bestimmt schöner, als den string komplett manuell zusammenzusetzen und jeden wert einzeln mit HexToStr umzuwandeln. Und das mit Record hat den Vorteil, daß du diesen Record nur einmal auslesen mußt und da gleich alle Werte auf einmal aus der datei rausbekommst anstatt jeden Wert einzeln auszulesen. PS: besser einen packed Record verwenden >
Delphi-Quellcode:
TData = packed record ...
|
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Vielen Dank für die Antworten!
leider erziele ich nach wie vor nicht das erwartete Ergebnis. ich habe zum testen das ganze file durchwandert und immer um 1 byte versetzt ein 4 byte langes DWord ausgelesen. dieses dann mit inttohex() in einer listbox ausgegeben und dann nach diesen eindeutigen identifizierern gesucht... ohne erfolg. |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Ich bin durch zufall darauf gekommen das es für diesen Typ eine delphi komponente TGUID zu geben scheint.
zusätzlich habe ich diese Klasse gefunden: ![]() jetzt habe ich meinen code umgebaut:
Delphi-Quellcode:
bekomme aber einen
procedure TForm1.Button9Click(Sender: TObject);
var MyGUID:TGuid; fs: TFilestream; MyGuidStr:string; begin fs:=TFilestream.Create(edit1.Text,fmopenread); fs.Position:=89; fs.Readbuffer(MyGUID,16); //leider bekomme ich jetzt hier einen fehler MyGuidStr:=TGuidex.ToString(MyGuid); Listbox1.items.add(MyGuidStr); fs.free; end; Zitat:
|
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Zitat:
Code:
(gut, man könnte jetzt einfach noch die zusätzlichen "-" da reinschieben)
deins {3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}
GUID {3F2504E0-4F89-11D3-9A0C-0305E82C3301} Zitat:
PS: auf BigEndian/LittleEndian müßte man auch mal schauen (z.B. könnte da auch das mit dem "-" reinschieben schwer werden, wenn die Reihenfolge nicht stimmt) |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Zitat:
in der datei ist das zeugs ja als bytes und die string darstellung ist ja nur zum manuellen vergleich? (oder übersehe ich da etwas?) Zitat:
Zitat:
ich habe demnach hier eine funktion gefunden und ausprobiert was dann herauskommt... diese macht beispielsweise aus 00000002 dann 02000000 aber auch so habe ich keine ID entdecken können weder an den Stellen, wo sie meiner Meinung nach sein müssten, noch beim byteweisen durchkriechen. deswegen vermute ich das meine typen falsch sind. EDIT: Lesefehler ist behoben... es liest das zeugs jetzt ein. aber sie stimmen halt nicht... ich probier mal noch ein wenig herum. |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
mit D2006 läuft folgender Code:
Delphi-Quellcode:
Gruß
var
MyGUID:TGuid; fs: TFilestream; MyGuidStr:string; begin fs:=TFilestream.Create('c:\temp\mydate.doc',fmopenread); fs.Position:=89; fs.Readbuffer(MyGUID,16); //leider bekomme ich jetzt hier einen fehler MyGuidStr:=GuidToString(MyGuid); label4.Caption:=MyGuidStr; fs.free; end; K-H |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Ja, leider bringt mich das nicht weiter, offenbar hat himutsu recht und man muß noch auf little und big endian achten und stellenweise muß auch bitweise eingelesen werden.
die gute nachricht ist, ich habe einen source code der genau das alles macht was ich gerne auch machen können will... die schlechte nachricht ist, er ist in java und ich kann noch weniger java als delphi... trotzdem wühle ich mich mal durch die vielen proceduren und versuche die entscheidenden herauszusuchen.
Code:
also hiermit liest java wohl das GUID ding ein.
public GUID readGUID() throws IOException {
GUID g = new GUID(); g.w1 = readU32(); // 4 g.w2 = readU16(); // 2 g.w3 = readU16(); // 2 g.w4 = readU8(); g.w5 = readU8(); g.w6 = readU8(); g.w7 = readU8(); g.w8 = readU8(); g.w9 = readU8(); g.w10 = readU8(); g.w11 = readU8(); // 8 return g; } welches wohl so definiert wurde:
Code:
es werden also readU32 readU16 und readU8 methoden verwendet...
public class GUID {
/** * Special GUID indicating the end of elements in a section of the Logical Scene graph */ public static final GUID END_OF_ELEMENTS = fromString("{FFFFFFFF-FFFF-FFFF-FF-FF-FF-FF-FF-FF-FF-FF}"); public static final int LENGTH = 16; public long w1; public int w2; public int w3; public int w4; public int w5; public int w6; public int w7; public int w8; public int w9; public int w10; public int w11; ich häng mal noch eine an:
Code:
also ich verstehe die letzte Funktion bisher so, das mit den zeilen int ch1 = get(); usw sowas ähnliches wie
// An unsigned 32-bit integer
public long readU32() throws IOException { try { int ch1 = get(); int ch2 = get(); int ch3 = get(); int ch4 = get(); if (getByteOrder() == ByteOrder.LITTLE_ENDIAN) return ((ch4 << 24) | (ch3 << 16) | (ch2 << 8) | (ch1 << 0)) & 0xFFFFFFFFL; else return ((ch1 << 24) | (ch2 << 16) | (ch3 << 8) | (ch4 << 0)) & 0xFFFFFFFFL; } catch (BufferOverflowException e) { throw new IOException(e); } fs.read(puffer,1) gemacht wird, aber ich verstehe nicht was in der if anweisung genau gemacht wird. Wenn ich nun versuchen würde das in delphianisch zu bekommen, wie würde ich einen datentyp definieren so wie hier das GUID definiert ist? |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Du meinst die "<<"? Das ist Bit-Shifting, in Delphi sähe das etwa so aus (Pseudo-Code):
Delphi-Quellcode:
Wobei ich mir nicht sicher bin, wozu da noch mit MAX_DWORD ver"and"et wird, schaden kann es aber nicht.
if LITTLE_ENDIAN then
Result := ((ch4 shl 24) or (ch3 shl 16) or (ch2 shl 8) or ch1) and $FFFFFFFF else Result := ((ch1 shl 24) or (ch2 shl 16) or (ch3 shl 8) or ch4) and $FFFFFFFF; |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Je nachdem ob LITTLEENDIAN oder BIGENDIAN gespeichert wurde, werden die gelesenen Bytes in einer anderen Reihenfolge ausgegeben.
Du mußt nur wissen wie abgespeichert wurde. Gruß K-H |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
Zitat:
Delphi-Quellcode:
In meinen vorliegenden Beispielen ist die ByteOrder 0 also LITTLE ENDIAN.
procedure TForm1.Button2Click(Sender: TObject);
var fs: TFilestream; ByteOrder:byte; begin fs:=TFilestream.Create(edit1.Text,fmopenread); fs.Position:=80; fs.ReadBuffer(ByteOrder,1); case ByteOrder of 0 : Listbox1.Items.add('BYTE ORDER: LITTLE ENDIAN'); 1 : Listbox1.Items.add('BYTE ORDER: BIG ENDIAN'); else Listbox1.Items.add('WARNUNG! BYTE ORDER UNKLAR'); end; fs.free; end; |
AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
ich habe inzwischen einige funktionen geschrieben um einzelne bereiche der daten auszulesen...
ich bin aber nicht so wirklich geübt im erstellen von Funktionen, klassen und so, deshalb wäre ich für etwas feedback oder Hinweise was ich noch beachten muß dankbar: so sieht das zum beispiel jetzt aus:
Delphi-Quellcode:
Konkrete Fragen formuliere ich mal hier:
type
TJupTeReader = class(TObject) public class function getVersion (fs : Tfilestream) :string; class function getByteOrder (fs : Tfilestream) :shortint; class function getI32 (fs : TFilestream; pos : integer) :integer; class function getU32 (fs : TFilestream; pos : integer) :Longword; class function getMyGUID (fs : TFilestream; pos : integer) :TGUID; end; implementation class function TJupTeReader.getVersion(fs: TFilestream):string; var i:integer; var bufferchar:char; var ResultStr:string; begin for i := 0 to 79 do begin fs.Position:=i; fs.Readbuffer(bufferchar,1); ResultStr:=ResultStr+char(bufferchar); end; result:=ResultStr; end; class function TJupTeReader.getByteOrder(fs: Tfilestream):shortint; var ByteOrder:byte; ResultByteOrder:shortint; begin fs.Position:=80; fs.ReadBuffer(ByteOrder,1); if (ByteOrder=0) or (ByteOrder=1) then ResultByteOrder:=ByteOrder else ResultByteOrder:=-1; Result:=ResultByteOrder; end; class function TJupTeReader.getI32(fs: TFileStream; pos : integer):integer; begin fs.Position:=pos; fs.ReadBuffer(Result,4); end; class function TJupTeReader.getU32(fs:TFilestream; pos:integer):Longword; begin fs.Position:=pos; fs.ReadBuffer(Result,4); end; class function TJupTeReader.getMyGUID (fs : TFilestream; pos : integer) :TGUID; begin fs.Position:=pos; fs.read(Result,16); end; 1.) ist es überhaupt geschickt einen filestream zu übergeben um einzelne bereiche auszulesen? 2.) Mit der Funktion U32 soll ein unsigned 32 bit integer value geladen werden, deshalb habe ich LongWord gewählt, hätte ich auch Cardinal nehmen können oder sogar müssen? 3.) für ein Attribut soll ich an einer bestimmten stelle ein U32 einlesen, jetzt heisst es aber zur Interpretation des Atributes wie folgt: Zitat:
4.) nochmal eine delphi frage: ich rufe die einzelnen funktionen jetzt von ausserhalb etwa so auf:
Delphi-Quellcode:
was irgendwie umständlich aussieht.. gibt es dafür etwas besseres?
entrycount:=TJupteReader.getI32(testfs,TocOffset).
ich danke schonmal für eure Hilfe und Anregungen. bitte habt Nachsicht mit mir :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz