move tcpsvcs from the /apps directory to the /services directory
[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 int LoadOptions (TREE* tree);
19
20 void tree_end (void* tree, const char* tag);
21 void tree_start (void* usrdata, const char* tag, const char** arg);
22
23 int PML_XmlDownload (pTree tree, const char* file, void* usrdata, XML_StartElementHandler start,
24 XML_EndElementHandler end, XML_CharacterDataHandler text=0);
25
26
27 // Load the tree
28 extern "C" int PML_LoadTree (TREE** tree, char* url, PML_AddItem AddItem)
29 {
30 // get the memory
31 (*tree) = new TREE;
32
33 // set every to zero
34 memset((*tree), 0, sizeof((*tree)));
35
36 // set addItem callback
37 (*tree)->addItem = AddItem;
38
39 LoadOptions(*tree);
40
41 return PML_XmlDownload (*tree, url, (void*)(*tree), tree_start, tree_end);
42 }
43
44 // expat callback for start of a "node" tag
45 void tree_start (void* usrdata, const char* tag, const char** arg)
46 {
47 int i, icon = 0;
48 static int id = 1;
49
50 TREE* tree = (TREE*)usrdata;
51
52 // ignore if tag is the root tag ("tree")
53 if(!strcmp(tag, "tree"))
54 return;
55
56 // set the package memory
57 tree->packages.resize(id+1);
58 memset(&tree->packages[id], 0, sizeof(tree->packages[id]));
59
60 tree->packages[id].loaded = FALSE;
61 tree->packages[id].icon = FALSE;
62 tree->packages[id].none = TRUE;
63 tree->packages[id].path = NULL;
64 tree->packages[id].name = "\0";
65
66 // read the arguments
67 for (i=0; arg[i]; i+=2)
68 {
69 if(!strcmp(arg[i], "name"))
70 {
71 tree->packages[id].name = new char [strlen(arg[i+1])+1];
72 strcpy(tree->packages[id].name, arg[i+1]);
73 }
74
75 if(!strcmp(arg[i], "icon"))
76 {
77 icon = atoi(arg[i+1]);
78 tree->packages[id].icon = TRUE;
79 }
80
81 if(!strcmp(arg[i], "file"))
82 {
83 tree->packages[id].path = new char [strlen(arg[i+1])+1];
84 strcpy(tree->packages[id].path, arg[i+1]);
85
86 if(strcmp(tag, "bin"))
87 tree->packages[id].inst = TRUE;
88
89 if(strcmp(tag, "src"))
90 tree->packages[id].src_inst = TRUE;
91 }
92 }
93
94 if(tree->packages[id].name[0] == '\0') return;
95
96 // add it
97 if(!parents.size())
98 {
99 if(tree->addItem)
100 tree->addItem(id, tree->packages[id].name, 0, icon);
101 }
102
103 // do some manipulation at the parent
104 else
105 {
106 if(tree->addItem)
107 tree->addItem(id, tree->packages[id].name, parents.back(), icon);
108
109 // list as child in the parent node
110 tree->packages[parents.back()].children.push_back(id);
111
112 // this is for the buttons
113 tree->packages[parents.back()].inst = tree->packages[parents.back()].inst || tree->packages[id].inst;
114 tree->packages[parents.back()].src_inst = tree->packages[parents.back()].src_inst || tree->packages[id].src_inst;
115 }
116
117 parents.push_back(id++);
118 }
119
120 // expat callback for end of a "node" tag
121 void tree_end (void* tree, const char* tag)
122 {
123 // delete last item
124 parents.pop_back();
125 }
126