/* $Id: select.cpp 1.2 1995/02/27 12:22:03 leon Exp leon $
*/
#include "select.h"
#include <malloc.h>
#undef DEBUG
static void (*inOrderFunc)(ads_name name);
/**
** Naredi prazen izbor
**/
Selection::Selection()
{
root = NULL;
}
/** {duh} **/
Selection::~Selection()
{
typedef void (*DELFUNC) (void *);
if (root)
AVLrelease(&root, (DELFUNC) del);
}
/**
** Izbere gradnike iz ACAD baze podane s filtrom /xFilter/, nato pa
** z uporabo funkcije /getKey/ izbere kljuc /key/ iz gradnika in zgradi
** AVL drevo, ki za vsak element poleg kljuca hrani se ime gradnika /name/.
** Kljuc se lahko nahaja tudi v extended data, za kar je potrebno podati
** se /apps/ za ads_entgetx(). Funkcija /getKey/ mora vrniti 0, ce je nasla
** kljuc.
**/
Selection::Select(struct resbuf *xFilter,
int (*getKey)(struct resbuf *rb, int *key),
struct resbuf *apps)
{
struct resbuf *rb;
ads_name ss;
long ssLength, i;
int status, key;
status = ads_ssget("X", NULL, NULL, xFilter, ss);
if (status != RTNORM)
return -1;
ads_sslength(ss, &ssLength);
#ifdef DEBUG
ads_printf ("Stevilo izbranih elementov: %ld\n", ssLength);
#endif
for (i = 0; i < ssLength; i++)
{
ads_name ent;
status = ads_ssname(ss, i, ent);
if (status != RTNORM)
return status;
rb = ads_entgetx(ent, apps);
if (rb == NULL)
continue;
if ( (getKey)(rb, &key) == 0)
Insert(key, ent);
ads_relrb (rb);
}
ads_ssfree (ss);
return 0;
}
/**
** Vrine en element v seznam
**/
int Selection::Insert(int key, ads_name name)
{
typedef int (*COMPAREFUNC) (void *, void *);
struct ELEMENT *element;
element = (struct ELEMENT *) malloc (sizeof (struct ELEMENT));
if (!element)
return AVL_NO_MEM;
element->number = key;
element->name[0] = name[0];
element->name[1] = name[1];
return AVLinsert(element, &root, (COMPAREFUNC) compare);
}
/**
** Zbrise element iz izbora
**/
int Selection::Delete(int key)
{
typedef int (*COMPAREFUNC) (void *, void *);
typedef void (*DELFUNC) (void *);
struct ELEMENT element;
element.number = key;
return AVLdelete(&element, &root, (COMPAREFUNC)compare, (DELFUNC)del);
}
/**
** Poisce element v izboru in vrne ACL_OK, ce je vse v redu ter
** /name/ gradnika. Ob napaki vrne -1;
**/
int Selection::Find(int key, ads_name name)
{
typedef int (*COMPAREFUNC) (void *, void *);
struct ELEMENT element, *e;
element.number = key;
if (( e = (ELEMENT *)AVLfind(&element, root,
(COMPAREFUNC) compare)) == NULL)
return -1;
name[0] = e->name[0];
name[1] = e->name[1];
return AVL_OK;
}
/**
** Samo za razhroscevanje in testiranje. Izpise drevo v urejenem vrstnem
** redu po kljucih.
**/
void Selection::Print()
{
typedef void (*PRINTFUNC) (void *);
ads_printf("Seznam elementov, ki so v seznamu:\n");
AVLinorder(root, (PRINTFUNC) print);
ads_printf("\n");
}
/**
** V pravilnem vrstnem redu za vse gradnike izbora izvrsi to funkcijo
**/
void Selection::ForAll(void (*func)(ads_name name))
{
typedef void (*INORDERFUNC) (void *);
inOrderFunc = func;
AVLinorder(root, (INORDERFUNC) inOrder);
}
/**
** Zbrise en element, tako da sprosti spomin zanj.
**/
void Selection::del(struct ELEMENT *element)
{
free (element);
}
/**
** Primerja dva elementa v drevesu AVL glede na velikost
**/
int Selection::compare(struct ELEMENT *el1, struct ELEMENT *el2)
{
if (el1->number > el2->number)
return 1;
if (el1->number < el2->number)
return -1;
return 0;
}
/**
** Izpise en element na zaslon
**/
void Selection::print(struct ELEMENT *element)
{
ads_printf("[%d]", element->number);
}
void Selection::inOrder(struct ELEMENT *element)
{
(*inOrderFunc)(element->name);
}
syntax highlighted by Code2HTML, v. 0.9.1