PackageManager
[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 = 0;
44 static int id = 1;
45
46 TREE* tree = (TREE*)usrdata;
47
48 // ignore if tag is the root tag ("tree")
49 if(!strcmp(tag, "tree"))
50 return;
51
52 // set the package memory
53 tree->packages.resize(id+1);
54 memset(&tree->packages[id], 0, sizeof(tree->packages[id]));
55
56 tree->packages[id].loaded = FALSE;
57 tree->packages[id].icon = FALSE;
58 tree->packages[id].none = TRUE;
59 tree->packages[id].path = NULL;
60 tree->packages[id].name = "\0";
61
62 // read the arguments
63 for (i=0; arg[i]; i+=2)
64 {
65 if(!strcmp(arg[i], "name"))
66 {
67 tree->packages[id].name = new char [strlen(arg[i+1])+1];
68 strcpy(tree->packages[id].name, arg[i+1]);
69 }
70
71 if(!strcmp(arg[i], "icon"))
72 {
73 icon = atoi(arg[i+1]);
74 tree->packages[id].icon = TRUE;
75 }
76
77 if(!strcmp(arg[i], "file"))
78 {
79 tree->packages[id].path = new char [strlen(arg[i+1])+1];
80 strcpy(tree->packages[id].path, arg[i+1]);
81
82 if(strcmp(tag, "bin"))
83 tree->packages[id].inst = TRUE;
84
85 if(strcmp(tag, "src"))
86 tree->packages[id].src_inst = TRUE;
87 }
88 }
89
90 if(tree->packages[id].name[0] == '\0') return;
91
92 // add it
93 if(!parents.size())
94 {
95 if(tree->addItem)
96 tree->addItem(id, tree->packages[id].name, 0, icon);
97 }
98
99 // do some manipulation at the parent
100 else
101 {
102 tree->addItem(id, tree->packages[id].name, parents.back(), icon);
103
104 // list as child in the parent node
105 tree->packages[parents.back()].children.push_back(id);
106
107 // this is for the buttons
108 tree->packages[parents.back()].inst = tree->packages[parents.back()].inst || tree->packages[id].inst;
109 tree->packages[parents.back()].src_inst = tree->packages[parents.back()].src_inst || tree->packages[id].src_inst;
110 }
111
112 parents.push_back(id++);
113 }
114
115 // expat callback for end of a "node" tag
116 void tree_end (void* tree, const char* tag)
117 {
118 // delete last item
119 parents.pop_back();
120 }