00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035 #include "buffernode.h"
00036 #include "outputstream.h"
00037 #include <cstring>
00038 #include <cstdlib>
00039
00040 BufferNode::BufferNode(const char *_data,
00041 BufferNode * _parent):type(TYPE_PCDATA),
00042 parent(_parent),
00043 r_sibling(NULL),
00044 #ifdef ROLE_REFCOUNT
00045 cumulative_roles(0),
00046 non_cumulative_roles(0),
00047 #else
00048 cumulative_roles(NULL),
00049 non_cumulative_roles(NULL),
00050 #endif
00051
00052 node((void *) new CharNode(_data)),
00053 is_locked(false) {
00054 }
00055
00056 BufferNode::BufferNode(TAG _tag, BufferNode * _parent):type(TYPE_TAG),
00057 parent(_parent),
00058 r_sibling(NULL),
00059 #ifdef ROLE_REFCOUNT
00060 cumulative_roles(0),
00061 non_cumulative_roles(0),
00062 #else
00063 cumulative_roles(NULL),
00064 non_cumulative_roles(NULL),
00065 #endif
00066 node((void *) new TagNode(_tag)),
00067 is_locked(false) {
00068 }
00069
00070 BufferNode::BufferNode(const char *_data, BufferNode * _parent,
00071 vector < unsigned >*_cumulative_roles,
00072 vector <
00073 unsigned >*_non_cumulative_roles):type(TYPE_PCDATA),
00074 parent(_parent),
00075 r_sibling(NULL),
00076 #ifdef ROLE_REFCOUNT
00077 cumulative_roles(0),
00078 non_cumulative_roles(0),
00079 #else
00080 cumulative_roles(NULL),
00081 non_cumulative_roles(NULL),
00082 #endif
00083
00084 node((void *) new CharNode(_data)),
00085 is_locked(false) {
00086 appendRoles(_cumulative_roles, _non_cumulative_roles);
00087 }
00088
00089 BufferNode::BufferNode(TAG _tag, BufferNode * _parent,
00090 vector < unsigned >*_cumulative_roles,
00091 vector <
00092 unsigned >*_non_cumulative_roles):type(TYPE_TAG),
00093 parent(_parent),
00094 r_sibling(NULL),
00095 #ifdef ROLE_REFCOUNT
00096 cumulative_roles(0),
00097 non_cumulative_roles(0),
00098 #else
00099 cumulative_roles(NULL),
00100 non_cumulative_roles(NULL),
00101 #endif
00102
00103 node((void *) new TagNode(_tag)),
00104 is_locked(false) {
00105 appendRoles(_cumulative_roles, _non_cumulative_roles);
00106 }
00107
00108 BufferNode::~BufferNode() {
00109 if (type == TYPE_TAG) {
00110 TagNode *t = (TagNode *) node;
00111 delete t;
00112 } else if (type == TYPE_PCDATA) {
00113 CharNode *c = (CharNode *) node;
00114 delete c;
00115 }
00116 #ifndef ROLE_REFCOUNT
00117 delete cumulative_roles;
00118 delete non_cumulative_roles;
00119 #endif // #ifndef ROLE_REFCOUNT
00120 }
00121
00122 void BufferNode::addChild(BufferNode * child) {
00123 TagNode *t = (TagNode *) node;
00124
00125 t->children.push_back(child);
00126 }
00127
00128 void BufferNode::appendRoles(vector < unsigned >*_cumulative_roles,
00129 vector < unsigned >*_non_cumulative_roles) {
00130 #ifdef ROLE_REFCOUNT
00131 cumulative_roles = _cumulative_roles->size();
00132 non_cumulative_roles = _non_cumulative_roles->size();
00133 #else
00134 cumulative_roles = new IntMultiSet(_cumulative_roles);
00135 non_cumulative_roles = new IntMultiSet(_non_cumulative_roles);
00136 #endif // #ifdef ROLE_REFCOUNT
00137 }
00138
00139 void BufferNode::print(OutputStream & eos) {
00140 TagMap *tagmap = TagMap::getInstance();
00141
00142 if (type == TYPE_TAG) {
00143 if (((TagNode *) node)->children.isEmpty()) {
00144 if (parent != NULL)
00145 eos << "<" << tagmap->getTag(((TagNode *) node)->tag) << "/>";
00146 } else {
00147 if (parent != NULL)
00148 eos << "<" << tagmap->getTag(((TagNode *) node)->tag) << ">";
00149 for (BufferNode * it = ((TagNode *) node)->children.getFront();
00150 it; it = it->r_sibling) {
00151 it->print(eos);
00152 }
00153 if (((TagNode *) node)->is_closed && parent != NULL)
00154 eos << "</" << tagmap->getTag(((TagNode *) node)->tag) << ">";
00155 }
00156 } else if (type == TYPE_PCDATA) {
00157 eos << ((CharNode *) node)->data;
00158 }
00159 }
00160
00161 void BufferNode::printNoSubnodes(OutputStream & dos) {
00162 TagMap *tagmap = TagMap::getInstance();
00163
00164 if (type == TYPE_TAG) {
00165 dos << "<" << tagmap->getTag(((TagNode *) node)->tag) << ">";
00166 } else if (type == TYPE_PCDATA) {
00167 dos << ((CharNode *) node)->data;
00168 }
00169 }
00170
00171 void BufferNode::debugPrint(OutputStream & dos) {
00172 TagMap *tagmap = TagMap::getInstance();
00173
00174 if (type == TYPE_TAG) {
00175 dos << "(<" << tagmap->getTag(((TagNode *) node)->tag) << ">";
00176 } else if (type == TYPE_PCDATA) {
00177 dos << "(" << ((CharNode *) node)->data;
00178 }
00179
00180 (is_locked) ? dos << "[locked],{" : dos << "{";
00181 #ifdef ROLE_REFCOUNT
00182 dos << "cc=" << cumulative_roles << ",nc=" << non_cumulative_roles;
00183 #else
00184 if (cumulative_roles) {
00185 cumulative_roles->print(dos);
00186 }
00187 dos << "},{";
00188 if (non_cumulative_roles) {
00189 non_cumulative_roles->print(dos);
00190 }
00191 #endif // #ifdef ROLE_REFCOUNT
00192 dos << "})";
00193
00194
00195 if (type == TYPE_TAG) {
00196 for (BufferNode * it = ((TagNode *) node)->children.getFront(); it; it
00197 = it->r_sibling) {
00198 it->debugPrint(dos);
00199 }
00200 if (((TagNode *) node)->is_closed)
00201 dos << "</" << tagmap->getTag(((TagNode *) node)->tag) << ">";
00202 }
00203 dos << NEWLINE;
00204 }
00205
00206 void BufferNode::debugPrintCompleteBuffer(OutputStream & dos) {
00207 parent == NULL ? debugPrint(dos) : parent->debugPrintCompleteBuffer(dos);
00208 }
00209
00210
00211 const char *BufferNode::getPCDataRepresentation() {
00212 std::ostringstream s;
00213 getPCDataRepresentation(s);
00214
00215
00216 return strdup(s.str().c_str());
00217 }
00218
00219 void BufferNode::getPCDataRepresentation(std::ostringstream & s) {
00220 if (type == TYPE_PCDATA) {
00221 s << ((CharNode *) node)->data;
00222 } else {
00223 TagNode *tag = (TagNode *) node;
00224
00225 for (BufferNode * it = tag->children.getFront(); it; it = it->r_sibling) {
00226 it->getPCDataRepresentation(s);
00227 }
00228 }
00229 }
00230
00231 bool BufferNode::isMarked() {
00232 #ifdef ROLE_REFCOUNT
00233 return (bool) (cumulative_roles + non_cumulative_roles);
00234 #else
00235 return (!non_cumulative_roles->isEmpty())
00236 || (!cumulative_roles->isEmpty());
00237 #endif // #ifdef ROLE_REFCOUNT
00238 }
00239
00240 bool BufferNode::isCumulativeMarked() {
00241 #ifdef ROLE_REFCOUNT
00242 return (bool) cumulative_roles;
00243 #else
00244 return !cumulative_roles->isEmpty();
00245 #endif // #ifdef ROLE_REFCOUNT
00246 }
00247
00248 bool BufferNode::hasCumulativeMarkedAncestor() {
00249 return isRoot()? false : parent->isCumulativeMarked() ||
00250 parent->hasCumulativeMarkedAncestor();
00251 }
00252
00253 bool BufferNode::hasNoMarkedAndNoLockedDos() {
00254
00255 if (isMarked() || is_locked)
00256 return false;
00257
00258 if (type == TYPE_PCDATA) {
00259 return true;
00260 } else {
00261 TagNode *t = (TagNode *) node;
00262
00263 for (BufferNode * it = t->children.getFront(); it; it = it->r_sibling) {
00264 if (!it->hasNoMarkedAndNoLockedDos()) {
00265 return false;
00266 }
00267 }
00268 return true;
00269 }
00270 }
00271
00272 void BufferNode::removeRoleFromNode(Role * role) {
00273 #ifdef ROLE_REFCOUNT
00274 role->isDosRole()? cumulative_roles-- : non_cumulative_roles--;
00275 #else
00276
00277
00278 cumulative_roles->removeElem(role->getId());
00279 non_cumulative_roles->removeElem(role->getId());
00280 #endif // #ifdef ROLE_REFCOUNT
00281 clear();
00282 }
00283
00284 void BufferNode::clear() {
00285
00286 clearSubtreeIfPossible();
00287
00288
00289 if (is_locked)
00290 return;
00291
00292 switch (type) {
00293 case TYPE_TAG:
00294 if (((TagNode *) node)->children.isEmpty() && !isRoot()) {
00295 parent->clear();
00296 }
00297 break;
00298
00299 case TYPE_PCDATA:
00300 parent->clear();
00301 break;
00302 }
00303 }
00304
00305 void BufferNode::clearSubtreeIfPossible() {
00306 if (type != TYPE_TAG)
00307 return;
00308
00309 TagNode *cur = ((TagNode *) node);
00310
00311 if (!(isCumulativeMarked() || hasCumulativeMarkedAncestor())) {
00312
00313 BufferNode *c_prev = NULL;
00314 bool deleted = true;
00315
00316 for (BufferNode * c = cur->children.getFront(); c && deleted;) {
00317
00318 BufferNode *c_next = c->r_sibling;
00319
00320 if (c->hasNoMarkedAndNoLockedDos() &&
00321 !(c->type == TYPE_TAG && !c->isClosed())) {
00322 cur->children.removeElem(c, c_prev);
00323 } else {
00324 deleted = false;
00325 c_prev = c;
00326 }
00327
00328 c = c_next;
00329 }
00330 }
00331 }