00001
00002
00003 #include "ACEXML/parser/parser/Parser.h"
00004
00005 #if !defined (__ACEXML_INLINE__)
00006 # include "ACEXML/parser/parser/Parser.inl"
00007 #endif
00008
00009 #include "ace/ACE.h"
00010 #include "ACEXML/common/Transcode.h"
00011 #include "ACEXML/common/AttributesImpl.h"
00012 #include "ACEXML/common/StrCharStream.h"
00013 #include "ACEXML/common/StreamFactory.h"
00014 #include "ACEXML/parser/parser/ParserInternals.h"
00015 #include "ace/OS_NS_string.h"
00016 #include "ace/OS_NS_strings.h"
00017
00018 static const ACEXML_Char default_attribute_type[] = ACE_TEXT ("CDATA");
00019 static const ACEXML_Char empty_string[] = { 0 };
00020
00021 const ACEXML_Char
00022 ACEXML_Parser::simple_parsing_feature_[] = ACE_TEXT ("Simple");
00023
00024 const ACEXML_Char
00025 ACEXML_Parser::namespaces_feature_[] = ACE_TEXT ("http://xml.org/sax/features/namespaces");
00026
00027 const ACEXML_Char
00028 ACEXML_Parser::namespace_prefixes_feature_[] = ACE_TEXT ("http://xml.org/sax/features/namespace-prefixes");
00029
00030 const ACEXML_Char
00031 ACEXML_Parser::validation_feature_[] = ACE_TEXT ("http://xml.org/sax/features/validation");
00032
00033 ACEXML_Parser::ACEXML_Parser (void)
00034 : dtd_handler_ (0),
00035 entity_resolver_ (0),
00036 content_handler_ (0),
00037 error_handler_ (0),
00038 doctype_ (0),
00039 current_ (0),
00040 alt_stack_ (MAXPATHLEN),
00041 nested_namespace_ (0),
00042 ref_state_ (ACEXML_ParserInt::INVALID),
00043 external_subset_ (0),
00044 external_entity_ (0),
00045 has_pe_refs_ (0),
00046 standalone_ (0),
00047 external_dtd_ (0),
00048 internal_dtd_ (0),
00049 simple_parsing_ (0),
00050 validate_ (1),
00051 namespaces_(1),
00052 namespace_prefixes_ (0)
00053 {
00054 }
00055
00056 ACEXML_Parser::~ACEXML_Parser (void)
00057 {
00058
00059 }
00060
00061 int
00062 ACEXML_Parser::initialize(ACEXML_InputSource* input)
00063 {
00064
00065 if (this->xml_namespace_.init() == -1)
00066 {
00067 ACE_ERROR ((LM_ERROR,
00068 ACE_TEXT ("Error initializing namespace support\n")));
00069 return -1;
00070 }
00071 for (int i = 0; i < 5; ++i)
00072 {
00073 if (this->predef_entities_.add_entity (ACEXML_ParserInt::predef_ent_[i],
00074 ACEXML_ParserInt::predef_val_[i])
00075 != 0)
00076 {
00077 ACE_ERROR ((LM_DEBUG,
00078 ACE_TEXT ("Error adding entity %s to Manager\n"),
00079 ACEXML_ParserInt::predef_ent_[i]));
00080 return -1;
00081 }
00082 }
00083 return this->switch_input (input, input->getSystemId());
00084 }
00085
00086 void
00087 ACEXML_Parser::parse (const ACEXML_Char *systemId ACEXML_ENV_ARG_DECL)
00088 {
00089 ACEXML_InputSource* input = 0;
00090 ACE_NEW (input, ACEXML_InputSource (systemId));
00091 this->parse (input ACEXML_ENV_ARG_PARAMETER);
00092 }
00093
00094 void
00095 ACEXML_Parser::parse (ACEXML_InputSource *input ACEXML_ENV_ARG_DECL)
00096 {
00097 if (input == 0)
00098 {
00099 this->fatal_error(ACE_TEXT ("Invalid input source")
00100 ACEXML_ENV_ARG_PARAMETER);
00101 ACEXML_CHECK;
00102 }
00103 if (this->content_handler_ == 0)
00104 {
00105 this->fatal_error (ACE_TEXT ("No content handlers defined. Exiting..")
00106 ACEXML_ENV_ARG_PARAMETER);
00107 ACEXML_CHECK;
00108 }
00109
00110 if (this->validate_ && this->dtd_handler_ == 0)
00111 {
00112 this->fatal_error (ACE_TEXT ("No DTD handlers defined. Exiting..")
00113 ACEXML_ENV_ARG_PARAMETER);
00114 ACEXML_CHECK;
00115 }
00116
00117
00118 if (this->initialize(input) == -1)
00119 {
00120 this->fatal_error (ACE_TEXT ("Failed to initialize parser state")
00121 ACEXML_ENV_ARG_PARAMETER);
00122 ACEXML_CHECK;
00123 }
00124
00125 this->content_handler_->setDocumentLocator (this->current_->getLocator());
00126
00127 int xmldecl_defined = 0;
00128 ACEXML_Char fwd = this->get();
00129 if (fwd == '<' && this->peek() == '?')
00130 {
00131 this->get();
00132 fwd = this->peek();
00133 if (fwd == 'x' && !xmldecl_defined)
00134 {
00135 this->parse_xml_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00136 ACEXML_CHECK;
00137 xmldecl_defined = 1;
00138 }
00139 }
00140
00141 if (this->validate_ && !xmldecl_defined)
00142 {
00143 this->fatal_error (ACE_TEXT ("Expecting an XMLDecl at the beginning of")
00144 ACE_TEXT (" a valid document")
00145 ACEXML_ENV_ARG_PARAMETER);
00146 ACEXML_CHECK;
00147 }
00148 this->content_handler_->startDocument (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00149 ACEXML_CHECK;
00150
00151 int doctype_defined = 0;
00152 for (int prolog_done = 0; prolog_done == 0; )
00153 {
00154
00155
00156 if (xmldecl_defined)
00157 {
00158 if (this->skip_whitespace () != '<')
00159 {
00160 this->fatal_error (ACE_TEXT ("Expecting '<' at the beginning of ")
00161 ACE_TEXT ("Misc section")
00162 ACEXML_ENV_ARG_PARAMETER);
00163 ACEXML_CHECK;
00164 }
00165 fwd = this->peek();
00166 }
00167 switch (fwd)
00168 {
00169 case '?':
00170 this->get();
00171 this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00172 ACEXML_CHECK;
00173 xmldecl_defined = 1;
00174 break;
00175 case '!':
00176 this->get();
00177 fwd = this->peek ();
00178 if (fwd == 'D' && !doctype_defined)
00179 {
00180
00181 this->parse_doctypedecl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00182 ACEXML_CHECK;
00183 doctype_defined = 1;
00184
00185
00186 xmldecl_defined = 1;
00187 }
00188 else if (fwd == 'D')
00189 {
00190 this->fatal_error (ACE_TEXT ("Duplicate DOCTYPE declaration")
00191 ACEXML_ENV_ARG_PARAMETER);
00192 ACEXML_CHECK;
00193 }
00194 else if (fwd == '-')
00195 {
00196 if (this->parse_comment () < 0)
00197 {
00198 this->fatal_error(ACE_TEXT ("Invalid comment in document")
00199 ACEXML_ENV_ARG_PARAMETER);
00200 ACEXML_CHECK;
00201 }
00202 xmldecl_defined = 1;
00203 }
00204 break;
00205 case 0:
00206 this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
00207 ACEXML_ENV_ARG_PARAMETER);
00208 ACEXML_CHECK;
00209 default:
00210 prolog_done = 1;
00211 break;
00212 }
00213 }
00214
00215 if (this->validate_ && !doctype_defined)
00216 {
00217 this->warning (ACE_TEXT ("No doctypeDecl in valid document")
00218 ACEXML_ENV_ARG_PARAMETER);
00219 ACEXML_CHECK;
00220 }
00221
00222
00223 this->parse_element (1 ACEXML_ENV_ARG_PARAMETER);
00224 ACEXML_CHECK;
00225
00226 this->content_handler_->endDocument (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00227 ACEXML_CHECK;
00228
00229
00230 this->reset();
00231
00232 }
00233
00234 int
00235 ACEXML_Parser::parse_doctypedecl (ACEXML_ENV_SINGLE_ARG_DECL)
00236 {
00237 if (this->parse_token (ACE_TEXT ("DOCTYPE")) < 0)
00238 {
00239 this->fatal_error(ACE_TEXT ("Expecting keyword DOCTYPE in a doctypedecl")
00240 ACEXML_ENV_ARG_PARAMETER);
00241 ACEXML_CHECK_RETURN (-1);
00242 }
00243
00244 ACEXML_Char nextch = 0;
00245 if (this->skip_whitespace_count (&nextch) == 0)
00246 {
00247 this->fatal_error(ACE_TEXT ("Expecting a space between DOCTYPE keyword ")
00248 ACE_TEXT ("and name") ACEXML_ENV_ARG_PARAMETER);
00249 ACEXML_CHECK_RETURN (-1);
00250 }
00251
00252 this->doctype_ = this->parse_name ();
00253 if (this->doctype_ == 0)
00254 {
00255 this->fatal_error(ACE_TEXT ("Invalid DOCTYPE name")
00256 ACEXML_ENV_ARG_PARAMETER);
00257 ACEXML_CHECK_RETURN (-1);
00258 }
00259 int count = this->skip_whitespace_count (&nextch);
00260
00261 if (nextch == 'S' || nextch == 'P')
00262 {
00263 if (count == 0)
00264 {
00265 this->fatal_error(ACE_TEXT ("Expecting a space between DOCTYPE")
00266 ACE_TEXT ("keyword and name")
00267 ACEXML_ENV_ARG_PARAMETER);
00268 ACEXML_CHECK_RETURN (-1);
00269 }
00270 this->external_dtd_ = 1;
00271 this->parse_external_dtd (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00272 ACEXML_CHECK_RETURN (-1);
00273 }
00274
00275 nextch = this->skip_whitespace ();
00276 switch (nextch)
00277 {
00278 case '[':
00279 this->internal_dtd_ = 1;
00280 this->parse_internal_dtd (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00281 ACEXML_CHECK_RETURN (-1);
00282 break;
00283 case '>':
00284
00285 if (this->validate_ && !this->external_dtd_)
00286 {
00287 this->fatal_error (ACE_TEXT ("No DTD defined")
00288 ACEXML_ENV_ARG_PARAMETER);
00289 ACEXML_CHECK_RETURN (-1);
00290 }
00291 return 0;
00292 case '0':
00293 this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
00294 ACEXML_ENV_ARG_PARAMETER);
00295 ACEXML_CHECK_RETURN (-1);
00296 default:
00297 break;
00298 }
00299
00300 if (this->skip_whitespace() != '>')
00301 {
00302 this->fatal_error(ACE_TEXT ("Expecting '>' at end of doctypedecl")
00303 ACEXML_ENV_ARG_PARAMETER);
00304 ACEXML_CHECK_RETURN (-1);
00305 }
00306 return 0;
00307 }
00308
00309 int
00310 ACEXML_Parser::parse_internal_dtd (ACEXML_ENV_SINGLE_ARG_DECL)
00311 {
00312 this->ref_state_ = ACEXML_ParserInt::IN_INT_DTD;
00313 ACEXML_Char nextch = this->skip_whitespace ();
00314 do {
00315 switch (nextch)
00316 {
00317 case '<':
00318 nextch = this->get();
00319 switch (nextch)
00320 {
00321 case '!':
00322 this->parse_markup_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00323 ACEXML_CHECK_RETURN (-1);
00324 break;
00325 case '?':
00326 this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00327 ACEXML_CHECK_RETURN (-1);
00328 break;
00329 default:
00330 this->fatal_error (ACE_TEXT ("Invalid internal subset")
00331 ACEXML_ENV_ARG_PARAMETER);
00332 ACEXML_CHECK_RETURN (-1);
00333 break;
00334 }
00335 break;
00336 case '%':
00337 this->has_pe_refs_ = 1;
00338 this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00339 ACEXML_CHECK_RETURN (-1);
00340 break;
00341 case ']':
00342 return 0;
00343 case '&':
00344 this->fatal_error (ACE_TEXT ("Invalid Reference in internal DTD")
00345 ACEXML_ENV_ARG_PARAMETER);
00346 ACEXML_CHECK_RETURN (-1);
00347 break;
00348 case 0:
00349 this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
00350 ACEXML_CHECK_RETURN (-1);
00351 break;
00352 default:
00353 this->fatal_error (ACE_TEXT ("Invalid content in internal subset")
00354 ACEXML_ENV_ARG_PARAMETER);
00355 ACEXML_CHECK_RETURN (-1);
00356 };
00357 nextch = this->skip_whitespace ();
00358 } while (1);
00359
00360 ACE_NOTREACHED (return -1);
00361 }
00362
00363 int
00364 ACEXML_Parser::parse_external_dtd (ACEXML_ENV_SINGLE_ARG_DECL)
00365 {
00366 this->ref_state_ = ACEXML_ParserInt::IN_EXT_DTD;
00367 ACEXML_Char* publicId = 0;
00368 ACEXML_Char* systemId = 0;
00369 if (this->parse_external_id (publicId, systemId
00370 ACEXML_ENV_ARG_PARAMETER) != 0)
00371 {
00372 this->fatal_error (ACE_TEXT ("Error in parsing ExternalID")
00373 ACEXML_ENV_ARG_PARAMETER);
00374 ACEXML_CHECK_RETURN (-1);
00375 }
00376 if (this->validate_)
00377 {
00378 ACEXML_Char* uri = this->normalize_systemid (systemId);
00379 ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
00380 ACEXML_InputSource* ip = 0;
00381 if (this->entity_resolver_)
00382 {
00383 ip = this->entity_resolver_->resolveEntity (publicId,
00384 (uri ? uri : systemId)
00385 ACEXML_ENV_ARG_PARAMETER);
00386 ACEXML_CHECK_RETURN (-1);
00387 }
00388 if (ip)
00389 {
00390 if (this->switch_input (ip, (uri ? uri : systemId), publicId) != 0)
00391 return -1;
00392 }
00393 else
00394 {
00395 ACEXML_StreamFactory factory;
00396 ACEXML_CharStream* cstream = factory.create_stream (uri ?
00397 uri: systemId);
00398 if (!cstream) {
00399 this->fatal_error (ACE_TEXT ("Invalid input source")
00400 ACEXML_ENV_ARG_PARAMETER);
00401 ACEXML_CHECK_RETURN (-1);
00402 }
00403 if (this->switch_input (cstream, systemId, publicId) != 0)
00404 return -1;
00405 }
00406 this->parse_external_subset (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00407 ACEXML_CHECK_RETURN (-1);
00408 }
00409 return 0;
00410 }
00411
00412
00413 int
00414 ACEXML_Parser::parse_external_subset (ACEXML_ENV_SINGLE_ARG_DECL)
00415 {
00416 this->ref_state_ = ACEXML_ParserInt::IN_EXT_DTD;
00417 this->external_subset_ = 1;
00418 size_t nrelems = 0;
00419 ACEXML_Char nextch = this->skip_whitespace();
00420 do {
00421 switch (nextch)
00422 {
00423 case '<':
00424 nextch = this->get();
00425 switch (nextch)
00426 {
00427 case '!':
00428 nextch = this->peek();
00429 if (nextch == '[')
00430 this->parse_conditional_section (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00431 else
00432 this->parse_markup_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00433 ACEXML_CHECK_RETURN (-1);
00434 break;
00435 case '?':
00436 nextch = this->peek();
00437 if (nextch == 'x')
00438 this->parse_text_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00439 else
00440 this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00441 ACEXML_CHECK_RETURN (-1);
00442 break;
00443 default:
00444 this->fatal_error (ACE_TEXT ("Invalid content in external DTD")
00445 ACEXML_ENV_ARG_PARAMETER);
00446 ACEXML_CHECK_RETURN (-1);
00447 }
00448 break;
00449 case '%':
00450 this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00451 ACEXML_CHECK_RETURN (-1);
00452 break;
00453 case 0:
00454 nrelems = this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
00455 ACEXML_CHECK_RETURN (-1);
00456 if (nrelems == 1)
00457 return 0;
00458 break;
00459 default:
00460 this->fatal_error (ACE_TEXT ("Invalid content in external DTD")
00461 ACEXML_ENV_ARG_PARAMETER);
00462 ACEXML_CHECK_RETURN (-1);
00463 }
00464 nextch = this->skip_whitespace();
00465 } while (1);
00466 }
00467
00468 int
00469 ACEXML_Parser::parse_conditional_section (ACEXML_ENV_SINGLE_ARG_DECL)
00470 {
00471 ACEXML_Char ch = this->get ();
00472 int include = 0;
00473 if (ch != '[')
00474 {
00475 this->fatal_error(ACE_TEXT ("Internal Parser Error")
00476 ACEXML_ENV_ARG_PARAMETER);
00477 ACEXML_CHECK_RETURN (-1);
00478 }
00479 ch = this->skip_whitespace();
00480 if (ch == '%')
00481 {
00482 this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00483 ACEXML_CHECK_RETURN (-1);
00484 ch = this->skip_whitespace();
00485 }
00486 if (ch == 'I')
00487 {
00488 ch = this->get();
00489 switch (ch)
00490 {
00491 case 'N':
00492 if (this->parse_token (ACE_TEXT ("CLUDE")) < 0)
00493 {
00494 this->fatal_error (ACE_TEXT ("Expecting keyword INCLUDE in ")
00495 ACE_TEXT ("conditionalSect")
00496 ACEXML_ENV_ARG_PARAMETER);
00497 ACEXML_CHECK_RETURN (-1);
00498 }
00499 include = 1;
00500 break;
00501 case 'G':
00502 if (this->parse_token (ACE_TEXT ("GNORE")) < 0)
00503 {
00504 this->fatal_error (ACE_TEXT ("Expecting keyword IGNORE in ")
00505 ACE_TEXT ("conditionalSect")
00506 ACEXML_ENV_ARG_PARAMETER);
00507 ACEXML_CHECK_RETURN (-1);
00508 }
00509 include = 0;
00510 break;
00511 default:
00512 this->fatal_error (ACE_TEXT ("Invalid conditionalSect")
00513 ACEXML_ENV_ARG_PARAMETER);
00514 ACEXML_CHECK_RETURN (-1);
00515 }
00516 ACEXML_Char fwd = '\xFF';
00517 this->skip_whitespace_count (&fwd);
00518 if (fwd == 0)
00519 {
00520 this->get();
00521 this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
00522 ACEXML_CHECK_RETURN (-1);
00523 }
00524 }
00525 else
00526 {
00527 this->fatal_error (ACE_TEXT ("Invalid conditionalSect")
00528 ACEXML_ENV_ARG_PARAMETER);
00529 ACEXML_CHECK_RETURN (-1);
00530 }
00531 if (this->skip_whitespace() != '[')
00532 {
00533 this->fatal_error (ACE_TEXT ("Expecting '[' in conditionalSect")
00534 ACEXML_ENV_ARG_PARAMETER);
00535 ACEXML_CHECK_RETURN (-1);
00536 }
00537 if (include)
00538 this->parse_includesect (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00539 else
00540 this->parse_ignoresect (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00541 ACEXML_CHECK_RETURN (-1);
00542 return 0;
00543 }
00544
00545 int
00546 ACEXML_Parser::parse_ignoresect (ACEXML_ENV_SINGLE_ARG_DECL)
00547 {
00548 ACEXML_Char nextch = this->skip_whitespace();
00549 int count = 0;
00550 int done = 0;
00551 do {
00552 switch (nextch)
00553 {
00554 case '<':
00555 if (this->peek() == '!')
00556 {
00557 this->get();
00558 if (this->peek() == '[')
00559 {
00560 this->get();
00561 count++;
00562 }
00563 }
00564 break;
00565 case ']':
00566 if (this->peek() == ']')
00567 {
00568 this->get();
00569 if (this->peek() == '>')
00570 {
00571 this->get();
00572 if (count)
00573 {
00574 --count;
00575 break;
00576 }
00577 done = 1;
00578 }
00579 }
00580 break;
00581 case 0:
00582 if (count != 0)
00583 {
00584 this->fatal_error (ACE_TEXT ("Invalid Conditional Section/PE ")
00585 ACE_TEXT ("Nesting ")
00586 ACEXML_ENV_ARG_PARAMETER);
00587 ACEXML_CHECK_RETURN (-1);
00588 }
00589 default:
00590 break;
00591 }
00592 if (done)
00593 break;
00594 nextch = this->get();
00595 } while (1);
00596
00597 return 0;
00598 }
00599
00600 int
00601 ACEXML_Parser::parse_includesect (ACEXML_ENV_SINGLE_ARG_DECL)
00602 {
00603 ACEXML_Char nextch = this->skip_whitespace();
00604 do {
00605 switch (nextch)
00606 {
00607 case '<':
00608 nextch = this->get();
00609 switch (nextch)
00610 {
00611 case '!':
00612 nextch = this->peek();
00613 if (nextch == '[')
00614 this->parse_conditional_section (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00615 else
00616 this->parse_markup_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00617 ACEXML_CHECK_RETURN (-1);
00618 break;
00619 case '?':
00620 nextch = this->peek();
00621 this->parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00622 ACEXML_CHECK_RETURN (-1);
00623 break;
00624 default:
00625 this->fatal_error (ACE_TEXT ("Invalid includeSect")
00626 ACEXML_ENV_ARG_PARAMETER);
00627 ACEXML_CHECK_RETURN (-1);
00628 }
00629 break;
00630 case '%':
00631 this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00632 ACEXML_CHECK_RETURN (-1);
00633 break;
00634 case 0:
00635 this->fatal_error (ACE_TEXT ("Invalid Conditional Section/PE ")
00636 ACE_TEXT ("Nesting ")
00637 ACEXML_ENV_ARG_PARAMETER);
00638 ACEXML_CHECK_RETURN (-1);
00639 case ']':
00640 if (this->peek() == ']')
00641 {
00642 nextch = this->get();
00643 if (this->peek() == '>')
00644 {
00645 nextch = this->get();
00646 return 0;
00647 }
00648 }
00649 default:
00650 this->fatal_error (ACE_TEXT ("Invalid includeSect")
00651 ACEXML_ENV_ARG_PARAMETER);
00652 ACEXML_CHECK_RETURN (-1);
00653 }
00654 nextch = this->skip_whitespace();
00655 } while (1);
00656 }
00657
00658 int
00659 ACEXML_Parser::parse_markup_decl (ACEXML_ENV_SINGLE_ARG_DECL)
00660 {
00661 ACEXML_Char nextch = this->peek ();
00662 switch (nextch)
00663 {
00664 case 'E':
00665 this->get ();
00666 nextch = this->peek ();
00667 switch (nextch)
00668 {
00669 case 'L':
00670 this->parse_element_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00671 ACEXML_CHECK_RETURN (-1);
00672 break;
00673 case 'N':
00674 this->parse_entity_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00675 ACEXML_CHECK_RETURN (-1);
00676 break;
00677 default:
00678 this->fatal_error(ACE_TEXT ("Expecting keyword ELEMENT/ENTITY")
00679 ACEXML_ENV_ARG_PARAMETER);
00680 ACEXML_CHECK_RETURN (-1);
00681 }
00682 break;
00683
00684 case 'A':
00685 this->parse_attlist_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00686 ACEXML_CHECK_RETURN (-1);
00687 break;
00688
00689 case 'N':
00690 this->parse_notation_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
00691 ACEXML_CHECK_RETURN (-1);
00692 break;
00693
00694 case '-':
00695 if (this->parse_comment () < 0)
00696 {
00697 this->fatal_error(ACE_TEXT ("Invalid comment")
00698 ACEXML_ENV_ARG_PARAMETER);
00699 ACEXML_CHECK_RETURN (-1);
00700 }
00701 break;
00702 case 0:
00703 this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
00704 ACEXML_ENV_ARG_PARAMETER);
00705 ACEXML_CHECK_RETURN (-1);
00706 default:
00707 this->fatal_error (ACE_TEXT ("Invalid markupDecl")
00708 ACEXML_ENV_ARG_PARAMETER);
00709 ACEXML_CHECK_RETURN (-1);
00710 }
00711 return 0;
00712 }
00713
00714 int
00715 ACEXML_Parser::parse_external_id (ACEXML_Char *&publicId,
00716 ACEXML_Char *&systemId
00717 ACEXML_ENV_ARG_DECL)
00718 {
00719 publicId = systemId = 0;
00720 ACEXML_Char nextch = this->get ();
00721 ACEXML_Char fwd = 0;
00722 switch (nextch)
00723 {
00724 case 'S':
00725 if (this->parse_token (ACE_TEXT ("YSTEM")) < 0 ||
00726 this->skip_whitespace_count () < 1)
00727 {
00728 this->fatal_error(ACE_TEXT ("Expecting keyword SYSTEM")
00729 ACEXML_ENV_ARG_PARAMETER);
00730 ACEXML_CHECK_RETURN (-1);
00731 }
00732 if (this->parse_system_literal (systemId) != 0)
00733 {
00734 this->fatal_error(ACE_TEXT ("Invalid systemLiteral")
00735 ACEXML_ENV_ARG_PARAMETER);
00736 ACEXML_CHECK_RETURN (-1);
00737 }
00738 break;
00739 case 'P':
00740 if (this->parse_token (ACE_TEXT ("UBLIC")) < 0 ||
00741 this->skip_whitespace_count () < 1)
00742 {
00743 this->fatal_error(ACE_TEXT ("Expecing keyword PUBLIC")
00744 ACEXML_ENV_ARG_PARAMETER);
00745 ACEXML_CHECK_RETURN (-1);
00746 }
00747 if (this->parse_pubid_literal (publicId) != 0)
00748 {
00749 this->fatal_error(ACE_TEXT ("Invalid PubidLiteral")
00750 ACEXML_ENV_ARG_PARAMETER);
00751 ACEXML_CHECK_RETURN (-1);
00752 }
00753 this->skip_whitespace_count(&fwd);
00754 if (fwd == '\'' || fwd == '"')
00755 {
00756 if (this->parse_system_literal (systemId) != 0)
00757 {
00758 this->fatal_error(ACE_TEXT ("Invalid systemLiteral")
00759 ACEXML_ENV_ARG_PARAMETER);
00760 ACEXML_CHECK_RETURN (-1);
00761 }
00762 }
00763 else if (this->ref_state_ != ACEXML_ParserInt::IN_NOTATION)
00764 {
00765 this->fatal_error(ACE_TEXT ("Expecting systemLiteral after a ")
00766 ACE_TEXT ("PUBLIC keyword")
00767 ACEXML_ENV_ARG_PARAMETER);
00768 ACEXML_CHECK_RETURN (-1);
00769 }
00770 break;
00771 default:
00772 this->fatal_error(ACE_TEXT ("Invalid system/public Literal")
00773 ACEXML_ENV_ARG_PARAMETER);
00774 ACEXML_CHECK_RETURN (-1);
00775 }
00776 return 0;
00777 }
00778
00779 ACEXML_Char*
00780 ACEXML_Parser::normalize_systemid (const ACEXML_Char* systemId)
00781 {
00782 if (ACE_OS::strstr (systemId, ACE_TEXT("ftp://")) != 0 ||
00783 ACE_OS::strstr (systemId, ACE_TEXT ("http://")) != 0 ||
00784 ACE_OS::strstr (systemId, ACE_TEXT ("file://")) != 0)
00785 return 0;
00786 else
00787 {
00788 ACEXML_Char* normalized_uri = 0;
00789 const ACEXML_Char* baseURI = this->current_->getLocator()->getSystemId();
00790 ACE_ASSERT (baseURI);
00791 const ACEXML_Char* temp = 0;
00792 if (ACE_OS::strstr (baseURI, ACE_TEXT ("http://")) != 0)
00793
00794
00795 temp = ACE_OS::strrchr (baseURI, '/');
00796 else
00797
00798
00799 temp = ACE_OS::strrchr (baseURI,ACE_DIRECTORY_SEPARATOR_CHAR);
00800 if (temp)
00801 {
00802 size_t pos = temp - baseURI + 1;
00803 size_t len = pos + ACE_OS::strlen (systemId) + 1;
00804 ACE_NEW_RETURN (normalized_uri, ACEXML_Char[len], 0);
00805 ACE_OS::strncpy (normalized_uri, baseURI, pos);
00806 ACE_OS::strcpy (normalized_uri + pos, systemId);
00807 return normalized_uri;
00808 }
00809 return 0;
00810 }
00811 }
00812
00813 void
00814 ACEXML_Parser::parse_element (int is_root ACEXML_ENV_ARG_DECL)
00815 {
00816
00817 const ACEXML_Char *startname = this->parse_name ();
00818 if (startname == 0)
00819 {
00820 this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
00821 ACEXML_ENV_ARG_PARAMETER);
00822 return;
00823 }
00824 if (is_root && this->doctype_ != 0
00825 && ACE_OS::strcmp (startname, this->doctype_) != 0)
00826 {
00827 this->fatal_error (ACE_TEXT ("Root element different from DOCTYPE")
00828 ACEXML_ENV_ARG_PARAMETER);
00829 return ;
00830 }
00831 ACEXML_AttributesImpl attributes;
00832 ACEXML_Char ch;
00833 int ns_flag = 0;
00834
00835
00836 const ACEXML_Char* ns_uri = 0;
00837 const ACEXML_Char* ns_lname = 0;
00838 for (int start_element_done = 0; start_element_done == 0;)
00839 {
00840 ch = this->skip_whitespace ();
00841
00842 switch (ch)
00843 {
00844 case 0:
00845 this->fatal_error(ACE_TEXT ("Internal Parser error")
00846 ACEXML_ENV_ARG_PARAMETER);
00847 return;
00848 case '/':
00849 if (this->get () != '>')
00850 {
00851 this->fatal_error(ACE_TEXT ("Expecting '>' at end of element ")
00852 ACE_TEXT ("definition")
00853 ACEXML_ENV_ARG_PARAMETER);
00854 return;
00855 }
00856 this->xml_namespace_.processName(startname, ns_uri,
00857 ns_lname, 0);
00858 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
00859 ns_uri, 1
00860 ACEXML_ENV_ARG_PARAMETER);
00861 ACEXML_CHECK;
00862 this->content_handler_->startElement(ns_uri, ns_lname,
00863 startname, &attributes
00864 ACEXML_ENV_ARG_PARAMETER);
00865 ACEXML_CHECK;
00866 this->content_handler_->endElement (ns_uri, ns_lname, startname
00867 ACEXML_ENV_ARG_PARAMETER);
00868 ACEXML_CHECK;
00869 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
00870 ns_uri, 0
00871 ACEXML_ENV_ARG_PARAMETER);
00872 ACEXML_CHECK;
00873 if (ns_flag)
00874 {
00875 this->xml_namespace_.popContext ();
00876 this->nested_namespace_--;
00877 }
00878 return;
00879 case '>':
00880 this->xml_namespace_.processName (startname, ns_uri,
00881 ns_lname, 0);
00882 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
00883 ns_uri, 1
00884 ACEXML_ENV_ARG_PARAMETER);
00885 ACEXML_CHECK;
00886 this->content_handler_->startElement(ns_uri, ns_lname, startname,
00887 &attributes
00888 ACEXML_ENV_ARG_PARAMETER);
00889 ACEXML_CHECK;
00890 start_element_done = 1;
00891 break;
00892 default:
00893 ACEXML_Char *attvalue = 0;
00894 ACEXML_Char *attname = this->parse_name (ch);
00895
00896 if (attname == 0 ||
00897 this->skip_equal () != 0 ||
00898 this->parse_attvalue (attvalue ACEXML_ENV_ARG_PARAMETER) != 0)
00899 {
00900 this->fatal_error(ACE_TEXT ("Error reading attribute value")
00901 ACEXML_ENV_ARG_PARAMETER);
00902 return;
00903 }
00904
00905
00906
00907 if (ACE_OS::strncmp (attname, ACE_TEXT("xmlns"), 5) == 0)
00908 {
00909 if (this->namespaces_)
00910 {
00911 if (!ns_flag)
00912 {
00913 this->xml_namespace_.pushContext ();
00914 this->nested_namespace_++;
00915 ns_flag = 1;
00916 }
00917
00918 ACEXML_Char* name = ACE_OS::strchr (attname, ':');
00919 const ACEXML_Char* ns_name = (name == 0)?
00920 empty_string:name+1;
00921 if (this->xml_namespace_.declarePrefix (ns_name,
00922 attvalue) == -1)
00923 {
00924 this->fatal_error(ACE_TEXT ("Duplicate definition of ")
00925 ACE_TEXT ("prefix")
00926 ACEXML_ENV_ARG_PARAMETER);
00927 return;
00928 }
00929 }
00930 if (this->namespace_prefixes_)
00931 {
00932
00933
00934 if (attributes.addAttribute (ACE_TEXT (""), ACE_TEXT (""),
00935 attname,
00936 default_attribute_type,
00937 attvalue) == -1)
00938 {
00939 this->fatal_error(ACE_TEXT ("Duplicate attribute ")
00940 ACE_TEXT ("definition. Hint: Try ")
00941 ACE_TEXT ("setting namespace_prefix")
00942 ACE_TEXT ("es feature to 0")
00943 ACEXML_ENV_ARG_PARAMETER);
00944 return;
00945 }
00946 }
00947 if (!this->namespaces_ && !this->namespace_prefixes_)
00948 {
00949 this->fatal_error(ACE_TEXT ("One of namespaces or ")
00950 ACE_TEXT ("namespace_prefixes should be")
00951 ACE_TEXT (" declared")
00952 ACEXML_ENV_ARG_PARAMETER);
00953 return;
00954 }
00955 }
00956 else
00957 {
00958 const ACEXML_Char *uri, *lName;
00959 this->xml_namespace_.processName (attname, uri, lName, 1);
00960 if (attributes.addAttribute (uri, lName, attname,
00961 default_attribute_type,
00962 attvalue) == -1)
00963 {
00964 this->fatal_error(ACE_TEXT ("Duplicate attribute ")
00965 ACE_TEXT ("definition")
00966 ACEXML_ENV_ARG_PARAMETER);
00967 return;
00968 }
00969 }
00970 break;
00971 }
00972 }
00973 if (this->parse_content (startname, ns_uri, ns_lname, ns_flag
00974 ACEXML_ENV_ARG_PARAMETER) != 0)
00975 return;
00976 }
00977
00978 int
00979 ACEXML_Parser::parse_content (const ACEXML_Char* startname,
00980 const ACEXML_Char*& ns_uri,
00981 const ACEXML_Char*& ns_lname, int ns_flag ACEXML_ENV_ARG_DECL)
00982 {
00983 ACEXML_Char *cdata;
00984 size_t cdata_length = 0;
00985
00986
00987 while (1)
00988 {
00989 ACEXML_Char ch = this->get ();
00990 switch (ch)
00991 {
00992 case 0:
00993 this->pop_context (1 ACEXML_ENV_ARG_PARAMETER);
00994 ACEXML_CHECK_RETURN (-1);
00995 break;
00996 case '<':
00997
00998 if (cdata_length != 0)
00999 {
01000 cdata = this->obstack_.freeze ();
01001 this->content_handler_->characters (cdata, 0, cdata_length
01002 ACEXML_ENV_ARG_PARAMETER);
01003 ACEXML_CHECK_RETURN (-1);
01004 this->obstack_.unwind (cdata);
01005 cdata_length = 0;
01006 }
01007 ch = this->peek();
01008 switch (ch)
01009 {
01010 case '!':
01011 this->get ();
01012 ch = this->peek ();
01013 if (ch == '-')
01014 {
01015 if (this->parse_comment () < 0)
01016 {
01017 this->fatal_error(ACE_TEXT ("Invalid comment in ")
01018 ACE_TEXT ("document")
01019 ACEXML_ENV_ARG_PARAMETER);
01020 ACEXML_CHECK_RETURN (-1);
01021 }
01022 }
01023 else if (ch == '[')
01024 {
01025 this->parse_cdata (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01026 ACEXML_CHECK_RETURN (-1);
01027 }
01028 else
01029 {
01030 this->fatal_error(ACE_TEXT ("Expecting a CDATA section ")
01031 ACE_TEXT ("or a comment section")
01032 ACEXML_ENV_ARG_PARAMETER);
01033 ACEXML_CHECK_RETURN (-1);
01034 }
01035 break;
01036 case '?':
01037 this->get();
01038 this->parse_processing_instruction
01039 (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01040 ACEXML_CHECK_RETURN (-1);
01041 break;
01042 case '/':
01043 {
01044 this->get ();
01045 ACEXML_Char* endname = this->parse_name ();
01046 if (endname == 0 ||
01047 ACE_OS::strcmp (startname, endname) != 0)
01048 {
01049 this->fatal_error(ACE_TEXT ("Name in ETag doesn't ")
01050 ACE_TEXT ("match name in STag")
01051 ACEXML_ENV_ARG_PARAMETER);
01052 ACEXML_CHECK_RETURN (-1);
01053 }
01054 if (this->skip_whitespace () != '>')
01055 {
01056 this->fatal_error(ACE_TEXT ("Expecting '>' at end ")
01057 ACE_TEXT ("of element")
01058 ACEXML_ENV_ARG_PARAMETER);
01059 return -1;
01060 }
01061 this->content_handler_->endElement (ns_uri, ns_lname,
01062 endname
01063 ACEXML_ENV_ARG_PARAMETER);
01064 ACEXML_CHECK_RETURN (-1);
01065 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
01066 ns_uri, 0
01067 ACEXML_ENV_ARG_PARAMETER);
01068 ACEXML_CHECK_RETURN (-1);
01069 if (this->namespaces_ && ns_flag)
01070 {
01071 if (this->nested_namespace_ >= 1)
01072 {
01073 this->xml_namespace_.popContext ();
01074 this->nested_namespace_--;
01075 }
01076 }
01077 return 0;
01078 }
01079 default:
01080 this->parse_element (0 ACEXML_ENV_ARG_PARAMETER);
01081 ACEXML_CHECK_RETURN (-1);
01082 break;
01083 }
01084 break;
01085 case '&':
01086 if (this->peek () == '#')
01087 {
01088 ACEXML_Char buf[7];
01089 size_t len = 0;
01090 do
01091 {
01092 len = sizeof (buf);
01093 if (this->parse_char_reference (buf, len) != 0)
01094 {
01095
01096 this->fatal_error (ACE_TEXT ("Invalid CharRef")
01097 ACEXML_ENV_ARG_PARAMETER);
01098 ACEXML_CHECK_RETURN (-1);
01099 }
01100 } while (buf[0] == '&' && this->peek() == '#');
01101 for (size_t j = 0; j < len; ++j)
01102 this->obstack_.grow (buf[j]);
01103 cdata_length += len;
01104 }
01105 else
01106 {
01107 this->ref_state_ = ACEXML_ParserInt::IN_CONTENT;
01108 int length = this->parse_entity_reference(ACEXML_ENV_SINGLE_ARG_PARAMETER);
01109 ACEXML_CHECK_RETURN (-1);
01110 if (length == 1)
01111 cdata_length++;
01112 }
01113 break;
01114 case '\x20': case '\x0D': case '\x0A': case '\x09':
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 default:
01152 ++cdata_length;
01153 this->obstack_.grow (ch);
01154 }
01155 }
01156 ACE_NOTREACHED (return 0;)
01157 }
01158
01159
01160 int
01161 ACEXML_Parser::parse_cdata (ACEXML_ENV_SINGLE_ARG_DECL)
01162 {
01163 if (this->parse_token (ACE_TEXT ("[CDATA[")) < 0)
01164 {
01165 this->fatal_error(ACE_TEXT ("Expecting '[CDATA[' at beginning of CDATA ")
01166 ACE_TEXT ("section")
01167 ACEXML_ENV_ARG_PARAMETER);
01168 ACEXML_CHECK_RETURN (-1);
01169 }
01170
01171 ACEXML_Char ch;
01172 int datalen = 0;
01173 ACEXML_Char *cdata = 0;
01174 while (1)
01175 {
01176 ch = this->get ();
01177
01178 if (ch == ']' && this->peek() == ']')
01179 {
01180 ACEXML_Char temp = ch;
01181 ch = this->get();
01182 if (ch == ']' && this->peek() == '>')
01183 {
01184 ch = this->get();
01185 cdata = this->obstack_.freeze ();
01186 this->content_handler_->characters (cdata, 0, datalen
01187 ACEXML_ENV_ARG_PARAMETER);
01188 ACEXML_CHECK_RETURN (-1);
01189 this->obstack_.unwind(cdata);
01190 return 0;
01191 }
01192 this->obstack_.grow (temp);
01193 ++datalen;
01194 }
01195 this->obstack_.grow (ch);
01196 ++datalen;
01197 };
01198 ACE_NOTREACHED (return -1);
01199 }
01200
01201
01202 int
01203 ACEXML_Parser::parse_entity_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01204 {
01205 ACEXML_Char nextch = 0;
01206
01207 if ((this->parse_token (ACE_TEXT ("NTITY")) < 0) ||
01208 this->skip_whitespace_count (&nextch) == 0)
01209 {
01210 this->fatal_error (ACE_TEXT ("Expecting keyword ENTITY followed by a ")
01211 ACE_TEXT ("space") ACEXML_ENV_ARG_PARAMETER);
01212 ACEXML_CHECK_RETURN (-1);
01213 }
01214
01215 int is_GEDecl = 1;
01216 if (nextch == '%')
01217 {
01218 is_GEDecl = 0;
01219 this->get ();
01220 if (this->skip_whitespace_count (&nextch) == 0)
01221 {
01222 this->fatal_error (ACE_TEXT ("Expecting space between % and ")
01223 ACE_TEXT ("entity name")
01224 ACEXML_ENV_ARG_PARAMETER);
01225 ACEXML_CHECK_RETURN (-1);
01226 }
01227 }
01228
01229 ACEXML_Char *entity_name = this->parse_name ();
01230 if (entity_name == 0)
01231 {
01232 this->fatal_error (ACE_TEXT ("Invalid entity name")
01233 ACEXML_ENV_ARG_PARAMETER);
01234 ACEXML_CHECK_RETURN (-1);
01235 }
01236
01237 if (this->skip_whitespace_count (&nextch) == 0)
01238 {
01239 this->fatal_error (ACE_TEXT ("Expecting space between entity name and ")
01240 ACE_TEXT ("entityDef")
01241 ACEXML_ENV_ARG_PARAMETER);
01242 ACEXML_CHECK_RETURN (-1);
01243 }
01244 int retval = 0;
01245 if (nextch == '\'' || nextch == '"')
01246 {
01247 ACEXML_Char *entity_value = 0;
01248 if (this->parse_entity_value (entity_value
01249 ACEXML_ENV_ARG_PARAMETER) != 0)
01250 {
01251 this->fatal_error(ACE_TEXT ("Invalid EntityValue")
01252 ACEXML_ENV_ARG_PARAMETER);
01253 ACEXML_CHECK_RETURN (-1);
01254 }
01255 if (is_GEDecl)
01256 retval = this->internal_GE_.add_entity (entity_name,
01257 entity_value);
01258 else
01259 retval = this->internal_PE_.add_entity (entity_name,
01260 entity_value);
01261 if (retval < 0)
01262 {
01263 this->fatal_error (ACE_TEXT ("Internal Parser Error in adding")
01264 ACE_TEXT ("Entity to map")
01265 ACEXML_ENV_ARG_PARAMETER);
01266 ACEXML_CHECK_RETURN (-1);
01267 }
01268 else if (retval == 1)
01269 {
01270 this->warning (ACE_TEXT ("Duplicate entity found")
01271 ACEXML_ENV_ARG_PARAMETER);
01272 ACEXML_CHECK_RETURN (-1);
01273 }
01274 }
01275 else
01276 {
01277 ACEXML_Char *systemid, *publicid;
01278
01279 this->parse_external_id (publicid, systemid
01280 ACEXML_ENV_ARG_PARAMETER);
01281 ACEXML_CHECK_RETURN (-1);
01282 if (systemid == 0)
01283 {
01284 this->fatal_error(ACE_TEXT ("Invalid SystemLiteral")
01285 ACEXML_ENV_ARG_PARAMETER);
01286 ACEXML_CHECK_RETURN (-1);
01287 }
01288 this->skip_whitespace_count (&nextch);
01289 if (nextch == 'N')
01290 {
01291 if (is_GEDecl == 0)
01292 {
01293 this->fatal_error(ACE_TEXT ("Invalid NDataDecl in PEDef")
01294 ACEXML_ENV_ARG_PARAMETER);
01295 ACEXML_CHECK_RETURN (-1);
01296 }
01297
01298 if ((this->parse_token (ACE_TEXT ("NDATA")) < 0) ||
01299 this->skip_whitespace_count (&nextch) == 0)
01300 {
01301 this->fatal_error(ACE_TEXT ("Expecting keyword NDATA followed ")
01302 ACE_TEXT ("by a space") ACEXML_ENV_ARG_PARAMETER);
01303 ACEXML_CHECK_RETURN (-1);
01304 }
01305
01306 ACEXML_Char *ndata = this->parse_name ();
01307 if (this->validate_)
01308 {
01309 if (!this->notations_.resolve_entity (ndata))
01310 {
01311 this->fatal_error (ACE_TEXT ("Undeclared Notation name")
01312 ACEXML_ENV_ARG_PARAMETER);
01313 ACEXML_CHECK_RETURN (-1);
01314 }
01315 this->dtd_handler_->unparsedEntityDecl(entity_name, publicid,
01316 systemid, ndata
01317 ACEXML_ENV_ARG_PARAMETER);
01318 ACEXML_CHECK_RETURN (-1);
01319 }
01320 }
01321 else
01322 {
01323 if (is_GEDecl)
01324 retval = this->external_GE_.add_entity (entity_name,
01325 systemid);
01326 else
01327 retval = this->external_PE_.add_entity (entity_name,
01328 systemid);
01329 if (retval < 0)
01330 {
01331 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01332 ACEXML_ENV_ARG_PARAMETER);
01333 ACEXML_CHECK_RETURN (-1);
01334 }
01335 else if (retval == 1)
01336 this->warning(ACE_TEXT ("Duplicate external entity")
01337 ACEXML_ENV_ARG_PARAMETER);
01338 if (is_GEDecl)
01339 retval = this->external_GE_.add_entity (entity_name,
01340 publicid);
01341 else
01342 retval = this->external_PE_.add_entity (entity_name,
01343 publicid);
01344 if (retval < 0)
01345 {
01346 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01347 ACEXML_ENV_ARG_PARAMETER);
01348 ACEXML_CHECK_RETURN (-1);
01349 }
01350 else if (retval == 1)
01351 this->warning (ACE_TEXT ("Duplicate entity definition")
01352 ACEXML_ENV_ARG_PARAMETER);
01353 }
01354 }
01355
01356
01357 if (this->skip_whitespace() != '>')
01358 {
01359 this->fatal_error(ACE_TEXT ("Expecting '>' at end of entityDef")
01360 ACEXML_ENV_ARG_PARAMETER);
01361 ACEXML_CHECK_RETURN (-1);
01362 }
01363 return 0;
01364 }
01365
01366 int
01367 ACEXML_Parser::parse_attlist_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01368 {
01369 if (this->parse_token (ACE_TEXT ("ATTLIST")) < 0)
01370 {
01371 this->fatal_error(ACE_TEXT ("Expecting keyword 'ATTLIST'")
01372 ACEXML_ENV_ARG_PARAMETER);
01373 ACEXML_CHECK_RETURN (-1);
01374 }
01375 int count = check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01376 ACEXML_CHECK_RETURN (-1);
01377 if (!count)
01378 {
01379 this->fatal_error(ACE_TEXT ("Expecting space between ATTLIST and ")
01380 ACE_TEXT ("element name") ACEXML_ENV_ARG_PARAMETER);
01381 ACEXML_CHECK_RETURN (-1);
01382 }
01383
01384 ACEXML_Char *element_name = this->parse_name ();
01385 if (element_name == 0)
01386 {
01387 this->fatal_error(ACE_TEXT ("Invalid element Name in attlistDecl")
01388 ACEXML_ENV_ARG_PARAMETER);
01389 ACEXML_CHECK_RETURN (-1);
01390 }
01391 ACEXML_Char fwd = 0;
01392 count = this->skip_whitespace_count (&fwd);
01393
01394 while (fwd != '>')
01395 {
01396 if (!this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER)
01397 && !count)
01398 this->fatal_error(ACE_TEXT ("Expecting space between element ")
01399 ACE_TEXT ("name and AttDef")
01400 ACEXML_ENV_ARG_PARAMETER);
01401 ACEXML_CHECK_RETURN (-1);
01402 this->skip_whitespace_count (&fwd);
01403 if (fwd == '>')
01404 break;
01405
01406 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01407 ACEXML_CHECK_RETURN (-1);
01408
01409 this->parse_attname (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01410 ACEXML_CHECK_RETURN (-1);
01411
01412 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01413 ACEXML_CHECK_RETURN (-1);
01414 if (!count)
01415 {
01416 this->fatal_error(ACE_TEXT ("Expecting space between AttName and ")
01417 ACE_TEXT ("AttType") ACEXML_ENV_ARG_PARAMETER);
01418 ACEXML_CHECK_RETURN (-1);
01419 }
01420 this->parse_atttype (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01421 ACEXML_CHECK_RETURN (-1);
01422
01423 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01424 ACEXML_CHECK_RETURN (-1);
01425 if (!count)
01426 {
01427 this->fatal_error(ACE_TEXT ("Expecting space between AttType and")
01428 ACE_TEXT (" DefaultDecl")
01429 ACEXML_ENV_ARG_PARAMETER);
01430 ACEXML_CHECK_RETURN (-1);
01431 }
01432 this->parse_defaultdecl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01433 ACEXML_CHECK_RETURN (-1);
01434
01435 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01436 ACEXML_CHECK_RETURN (-1);
01437 this->skip_whitespace_count(&fwd);
01438 }
01439 this->get ();
01440 return 0;
01441 }
01442
01443
01444 int
01445 ACEXML_Parser::check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_DECL)
01446 {
01447 ACEXML_Char fwd = '\xFF';
01448
01449 int count = this->skip_whitespace_count (&fwd);
01450 if (fwd == 0)
01451 {
01452 this->get();
01453 this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
01454 ACEXML_CHECK_RETURN (-1);
01455 fwd = this->peek();
01456 }
01457 if (fwd == '%')
01458 {
01459 this->get();
01460 if (this->external_subset_)
01461 {
01462 this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01463 ACEXML_CHECK_RETURN (-1);
01464 }
01465 else
01466 {
01467 this->fatal_error(ACE_TEXT ("Illegal PERef within markupDecl")
01468 ACEXML_ENV_ARG_PARAMETER);
01469 ACEXML_CHECK_RETURN (-1);
01470 }
01471 }
01472 if (count)
01473 {
01474
01475
01476 this->skip_whitespace_count();
01477 return count;
01478 }
01479 return this->skip_whitespace_count();
01480 }
01481
01482 ACEXML_Char*
01483 ACEXML_Parser::parse_attname (ACEXML_ENV_SINGLE_ARG_DECL)
01484 {
01485
01486 ACEXML_Char *att_name = this->parse_name ();
01487 if (att_name == 0)
01488 {
01489 this->fatal_error(ACE_TEXT ("Invalid AttName")
01490 ACEXML_ENV_ARG_PARAMETER);
01491 ACEXML_CHECK_RETURN (0);
01492 }
01493 return att_name;
01494 }
01495
01496 int
01497 ACEXML_Parser::parse_defaultdecl (ACEXML_ENV_SINGLE_ARG_DECL)
01498 {
01499
01500 ACEXML_Char nextch = this->peek ();
01501 ACEXML_Char *fixed_attr = 0;
01502 switch (nextch)
01503 {
01504 case '#':
01505 this->get ();
01506 switch (this->get ())
01507 {
01508 case 'R':
01509 if (this->parse_token (ACE_TEXT ("EQUIRED")) < 0)
01510 {
01511 this->fatal_error(ACE_TEXT ("Expecting keyword REQUIRED")
01512 ACEXML_ENV_ARG_PARAMETER);
01513 ACEXML_CHECK_RETURN (-1);
01514 }
01515
01516
01517 break;
01518 case 'I':
01519 if (this->parse_token (ACE_TEXT ("MPLIED")) < 0)
01520 {
01521 this->fatal_error(ACE_TEXT ("Expecting keyword IMPLIED")
01522 ACEXML_ENV_ARG_PARAMETER);
01523 ACEXML_CHECK_RETURN (-1);
01524 }
01525
01526
01527 break;
01528 case 'F':
01529 if (this->parse_token (ACE_TEXT ("IXED")) < 0 ||
01530 this->skip_whitespace_count () == 0)
01531 {
01532 this->fatal_error(ACE_TEXT ("Expecting keyword FIXED")
01533 ACEXML_ENV_ARG_PARAMETER);
01534 ACEXML_CHECK_RETURN (-1);
01535 }
01536
01537 if (this->parse_attvalue (fixed_attr
01538 ACEXML_ENV_ARG_PARAMETER) != 0)
01539 {
01540 this->fatal_error(ACE_TEXT ("Invalid Default AttValue")
01541 ACEXML_ENV_ARG_PARAMETER);
01542 ACEXML_CHECK_RETURN (-1);
01543 }
01544
01545 break;
01546 default:
01547 this->fatal_error (ACE_TEXT ("Invalid DefaultDecl")
01548 ACEXML_ENV_ARG_PARAMETER);
01549 ACEXML_CHECK_RETURN (-1);
01550 }
01551 break;
01552 case '\'':
01553 case '"':
01554 if (this->parse_attvalue (fixed_attr ACEXML_ENV_ARG_PARAMETER) != 0)
01555 {
01556 this->fatal_error(ACE_TEXT ("Invalid AttValue")
01557 ACEXML_ENV_ARG_PARAMETER);
01558 ACEXML_CHECK_RETURN (-1);
01559 }
01560
01561 break;
01562 default:
01563 this->fatal_error (ACE_TEXT ("Invalid DefaultDecl")
01564 ACEXML_ENV_ARG_PARAMETER);
01565 ACEXML_CHECK_RETURN (-1);
01566 break;
01567 }
01568 return 0;
01569 }
01570
01571 int
01572 ACEXML_Parser::parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_DECL)
01573 {
01574 ACEXML_Char ch = this->get();
01575 switch (ch)
01576 {
01577 case 'I':
01578 if (this->get () == 'D')
01579 {
01580 if (this->peek() != 'R' && this->is_whitespace (this->peek()))
01581 {
01582
01583
01584
01585 break;
01586 }
01587 if (this->parse_token (ACE_TEXT ("REF")) == 0)
01588 {
01589 if (this->peek() != 'S' && this->is_whitespace (this->peek()))
01590 {
01591
01592
01593
01594 break;
01595 }
01596 else if (this->peek() == 'S'
01597 && this->get()
01598 && this->is_whitespace (this->peek()))
01599 {
01600
01601
01602
01603 break;
01604 }
01605 }
01606 }
01607
01608 this->fatal_error(ACE_TEXT ("Expecting keyword `ID', `IDREF', or")
01609 ACE_TEXT ("`IDREFS'") ACEXML_ENV_ARG_PARAMETER);
01610 ACEXML_CHECK_RETURN (-1);
01611 case 'E':
01612 if (this->parse_token (ACE_TEXT ("NTIT")) == 0)
01613 {
01614 ACEXML_Char nextch = this->get ();
01615 if (nextch == 'Y')
01616 {
01617
01618
01619
01620 }
01621 else if (this->parse_token (ACE_TEXT ("IES")) == 0)
01622 {
01623
01624
01625
01626 }
01627 if (this->is_whitespace (this->peek()))
01628 {
01629
01630 break;
01631 }
01632 }
01633
01634 this->fatal_error(ACE_TEXT ("Expecting keyword `ENTITY', or")
01635 ACE_TEXT ("`ENTITIES'") ACEXML_ENV_ARG_PARAMETER);
01636 ACEXML_CHECK_RETURN (-1);
01637 case 'M':
01638 if (this->parse_token (ACE_TEXT ("TOKEN")) == 0)
01639 {
01640 if (this->is_whitespace (this->peek()))
01641 {
01642
01643
01644
01645 break;
01646 }
01647 else if (this->peek() == 'S'
01648 && this->get()
01649 && this->is_whitespace (this->peek()))
01650 {
01651
01652
01653
01654 break;
01655 }
01656 }
01657 this->fatal_error(ACE_TEXT ("Expecting keyword `NMTOKEN' or `NMTO")
01658 ACE_TEXT ("KENS'") ACEXML_ENV_ARG_PARAMETER);
01659 ACEXML_CHECK_RETURN (-1);
01660 break;
01661 default:
01662 this->fatal_error (ACE_TEXT ("Internal Parser Error")
01663 ACEXML_ENV_ARG_PARAMETER);
01664 ACEXML_CHECK_RETURN (-1);
01665 break;
01666 }
01667 return 0;
01668 }
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692 int
01693 ACEXML_Parser::parse_atttype (ACEXML_ENV_SINGLE_ARG_DECL)
01694 {
01695 ACEXML_Char nextch = this->peek();
01696 switch (nextch)
01697 {
01698 case 'C':
01699 if (this->parse_token (ACE_TEXT ("CDATA")) < 0)
01700 {
01701 this->fatal_error(ACE_TEXT ("Expecting keyword 'CDATA'")
01702 ACEXML_ENV_ARG_PARAMETER);
01703 ACEXML_CHECK_RETURN (-1);
01704 }
01705
01706
01707
01708 break;
01709 case 'I': case 'E':
01710 this->parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01711 ACEXML_CHECK_RETURN (-1);
01712 break;
01713 case 'N':
01714 this->get();
01715 nextch = this->peek();
01716 if (nextch != 'M' && nextch != 'O')
01717 {
01718 this->fatal_error (ACE_TEXT ("Expecting keyword 'NMTOKEN', ")
01719 ACE_TEXT ("'NMTOKENS' or 'NOTATION'")
01720 ACEXML_ENV_ARG_PARAMETER);
01721 ACEXML_CHECK_RETURN (-1);
01722 }
01723 if (nextch == 'M')
01724 {
01725 this->parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01726 ACEXML_CHECK_RETURN (-1);
01727 break;
01728 }
01729 else
01730 {
01731 if (this->parse_token (ACE_TEXT ("OTATION")) < 0)
01732 {
01733 this->fatal_error(ACE_TEXT ("Expecting keyword `NOTATION'")
01734 ACEXML_ENV_ARG_PARAMETER);
01735 ACEXML_CHECK_RETURN (-1);
01736 }
01737 int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01738 ACEXML_CHECK_RETURN (-1);
01739 if (!count)
01740 {
01741 this->fatal_error (ACE_TEXT ("Expecting space between keyword ")
01742 ACE_TEXT ("NOTATION and '('")
01743 ACEXML_ENV_ARG_PARAMETER);
01744 ACEXML_CHECK_RETURN (-1);
01745 }
01746 if (this->get () != '(')
01747 {
01748 this->fatal_error(ACE_TEXT ("Expecting '(' in NotationType")
01749 ACEXML_ENV_ARG_PARAMETER);
01750 ACEXML_CHECK_RETURN (-1);
01751 }
01752 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01753 ACEXML_CHECK_RETURN (-1);
01754 do {
01755 this->skip_whitespace_count();
01756 ACEXML_Char *notation_name = this->parse_name ();
01757 if (notation_name == 0)
01758 {
01759 this->fatal_error(ACE_TEXT ("Invalid notation name")
01760 ACEXML_ENV_ARG_PARAMETER);
01761 ACEXML_CHECK_RETURN (-1);
01762 }
01763
01764 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01765 ACEXML_CHECK_RETURN (-1);
01766 nextch = this->get();
01767 } while (nextch == '|');
01768 if (nextch != ')')
01769 {
01770 this->fatal_error (ACE_TEXT ("Expecting a ')' after a ")
01771 ACE_TEXT ("NotationType declaration")
01772 ACEXML_ENV_ARG_PARAMETER);
01773 ACEXML_CHECK_RETURN (-1);
01774 }
01775 }
01776 break;
01777 case '(':
01778 this->get();
01779 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01780 ACEXML_CHECK_RETURN (-1);
01781 do {
01782 this->skip_whitespace_count();
01783 ACEXML_Char *token_name = this->parse_nmtoken ();
01784 if (token_name == 0)
01785 {
01786 this->fatal_error(ACE_TEXT ("Invalid enumeration name")
01787 ACEXML_ENV_ARG_PARAMETER);
01788 ACEXML_CHECK_RETURN (-1);
01789 }
01790
01791 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01792 ACEXML_CHECK_RETURN (-1);
01793 nextch = this->get();
01794 } while (nextch == '|');
01795 if (nextch != ')')
01796 {
01797 this->fatal_error (ACE_TEXT ("Expecting a ')' after a ")
01798 ACE_TEXT ("Enumeration declaration")
01799 ACEXML_ENV_ARG_PARAMETER);
01800 ACEXML_CHECK_RETURN (-1);
01801 }
01802 break;
01803 default:
01804 {
01805 this->fatal_error(ACE_TEXT ("Invalid AttType")
01806 ACEXML_ENV_ARG_PARAMETER);
01807 ACEXML_CHECK_RETURN (-1);
01808 }
01809 ACE_NOTREACHED (break);
01810 }
01811 return 0;
01812 }
01813
01814 int
01815 ACEXML_Parser::parse_notation_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01816 {
01817 if (this->parse_token (ACE_TEXT ("NOTATION")) < 0)
01818 {
01819 this->fatal_error(ACE_TEXT ("Expecting Keyword 'NOTATION'")
01820 ACEXML_ENV_ARG_PARAMETER);
01821 ACEXML_CHECK_RETURN (-1);
01822 }
01823 int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01824 ACEXML_CHECK_RETURN (-1);
01825 if (!count)
01826 {
01827 this->fatal_error (ACE_TEXT ("Expecting a space between keyword NOTATION")
01828 ACE_TEXT (" and notation name")
01829 ACEXML_ENV_ARG_PARAMETER);
01830 ACEXML_CHECK_RETURN (-1);
01831 }
01832 ACEXML_Char *notation = this->parse_name ();
01833 if (notation == 0)
01834 {
01835 this->fatal_error(ACE_TEXT ("Invalid Notation name")
01836 ACEXML_ENV_ARG_PARAMETER);
01837 ACEXML_CHECK_RETURN (-1);
01838 }
01839 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01840 ACEXML_CHECK_RETURN (-1);
01841 if (!count)
01842 {
01843 this->fatal_error (ACE_TEXT ("Expecting a space between notation name ")
01844 ACE_TEXT ("and ExternalID/PublicID")
01845 ACEXML_ENV_ARG_PARAMETER);
01846 ACEXML_CHECK_RETURN (-1);
01847 }
01848
01849 ACEXML_Char *systemid, *publicid;
01850
01851
01852
01853
01854 ACEXML_ParserInt::ReferenceState temp = this->ref_state_;
01855 this->ref_state_ = ACEXML_ParserInt::IN_NOTATION;
01856
01857 this->parse_external_id (publicid, systemid
01858 ACEXML_ENV_ARG_PARAMETER);
01859 ACEXML_CHECK_RETURN (-1);
01860
01861 this->ref_state_ = temp;
01862
01863
01864 if (systemid && this->notations_.add_entity (notation, systemid) != 0
01865 && this->validate_)
01866 {
01867 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01868 ACEXML_ENV_ARG_PARAMETER);
01869 ACEXML_CHECK_RETURN (-1);
01870 }
01871 if (publicid)
01872 {
01873 int retval = this->notations_.add_entity (notation, publicid);
01874 if (retval != 0 && !systemid && this->validate_)
01875 {
01876 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01877 ACEXML_ENV_ARG_PARAMETER);
01878 ACEXML_CHECK_RETURN (-1);
01879 }
01880 }
01881
01882 if (this->skip_whitespace() != '>')
01883 {
01884 this->fatal_error(ACE_TEXT ("Expecting '>' at end of NotationDecl")
01885 ACEXML_ENV_ARG_PARAMETER);
01886 ACEXML_CHECK_RETURN (-1);
01887 }
01888
01889 if (this->validate_ && this->dtd_handler_)
01890 {
01891 this->dtd_handler_->notationDecl (notation,
01892 publicid,
01893 systemid ACEXML_ENV_ARG_PARAMETER);
01894 ACEXML_CHECK_RETURN (-1);
01895 }
01896 return 0;
01897 }
01898
01899 int
01900 ACEXML_Parser::parse_element_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01901 {
01902 if (this->parse_token (ACE_TEXT ("LEMENT")) < 0)
01903 {
01904 this->fatal_error (ACE_TEXT ("Expecting keyword ELEMENT")
01905 ACEXML_ENV_ARG_PARAMETER);
01906 ACEXML_CHECK_RETURN (-1);
01907 }
01908 int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01909 ACEXML_CHECK_RETURN (-1);
01910 if (!count)
01911 {
01912 this->fatal_error (ACE_TEXT ("Expecting a space between keyword ELEMENT")
01913 ACE_TEXT (" and element name")
01914 ACEXML_ENV_ARG_PARAMETER);
01915 ACEXML_CHECK_RETURN (-1);
01916 }
01917 ACEXML_Char *element_name = this->parse_name ();
01918 if (element_name == 0)
01919 {
01920 this->fatal_error (ACE_TEXT ("Invalid element name")
01921 ACEXML_ENV_ARG_PARAMETER);
01922 ACEXML_CHECK_RETURN (-1);
01923 }
01924 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01925 ACEXML_CHECK_RETURN (-1);
01926 if (!count)
01927 {
01928 this->fatal_error (ACE_TEXT ("Expecting a space between element name ")
01929 ACE_TEXT ("and element definition")
01930 ACEXML_ENV_ARG_PARAMETER);
01931 ACEXML_CHECK_RETURN (-1);
01932 }
01933 ACEXML_Char nextch = this->peek();
01934 switch (nextch)
01935 {
01936 case 'E':
01937 if (this->parse_token (ACE_TEXT ("EMPTY")) < 0)
01938 {
01939 this->fatal_error (ACE_TEXT ("Expecting keyword EMPTY")
01940 ACEXML_ENV_ARG_PARAMETER);
01941 ACEXML_CHECK_RETURN (-1);
01942 }
01943 break;
01944 case 'A':
01945 if (this->parse_token (ACE_TEXT ("ANY")) < 0)
01946 {
01947 this->fatal_error (ACE_TEXT ("Expecting keyword ANY")
01948 ACEXML_ENV_ARG_PARAMETER);
01949 ACEXML_CHECK_RETURN (-1);
01950 }
01951 break;
01952 case '(':
01953 this->parse_children_definition (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01954 ACEXML_CHECK_RETURN (-1);
01955 break;
01956 default:
01957 this->fatal_error (ACE_TEXT ("Invalid element definition")
01958 ACEXML_ENV_ARG_PARAMETER);
01959 ACEXML_CHECK_RETURN (-1);
01960 }
01961 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01962 ACEXML_CHECK_RETURN (-1);
01963 if (this->skip_whitespace () != '>')
01964 {
01965 this->fatal_error (ACE_TEXT ("Expecting '>' after element defintion")
01966 ACEXML_ENV_ARG_PARAMETER);
01967 ACEXML_CHECK_RETURN (-1);
01968 }
01969 return 0;
01970 }
01971
01972
01973 int
01974 ACEXML_Parser::parse_children_definition (ACEXML_ENV_SINGLE_ARG_DECL)
01975 {
01976 this->get ();
01977 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01978 ACEXML_CHECK_RETURN (-1);
01979 int subelement_number = 0;
01980 ACEXML_Char nextch = this->peek();
01981 switch (nextch)
01982 {
01983 case '#':
01984 if (this->parse_token (ACE_TEXT ("#PCDATA")) < 0)
01985 {
01986 this->fatal_error(ACE_TEXT ("Expecting keyword '#PCDATA'")
01987 ACEXML_ENV_ARG_PARAMETER);
01988 ACEXML_CHECK_RETURN (-1);
01989 }
01990 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01991 ACEXML_CHECK_RETURN (-1);
01992 nextch = this->get();
01993 while (nextch == '|')
01994 {
01995 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01996 ACEXML_CHECK_RETURN (-1);
01997 ACEXML_Char *name = this->parse_name ();
01998
01999 ACE_UNUSED_ARG (name);
02000 ++subelement_number;
02001
02002 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02003 ACEXML_CHECK_RETURN (-1);
02004 nextch = this->skip_whitespace();
02005 }
02006 if (nextch != ')' ||
02007 (subelement_number && this->get () != '*'))
02008 {
02009 this->fatal_error(ACE_TEXT ("Expecing ')' or ')*' at end of Mixed")
02010 ACE_TEXT (" element") ACEXML_ENV_ARG_PARAMETER);
02011 ACEXML_CHECK_RETURN (-1);
02012 }
02013
02014 break;
02015 default:
02016 int status = this->parse_child (1 ACEXML_ENV_ARG_PARAMETER);
02017 ACEXML_CHECK_RETURN (-1);
02018 if (status != 0)
02019 return -1;
02020 }
02021
02022
02023 nextch = this->peek ();
02024 switch (nextch)
02025 {
02026 case '?':
02027
02028 this->get ();
02029 break;
02030 case '*':
02031
02032 this->get ();
02033 break;
02034 case '+':
02035
02036 this->get ();
02037 break;
02038 default:
02039 break;
02040 }
02041
02042 return 0;
02043 }
02044
02045 int
02046 ACEXML_Parser::parse_child (int skip_open_paren ACEXML_ENV_ARG_DECL)
02047 {
02048
02049 if (skip_open_paren == 0 && this->get () != '(')
02050 {
02051 this->fatal_error(ACE_TEXT ("Expecting '(' at beginning of children")
02052 ACEXML_ENV_ARG_PARAMETER);
02053 ACEXML_CHECK_RETURN (-1);
02054 }
02055
02056 ACEXML_Char node_type = 0;
02057 ACEXML_Char nextch;
02058
02059 do {
02060 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02061 ACEXML_CHECK_RETURN (-1);
02062 this->skip_whitespace_count (&nextch);
02063 switch (nextch)
02064 {
02065 case '(':
02066 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02067 ACEXML_CHECK_RETURN (-1);
02068 this->parse_child (0 ACEXML_ENV_ARG_PARAMETER);
02069 ACEXML_CHECK_RETURN (-1);
02070 break;
02071 default:
02072 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02073 ACEXML_CHECK_RETURN (-1);
02074
02075 ACEXML_Char *subelement = this->parse_name ();
02076 if (subelement == 0)
02077 {
02078 this->fatal_error(ACE_TEXT ("Invalid subelement name")
02079 ACEXML_ENV_ARG_PARAMETER);
02080 ACEXML_CHECK_RETURN (-1);
02081 }
02082
02083 nextch = this->peek ();
02084 switch (nextch)
02085 {
02086 case '?':
02087
02088 this->get ();
02089 break;
02090 case '*':
02091
02092 this->get ();
02093 break;
02094 case '+':
02095
02096 this->get ();
02097 break;
02098 default:
02099 break;
02100 }
02101
02102
02103 break;
02104 }
02105 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02106 ACEXML_CHECK_RETURN (-1);
02107 this->skip_whitespace_count (&nextch);
02108 switch (nextch)
02109 {
02110 case '|':
02111 switch (node_type)
02112 {
02113 case 0:
02114 node_type = '|';
02115
02116 break;
02117 case '|':
02118 break;
02119 default:
02120 this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
02121 ACE_TEXT ("while defining an element")
02122 ACEXML_ENV_ARG_PARAMETER);
02123 ACEXML_CHECK_RETURN (-1);
02124 }
02125 break;
02126 case ',':
02127 switch (node_type)
02128 {
02129 case 0:
02130 node_type = ',';
02131
02132 break;
02133 case ',':
02134 break;
02135 default:
02136 this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
02137 ACE_TEXT ("while defining an element")
02138 ACEXML_ENV_ARG_PARAMETER);
02139 ACEXML_CHECK_RETURN (-1);
02140 }
02141 break;
02142 case ')':
02143 break;
02144 default:
02145 this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
02146 ACE_TEXT ("while defining an element")
02147 ACEXML_ENV_ARG_PARAMETER);
02148 ACEXML_CHECK_RETURN (-1);
02149 }
02150 nextch = this->get();
02151 if (nextch == ')')
02152 break;
02153 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02154 ACEXML_CHECK_RETURN (-1);
02155 this->skip_whitespace_count (&nextch);
02156 } while (nextch != ')');
02157
02158
02159 nextch = this->peek ();
02160 switch (nextch)
02161 {
02162 case '?':
02163
02164 this->get ();
02165 break;
02166 case '*':
02167
02168 this->get ();
02169 break;
02170 case '+':
02171
02172 this->get ();
02173 break;
02174 default:
02175 break;
02176 }
02177
02178
02179 return 0;
02180 }
02181
02182 int
02183 ACEXML_Parser::parse_char_reference (ACEXML_Char *buf, size_t& len)
02184 {
02185 if (len < 7)
02186 return -1;
02187 ACEXML_Char ch = this->get();
02188 if (ch != '#')
02189 return -1;
02190 int hex = 0;
02191 ch = this->peek();
02192 if (ch == 'x')
02193 {
02194 hex = 1;
02195 this->get ();
02196 }
02197 size_t i = 0;
02198 int more_digit = 0;
02199 ch = this->get ();
02200 for ( ; i < len &&
02201 (this->isNormalDigit (ch) || (hex ? this->isCharRef(ch): 0)); ++i)
02202 {
02203 buf[i] = ch;
02204 ch = this->get();
02205 ++more_digit;
02206 }
02207 if (ch != ';' || !more_digit)
02208 return -1;
02209 buf[i] = 0;
02210 ACEXML_UCS4 sum = (ACEXML_UCS4) ACE_OS::strtol (buf, 0, (hex ? 16 : 10));
02211
02212 if (!this->isChar (sum))
02213 return -1;
02214 int clen;
02215 #if defined (ACE_USES_WCHAR)
02216 # if (ACE_SIZEOF_WCHAR == 2) // UTF-16
02217 if ((clen = ACEXML_Transcoder::ucs42utf16 (sum, buf, len)) < 0)
02218 return -1;
02219 # elif (ACE_SIZEOF_WCHAR == 4) // UCS 4
02220 buf [0] = sum;
02221 buf [1] = 0;
02222 clen = 2;
02223 # endif
02224
02225 #else // or UTF-8
02226 if ((clen = ACEXML_Transcoder::ucs42utf8 (sum, buf, len)) < 0)
02227 return -1;
02228 #endif
02229 buf [clen] = 0;
02230 len = clen;
02231 return 0;
02232 }
02233
02234 ACEXML_Char*
02235 ACEXML_Parser::parse_reference_name (void)
02236 {
02237 ACEXML_Char ch = this->get ();
02238 if (!this->isLetter (ch) && (ch != '_' || ch != ':'))
02239 return 0;
02240 while (ch) {
02241 this->alt_stack_.grow (ch);
02242 ch = this->peek ();
02243 if (!this->isNameChar (ch))
02244 break;
02245 ch = this->get ();
02246 };
02247 if (ch != ';')
02248 return 0;
02249 ch = this->get();
02250 return this->alt_stack_.freeze ();
02251 }
02252
02253 int
02254 ACEXML_Parser::parse_attvalue (ACEXML_Char *&str ACEXML_ENV_ARG_DECL)
02255 {
02256 ACEXML_Char quote = this->get ();
02257 if (quote != '\'' && quote != '"')
02258 return -1;
02259 ACEXML_Char ch = this->get ();
02260 while (1)
02261 {
02262 if (ch == quote)
02263 {
02264 ACEXML_Char* temp = this->obstack_.freeze ();
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287 str = temp;
02288 return 0;
02289 }
02290 switch (ch)
02291 {
02292 case '&':
02293 if (this->peek () == '#')
02294 {
02295 ACEXML_Char buf[7];
02296 size_t len = sizeof (buf);
02297 if (this->parse_char_reference (buf, len) != 0)
02298 {
02299
02300 this->fatal_error (ACE_TEXT ("Invalid CharacterRef")
02301 ACEXML_ENV_ARG_PARAMETER);
02302 ACEXML_CHECK_RETURN (-1);
02303 }
02304 for (size_t j = 0; j < len; ++j)
02305 this->obstack_.grow (buf[j]);
02306 }
02307 else
02308 {
02309 this->ref_state_ = ACEXML_ParserInt::IN_ATT_VALUE;
02310 this->parse_entity_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02311 ACEXML_CHECK_RETURN (-1);
02312 }
02313 break;
02314 case '\x20': case '\x0D': case '\x0A': case '\x09':
02315 this->obstack_.grow ('\x20');
02316 break;
02317 case '<':
02318 this->fatal_error (ACE_TEXT ("Illegal '<' in AttValue")
02319 ACEXML_ENV_ARG_PARAMETER);
02320 ACEXML_CHECK_RETURN (-1);
02321 break;
02322 case 0:
02323 this->pop_context (1 ACEXML_ENV_ARG_PARAMETER);
02324 ACEXML_CHECK_RETURN (-1);
02325 break;
02326 default:
02327 this->obstack_.grow (ch);
02328 break;
02329 }
02330 ch = this->get();
02331 }
02332 }
02333
02334
02335
02336 int
02337 ACEXML_Parser::parse_entity_reference (ACEXML_ENV_SINGLE_ARG_DECL)
02338 {
02339 ACEXML_Char* replace = this->parse_reference_name ();
02340 if (replace == 0)
02341 {
02342 this->fatal_error (ACE_TEXT ("Invalid Reference name")
02343 ACEXML_ENV_ARG_PARAMETER);
02344 ACEXML_CHECK_RETURN (-1);
02345 }
02346
02347
02348 if (this->unparsed_entities_.resolve_entity (replace)) {
02349 this->fatal_error (ACE_TEXT ("EntityRef refers to unparsed entity")
02350 ACEXML_ENV_ARG_PARAMETER);
02351 ACEXML_CHECK_RETURN (-1);
02352 }
02353
02354 const ACEXML_Char* entity = this->internal_GE_.resolve_entity(replace);
02355
02356
02357 if (!entity)
02358 {
02359 entity = this->predef_entities_.resolve_entity (replace);
02360 if (entity)
02361 {
02362
02363 this->obstack_.grow (*entity);
02364 return 1;
02365 }
02366 }
02367
02368 if (!this->validate_)
02369 {
02370 if (this->standalone_)
02371 {
02372
02373 this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
02374 ACEXML_ENV_ARG_PARAMETER);
02375 ACEXML_CHECK_RETURN (-1);
02376 }
02377 else
02378 {
02379 this->content_handler_->skippedEntity (replace
02380 ACEXML_ENV_ARG_PARAMETER);
02381 ACEXML_CHECK_RETURN (-1);
02382 return 0;
02383 }
02384 }
02385
02386
02387 if (!entity
02388
02389 && (!(this->internal_dtd_ || this->external_dtd_)
02390
02391 || (this->internal_dtd_ && !this->external_dtd_
02392 && !this->has_pe_refs_)
02393
02394 || this->standalone_))
02395 {
02396
02397 this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
02398 ACEXML_ENV_ARG_PARAMETER);
02399 ACEXML_CHECK_RETURN (-1);
02400 }
02401
02402 ACEXML_Char* systemId = 0;
02403 ACEXML_Char* publicId = 0;
02404 if (!entity)
02405 {
02406 if (this->external_GE_.resolve_entity (replace, systemId, publicId) < 0)
02407 {
02408 this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
02409 ACEXML_ENV_ARG_PARAMETER);
02410 ACEXML_CHECK_RETURN (-1);
02411 }
02412 if (this->ref_state_ == ACEXML_ParserInt::IN_ATT_VALUE)
02413 {
02414 this->fatal_error (ACE_TEXT ("External EntityRef in Attribute Value")
02415 ACEXML_ENV_ARG_PARAMETER);
02416 ACEXML_CHECK_RETURN (-1);
02417 }
02418 this->external_entity_++;
02419 }
02420
02421
02422
02423 ACEXML_Char* ref_name = replace;
02424 int present = this->GE_reference_.insert (ref_name);
02425 if (present == 1 || present == -1)
02426 {
02427 while (this->GE_reference_.pop(ref_name) != -1)
02428 ;
02429 this->fatal_error (ACE_TEXT ("Recursion in resolving entity")
02430 ACEXML_ENV_ARG_PARAMETER);
02431 ACEXML_CHECK_RETURN (-1);
02432 }
02433
02434 if (!this->external_entity_)
02435 {
02436 ACEXML_StrCharStream* str = 0;
02437 ACE_NEW_RETURN (str, ACEXML_StrCharStream, -1);
02438 if (str->open (entity, replace) < 0
02439 || this->switch_input (str, replace) != 0)
02440 {
02441 this->fatal_error (ACE_TEXT ("Unable to create internal input ")
02442 ACE_TEXT ("stream")
02443 ACEXML_ENV_ARG_PARAMETER);
02444 ACEXML_CHECK_RETURN (-1);
02445 }
02446 return 0;
02447 }
02448 else
02449 {
02450 ACEXML_Char* uri = this->normalize_systemid (systemId);
02451 ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
02452 ACEXML_InputSource* ip = 0;
02453 if (this->entity_resolver_)
02454 {
02455 ip = this->entity_resolver_->resolveEntity (publicId,
02456 (uri ? uri : systemId)
02457 ACEXML_ENV_ARG_PARAMETER);
02458 ACEXML_CHECK_RETURN (-1);
02459 if (ip)
02460 {
02461 if (this->switch_input (ip, (uri ? uri : systemId),
02462 publicId) != 0)
02463 {
02464 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02465 ACEXML_ENV_ARG_PARAMETER);
02466 ACEXML_CHECK_RETURN (-1);
02467 }
02468 return 0;
02469 }
02470 }
02471 ACEXML_StreamFactory factory;
02472 ACEXML_CharStream* cstream = factory.create_stream (uri ? uri: systemId);
02473 if (!cstream) {
02474 this->fatal_error (ACE_TEXT ("Invalid input source")
02475 ACEXML_ENV_ARG_PARAMETER);
02476 ACEXML_CHECK_RETURN (-1);
02477 }
02478 if (this->switch_input (cstream, systemId, publicId) != 0)
02479 {
02480 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02481 ACEXML_ENV_ARG_PARAMETER);
02482 ACEXML_CHECK_RETURN (-1);
02483 }
02484 }
02485 return 0;
02486 }
02487
02488 int
02489 ACEXML_Parser::parse_PE_reference (ACEXML_ENV_SINGLE_ARG_DECL)
02490 {
02491 ACEXML_Char* replace = this->parse_reference_name ();
02492 if (replace == 0)
02493 {
02494 this->fatal_error (ACE_TEXT ("Invalid PEReference name")
02495 ACEXML_ENV_ARG_PARAMETER);
02496 ACEXML_CHECK_RETURN (-1);
02497 }
02498
02499
02500 const ACEXML_Char* entity = this->internal_PE_.resolve_entity(replace);
02501
02502 if (!entity &&
02503 (!this->external_dtd_ ||
02504 this->standalone_))
02505 {
02506
02507 this->fatal_error (ACE_TEXT ("Undefined Internal PEReference")
02508 ACEXML_ENV_ARG_PARAMETER);
02509 ACEXML_CHECK_RETURN (-1);
02510 }
02511
02512 ACEXML_Char* systemId = 0;
02513 ACEXML_Char* publicId = 0;
02514 if (!entity && this->validate_)
02515 {
02516 if (this->external_PE_.resolve_entity (replace, systemId, publicId) < 0)
02517 {
02518 this->fatal_error (ACE_TEXT ("Undefined PEReference")
02519 ACEXML_ENV_ARG_PARAMETER);
02520 ACEXML_CHECK_RETURN (-1);
02521 }
02522 this->external_entity_++;
02523 }
02524
02525
02526 ACEXML_Char* ref_name = replace;
02527 int present = this->PE_reference_.insert (ref_name);
02528 if (present == 1 || present == -1)
02529 {
02530 while (this->PE_reference_.pop(ref_name) != -1)
02531 ;
02532 this->fatal_error (ACE_TEXT ("Recursion in resolving entity")
02533 ACEXML_ENV_ARG_PARAMETER);
02534 ACEXML_CHECK_RETURN (-1);
02535 }
02536
02537 if (entity && !this->external_entity_)
02538 {
02539 ACEXML_StrCharStream* sstream = 0;
02540 ACEXML_String str (entity);
02541 if (this->ref_state_ != ACEXML_ParserInt::IN_ENTITY_VALUE)
02542 {
02543 const ACEXML_Char* ch = ACE_TEXT (" ");
02544 str = ch + str + ch;
02545 }
02546
02547
02548
02549 ACE_NEW_RETURN (sstream, ACEXML_StrCharStream, -1);
02550 if (sstream->open (str.c_str(), replace) < 0
02551 || this->switch_input (sstream, replace) != 0)
02552 {
02553 this->fatal_error (ACE_TEXT ("Error in switching InputSource")
02554 ACEXML_ENV_ARG_PARAMETER);
02555 ACEXML_CHECK_RETURN (-1);
02556 }
02557 return 0;
02558 }
02559 else if (this->external_entity_ && this->validate_)
02560 {
02561 ACEXML_Char* uri = this->normalize_systemid (systemId);
02562 ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
02563 ACEXML_InputSource* ip = 0;
02564 if (this->entity_resolver_)
02565 {
02566 ip = this->entity_resolver_->resolveEntity (publicId,
02567 (uri ? uri : systemId)
02568 ACEXML_ENV_ARG_PARAMETER);
02569 ACEXML_CHECK_RETURN (-1);
02570 }
02571 if (ip)
02572 {
02573 if (this->switch_input (ip, (uri ? uri : systemId), publicId) != 0)
02574 {
02575 this->fatal_error (ACE_TEXT ("Error in switching InputSource")
02576 ACEXML_ENV_ARG_PARAMETER);
02577 ACEXML_CHECK_RETURN (-1);
02578 }
02579 return 0;
02580 }
02581 else
02582 {
02583 ACEXML_StreamFactory factory;
02584 ACEXML_CharStream* cstream = factory.create_stream (uri ? uri: systemId);
02585 if (!cstream) {
02586 this->fatal_error (ACE_TEXT ("Invalid input source")
02587 ACEXML_ENV_ARG_PARAMETER);
02588 ACEXML_CHECK_RETURN (-1);
02589 }
02590 if (this->switch_input (cstream, systemId, publicId) != 0)
02591 {
02592 this->fatal_error (ACE_TEXT ("Error in switching InputSource")
02593 ACEXML_ENV_ARG_PARAMETER);
02594 ACEXML_CHECK_RETURN (-1);
02595 }
02596 if (this->ref_state_ == ACEXML_ParserInt::IN_ENTITY_VALUE)
02597 {
02598 ACEXML_Char less, mark;
02599 if (this->peek() == '<')
02600 {
02601 less = this->get();
02602 if (this->peek() == '?')
02603 {
02604 mark = this->get();
02605 if (this->peek() == 'x')
02606 {
02607 this->parse_text_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02608 ACEXML_CHECK_RETURN (-1);
02609 }
02610 else
02611 {
02612 this->obstack_.grow (less);
02613 this->obstack_.grow (mark);
02614 }
02615 }
02616 this->obstack_.grow (less);
02617 }
02618 }
02619 return 0;
02620 }
02621 }
02622 this->fatal_error (ACE_TEXT ("Undefined PEReference")
02623 ACEXML_ENV_ARG_PARAMETER);
02624 ACEXML_CHECK_RETURN (-1);
02625 return -1;
02626 }
02627
02628 int
02629 ACEXML_Parser::parse_entity_value (ACEXML_Char *&str
02630 ACEXML_ENV_ARG_DECL)
02631 {
02632 ACEXML_ParserInt::ReferenceState temp = this->ref_state_;
02633 ACEXML_Char quote = this->get ();
02634 if (quote != '\'' && quote != '"')
02635 return -1;
02636 ACEXML_Char ch = this->get ();
02637 while (1)
02638 {
02639 if (ch == quote)
02640 {
02641 str = this->obstack_.freeze ();
02642 this->ref_state_ = temp;
02643 return 0;
02644 }
02645 switch (ch)
02646 {
02647 case '&':
02648 if (this->peek () == '#')
02649 {
02650 if (!this->external_entity_)
02651 {
02652 ACEXML_Char buf[7];
02653 size_t len = sizeof (buf);
02654 if (this->parse_char_reference (buf, len) != 0)
02655 {
02656
02657 this->fatal_error (ACE_TEXT ("Invalid character ")
02658 ACE_TEXT ("reference")
02659 ACEXML_ENV_ARG_PARAMETER);
02660 return -1;
02661 }
02662 for (size_t j = 0; j < len; ++j)
02663 this->obstack_.grow (buf[j]);
02664 break;
02665 }
02666 }
02667 this->obstack_.grow (ch);
02668 break;
02669 case '%':
02670 if (!this->external_entity_)
02671 {
02672 this->ref_state_ = ACEXML_ParserInt::IN_ENTITY_VALUE;
02673 this->parse_PE_reference(ACEXML_ENV_SINGLE_ARG_PARAMETER);
02674 ACEXML_CHECK_RETURN (-1);
02675 break;
02676 }
02677 this->obstack_.grow (ch);
02678 break;
02679 case 0:
02680 this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
02681 ACEXML_CHECK_RETURN (-1);
02682 break;
02683 default:
02684 this->obstack_.grow (ch);
02685 break;
02686 }
02687 ch = this->get();
02688 }
02689 }
02690
02691 ACEXML_Char *
02692 ACEXML_Parser::parse_name (ACEXML_Char ch)
02693 {
02694 if (ch == 0)
02695 ch = this->get ();
02696 if (!this->isLetter (ch) && ch != '_' && ch != ':')
02697 return 0;
02698 while (ch) {
02699 this->obstack_.grow (ch);
02700 ch = this->peek ();
02701 if (!this->isNameChar (ch))
02702 break;
02703 ch = this->get ();
02704 };
02705 return this->obstack_.freeze ();
02706 }
02707
02708 ACEXML_Char*
02709 ACEXML_Parser::parse_nmtoken (ACEXML_Char ch)
02710 {
02711 if (ch == 0)
02712 ch = this->get ();
02713 if (!this->isNameChar (ch))
02714 return 0;
02715 while (ch) {
02716 this->obstack_.grow (ch);
02717 ch = this->peek ();
02718 if (!this->isNameChar (ch))
02719 break;
02720 ch = this->get ();
02721 };
02722 return this->obstack_.freeze ();
02723 }
02724
02725 int
02726 ACEXML_Parser::parse_version_num (ACEXML_Char*& str)
02727 {
02728 ACEXML_Char quote = this->get ();
02729 if (quote != '\'' && quote != '"')
02730 return -1;
02731 int numchars = 0;
02732 while (1)
02733 {
02734 ACEXML_Char ch = this->get ();
02735 if (ch == quote && !numchars)
02736 return -1;
02737 else if (ch == quote)
02738 {
02739 str = this->obstack_.freeze ();
02740 return 0;
02741 }
02742
02743 if (ch == '-' || ((ch >= 'a' && ch <= 'z') ||
02744 (ch >= 'A' && ch <= 'Z') ||
02745 (ch >= '0' && ch <= '9') ||
02746 (ch == '_' || ch == '.' || ch == ':')))
02747 {
02748 this->obstack_.grow (ch);
02749 numchars++;
02750 }
02751 else
02752 return -1;
02753 }
02754 }
02755
02756 int
02757 ACEXML_Parser::parse_system_literal (ACEXML_Char*& str)
02758 {
02759 const ACEXML_Char quote = this->get();
02760 if (quote != '\'' && quote != '"')
02761 return -1;
02762 while (1)
02763 {
02764 ACEXML_Char ch = this->get ();
02765 if (ch == quote)
02766 {
02767 str = this->obstack_.freeze ();
02768 return 0;
02769 }
02770 switch (ch)
02771 {
02772 case '\x00': case '\x01': case '\x02': case '\x03': case '\x04':
02773 case '\x05': case '\x06': case '\x07': case '\x08': case '\x09':
02774 case '\x0A': case '\x0B': case '\x0C': case '\x0D': case '\x0E':
02775 case '\x0F': case '\x10': case '\x11': case '\x12': case '\x13':
02776 case '\x14': case '\x15': case '\x16': case '\x17': case '\x18':
02777 case '\x19': case '\x1A': case '\x1B': case '\x1C': case '\x1D':
02778 case '\x1E': case '\x1F': case '\x7F': case '\x20': case '<':
02779 case '>': case '#': case '%':
02780 ACE_ERROR ((LM_ERROR,
02781 ACE_TEXT ("Invalid char %c in SystemLiteral\n"), ch));
02782 return -1;
02783 default:
02784 this->obstack_.grow (ch);
02785 }
02786 }
02787 }
02788
02789 int
02790 ACEXML_Parser::parse_pubid_literal (ACEXML_Char*& str)
02791 {
02792 const ACEXML_Char quote = this->get();
02793 if (quote != '\'' && quote != '"')
02794 return -1;
02795 while (1)
02796 {
02797 ACEXML_Char ch = this->get ();
02798 if (ch == quote)
02799 {
02800 str = this->obstack_.freeze ();
02801 return 0;
02802 }
02803 else if (this->isPubidChar (ch))
02804 this->obstack_.grow (ch);
02805 else
02806 return -1;
02807 }
02808 }
02809
02810 int
02811 ACEXML_Parser::parse_encname (ACEXML_Char*& str)
02812 {
02813 const ACEXML_Char quote = this->get ();
02814 if (quote != '\'' && quote != '"')
02815 return -1;
02816 int numchars = 0;
02817 while (1)
02818 {
02819 ACEXML_Char ch = this->get ();
02820 if (ch == quote && !numchars)
02821 return -1;
02822 else if (ch == quote)
02823 {
02824 str = this->obstack_.freeze ();
02825 return 0;
02826 }
02827
02828 if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
02829 && !numchars)
02830 return -1;
02831 if (ch == '-' || ((ch >= 'a' && ch <= 'z') ||
02832 (ch >= 'A' && ch <= 'Z') ||
02833 (ch >= '0' && ch <= '9') ||
02834 (ch == '_' || ch == '.')))
02835 {
02836 this->obstack_.grow (ch);
02837 numchars++;
02838 }
02839 else
02840 return -1;
02841 }
02842 }
02843
02844 int
02845 ACEXML_Parser::parse_sddecl (ACEXML_Char*& str)
02846 {
02847 ACEXML_Char quote = this->get ();
02848 if (quote != '\'' && quote != '"')
02849 return -1;
02850 int numchars = 0;
02851 while (1)
02852 {
02853 ACEXML_Char ch = this->get ();
02854 if (ch == quote && numchars < 2)
02855 return -1;
02856 else if (ch == quote)
02857 {
02858 str = this->obstack_.freeze ();
02859 return 0;
02860 }
02861
02862
02863 switch (ch)
02864 {
02865 case 'y': case 'e': case 's': case 'n': case 'o':
02866 this->obstack_.grow (ch);
02867 numchars++;
02868 break;
02869 default:
02870 return -1;
02871 }
02872 }
02873 }
02874
02875 void
02876 ACEXML_Parser::prefix_mapping (const ACEXML_Char* prefix,
02877 const ACEXML_Char* uri,
02878 int start ACEXML_ENV_ARG_DECL)
02879 {
02880 if (this->namespaces_)
02881 {
02882 const ACEXML_Char* temp = (prefix == 0) ? empty_string : prefix;
02883 if (start) {
02884 this->content_handler_->startPrefixMapping (temp, uri
02885 ACEXML_ENV_ARG_PARAMETER);
02886 ACEXML_CHECK;
02887 }
02888 else
02889 {
02890 this->content_handler_->endPrefixMapping(temp
02891 ACEXML_ENV_ARG_PARAMETER);
02892 ACEXML_CHECK;
02893 }
02894 }
02895 }
02896
02897 int
02898 ACEXML_Parser::switch_input (ACEXML_CharStream* cstream,
02899 const ACEXML_Char* systemId,
02900 const ACEXML_Char* publicId)
02901 {
02902 ACEXML_InputSource* input = 0;
02903 ACE_NEW_RETURN (input, ACEXML_InputSource (cstream), -1);
02904 return this->switch_input (input, systemId, publicId);
02905 }
02906
02907 int
02908 ACEXML_Parser::switch_input (ACEXML_InputSource* input,
02909 const ACEXML_Char* systemId,
02910 const ACEXML_Char* publicId)
02911 {
02912 ACEXML_LocatorImpl* locator = 0;
02913 if (!systemId)
02914 systemId = input->getSystemId();
02915 ACE_NEW_RETURN (locator, ACEXML_LocatorImpl (systemId, publicId), -1);
02916 ACEXML_Parser_Context* new_context = 0;
02917 ACE_NEW_RETURN (new_context, ACEXML_Parser_Context(input, locator), -1);
02918 if (this->push_context (new_context) != 0)
02919 {
02920 ACE_ERROR ((LM_ERROR, "Unable to switch input streams"));
02921 delete new_context;
02922 return -1;
02923 }
02924 this->current_ = new_context;
02925 this->content_handler_->setDocumentLocator (this->current_->getLocator());
02926 return 0;
02927 }
02928
02929 int
02930 ACEXML_Parser::push_context (ACEXML_Parser_Context* context)
02931 {
02932 if (this->ctx_stack_.push (context) < 0)
02933 {
02934 ACE_ERROR ((LM_ERROR, "Unable to push input source onto the stack"));
02935 return -1;
02936 }
02937 return 0;
02938 }
02939
02940 size_t
02941 ACEXML_Parser::pop_context (int GE_ref ACEXML_ENV_ARG_DECL)
02942 {
02943 size_t nrelems = this->ctx_stack_.size();
02944 if (nrelems <= 1)
02945 {
02946 this->fatal_error(ACE_TEXT ("Unexpected end-of-file")
02947 ACEXML_ENV_ARG_PARAMETER);
02948 ACEXML_CHECK_RETURN (-1);
02949 }
02950
02951 ACEXML_Parser_Context* temp = 0;
02952 int retval = this->ctx_stack_.pop (temp);
02953 if (retval != 0)
02954 {
02955 this->fatal_error (ACE_TEXT ("Unable to pop element of the input stack")
02956 ACEXML_ENV_ARG_PARAMETER);
02957 ACEXML_CHECK_RETURN (-1);
02958 }
02959 delete temp;
02960 if (this->ctx_stack_.top (this->current_) != 0)
02961 {
02962 this->fatal_error (ACE_TEXT ("Unable to read top element of input stack")
02963 ACEXML_ENV_ARG_PARAMETER);
02964 ACEXML_CHECK_RETURN (-1);
02965 }
02966 ACEXML_Char* reference = 0;
02967 if (GE_ref == 1 && this->GE_reference_.size() > 0)
02968 {
02969 if (this->GE_reference_.pop (reference) < 0)
02970 {
02971 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02972 ACEXML_ENV_ARG_PARAMETER);
02973 ACEXML_CHECK_RETURN (-1);
02974 }
02975 }
02976 else if (GE_ref == 0 && this->PE_reference_.size() > 0)
02977 {
02978 if (this->PE_reference_.pop (reference) < 0)
02979 {
02980 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02981 ACEXML_ENV_ARG_PARAMETER);
02982 ACEXML_CHECK_RETURN (-1);
02983 }
02984 }
02985 nrelems = this->ctx_stack_.size();
02986
02987 if (this->external_entity_ && (GE_ref == 0 || GE_ref == 1))
02988 this->external_entity_--;
02989
02990 this->content_handler_->setDocumentLocator (this->current_->getLocator());
02991
02992 return nrelems;
02993 }
02994
02995 int
02996 ACEXML_Parser::getFeature (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
02997 {
02998 if (ACE_OS::strcmp (name, ACEXML_Parser::simple_parsing_feature_) == 0)
02999 {
03000 return this->simple_parsing_;
03001 }
03002 else if (ACE_OS::strcmp (name, ACEXML_Parser::namespaces_feature_) == 0)
03003 {
03004 return this->namespaces_;
03005 }
03006 else if (ACE_OS::strcmp (name,
03007 ACEXML_Parser::namespace_prefixes_feature_) == 0)
03008 {
03009 return this->namespace_prefixes_;
03010 }
03011 else if (ACE_OS::strcmp (name, ACEXML_Parser::validation_feature_) == 0)
03012 {
03013 return this->validate_;
03014 }
03015 ACEXML_THROW_RETURN (ACEXML_SAXNotRecognizedException (name), -1);
03016 }
03017
03018
03019
03020 void
03021 ACEXML_Parser::setFeature (const ACEXML_Char *name,
03022 int boolean_value ACEXML_ENV_ARG_DECL)
03023 {
03024 if (ACE_OS::strcmp (name, ACEXML_Parser::simple_parsing_feature_) == 0)
03025 {
03026 this->simple_parsing_ = (boolean_value == 0 ? 0 : 1);
03027 return;
03028 }
03029 else if (ACE_OS::strcmp (name, ACEXML_Parser::namespaces_feature_) == 0)
03030 {
03031 this->namespaces_ = (boolean_value == 0 ? 0 : 1);
03032 return;
03033 }
03034 else if (ACE_OS::strcmp (name,
03035 ACEXML_Parser::namespace_prefixes_feature_) == 0)
03036 {
03037 this->namespace_prefixes_ = (boolean_value == 0 ? 0 : 1);
03038 return;
03039 }
03040 else if (ACE_OS::strcmp (name, ACEXML_Parser::validation_feature_) == 0)
03041 {
03042 this->validate_ = (boolean_value == 0 ? 0 : 1);
03043 return;
03044 }
03045
03046 ACEXML_THROW (ACEXML_SAXNotRecognizedException (name));
03047 }
03048
03049 void *
03050 ACEXML_Parser::getProperty (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
03051 {
03052 ACEXML_THROW_RETURN (ACEXML_SAXNotSupportedException (name), 0);
03053 }
03054
03055 void
03056 ACEXML_Parser::setProperty (const ACEXML_Char *name,
03057 void *value ACEXML_ENV_ARG_DECL)
03058 {
03059 ACE_UNUSED_ARG (value);
03060
03061 ACEXML_THROW (ACEXML_SAXNotSupportedException (name));
03062 }
03063
03064 void
03065 ACEXML_Parser::error (const ACEXML_Char* msg ACEXML_ENV_ARG_DECL)
03066 {
03067 ACEXML_SAXParseException* exception = 0;
03068 ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
03069 if (this->error_handler_)
03070 this->error_handler_->error (*exception ACEXML_ENV_ARG_PARAMETER);
03071 else
03072 ACEXML_ENV_RAISE (exception);
03073 return;
03074 }
03075
03076 void
03077 ACEXML_Parser::warning (const ACEXML_Char* msg ACEXML_ENV_ARG_DECL)
03078 {
03079 ACEXML_SAXParseException* exception = 0;
03080 ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
03081 if (this->error_handler_)
03082 this->error_handler_->warning (*exception ACEXML_ENV_ARG_PARAMETER);
03083 delete exception;
03084 return;
03085 }
03086
03087 void
03088 ACEXML_Parser::fatal_error (const ACEXML_Char* msg ACEXML_ENV_ARG_DECL)
03089 {
03090 ACEXML_SAXParseException* exception = 0;
03091 ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
03092 if (this->error_handler_)
03093 this->error_handler_->fatalError (*exception ACEXML_ENV_ARG_PARAMETER);
03094 this->reset();
03095 ACEXML_ENV_RAISE (exception);
03096 return;
03097 }
03098
03099 void
03100 ACEXML_Parser::parse_version_info (ACEXML_ENV_SINGLE_ARG_DECL)
03101 {
03102 ACEXML_Char* astring;
03103 if (this->parse_token (ACE_TEXT("ersion")) < 0
03104 || this->skip_equal () != 0
03105 || this->parse_version_num (astring) != 0)
03106 {
03107 this->fatal_error (ACE_TEXT ("Invalid VersionInfo specification")
03108 ACEXML_ENV_ARG_PARAMETER);
03109 return;
03110 }
03111 if (ACE_OS::strcmp (astring, ACE_TEXT ("1.0")) != 0)
03112 {
03113 this->fatal_error (ACE_TEXT ("ACEXML Parser supports XML version 1.0 ")
03114 ACE_TEXT ("documents only") ACEXML_ENV_ARG_PARAMETER);
03115 return;
03116 }
03117 }
03118
03119 void
03120 ACEXML_Parser::parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_DECL)
03121 {
03122 ACEXML_Char* astring = 0;
03123 if ((this->parse_token (ACE_TEXT("ncoding")) < 0)
03124 || this->skip_equal () != 0
03125 || this->parse_encname (astring) != 0)
03126 {
03127 this->fatal_error (ACE_TEXT ("Invalid EncodingDecl specification")
03128 ACEXML_ENV_ARG_PARAMETER);
03129 ACEXML_CHECK;
03130 }
03131 const ACEXML_Char* encoding = this->current_->getInputSource()->getEncoding();
03132 if (encoding != 0 && ACE_OS::strcmp (astring, encoding) != 0)
03133 {
03134 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Detected Encoding is %s ")
03135 ACE_TEXT (": Declared Encoding is %s\n"),
03136 encoding, astring));
03137 this->warning (ACE_TEXT ("Declared encoding differs from detected ")
03138 ACE_TEXT ("encoding") ACEXML_ENV_ARG_PARAMETER);
03139 }
03140 }
03141
03142 int
03143 ACEXML_Parser::parse_text_decl (ACEXML_ENV_SINGLE_ARG_DECL)
03144 {
03145
03146 if (this->parse_token (ACE_TEXT("xml")) < 0)
03147 {
03148 this->fatal_error(ACE_TEXT ("Expecting keyword 'xml' in TextDecl")
03149 ACEXML_ENV_ARG_PARAMETER);
03150 ACEXML_CHECK_RETURN (-1);
03151 }
03152
03153 ACEXML_Char fwd = this->skip_whitespace();
03154
03155 if (fwd == 'v')
03156 {
03157 this->parse_version_info (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03158 ACEXML_CHECK_RETURN (-1);
03159 fwd = this->skip_whitespace();
03160 }
03161
03162 if (fwd == 'e')
03163 {
03164 this->parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03165 ACEXML_CHECK_RETURN (-1);
03166 fwd = this->skip_whitespace();
03167 }
03168 else
03169 {
03170 this->fatal_error (ACE_TEXT ("Missing encodingDecl in TextDecl")
03171 ACEXML_ENV_ARG_PARAMETER);
03172 ACEXML_CHECK_RETURN (-1);
03173 }
03174
03175 if (fwd == '?' && this->get() == '>')
03176 return 0;
03177
03178 this->fatal_error (ACE_TEXT ("Invalid TextDecl") ACEXML_ENV_ARG_PARAMETER);
03179 ACEXML_CHECK_RETURN (-1);
03180 return -1;
03181 }
03182
03183 void
03184 ACEXML_Parser::parse_xml_decl (ACEXML_ENV_SINGLE_ARG_DECL)
03185 {
03186
03187 if (this->parse_token (ACE_TEXT("xml")) < 0)
03188 {
03189 this->fatal_error(ACE_TEXT ("Expecting keyword xml in XMLDecl")
03190 ACEXML_ENV_ARG_PARAMETER);
03191 ACEXML_CHECK;
03192 }
03193
03194 ACEXML_Char fwd = this->skip_whitespace();
03195
03196
03197 if (fwd != 'v')
03198 {
03199 this->fatal_error (ACE_TEXT ("Expecting VersionInfo declaration")
03200 ACEXML_ENV_ARG_PARAMETER);
03201 ACEXML_CHECK;
03202 }
03203
03204 this->parse_version_info (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03205 ACEXML_CHECK;
03206
03207 fwd = this->skip_whitespace();
03208 if (fwd != '?')
03209 {
03210 if (fwd == 'e')
03211 {
03212 this->parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03213 ACEXML_CHECK;
03214 fwd = this->skip_whitespace();
03215 }
03216 if (fwd == 's')
03217 {
03218 ACEXML_Char* astring;
03219 if ((this->parse_token (ACE_TEXT("tandalone")) == 0) &&
03220 this->skip_equal () == 0 &&
03221 this->parse_sddecl (astring) == 0)
03222 {
03223 if (ACE_OS::strcmp (astring, ACE_TEXT ("yes")) == 0)
03224 this->standalone_ = 1;
03225 fwd = this->skip_whitespace();
03226 }
03227 }
03228 }
03229 if (fwd == '?' && this->get() == '>')
03230 return;
03231
03232 this->fatal_error (ACE_TEXT ("Invalid XMLDecl declaration")
03233 ACEXML_ENV_ARG_PARAMETER);
03234 ACEXML_CHECK;
03235 }
03236
03237 int
03238 ACEXML_Parser::parse_comment (void)
03239 {
03240 int state = 0;
03241
03242 if (this->get () != '-' ||
03243 this->get () != '-' ||
03244 this->get () == '-')
03245 return -1;
03246
03247 while (state < 3)
03248
03249
03250
03251 {
03252 ACEXML_Char fwd = this->get ();
03253 if ((fwd == '-' && state < 2) ||
03254 (fwd == '>' && state == 2))
03255 state += 1;
03256 else
03257 state = 0;
03258 }
03259 return 0;
03260 }
03261
03262 int
03263 ACEXML_Parser::parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_DECL)
03264 {
03265 const ACEXML_Char *pitarget = this->parse_name ();
03266 ACEXML_Char *instruction = 0;
03267
03268 if (!ACE_OS::strcasecmp (ACE_TEXT ("xml"), pitarget))
03269 {
03270
03271 this->fatal_error(ACE_TEXT ("PI can't have 'xml' in PITarget")
03272 ACEXML_ENV_ARG_PARAMETER);
03273 ACEXML_CHECK_RETURN (-1);
03274 }
03275
03276 int state = 0;
03277
03278 ACEXML_Char ch = this->skip_whitespace();
03279 while (state < 2)
03280 {
03281 switch (ch)
03282 {
03283 case '?':
03284 if (state == 0)
03285 state = 1;
03286 break;
03287 case '>':
03288 if (state == 1)
03289 {
03290 instruction = this->obstack_.freeze ();
03291 this->content_handler_->processingInstruction (pitarget,
03292 instruction
03293 ACEXML_ENV_ARG_PARAMETER);
03294 ACEXML_CHECK_RETURN (-1);
03295 this->obstack_.unwind (const_cast<ACEXML_Char*> (pitarget));
03296 return 0;
03297 }
03298 break;
03299 case 0x0A:
03300
03301 default:
03302 if (state == 1)
03303 this->obstack_.grow ('?');
03304 this->obstack_.grow (ch);
03305 state = 0;
03306 }
03307 ch = this->get ();
03308 }
03309 return -1;
03310 }
03311
03312 void
03313 ACEXML_Parser::reset (void)
03314 {
03315 this->doctype_ = 0;
03316 if (this->ctx_stack_.pop (this->current_) == -1)
03317 ACE_ERROR ((LM_ERROR,
03318 ACE_TEXT ("Mismatched push/pop of Context stack")));
03319 if (this->current_)
03320 {
03321 this->current_->getInputSource()->getCharStream()->rewind();
03322
03323 this->current_->setInputSource (0);
03324 delete this->current_;
03325 this->current_ = 0;
03326 }
03327
03328 ACEXML_Char* temp = 0;
03329 while (this->GE_reference_.pop (temp) != -1)
03330 ;
03331 while (this->PE_reference_.pop (temp) != -1)
03332 ;
03333 this->obstack_.release();
03334 this->alt_stack_.release();
03335 this->xml_namespace_.reset();
03336 this->nested_namespace_ = 0;
03337 this->internal_GE_.reset();
03338 this->external_GE_.reset();
03339 this->unparsed_entities_.reset();
03340 this->predef_entities_.reset();
03341 this->internal_PE_.reset();
03342 this->external_PE_.reset();
03343 this->notations_.reset();
03344 this->ref_state_ = ACEXML_ParserInt::INVALID;
03345 this->external_subset_ = 0;
03346 this->external_entity_ = 0;
03347 this->has_pe_refs_ = 0;
03348 this->standalone_ = 0;
03349 this->external_dtd_ = 0;
03350 this->internal_dtd_ = 0;
03351 }
03352