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
00027
00028 #include "xml/sxs.hpp"
00029 #include "xml/defxml.hpp"
00030 #include "xml/declxml.hpp"
00031
00032 #include "base/common.hpp"
00033 #include "base/memory.hpp"
00034 #include "base/list.hpp"
00035 #include "base/map.hpp"
00036 #include "base/string.hpp"
00037 #include "base/template.hpp"
00038
00039 BEGIN_TERIMBER_NAMESPACE
00040 #pragma pack(4)
00041
00043 nodeDecl::~nodeDecl()
00044 {
00045 }
00046
00047 nodeDecl::nodeDecl(xmlNodeType type) :
00048 _type(type)
00049 {
00050 }
00051
00052 nodeDecl::nodeDecl(const nodeDecl& x) :
00053 _type(x._type)
00054 {
00055 }
00056
00058 namedNode::namedNode(const char* name, byte_allocator* allocator_) :
00059 _name(name, allocator_)
00060 {
00061 }
00062
00063 namedNode::namedNode(const namedNode& x) : _name(x._name)
00064 {
00065 }
00066
00067 void
00068 namedNode::clear()
00069 {
00070 _name = 0;
00071 }
00072
00074 namedNodeDecl::namedNodeDecl(xmlNodeType type, const char* name, byte_allocator* allocator_) :
00075 nodeDecl(type),
00076 namedNode(name, allocator_)
00077 {
00078 }
00079
00080 namedNodeDecl::namedNodeDecl(const namedNodeDecl& x) :
00081 nodeDecl(x), namedNode(x)
00082 {
00083 }
00084
00085 void
00086 namedNodeDecl::clear()
00087 {
00088 namedNode::clear();
00089 }
00090
00092 enumNodeDecl::enumNodeDecl(byte_allocator* allocator_) :
00093 _id(0), _value(allocator_)
00094 {
00095 }
00096
00097 enumNodeDecl::enumNodeDecl(const enumNodeDecl& x) :
00098 _id(x._id), _value(x._value)
00099 {
00100 }
00101
00103 attributeDecl::attributeDecl(const char* name, byte_allocator* allocator_) :
00104 namedNodeDecl(ATTRIBUTE_NODE, name, allocator_),
00105 _atype(attributeType_MIN),
00106 _ctype(vt_unknown),
00107 _defval(allocator_),
00108 _rule(attributeRule_MIN)
00109 {
00110 }
00111
00112 attributeDecl::attributeDecl(const attributeDecl& x) :
00113 namedNodeDecl(x),
00114 _atype(x._atype),
00115 _ctype(x._ctype),
00116 _enum(x._enum),
00117 _defval(x._defval),
00118 _rule(x._rule)
00119 {
00120 }
00121
00122 const char*
00123 attributeDecl::persist_attribute(const terimber_xml_value& value, byte_allocator* allocator_) const
00124 {
00125 if (_ctype == vt_enum)
00126 {
00127 for (_list< enumNodeDecl >::const_iterator iter = _enum.begin(); iter != _enum.end(); ++iter)
00128 if (iter->_id == value.lVal)
00129 {
00130 terimber_xml_value dummy;
00131 dummy.strVal = iter->_value;
00132 return persist_value(vt_string, dummy, allocator_);
00133 }
00134
00135 return 0;
00136 }
00137 else
00138 return persist_value(_ctype, value, allocator_);
00139
00140 }
00141
00143 notationDecl::notationDecl(const char* name, byte_allocator* allocator_) :
00144 namedNodeDecl(NOTATION_NODE, name, allocator_),
00145 _systemId(allocator_),
00146 _publicId(allocator_)
00147 {
00148 }
00149
00150
00151 notationDecl::notationDecl(const notationDecl& x) :
00152 namedNodeDecl(x),
00153 _systemId(x._systemId),
00154 _publicId(x._publicId)
00155 {
00156 }
00157
00159 entityDecl::entityDecl(const char* name, byte_allocator* allocator_) :
00160 namedNodeDecl(ENTITY_NODE, name, allocator_),
00161 _systemId(allocator_),
00162 _publicId(allocator_),
00163 _notation(allocator_),
00164 _value(allocator_),
00165 _is_in_subset(false),
00166 _is_parameter(false),
00167 _is_encoded_char(false),
00168 _is_unparsed(false)
00169 {
00170 }
00171
00172 entityDecl::entityDecl(const entityDecl& x) :
00173 namedNodeDecl(x),
00174 _systemId(x._systemId),
00175 _publicId(x._publicId),
00176 _notation(x._notation),
00177 _value(x._value),
00178 _is_in_subset(x._is_in_subset),
00179 _is_parameter(x._is_parameter),
00180 _is_encoded_char(x._is_encoded_char),
00181 _is_unparsed(x._is_unparsed)
00182 {
00183 }
00184
00186 attributeRefDecl::attributeRefDecl(const char* name, byte_allocator* allocator_) :
00187 namedNode(name, allocator_),
00188 _declared(false),
00189 _refered(false)
00190 {
00191 }
00192
00193 attributeRefDecl::attributeRefDecl(const attributeRefDecl& x) :
00194 namedNode(x),
00195 _declared(x._declared),
00196 _refered(x._refered)
00197 {
00198 }
00199
00201 elementDecl::elementDecl(const char*name, byte_allocator* allocator_) :
00202 namedNodeDecl(ELEMENT_NODE, name, allocator_),
00203 _content(contentSpec_MIN),
00204 _token(0),
00205 _attributes()
00206 {
00207 }
00208
00209 elementDecl::elementDecl(const elementDecl& x) :
00210 namedNodeDecl(x),
00211 _content(x._content),
00212 _token(x._token),
00213 _attributes(x._attributes)
00214 {
00215 }
00216
00217
00219 dfa_token::dfa_token() :
00220 _rule(dfaRule_MIN), _decl(0), _first(0), _last(0)
00221 {
00222 }
00223
00224 dfa_token::dfa_token(byte_allocator& allocator_, const dfa_token& x) :
00225 _rule(x._rule), _decl(x._decl), _first(x._first), _last(x._last)
00226 {
00227 }
00228
00229 dfa_token::dfa_token(dfaRule rule, const elementDecl* decl, dfa_token* first, dfa_token* last) :
00230 _rule(rule), _decl(decl), _first(first), _last(last)
00231 {
00232 }
00233
00234 dfa_token::~dfa_token()
00235 {
00236 }
00237
00238 void
00239 dfa_token::assign(byte_allocator& allocator_, const dfa_token& x)
00240 {
00241 _decl = x._decl;
00242 _rule = x._rule;
00243
00244 if (x._first)
00245 {
00246 _first = new(check_pointer(allocator_.allocate(sizeof(dfa_token)))) dfa_token(allocator_, *x._first);
00247
00248 _first->assign(allocator_, *x._first);
00249 }
00250
00251 if (x._last)
00252 {
00253 _last = new(check_pointer(allocator_.allocate(sizeof(dfa_token)))) dfa_token(allocator_, *x._last);
00254
00255 _last->assign(allocator_, *x._last);
00256 }
00257 }
00258
00259 bool
00260 dfa_token::find_any_resursively() const
00261 {
00262 if (_first
00263 && (_first->_decl && _first->_decl->_content == CONTENT_ANY
00264 || _first->find_any_resursively())
00265 )
00266 return true;
00267
00268 if (_last
00269 && (_last->_decl && _last->_decl->_content == CONTENT_ANY
00270 || _last->find_any_resursively())
00271 )
00272 return true;
00273
00274 return false;
00275 }
00276
00278 xml_grammar::xml_grammar(mem_pool_t& small_manager, mem_pool_t& big_manager, size_t xml_size) :
00279 _small_manager(small_manager),
00280 _big_manager(big_manager),
00281 _xml_size(__max(xml_size, os_def_size)),
00282 _data_allocator(xml_size <= os_def_size ? *small_manager.loan_object() : *big_manager.loan_object()),
00283 _tmp_allocator(*small_manager.loan_object()),
00284 _document_decl(DOCUMENT_NODE, 0, 0),
00285 _doctype_decl(DOCUMENT_TYPE_NODE, 0, 0),
00286 _text_decl(TEXT_NODE, 0, 0),
00287 _comment_decl(COMMENT_NODE, 0, 0),
00288 _cdata_decl(CDATA_SECTION_NODE, 0, 0),
00289 _read_only(false),
00290 _doc_name(&_data_allocator),
00291 _public_id(&_data_allocator),
00292 _system_id(&_data_allocator)
00293 {
00294 }
00295
00296 xml_grammar::~xml_grammar()
00297 {
00298 clear();
00299 _xml_size <= os_def_size ? _small_manager.return_object(&_data_allocator) : _big_manager.return_object(&_data_allocator);
00300 _small_manager.return_object(&_tmp_allocator);
00301 }
00302
00303 xml_grammar&
00304 xml_grammar::copy(const xml_grammar& x)
00305 {
00306 if (this != &x)
00307 {
00308 _doc_name = x._doc_name;
00309 _public_id = x._public_id;
00310 _system_id = x._system_id;
00311
00312
00313 notationDecl dummy_notation(0, &_data_allocator);
00314 _notationMap.clear();
00315 for (notation_decl_map_t::const_iterator INot = x._notationMap.begin(); INot != x._notationMap.end(); ++INot)
00316 {
00317 notationDecl& decl = *_notationMap.insert(_data_allocator, INot.key(), dummy_notation).first;
00318 decl._name = INot->_name;
00319 decl._publicId = INot->_publicId;
00320 decl._systemId = INot->_systemId;
00321 }
00322
00323 entityDecl dummy_entity(0, &_data_allocator);
00324 _entityMap.clear();
00325 for (entity_decl_map_t::const_iterator IEnt = x._entityMap.begin(); IEnt != x._entityMap.end(); ++IEnt)
00326 {
00327 entityDecl& decl = *_entityMap.insert(_data_allocator, IEnt.key(), dummy_entity).first;
00328 decl._is_encoded_char = IEnt->_is_encoded_char;
00329 decl._is_in_subset = IEnt->_is_in_subset;
00330 decl._is_parameter = IEnt->_is_parameter;
00331 decl._is_unparsed = IEnt->_is_unparsed;
00332 decl._name = IEnt->_name;
00333 decl._notation = IEnt->_notation;
00334 decl._publicId = IEnt->_publicId;
00335 decl._systemId = IEnt->_systemId;
00336 decl._value = IEnt->_value;
00337 }
00338
00339 attributeRefDecl dummy_attributeRef(0, &_data_allocator);
00340 _attributeRefMap.clear();
00341 for (attribute_ref_decl_map_t::const_iterator iterAttRef = x._attributeRefMap.begin(); iterAttRef != x._attributeRefMap.end(); ++iterAttRef)
00342 {
00343 attributeRefDecl& decl = *_attributeRefMap.insert(_data_allocator, iterAttRef.key(), dummy_attributeRef).first;
00344 decl._declared = iterAttRef->_declared;
00345 decl._name = iterAttRef->_name;
00346 decl._refered = iterAttRef->_refered;
00347 }
00348
00349 namedNodeDecl dummy_pi(PROCESSING_INSTRUCTION_NODE, 0, &_data_allocator);
00350 _piMap.clear();
00351 for (namednode_decl_map_t::const_iterator IPi = x._piMap.begin(); IPi != x._piMap.end(); ++IPi)
00352 {
00353 namedNodeDecl& decl = *_piMap.insert(_data_allocator, IPi.key(), dummy_pi).first;
00354 decl._name = IPi->_name;
00355 }
00356
00357 elementDecl dummy_element(0, &_data_allocator);
00358 attributeDecl dummy_attribute(0, &_data_allocator);
00359 enumNodeDecl dummy_enum(&_data_allocator);
00360 _elementMap.clear();
00361 for (element_decl_map_t::const_iterator IEl = x._elementMap.begin(); IEl != x._elementMap.end(); ++IEl)
00362 {
00363 elementDecl& decl = *_elementMap.insert(_data_allocator, IEl.key(), dummy_element).first;
00364
00365
00366 decl._name = IEl->_name;
00367
00368
00369 for (attribute_decl_map_t::const_iterator IAttr = IEl->_attributes.begin(); IAttr != IEl->_attributes.end(); ++IAttr)
00370 {
00371 attributeDecl& declAttr = *decl._attributes.insert(_data_allocator, IAttr.key(), dummy_attribute).first;
00372 declAttr._atype = IAttr->_atype;
00373 declAttr._ctype = IAttr->_ctype;
00374 declAttr._defval = IAttr->_defval;
00375 declAttr._name = IAttr->_name;
00376 declAttr._rule = IAttr->_rule;
00377
00378
00379 for (_list< enumNodeDecl >::const_iterator IEn = IAttr->_enum.begin(); IEn != IAttr->_enum.end(); ++IEn)
00380 {
00381 enumNodeDecl& entryEn = *declAttr._enum.push_back(_data_allocator, dummy_enum);
00382 entryEn._id = IEn->_id;
00383 entryEn._value = IEn->_value;
00384 }
00385 }
00386
00387
00388 decl._content = IEl->_content;
00389 if (IEl->_token)
00390 {
00391 decl._token = new(check_pointer(_data_allocator.allocate(sizeof(dfa_token)))) dfa_token(_data_allocator, *IEl->_token);
00392 decl._token->assign(_data_allocator, *IEl->_token);
00393 }
00394 }
00395
00396 _read_only = true;
00397 }
00398 return *this;
00399 }
00400
00401 elementDecl&
00402 xml_grammar::add_element_decl(const char* name, bool on_fly, bool fromDecl, bool modelAny)
00403 {
00404
00405 check_readonly();
00406
00407
00408 size_t hash_value = do_hash((const char*)name, os_minus_one);
00409 element_decl_map_t::pairii_t range = _elementMap.equal_range(hash_value);
00410 element_decl_map_t::iterator start(range.first);
00411
00412 if (start != range.second)
00413 for (start = range.first; start != range.second; ++start)
00414 if (start->_name == name)
00415 {
00416 if (fromDecl && start->_content != contentSpec_MIN)
00417 xml_exception_throw("Dublicate element name: ",
00418 (const char*)name,
00419 0);
00420 return *start;
00421 }
00422
00423
00424
00425 elementDecl decl(0, &_data_allocator);
00426 start = _elementMap.insert(_data_allocator, hash_value, decl).first;
00427 if (start == _elementMap.end())
00428 xml_exception_throw("Not enough memory", 0);
00429
00430 start->_name = name;
00431
00432 if (on_fly || fromDecl || modelAny || (name[0] == 'A' && name[1] == 'N' && name[2] == 'Y' && name[3] == 0))
00433 start->_content = CONTENT_ANY;
00434
00435 return *start;
00436 }
00437
00438 const elementDecl*
00439 xml_grammar::find_element_decl(const char* name) const
00440 {
00441 if (_elementMap.empty())
00442 return 0;
00443
00444 element_decl_map_t::paircc_t range = _elementMap.equal_range(do_hash(name, os_minus_one));
00445 for (element_decl_map_t::const_iterator start = range.first; start != range.second; ++start)
00446 if (start->_name == name)
00447 return &*start;
00448
00449 return 0;
00450 }
00451
00452 elementDecl*
00453 xml_grammar::find_element_decl(const char* name)
00454 {
00455 check_readonly();
00456 if (_elementMap.empty())
00457 return 0;
00458
00459 element_decl_map_t::pairii_t range = _elementMap.equal_range(do_hash(name, os_minus_one));
00460 for (element_decl_map_t::iterator start = range.first; start != range.second; ++start)
00461 if (start->_name == name)
00462 return &*start;
00463
00464 return 0;
00465 }
00466
00467 notationDecl&
00468 xml_grammar::add_notation_decl(const char* name)
00469 {
00470 check_readonly();
00471 size_t hash_value = do_hash(name, os_minus_one);
00472 notation_decl_map_t::pairii_t range = _notationMap.equal_range(hash_value);
00473 notation_decl_map_t::iterator start(range.first);
00474
00475 if (start != range.second)
00476 for (start = range.first; start != range.second; ++start)
00477 if (start->_name == name)
00478 xml_exception_throw("Dublicate notation name: ",
00479 (const char*)name,
00480 0);
00481
00482
00483 notationDecl decl(0, &_data_allocator);
00484 start = _notationMap.insert(_data_allocator, hash_value, decl).first;
00485 if (start == _notationMap.end())
00486 xml_exception_throw("Not enough memory", 0);
00487
00488 start->_name = name;
00489 return *start;
00490 }
00491
00492 const notationDecl*
00493 xml_grammar::find_notation_decl(const char* name) const
00494 {
00495 if (_notationMap.empty())
00496 return 0;
00497
00498 notation_decl_map_t::paircc_t range = _notationMap.equal_range(do_hash(name, os_minus_one));
00499
00500 for (notation_decl_map_t::const_iterator start = range.first; start != range.second; ++start)
00501 if (start->_name == name)
00502 return &*start;
00503
00504 return 0;
00505 }
00506
00507 entityDecl&
00508 xml_grammar::add_entity_decl(const char* name, bool& wasAdded)
00509 {
00510 check_readonly();
00511 wasAdded = false;
00512 size_t hash_value = do_hash(name, os_minus_one);
00513 entity_decl_map_t::pairii_t range = _entityMap.equal_range(hash_value);
00514 entity_decl_map_t::iterator start(range.first);
00515
00516 if (start != range.second)
00517 for (start = range.first; start != range.second; ++start)
00518 if (start->_name == name)
00519 return *start;
00520
00521
00522 entityDecl decl(0, &_data_allocator);
00523 start = _entityMap.insert(_data_allocator, hash_value, decl).first;
00524 if (start == _entityMap.end())
00525 xml_exception_throw("Not enough memory", 0);
00526
00527 start->_name = name;
00528 wasAdded = true;
00529
00530 return *start;
00531 }
00532
00533 const entityDecl*
00534 xml_grammar::find_entity_decl(const char* name) const
00535 {
00536 if (_entityMap.empty())
00537 return 0;
00538
00539 entity_decl_map_t::paircc_t range = _entityMap.equal_range(do_hash(name, os_minus_one));
00540
00541 for (entity_decl_map_t::const_iterator start = range.first; start != range.second; ++start)
00542 if (start->_name == name)
00543 return &*start;
00544
00545 return 0;
00546 }
00547
00548 entityDecl*
00549 xml_grammar::find_entity_decl(const char* name)
00550 {
00551 check_readonly();
00552
00553 if (_entityMap.empty())
00554 return 0;
00555
00556 entity_decl_map_t::pairii_t range = _entityMap.equal_range(do_hash(name, os_minus_one));
00557
00558 for (entity_decl_map_t::iterator start = range.first; start != range.second; ++start)
00559 if (start->_name == name)
00560 return &*start;
00561
00562 return 0;
00563 }
00564
00565 attributeDecl&
00566 xml_grammar::add_attribute_decl(const elementDecl& decl, const char* name, bool mustPresent, bool& wasAdded)
00567 {
00568
00569 check_readonly();
00570
00571 elementDecl& decl_ = const_cast< elementDecl& >(decl);
00572 wasAdded = false;
00573
00574 size_t hash_value = do_hash(name, os_minus_one);
00575 attribute_decl_map_t::pairii_t range = decl_._attributes.equal_range(hash_value);
00576 attribute_decl_map_t::iterator start(range.first);
00577
00578 if (start != range.second)
00579 for (start = range.first; start != range.second; ++start)
00580 if (start->_name == name)
00581 return *start;
00582
00583 if (mustPresent && decl._content != CONTENT_ANY)
00584 {
00585 xml_exception_throw("Unknown attribute found: ",
00586 name,
00587 " beneath parent element: ",
00588 (const char*)decl._name,
00589 0);
00590 }
00591
00592 attributeDecl adecl(0, &_data_allocator);
00593 start = decl_._attributes.insert(_data_allocator, hash_value, adecl).first;
00594 if (start == decl_._attributes.end())
00595 xml_exception_throw("Not enough memory", 0);
00596
00597 start->_name = name;
00598 start->_atype = ATTR_TYPE_CDATA;
00599 start->_ctype = vt_string;
00600 start->_rule = ATTR_RULE_IMPLIED;
00601
00602 wasAdded = true;
00603
00604 return *start;
00605 }
00606
00607 const attributeDecl*
00608 xml_grammar::find_attribute_decl(const elementDecl& decl, const char* qname) const
00609 {
00610 if (decl._attributes.empty())
00611 return 0;
00612
00613 attribute_decl_map_t::paircc_t range = decl._attributes.equal_range(do_hash(qname, os_minus_one));
00614 for (attribute_decl_map_t::const_iterator start = range.first; start != range.second; ++start)
00615 if (start->_name == qname)
00616 return &*start;
00617
00618 return 0;
00619 }
00620
00621 attributeRefDecl&
00622 xml_grammar::add_reference_decl(const char* name, bool fromID)
00623 {
00624 check_readonly();
00625 size_t hash_value = do_hash(name, os_minus_one);
00626 attribute_ref_decl_map_t::pairii_t range = _attributeRefMap.equal_range(hash_value);
00627 attribute_ref_decl_map_t::iterator start(range.first);
00628
00629 if (start != range.second)
00630 for (start = range.first; start != range.second; ++start)
00631 if (start->_name == name)
00632 xml_exception_throw("Dublicate attribute reference name: ",
00633 (const char*)name,
00634 0);
00635
00636
00637 attributeRefDecl decl(0, &_data_allocator);
00638 start = _attributeRefMap.insert(_data_allocator, hash_value, decl).first;
00639 if (start == _attributeRefMap.end())
00640 xml_exception_throw("Not enough memory", 0);
00641
00642 start->_name = name;
00643 (fromID ? start->_declared : start->_refered) = true;
00644
00645 return *start;
00646 }
00647
00648 attributeRefDecl*
00649 xml_grammar::find_reference_decl(const char* name)
00650 {
00651 if (_attributeRefMap.empty())
00652 return 0;
00653
00654 size_t hash_value = do_hash(name, os_minus_one);
00655 attribute_ref_decl_map_t::pairii_t range = _attributeRefMap.equal_range(hash_value);
00656
00657 for (attribute_ref_decl_map_t::iterator start = range.first; start != range.second; ++start)
00658 if (start->_name == name)
00659 return &*start;
00660
00661 return 0;
00662 }
00663
00664 namedNodeDecl&
00665 xml_grammar::add_pi_decl(const char* name)
00666 {
00667 check_readonly();
00668 size_t hash_value = do_hash(name, os_minus_one);
00669 namednode_decl_map_t::pairii_t range = _piMap.equal_range(hash_value);
00670 namednode_decl_map_t::iterator start(range.first);
00671
00672 if (start != range.second)
00673 for (start = range.first; start != range.second; ++start)
00674 if (start->_name == name)
00675 return *start;
00676
00677
00678 namedNodeDecl decl(PROCESSING_INSTRUCTION_NODE, 0, &_data_allocator);
00679 start = _piMap.insert(_data_allocator, hash_value, decl).first;
00680 if (start == _piMap.end())
00681 xml_exception_throw("Not enough memory", 0);
00682
00683 start->_name = name;
00684 return *start;
00685 }
00686
00687 const namedNodeDecl*
00688 xml_grammar::find_pi_decl(const char* name) const
00689 {
00690 if (_piMap.empty())
00691 return 0;
00692
00693 namednode_decl_map_t::paircc_t range = _piMap.equal_range(do_hash(name, os_minus_one));
00694
00695 for (namednode_decl_map_t::const_iterator start = range.first; start != range.second; ++start)
00696 if (start->_name == name)
00697 return &*start;
00698
00699 return 0;
00700 }
00701
00702
00703 void
00704 xml_grammar::resolve_references()
00705 {
00706 for (attribute_ref_decl_map_t::const_iterator iter = _attributeRefMap.begin(); iter != _attributeRefMap.end(); ++iter)
00707 if (!iter->_declared && iter->_refered)
00708 xml_exception_throw("Undeclared ID: ", (const char*)iter->_name, 0);
00709 }
00710
00711
00713 void xml_exception_throw(const char* first, ...)
00714 {
00715 va_list va;
00716 va_start(va, first);
00717 const char* entry = first;
00718 string_t ex;
00719 while (entry)
00720 {
00721 ex += entry;
00722 entry = va_arg(va, const char*);
00723 }
00724 va_end(va);
00725
00726 exception::_throw(ex);
00727 }
00728
00729 #pragma pack()
00730 END_TERIMBER_NAMESPACE
00731