Blog

@Komposit zum Entpacken von COFF-Daten

Wilfred Springer

Wilfred Springer

Aktualisiert Oktober 23, 2025
3 Minuten

Vor einiger Zeit habe ichPreon mit der Bit-Syntax von Erlang verglichen . Ich habe mir vor allem eines der Beispiele aus "Programming Erlang" angesehen, ein Beispiel, das zeigt, wie man MPEG-Header mit Erlang dekodiert. Da dies jedoch nicht das einzige Beispiel in diesem Kapitel ist, habe ich beschlossen, mich auch an einem der anderen Beispiele zu versuchen.

Das zweite Beispiel aus dem Bit-Syntax-Kapitel in "Programming Erlang" handelt vom Entpacken von COFF-Daten. Das Besondere an COFF ist, dass es keine IDL-ähnliche Sprache oder irgendetwas anderes für die Definition der Datenstrukturen gibt: Alles, was Sie haben, ist die Definition von C++-Datenstrukturen, wie die folgende: [c] typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries; } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; [/c] In seinem Buch erklärt Joe Armstrong, dass Sie mit der Bit-Syntax und den Makrolösungen von Erlang in der Lage wären, COFF-Daten, die durch die obige C++-Struktur charakterisiert sind, mit dem unten aufgeführten Erlang-Code zu entpacken. [source] unpack_image_resourcedirectory(Dir) -> <<Characteristics : ?DWORD, TimeDateStamp : ?DWORD, MajorVersion : ?WORD, MinorVersion : ?WORD, NumberOfNamedEntries : ?WORD, NumberOfIdEntries : ?WORD, /binary>> = Dir, ... [/source] Die Schlüsselbotschaft hier ist, dass Erlang es Ihnen nicht nur erlaubt, binäre Daten einfach zu entpacken, sondern auch, dass es Ihnen erlaubt, diese klar auf die einzige Quelle der Definition der Datenstruktur abzubilden: die C++ API. Wenn Sie nur Preon verwenden würden, würde die obige C++-Datenstruktur folgendermaßen aussehen: [java] class ImageResourceDirectory { @BoundNumber(size="32") long characteristics; @BoundNumber(size="32") long timeDateStamp; @BoundNumber(size="16") int majorVersion; @BoundNumber(size="16") int minorVersion; [/java] @BoundNumber(size="16") int numberOfNamedEntries; @BoundNumber(size="16") int numberOfIdEntries; } .... und damit könnten Sie es entschlüsseln: [java] Codec<ImageResourceDirectory> codec = Codecs.create(ImageResourceDirectory.class); Codecs.decode(codec, ...); [/java] Nun, das ist nicht schlecht, aber es hat nicht so viel Ähnlichkeit mit dem ursprünglichen C++-API-Code, den das Erlang-Beispiel hat. Mit dem @Composite-Framework von Andrew Philips könnten Sie dies jedoch tatsächlich schreiben: [java] class ImageResourceDirectory { [/java] @DWORD long characteristics; @DWORD long timeDateStamp; @WORD int majorVersion; @WORD int minorVersion; @WORD int numberOfNamedEntries; @WORD int numberOfIdEntries; } .... was bereits viel näher an der ursprünglichen C++-Struktur ist als das, was wir vorher hatten. Unterstützung für @Composite wurde noch nicht in Preon aufgenommen. Auf den ersten Blick scheint es zwei Möglichkeiten zu geben, damit umzugehen. Erstens könnte es in das Framework eingebaut werden, und zwar durch die Schnittstelle AnnotatedElements, die überall vorhanden ist. Das sollte funktionieren und ist vielleicht sogar das Vernünftigste.Es gibt jedoch vielleicht eine andere Möglichkeit, es einzubauen. Preon definiert bereits eine CodecDecorator-Schnittstelle, mit der Sie Codec-Implementierungen um erstellte Codec-Instanzen wickeln können. Als ich mir das ansah, kam mir der Gedanke, dass es eigentlich recht attraktiv sein könnte, auch einen CodecFactoryDecorator zu definieren, der CodecFactories um andere CodecFactories in der Verantwortungskette wickelt. [java] public interface CodecFactory { <T> Codec<T> create(AnnotatedElement metadata, Class<T> type, ResolverContext context); } [/java] Die vom CodecFactoryDecorator erstellten Wrapper wären in der Lage, jeden Verweis auf Annotationen abzufangen, der weiter unten in der Kette übergeben wird, und ihn durch ein AnnotatedElement zu ersetzen, das AnnotatedElements verwendet, um Zugriff auf die Annotationen zu erhalten. Infolgedessen würden die CodecFactories, die für die Erstellung des eigentlichen Codec aus den übergebenen Metadaten verantwortlich sind, nur die Preon-Annotationen zu sehen bekommen, anstatt der @DWORD- und @WORD-Annotationen. Es ist nur ein Gedanke. Nichts davon ist bisher implementiert worden. Sie können es gerne kommentieren. In Zukunft werden wir sicher noch mehr davon sehen.

Verfasst von

Wilfred Springer

Contact

Let’s discuss how we can support your journey.