ReactOS Package Manager
[reactos.git] / rosapps / packmgr / lib / tree.cpp
1 ////////////////////////////////////////////////////////
2 //
3 // tree.cpp
4 //
5 // Loading of the package tree
6 //
7 //
8 // Maarten Bosma, 09.01.2004
9 // maarten.paul@bosma.de
10 //
11 ////////////////////////////////////////////////////////////////////
12
13 #include "package.hpp"
14 #include "expat.h"
15
16 vector <int> parents;
17
18 void tree_end (void* tree, const char* tag);
19 void tree_start (void* usrdata, const char* tag, const char** arg);
20
21 int PML_XmlDownload (const char* file, void* usrdata, XML_StartElementHandler start,
22 XML_EndElementHandler end, XML_CharacterDataHandler text=0);
23
24
25 // Load the tree
26 extern "C" int PML_LoadTree (TREE** tree, char* url, PML_AddItem AddItem)
27 {
28 // get the memory
29 (*tree) = new TREE;
30
31 // set every to zero
32 memset((*tree), 0, sizeof((*tree)));
33
34 // set addItem callback
35 (*tree)->addItem = AddItem;
36
37 return PML_XmlDownload (url, (void*)(*tree), tree_start, tree_end);
38 }
39
40 // expat callback for start of a "node" tag
41 void tree_start (void* usrdata, const char* tag, const char** arg)
42 {
43 int i, icon;
44 static int id = 1;
45 const char* name = "\0";
46
47 TREE* tree = (TREE*)usrdata;
48
49 // ignore if tag is the root tag ("tree")
50 if(!strcmp(tag, "tree"))
51 return;
52
53 // set the package memory
54 tree->packages.resize(id+1);
55 memset(&tree->packages[id], 0, sizeof(tree->packages[id]));
56
57 tree->packages[id].loaded = FALSE;
58 tree->packages[id].icon = FALSE;
59 tree->packages[id].none = TRUE;
60 tree->packages[id].path = NULL;
61
62 // read the arguments
63 for (i=0; arg[i]; i+=2)
64 {
65 if(!strcmp(arg[i], "name"))
66 name = arg[i+1];
67
68 if(!strcmp(arg[i], "icon"))
69 {
70 icon = atoi(arg[i+1]);
71 tree->packages[id].icon = TRUE;
72 }
73
74 if(!strcmp(arg[i], "file"))
75 {
76 tree->packages[id].path = new char [strlen(arg[i+1])];
77 strcpy(tree->packages[id].path, arg[i+1]);
78
79 if(strcmp(tag, "bin"))
80 tree->packages[id].inst = TRUE;
81
82 if(strcmp(tag, "src"))
83 tree->packages[id].src_inst = TRUE;
84 }
85 }
86
87 if(name[0]=='\0') return;
88
89 // add it
90 if(!parents.size())
91 tree->addItem(id, name, 0, icon);
92 else
93 {
94 tree->addItem(id, name, parents.back(), icon);
95
96 // list as child in the parent node
97 tree->packages[parents.back()].children.push_back(id);
98
99 // this is for the buttons
100 tree->packages[parents.back()].inst = tree->packages[parents.back()].inst || tree->packages[id].inst;
101 tree->packages[parents.back()].src_inst = tree->packages[parents.back()].src_inst || tree->packages[id].src_inst;
102 }
103
104 parents.push_back(id++);
105 }
106
107 // expat callback for end of a "node" tag
108 void tree_end (void* tree, const char* tag)
109 {
110 // delete last item
111 parents.pop_back();
112 }