Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   [nicht-Profi] Datentyp auf bestimmte Weise darstellen (https://www.delphipraxis.net/163567-%5Bnicht-profi%5D-datentyp-auf-bestimmte-weise-darstellen.html)

Nelphin 4. Okt 2011 21:25

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:

The type is a 16 byte (128-bit) number. It is stored/written to the file using a four-byte word (U32), 2 two-byte words (U16), and 8 one-byte words (U8) such as:
{3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}
In the given format types are used as unique identifiers (e.g. Data Segment ID, Object Type ID, etc.)
Also mein Ansatz wäre an die Stelle im File zu springen (die ist mir bekannt) wo dieser Datentyp steht und ihn dann in entsprechenden Variablen einzulesen...

also etwa so:
Delphi-Quellcode:
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;
was mir nicht klar ist, wie ich das jetzt mal auf den bildschirm bekomme damit es so aussieht:

Zitat:

{3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}
Für Tipps wäre ich dankbar!

Klaus01 4. Okt 2011 21:52

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

himitsu 4. Okt 2011 22:38

AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
 
zur Anzeige:
Delphi-Referenz durchsuchenFormat

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 ...

Nelphin 5. Okt 2011 07:38

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.

Nelphin 5. Okt 2011 14:18

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: http://delphi.about.com/library/weekly/aa022205a.htm

jetzt habe ich meinen code umgebaut:

Delphi-Quellcode:
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;
bekomme aber einen
Zitat:

stream lesefehler
kann mir jemand weiterhelfen?

himitsu 5. Okt 2011 14:24

AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
 
Zitat:

Zitat von Nelphin (Beitrag 1128588)
Ich bin durch zufall darauf gekommen das es für diesen Typ eine delphi komponente TGUID zu geben scheint.

Fällt dir was auf?
Code:
deins {3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}
GUID  {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
(gut, man könnte jetzt einfach noch die zusätzlichen "-" da reinschieben)

Zitat:

Zitat von Nelphin (Beitrag 1128588)
//leider bekomme ich jetzt hier einen fehler

Ist die Datei groß genug? (mindestens 105 Byte)


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)

Nelphin 5. Okt 2011 14:51

AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
 
Zitat:

Zitat von himitsu (Beitrag 1128592)
Zitat:

Zitat von Nelphin (Beitrag 1128588)
Ich bin durch zufall darauf gekommen das es für diesen Typ eine delphi komponente TGUID zu geben scheint.

Fällt dir was auf?
Code:
deins {3F2504E0-4F89-11D3-9A-0C-03-05-E8-2C-33-01}
GUID  {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
(gut, man könnte jetzt einfach noch die zusätzlichen "-" da reinschieben)

das mit den zusätzlichen "-" hatte ich gehofft, weil ansonsten doch die spezifikationen gleich sind: 1x4byte 2x2byte und 8x1byte.
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 von himitsu (Beitrag 1128592)
Ist die Datei groß genug? (mindestens 105 Byte)

ich habe einige test dateien für das format, keine ist kleiner als 3kbyte.
Zitat:

Zitat von himitsu (Beitrag 1128592)
PS: auf BigEndian/LittleEndian müßte man auch mal schauen

in dem format gibt es im header ein byte das 1 oder 0 sein kann, das vorgibt in welcher reihenfolge die bytes gespeichert sind...
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.

p80286 5. Okt 2011 15:23

AW: [nicht-Profi] Datentyp auf bestimmte Weise darstellen
 
mit D2006 läuft folgender Code:
Delphi-Quellcode:
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;
Gruß
K-H

Nelphin 5. Okt 2011 16:41

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:
    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;

    }
also hiermit liest java wohl das GUID ding ein.
welches wohl so definiert wurde:
Code:
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;
es werden also readU32 readU16 und readU8 methoden verwendet...

ich häng mal noch eine an:

Code:
    // 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);
        }
also ich verstehe die letzte Funktion bisher so, das mit den zeilen int ch1 = get(); usw sowas ähnliches wie
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?

DeddyH 5. Okt 2011 17:13

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:
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;
Wobei ich mir nicht sicher bin, wozu da noch mit MAX_DWORD ver"and"et wird, schaden kann es aber nicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:53 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz