.
[SXSI/XMLTree.git] / XMLTreeBuilder.cpp
1 #include "basics.h"\r
2 #include "XMLTreeBuilder.h"\r
3 #include "timings.h"\r
4 \r
5 XMLTreeBuilder::~XMLTreeBuilder(){\r
6   \r
7 }\r
8 \r
9 // OpenDocument(empty_texts): it starts the construction of the data structure for\r
10 // the XML document. Parameter empty_texts indicates whether we index empty texts\r
11 // in document or not. Returns a non-zero value upon success, NULLT in case of error.\r
12 int XMLTreeBuilder::OpenDocument(bool empty_texts, int sample_rate_text, bool dtc)\r
13  {\r
14     npar = 0;\r
15     parArraySize = 1;\r
16     disable_tc = dtc;\r
17 \r
18     STARTTIMER();\r
19    \r
20     par_aux = (pb *)umalloc(sizeof(pb)*parArraySize);\r
21     \r
22     tags_aux = (TagType *) umalloc(sizeof(TagType));\r
23     \r
24     TagName = new vector<string>();\r
25     tIdMap = new std::unordered_map<string,int>();\r
26 \r
27     REGISTER_TAG(TagName,tIdMap,DOCUMENT_OPEN_TAG);\r
28     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_OPEN_TAG);\r
29     REGISTER_TAG(TagName,tIdMap,PCDATA_OPEN_TAG);\r
30     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_DATA_OPEN_TAG);\r
31     REGISTER_TAG(TagName,tIdMap,CLOSING_TAG);\r
32     REGISTER_TAG(TagName,tIdMap,DOCUMENT_CLOSE_TAG);\r
33     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_CLOSE_TAG);\r
34     REGISTER_TAG(TagName,tIdMap,PCDATA_CLOSE_TAG);\r
35     REGISTER_TAG(TagName,tIdMap,ATTRIBUTE_DATA_CLOSE_TAG);\r
36 \r
37 \r
38     if (disable_tc)\r
39         TextBuilder = 0;\r
40     else \r
41       TextBuilder = new TextCollectionBuilder((unsigned)sample_rate_text);\r
42     Text = 0;\r
43     empty_texts_aux = (unsigned int *)ucalloc(sizeof(unsigned int),1);\r
44     eta_size = sizeof(unsigned int);\r
45     return 1;  // indicates success in the initialization of the data structure\r
46  }\r
47 \r
48 // CloseDocument(): it finishes the construction of the data structure for the XML\r
49 // document. Tree and tags are represented in the final form, dynamic data \r
50 // structures are made static, and the flag "finished" is set to true. After that, \r
51 // the data structure can be queried.\r
52 XMLTree *XMLTreeBuilder::CloseDocument()\r
53  {    \r
54     //closing parenthesis for the tree root\r
55     //par_aux = (pb *)urealloc(par_aux, sizeof(pb)*(1+npar/(8*sizeof(pb))));\r
56     //setbit(par_aux, npar, CP);\r
57     //npar++;\r
58     \r
59     // makes the text collection static\r
60    STOPTIMER(Parsing);\r
61    PRINTTIME("Parsing XML Document", Parsing);\r
62 \r
63     if (!disable_tc) {\r
64        assert(Text == 0);\r
65        assert(TextBuilder != 0);\r
66        STARTTIMER();\r
67        Text = TextBuilder->InitTextCollection();\r
68        delete TextBuilder;\r
69        TextBuilder = 0;\r
70        STOPTIMER(Building);\r
71        PRINTTIME("Building TextCollection", Building);\r
72 \r
73     }\r
74     \r
75     XMLTree *T = new XMLTree(par_aux,\r
76                              npar, \r
77                              TagName,\r
78                              tIdMap,\r
79                              empty_texts_aux,                // freed by the constructor\r
80                              tags_aux,                       //freed by the constructor\r
81                              Text,\r
82                              disable_tc);\r
83     return T; \r
84  }\r
85 \r
86 \r
87 // NewOpenTag(tagname): indicates the event of finding a new opening tag in the document.\r
88 // Tag name is given. Returns a non-zero value upon success, and returns NULLT\r
89 // in case of failing when trying to insert the new tag.\r
90 int XMLTreeBuilder::NewOpenTag(string tagname)\r
91  {\r
92     int i;\r
93     \r
94     // inserts a new opening parentheses in the bit sequence\r
95     if (sizeof(pb)*8*parArraySize == npar) { // no space left for the new parenthesis\r
96        par_aux = (pb *)urealloc(par_aux, sizeof(pb)*2*parArraySize);\r
97        parArraySize *= 2;\r
98     }\r
99     \r
100     setbit(par_aux,npar,OP);  // marks a new opening parenthesis\r
101     \r
102     TagIdMapIT tag_id = tIdMap->find(tagname);\r
103    \r
104     if (tag_id == tIdMap->end()){\r
105       REGISTER_TAG(TagName,tIdMap,tagname);\r
106       i = TagName->size() - 1;\r
107     }\r
108     else\r
109       i = tag_id->second;\r
110 \r
111     if (tagname.compare(PCDATA_OPEN_TAG) == 0 ||\r
112         tagname.compare(ATTRIBUTE_DATA_OPEN_TAG) == 0){\r
113     };\r
114     \r
115     tags_aux = (TagType *) urealloc(tags_aux, sizeof(TagType)*(npar + 1));\r
116     \r
117     tags_aux[npar] = i; // inserts the new tag id within the preorder sequence of tags\r
118     \r
119     npar++;\r
120     \r
121     return 1; // success    \r
122  }\r
123 \r
124 \r
125 // NewClosingTag(tagname): indicates the event of finding a new closing tag in the document.\r
126 // Tag name is given. Returns a non-zero value upon success, and returns NULLT\r
127 // in case of failing when trying to insert the new tag.\r
128 int XMLTreeBuilder::NewClosingTag(string tagname)\r
129  {\r
130     int i;\r
131     \r
132     // inserts a new closing parentheses in the bit sequence\r
133     if (sizeof(pb)*8*parArraySize == npar) { // no space left for the new parenthesis\r
134        par_aux = (pb *)urealloc(par_aux, sizeof(pb)*2*parArraySize);\r
135        parArraySize *= 2;\r
136     }\r
137     \r
138     setbit(par_aux,npar,CP);  // marks a new closing parenthesis\r
139     \r
140     //tagname.insert(0,"/");\r
141 \r
142     //TagIdMapIT tag_id = tIdMap->find(tagname);    \r
143 \r
144     // if (tag_id == tIdMap->end()){\r
145     //   REGISTER_TAG(TagName,tIdMap,tagname);\r
146     //   i = TagName->size() - 1;\r
147     // }\r
148     // else\r
149     //   i = tag_id->second;\r
150 \r
151     tags_aux = (TagType *)urealloc(tags_aux, sizeof(TagType)*(npar + 1));\r
152 \r
153     tags_aux[npar] = CLOSING_TAG_ID; // inserts the new tag id within the preorder sequence of tags\r
154     \r
155     npar++;\r
156 \r
157     return 1; // success\r
158  }\r
159 \r
160 \r
161 // NewText(s): indicates the event of finding a new (non-empty) text s in the document.\r
162 // The new text is inserted within the text collection. Returns a non-zero value upon\r
163 // success, NULLT in case of error.\r
164 int XMLTreeBuilder::NewText(string text)\r
165  {\r
166    if (!disable_tc) {\r
167      if  (text.empty())\r
168        TextBuilder->InsertText((uchar *)"\001");\r
169      else\r
170        TextBuilder->InsertText((uchar *) text.c_str());\r
171    };\r
172 \r
173    int n_eta_size = sizeof(uint)*(1+(npar-1)/(8*sizeof(uint)));\r
174    //see basics.h, recalloc resizes and sets the new area to 0.\r
175    \r
176    empty_texts_aux = (uint *)urecalloc(empty_texts_aux,eta_size,n_eta_size);\r
177    eta_size = n_eta_size;\r
178    bitset(empty_texts_aux, npar-1);  // marks the non-empty text with a 1 in the bit vector\r
179 \r
180    return 1; // success\r
181  }\r
182 \r
183 \r