Hlavní navigace

GLib: Soupravy dat (2)

Michal Burda 27. 11. 2000

V dnešním díle vyprávění o soupravách dat dokončíme.

Odstraňování prvků z datových souprav

#define g_dataset_id_remove_data(l, k)
#define g_dataset_remove_data(l, k)

Tyto makra slouží ke zrušení položek soupravy dat napojených na data l. Rušenou položku můžete určit buď číselnou ( GQuark ovou) konstantou k (v případě g_dataset_id_remove_data()) nebo řetězcovým klíčem k (u makra g_dataset_remove_data()). Má-li rušená položka přiřazenou dealokovací funkci, její data se navíc automaticky uvolní z paměti.

Podobně jako v klíčovaných seznamech i u datových souprav máte možnost odstranit položku bez automatického volání dealokovací funkce. Provede se to jedním z následujících dvou způsobů:

void g_dataset_id_remove_no_notify(gconstpointer dataset_location,
                                   GQuark key_id);
#define g_dataset_remove_no_notify(l, k)

Přístupy se opět liší pouze způsobem adresace rušené položky. dataset_location a l je lokace „hlavních“ dat v paměti, key_id GQuark ový klíč a k řetězcový klíč odstraňované položky. I kdyby rušená položka měla asociovánu dealokovací funkci, voláním těchto dvou rutin se proces uvolnění dat nikdy neprovede.

Konstrukce „foreach“

void g_dataset_foreach(gconstpointer dataset_location,
                       GDataForeachFunc func,
                       gpointer user_data);

void(*GDataForeachFunc)(GQuark key_id, gpointer data,
                        gpointer user_data);

Pokud čtete články o knihovně GLib pravidelně, musí vás už (stejně jako mě) dost nudit znovu a znovu číst o funkcích „foreach“. Aby ale tento seriál mohl sloužit také trochu jako referenční příručka, nezbývá mi než poznamenat, že také soupravy dat disponují tímto voláním a ještě jednou zopakovat, jak funkce „foreach“ fungují:

Funkce g_dataset_foreach() zavolá na každý prvek soupravy dat, jejíž rozpoznávacím znakem je pointer dataset_location, uživatelskou funkci func, které předá GQuark ový klíč key_id prvku, jeho data data a uživatelská data user_data. Vykoná se tak něco jako příkaz „pro každou položku soupravy dat udělej __něco__“.

Uvolnění soupravy dat z paměti

void g_dataset_destroy(gconstpointer dataset_location); 

…voláním této funkce se souprava dat, která je napojena na dataset_location, uvolní z paměti. Na všechny její prvky budou zavolány (pokud existují) příslušné dealokovací funkce, takže se uvolní i uložená data. S „hlavními“ daty dataset_location se pochopitelně nestane nic – to musíte obstarat sami.

Příklad

Následující příklad simuluje typické použití souprav dat. Sestává ze tří souborů: libclovek.c a libclovek.h je jakási knihovna funkcí pro práci s databází kontaktů (opravdu primitivní – jen pro ukázku). Soubor main.c je pak hlavní program, který tuto knihovnu používá.

/************** Soubor: libclovek.h ***************/

/* struktura definujici jednoho cloveka */
typedef struct {
  gchar *jmeno;
  gchar *prijmeni;
} LibClovek;

/* deklarace funkce */
extern LibClovek* lib_cti_cloveka(void);



/************** Soubor: libclovek.c ***************/

/* Vnejsi knihovna pracujici s databazi kontaktu */

#include <glib.h>
#include „libclovek.h“

/* Funkce, ktera cte jednoho cloveka z databaze */
LibClovek* lib_cti_cloveka(void)
{
  LibClovek *clovek;

  clovek = g_malloc(sizeof(LibClovek));

  /* Tady by spravne melo byt cteni z databaze.
   * Pro jednoduchost vsak promennou clovek jen nejak
   * inicializujeme: */
  clovek->jmeno = "Karel";
  clovek->prijmeni = "Novak";

  return clovek;
}


/* Nacteni dalsiho cloveka :-) */
LibClovek* lib_cti_dalsiho_cloveka(void)
{
  LibClovek *clovek;

  clovek = g_malloc(sizeof(LibClovek));

  clovek->jmeno = "Josef";
  clovek->prijmeni = "Kvetinac";

  return clovek;
}



/**************** Soubor: main.c ******************/

/* Hlavni program */

#include <glib.h>
#include „libclovek.h“

#define ADRESA  1
#define TELEFON 2

gint main(void)
{
  LibClovek *clovek, *clovek2;

  /* Nacteni cloveka z databaze */
  clovek = lib_cti_cloveka();

  /* Struktura LibClovek nam nestaci. Chteli bychom u kazdeho
   * cloveka uchovavat jeste jeho telefonni cislo a adresu. */
  g_dataset_id_set_data(clovek, ADRESA, "Polni 22, Praha 8");
  g_dataset_id_set_data(clovek, TELEFON, "02/321321");

  /* Nacteni dalsiho cloveka */
  clovek2 = lib_cti_dalsiho_cloveka();
  g_dataset_id_set_data(clovek2, ADRESA, "Zahradni 1, Liberec");
  g_dataset_id_set_data(clovek2, TELEFON, "0386/111222");

/* ... nejake zpracovani ... */

  /* Kontrolni tisk */
  printf("%s %s, %s; telefon: %s\n",
    clovek->jmeno, clovek2->prijmeni,
    g_dataset_id_get_data(clovek, ADRESA),
    g_dataset_id_get_data(clovek, TELEFON));

  printf("%s %s, %s; telefon: %s\n",
    clovek2->jmeno, clovek2->prijmeni,
    g_dataset_id_get_data(clovek2, ADRESA),
    g_dataset_id_get_data(clovek2, TELEFON));

  g_dataset_destroy(clovek);
  g_dataset_destroy(clovek2);
  g_free(clovek);
  g_free(clovek2);
}

Soubor libclovek.h definuje strukturu LibClovek jejímiž prvky jsou řetězce jmenoprijmeni.

Soubor libclovek.c obsahuje dvě funkce, které toho opravdu moc nedělají – slouží jen k demonstraci. V reálném programu by načítaly z databáze jeden záznam a ve struktuře LibClovek jej předávaly jako návratovou hodnotu. Pro naši ukázku stačí, když alokují místo pro jeden záznam a inicializují ho nějakými statickými hodnotami.

Dostáváme k hlavnímu programu, souboru main.c. Jeho úkolem by v reálné situaci bylo nějakým způsobem údaje o lidech zpracovávat. Program využívá knihovnu libclovek, ale struktura LibClovek jeho účelům nestačí. Bylo by třeba u každého záznamu uchovávat ještě nějaké další údaje: třeba adresu a telefonní číslo. Do „standardní“ knihovny libclovek zasahovat nemůžeme, proto použijeme soupravy dat.

Ve zdrojovém kódu můžete vidět, jak se k adrese paměti, kterou uchovávají pointery clovek a clovek2 asociují řetězcové položky s klíči ADRESA a TELEFON.

Následuje kontrolní tisk všech údajů na obrazovku a dealokování veškerých dynamických dat.

V příkladu jsem záměrně nepoužil řetězcové konstanty – dokonce jsem vypustil celý mechanizmus kvarků. Chtěl jsem totiž ukázat, že k použití souprav dat, ale i klíčovaných seznamů dat je vůbec nepotřebujeme. Stačí, když si uvědomíme, že GQuark y nejsou nic jiného než přirozená čísla (1..???). A tak místo řetězců můžeme jednoduše používat konstantní makra (viz ADRESA a TELEFON).

Ukázka by po zkompilování měla vypsat:

Karel Novak, Polni 22, Praha 8; telefon: 02/321321
Josef Kvetinac, Zahradni 1, Liberec; telefon: 0386/111222
Našli jste v článku chybu?
Podnikatel.cz: Babiše přesvědčila 89letá podnikatelka?!

Babiše přesvědčila 89letá podnikatelka?!

Vitalia.cz: 7 originálních adventních kalendářů pro mlsné

7 originálních adventních kalendářů pro mlsné

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

120na80.cz: Jak oddálit Alzheimera?

Jak oddálit Alzheimera?

Vitalia.cz: Říká amoleta - a myslí palačinka

Říká amoleta - a myslí palačinka

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Vitalia.cz: 9 největších mýtů o mase

9 největších mýtů o mase

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: Dáte si jahody s plísní?

Dáte si jahody s plísní?

Podnikatel.cz: Zavře krám u #EET Malá pokladna a Teeta?

Zavře krám u #EET Malá pokladna a Teeta?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

DigiZone.cz: ČRa DVB-T2 ověřeno: Hisense a Sencor

ČRa DVB-T2 ověřeno: Hisense a Sencor

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka