diff options
Diffstat (limited to 'src/format')
-rw-r--r-- | src/format/executable.c | 20 | ||||
-rw-r--r-- | src/format/flat.c | 34 | ||||
-rw-r--r-- | src/format/format-int.h | 35 | ||||
-rw-r--r-- | src/format/format.c | 181 | ||||
-rw-r--r-- | src/format/format.h | 15 | ||||
-rw-r--r-- | src/format/known-int.h | 4 | ||||
-rw-r--r-- | src/format/known.c | 33 | ||||
-rw-r--r-- | src/format/known.h | 3 | ||||
-rw-r--r-- | src/format/strsym.c | 6 | ||||
-rw-r--r-- | src/format/strsym.h | 17 |
10 files changed, 77 insertions, 271 deletions
diff --git a/src/format/executable.c b/src/format/executable.c index 553b157..26c418e 100644 --- a/src/format/executable.c +++ b/src/format/executable.c @@ -174,7 +174,7 @@ void g_exe_format_add_debug_info(GExeFormat *format, GDbgFormat *info) { const char *desc; /* Description humaine associée*/ - desc = g_binary_format_get_description(G_BIN_FORMAT(info)); + desc = g_known_format_get_description(G_KNOWN_FORMAT(info)); if (desc == NULL) log_simple_message(LMT_WARNING, _("Unnamed debug information")); @@ -313,20 +313,17 @@ bool g_exe_format_get_main_address(GExeFormat *format, vmpa2t *addr) void g_executable_format_setup_portions(GExeFormat *format, GtkStatusStack *status) { - GBinFormat *base; /* Version basique du format */ vmpa2t addr; /* Emplacement vide de sens */ phys_t length; /* Taille de portion globale */ GExeFormatClass *class; /* Classe de l'instance */ size_t i; /* Boucle de parcours */ - base = G_BIN_FORMAT(format); - /** * Avant de lire l'entête du format, on ne sait pas où on se trouve ! */ init_vmpa(&addr, 0, VMPA_NO_VIRTUAL); - length = g_binary_content_compute_size(base->content); + length = g_binary_content_compute_size(G_KNOWN_FORMAT(format)->content); format->portions = g_binary_portion_new(BPC_RAW, &addr, length); @@ -364,7 +361,6 @@ bool g_executable_format_complete_loading(GExeFormat *format, wgroup_id_t gid, G size_t count; /* Qté d'infos supplémentaires */ size_t i; /* Boucle de parcours */ GDbgFormat *dbg; /* Informations de débogage */ - GBinFormat *base; /* Version basique du format */ result = true; @@ -376,20 +372,12 @@ bool g_executable_format_complete_loading(GExeFormat *format, wgroup_id_t gid, G { dbg = g_exe_format_get_debug_info(format, i); - result = g_binary_format_analyze(G_BIN_FORMAT(dbg), gid, status); + result = g_known_format_analyze(G_KNOWN_FORMAT(dbg), gid, status); g_object_unref(G_OBJECT(dbg)); } - if (result) - { - base = G_BIN_FORMAT(format); - - result = g_binary_format_complete_loading(base, status); - - } - return result; } @@ -445,7 +433,7 @@ void g_exe_format_include_portion(GExeFormat *format, GBinPortion *portion, cons phys_t remaining; /* Taille maximale envisageable*/ bool truncated; /* Modification faite ? */ - available = g_binary_content_compute_size(G_BIN_FORMAT(format)->content); + available = g_binary_content_compute_size(G_KNOWN_FORMAT(format)->content); range = g_binary_portion_get_range(portion); diff --git a/src/format/flat.c b/src/format/flat.c index 75e359e..6b8b074 100644 --- a/src/format/flat.c +++ b/src/format/flat.c @@ -28,9 +28,6 @@ #include <string.h> -#include <i18n.h> - - #include "flat-int.h" @@ -48,10 +45,10 @@ static void g_flat_format_dispose(GFlatFormat *); static void g_flat_format_finalize(GFlatFormat *); /* Indique la désignation interne du format. */ -static const char *g_flat_format_get_name(const GFlatFormat *); +static char *g_flat_format_get_key(const GFlatFormat *); /* Fournit une description humaine du format. */ -static const char *g_flat_format_get_description(const GFlatFormat *); +static char *g_flat_format_get_description(const GFlatFormat *); /* Assure l'interprétation d'un format en différé. */ static bool g_flat_format_analyze(GFlatFormat *, wgroup_id_t, GtkStatusStack *); @@ -86,6 +83,7 @@ G_DEFINE_TYPE(GFlatFormat, g_flat_format, G_TYPE_EXE_FORMAT); static void g_flat_format_class_init(GFlatFormatClass *klass) { GObjectClass *object; /* Autre version de la classe */ + GKnownFormatClass *known; /* Version de format connu */ GBinFormatClass *fmt; /* Version en format basique */ GExeFormatClass *exe; /* Version en exécutable */ @@ -94,11 +92,15 @@ static void g_flat_format_class_init(GFlatFormatClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_flat_format_dispose; object->finalize = (GObjectFinalizeFunc)g_flat_format_finalize; + known = G_KNOWN_FORMAT_CLASS(klass); + + known->get_key = (known_get_key_fc)g_flat_format_get_key; + known->get_desc = (known_get_desc_fc)g_flat_format_get_description; + + known->analyze = (known_analyze_fc)g_flat_format_analyze; + fmt = G_BIN_FORMAT_CLASS(klass); - fmt->get_name = (format_get_name_fc)g_flat_format_get_name; - fmt->get_desc = (format_get_desc_fc)g_flat_format_get_description; - fmt->analyze = (format_analyze_fc)g_flat_format_analyze; fmt->get_endian = (format_get_endian_fc)g_flat_format_get_endianness; exe = G_EXE_FORMAT_CLASS(klass); @@ -191,7 +193,7 @@ GExeFormat *g_flat_format_new(GBinContent *content, const char *machine, SourceE result = g_object_new(G_TYPE_FLAT_FORMAT, NULL); - g_binary_format_set_content(G_BIN_FORMAT(result), content); + g_known_format_set_content(G_KNOWN_FORMAT(result), content); result->machine = strdup(machine); result->endian = endian; @@ -207,17 +209,17 @@ GExeFormat *g_flat_format_new(GBinContent *content, const char *machine, SourceE * * * Description : Indique la désignation interne du format. * * * -* Retour : Description du format. * +* Retour : Désignation du format. * * * * Remarques : - * * * ******************************************************************************/ -static const char *g_flat_format_get_name(const GFlatFormat *format) +static char *g_flat_format_get_key(const GFlatFormat *format) { - const char *result; /* Désignation à retourner */ + char *result; /* Désignation à retourner */ - result = "flat"; + result = strdup("flat"); return result; @@ -236,11 +238,11 @@ static const char *g_flat_format_get_name(const GFlatFormat *format) * * ******************************************************************************/ -static const char *g_flat_format_get_description(const GFlatFormat *format) +static char *g_flat_format_get_description(const GFlatFormat *format) { - const char *result; /* Désignation à retourner */ + char *result; /* Désignation à retourner */ - result = _("Flat executable format"); + result = strdup("Flat executable format"); return result; diff --git a/src/format/format-int.h b/src/format/format-int.h index 4ef9793..de29751 100644 --- a/src/format/format-int.h +++ b/src/format/format-int.h @@ -28,6 +28,7 @@ #include "format.h" +#include "known-int.h" #include "preload.h" #include "../glibext/objhole.h" #include "../gtkext/gtkstatusstack.h" @@ -38,22 +39,9 @@ /* ------------------------ TRAITEMENT INDIVIDUEL DE FORMATS ------------------------ */ -/* Indique la désignation interne du format. */ -typedef const char * (* format_get_name_fc) (const GBinFormat *); - -/* Fournit une description humaine du format. */ -typedef const char * (* format_get_desc_fc) (const GBinFormat *); - -/*Assure l'interprétation d'un format en différé. */ -typedef bool (* format_analyze_fc) (GBinFormat *, wgroup_id_t, GtkStatusStack *); - /* Indique le boutisme employé par le format binaire analysé. */ typedef SourceEndian (* format_get_endian_fc) (const GBinFormat *); -/* Réalise un traitement post-désassemblage. */ -typedef void (* format_complete_analysis_fc) (GBinFormat *, wgroup_id_t, GtkStatusStack *); - - /* Rythme des allocations pour les entrées de code */ #define EXTRA_POINT_BLOCK 20 @@ -83,9 +71,7 @@ typedef struct _fmt_error /* Format binaire générique (instance) */ struct _GBinFormat { - GObject parent; /* A laisser en premier */ - - GBinContent *content; /* Contenu binaire à étudier */ + GKnownFormat parent; /* A laisser en premier */ virt_t *start_points[DPL_COUNT]; /* Départ de désassemblage */ size_t pt_allocated[DPL_COUNT]; /* Taille d'inscription allouée*/ @@ -147,17 +133,10 @@ struct _GBinFormat /* Format binaire générique (classe) */ struct _GBinFormatClass { - GObjectClass parent; /* A laisser en premier */ - - format_get_name_fc get_name; /* Désignation interne */ - format_get_desc_fc get_desc; /* Désignation humaine */ - - format_analyze_fc analyze; /* Interprétation du format */ + GKnownFormatClass parent; /* A laisser en premier */ format_get_endian_fc get_endian; /* Boutisme employé */ - format_complete_analysis_fc complete; /* Terminaison d'analyse */ - /* Signaux */ void (* symbol_added) (GBinFormat *, GBinSymbol *); @@ -166,14 +145,6 @@ struct _GBinFormatClass }; -/* Effectue les ultimes opérations de chargement d'un binaire. */ -bool g_binary_format_complete_loading(GBinFormat *, GtkStatusStack *); - -/* Définit le contenu binaire à analyser. */ -void g_binary_format_set_content(GBinFormat *, GBinContent *); - - - /* ------------------------------ DECODAGE DE SYMBOLES ------------------------------ */ diff --git a/src/format/format.c b/src/format/format.c index 18ddc03..0cebc98 100644 --- a/src/format/format.c +++ b/src/format/format.c @@ -66,7 +66,7 @@ static bool __g_binary_format_find_symbol(const GBinFormat *, const void *, __co /* Indique le type défini pour un format binaire générique. */ -G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_OBJECT); +G_DEFINE_TYPE(GBinFormat, g_binary_format, G_TYPE_KNOWN_FORMAT); /****************************************************************************** @@ -162,8 +162,6 @@ static void g_binary_format_dispose(GBinFormat *format) { size_t i; /* Boucle de parcours */ - g_clear_object(&format->content); - g_rw_lock_clear(&format->pt_lock); g_clear_object(&format->info); @@ -223,75 +221,6 @@ static void g_binary_format_finalize(GBinFormat *format) /****************************************************************************** * * -* Paramètres : format = instance à traiter. * -* status = barre de statut à tenir informée. * -* * -* Description : Effectue les ultimes opérations de chargement d'un binaire. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_format_complete_loading(GBinFormat *format, GtkStatusStack *status) -{ - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* content = contenu binaire à parcourir. * -* * -* Description : Définit le contenu binaire à analyser. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_format_set_content(GBinFormat *format, GBinContent *content) -{ - assert(format->content == NULL); - - g_object_ref(G_OBJECT(content)); - - format->content = content; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* * -* Description : Fournit une référence vers le contenu binaire analysé. * -* * -* Retour : Gestionnaire de contenu binaire en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinContent *g_binary_format_get_content(const GBinFormat *format) -{ - GBinContent *result; /* Instance à retourner */ - - result = format->content; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * * Paramètres : format = format à venir modifier. * * flag = drapeau d'information complémentaire à planter. * * * @@ -421,84 +350,6 @@ FormatFlag g_binary_format_get_flags(const GBinFormat *format) * * * Paramètres : format = description de l'exécutable à consulter. * * * -* Description : Indique la désignation interne du format. * -* * -* Retour : Description du format. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_binary_format_get_name(const GBinFormat *format) -{ - const char *result; /* Désignation à retourner */ - - result = G_BIN_FORMAT_GET_CLASS(format)->get_name(format); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* * -* Description : Fournit une description humaine du format. * -* * -* Retour : Description du format. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_binary_format_get_description(const GBinFormat *format) -{ - const char *result; /* Désignation à retourner */ - - result = G_BIN_FORMAT_GET_CLASS(format)->get_desc(format); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = format chargé dont l'analyse est lancée. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * -* * -* Description : Assure l'interprétation d'un format en différé. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_binary_format_analyze(GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) -{ - bool result; /* Bilan à retourner */ - GBinFormatClass *class; /* Classe de l'instance */ - - handle_binary_format_analysis(PGA_FORMAT_ANALYSIS_STARTED, format, gid, status); - - class = G_BIN_FORMAT_GET_CLASS(format); - - result = class->analyze(format, gid, status); - - handle_binary_format_analysis(PGA_FORMAT_ANALYSIS_ENDED, format, gid, status); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* * * Description : Indique le boutisme employé par le format binaire analysé. * * * * Retour : Boutisme associé au format. * @@ -601,36 +452,6 @@ void g_binary_format_activate_disassembling_context(GBinFormat *format, GProcCon } -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à manipuler. * -* gid = groupe de travail dédié. * -* status = barre de statut à tenir informée. * -* * -* Description : Réalise un traitement post-désassemblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_binary_format_complete_analysis(GBinFormat *format, wgroup_id_t gid, GtkStatusStack *status) -{ - GBinFormatClass *class; /* Classe de l'instance */ - - handle_binary_format_analysis(PGA_FORMAT_POST_ANALYSIS_STARTED, format, gid, status); - - class = G_BIN_FORMAT_GET_CLASS(format); - - if (class->complete != NULL) - class->complete(format, gid, status); - - handle_binary_format_analysis(PGA_FORMAT_POST_ANALYSIS_ENDED, format, gid, status); - -} - - /* ---------------------------------------------------------------------------------- */ /* DECODAGE DE SYMBOLES */ diff --git a/src/format/format.h b/src/format/format.h index f11b1db..a23782c 100644 --- a/src/format/format.h +++ b/src/format/format.h @@ -69,9 +69,6 @@ typedef struct _GBinFormatClass GBinFormatClass; /* Indique le type défini pour un format binaire générique. */ GType g_binary_format_get_type(void); -/* Fournit une référence vers le contenu binaire analysé. */ -GBinContent *g_binary_format_get_content(const GBinFormat *); - /* Ajoute une information complémentaire à un format. */ bool g_binary_format_set_flag(GBinFormat *, FormatFlag); @@ -84,15 +81,6 @@ bool g_binary_format_has_flag(const GBinFormat *, FormatFlag); /* Fournit les particularités du format. */ FormatFlag g_binary_format_get_flags(const GBinFormat *); -/* Indique la désignation interne du format. */ -const char *g_binary_format_get_name(const GBinFormat *); - -/* Fournit une description humaine du format. */ -const char *g_binary_format_get_description(const GBinFormat *); - -/* Assure l'interprétation d'un format en différé. */ -bool g_binary_format_analyze(GBinFormat *, wgroup_id_t, GtkStatusStack *); - /* Indique le boutisme employé par le format binaire analysé. */ SourceEndian g_binary_format_get_endianness(const GBinFormat *); @@ -105,9 +93,6 @@ void g_binary_format_preload_disassembling_context(GBinFormat *, GProcContext *, /* Définit les points de départ d'un contexte de désassemblage. */ void g_binary_format_activate_disassembling_context(GBinFormat *, GProcContext *, GtkStatusStack *); -/* Réalise un traitement post-désassemblage. */ -void g_binary_format_complete_analysis(GBinFormat *, wgroup_id_t, GtkStatusStack *); - /* ------------------------------ DECODAGE DE SYMBOLES ------------------------------ */ diff --git a/src/format/known-int.h b/src/format/known-int.h index 7b79e50..950c75f 100644 --- a/src/format/known-int.h +++ b/src/format/known-int.h @@ -38,6 +38,9 @@ typedef char * (* known_get_desc_fc) (const GKnownFormat *); /*Assure l'interprétation d'un format en différé. */ typedef bool (* known_analyze_fc) (GKnownFormat *, wgroup_id_t, GtkStatusStack *); +/* Réalise un traitement post-désassemblage. */ +typedef void (* known_complete_analysis_fc) (GKnownFormat *, wgroup_id_t, GtkStatusStack *); + /* Format binaire générique (instance) */ struct _GKnownFormat @@ -57,6 +60,7 @@ struct _GKnownFormatClass known_get_desc_fc get_desc; /* Désignation humaine */ known_analyze_fc analyze; /* Interprétation du format */ + known_complete_analysis_fc complete; /* Terminaison d'analyse */ }; diff --git a/src/format/known.c b/src/format/known.c index c1850bc..6865d0d 100644 --- a/src/format/known.c +++ b/src/format/known.c @@ -175,7 +175,8 @@ GBinContent *g_known_format_get_content(const GKnownFormat *format) result = format->content; - g_object_ref(G_OBJECT(result)); + if (result != NULL) + g_object_ref(G_OBJECT(result)); return result; @@ -258,3 +259,33 @@ bool g_known_format_analyze(GKnownFormat *format, wgroup_id_t gid, GtkStatusStac return result; } + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à manipuler. * +* gid = groupe de travail dédié. * +* status = barre de statut à tenir informée. * +* * +* Description : Réalise un traitement post-désassemblage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_known_format_complete_analysis(GKnownFormat *format, wgroup_id_t gid, GtkStatusStack *status) +{ + GKnownFormatClass *class; /* Classe de l'instance */ + + handle_known_format_analysis(PGA_FORMAT_POST_ANALYSIS_STARTED, format, gid, status); + + class = G_KNOWN_FORMAT_GET_CLASS(format); + + if (class->complete != NULL) + class->complete(format, gid, status); + + handle_known_format_analysis(PGA_FORMAT_POST_ANALYSIS_ENDED, format, gid, status); + +} diff --git a/src/format/known.h b/src/format/known.h index 2d30147..8319a63 100644 --- a/src/format/known.h +++ b/src/format/known.h @@ -67,6 +67,9 @@ char *g_known_format_get_description(const GKnownFormat *); /* Assure l'interprétation d'un format en différé. */ bool g_known_format_analyze(GKnownFormat *, wgroup_id_t, GtkStatusStack *); +/* Réalise un traitement post-désassemblage. */ +void g_known_format_complete_analysis(GKnownFormat *, wgroup_id_t, GtkStatusStack *); + #endif /* _FORMAT_KNOWN_H */ diff --git a/src/format/strsym.c b/src/format/strsym.c index 91232f4..97c62d9 100644 --- a/src/format/strsym.c +++ b/src/format/strsym.c @@ -245,7 +245,7 @@ static void g_string_symbol_finalize(GStrSymbol *symbol) * * ******************************************************************************/ -GBinSymbol *g_string_symbol_new_read_only(StringEncodingType encoding, GBinFormat *format, const mrange_t *range) +GBinSymbol *g_string_symbol_new_read_only(StringEncodingType encoding, GKnownFormat *format, const mrange_t *range) { GStrSymbol *result; /* Nouveau symbole à renvoyer */ @@ -273,7 +273,7 @@ GBinSymbol *g_string_symbol_new_read_only(StringEncodingType encoding, GBinForma * * ******************************************************************************/ -void g_string_symbol_init_read_only(GStrSymbol *symbol, StringEncodingType encoding, GBinFormat *format, const mrange_t *range) +void g_string_symbol_init_read_only(GStrSymbol *symbol, StringEncodingType encoding, GKnownFormat *format, const mrange_t *range) { GBinSymbol *parent; /* Type d'instance parent */ @@ -284,7 +284,7 @@ void g_string_symbol_init_read_only(GStrSymbol *symbol, StringEncodingType encod symbol->encoding = encoding; - symbol->content = g_binary_format_get_content(format); + symbol->content = g_known_format_get_content(format); symbol->has_content = true; g_string_symbol_check_encoding(symbol); diff --git a/src/format/strsym.h b/src/format/strsym.h index 6900251..5c8a34f 100644 --- a/src/format/strsym.h +++ b/src/format/strsym.h @@ -28,6 +28,7 @@ #include <glib-object.h> +#include "known.h" #include "format.h" #include "symbol.h" @@ -50,12 +51,12 @@ typedef enum _StringEncodingType } StringEncodingType; -#define G_TYPE_STR_SYMBOL g_string_symbol_get_type() -#define G_STR_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_string_symbol_get_type(), GStrSymbol)) -#define G_IS_STR_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_string_symbol_get_type())) -#define G_STR_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STR_SYMBOL, GStrSymbolClass)) -#define G_IS_STR_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STR_SYMBOL)) -#define G_STR_SYMBOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STR_SYMBOL, GStrSymbolClass)) +#define G_TYPE_STR_SYMBOL g_string_symbol_get_type() +#define G_STR_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_string_symbol_get_type(), GStrSymbol)) +#define G_IS_STR_SYMBOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_string_symbol_get_type())) +#define G_STR_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_STR_SYMBOL, GStrSymbolClass)) +#define G_IS_STR_SYMBOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_STR_SYMBOL)) +#define G_STR_SYMBOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_STR_SYMBOL, GStrSymbolClass)) /*/* Symbole pour chaîne de caractères (instance) */ @@ -69,10 +70,10 @@ typedef struct _GStrSymbolClass GStrSymbolClass; GType g_string_symbol_get_type(void); /* Crée un nouveau symbole pour chaîne de caractères. */ -GBinSymbol *g_string_symbol_new_read_only(StringEncodingType, GBinFormat *, const mrange_t *); +GBinSymbol *g_string_symbol_new_read_only(StringEncodingType, GKnownFormat *, const mrange_t *); /* Réalise la complète initialisation d'unsymbole pour chaîne. */ -void g_string_symbol_init_read_only(GStrSymbol *, StringEncodingType, GBinFormat *, const mrange_t *); +void g_string_symbol_init_read_only(GStrSymbol *, StringEncodingType, GKnownFormat *, const mrange_t *); /* Crée un nouveau symbole pour chaîne de caractères. */ GBinSymbol *g_string_symbol_new_dynamic(StringEncodingType, const char *, const vmpa2t *); |