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
00796 temp = ACE_OS::strrchr (baseURI, '/');
00797 }
00798 else
00799 {
00800
00801
00802 temp = ACE_OS::strrchr (baseURI, ACE_TEXT ('\\'));
00803 if (!temp)
00804 {
00805 temp = ACE_OS::strrchr (baseURI, ACE_TEXT ('/'));
00806 }
00807 }
00808
00809 if (temp)
00810 {
00811 size_t pos = temp - baseURI + 1;
00812 size_t len = pos + ACE_OS::strlen (systemId) + 1;
00813 ACE_NEW_RETURN (normalized_uri, ACEXML_Char[len], 0);
00814 ACE_OS::strncpy (normalized_uri, baseURI, pos);
00815 ACE_OS::strcpy (normalized_uri + pos, systemId);
00816 return normalized_uri;
00817 }
00818 return 0;
00819 }
00820 }
00821
00822 void
00823 ACEXML_Parser::parse_element (int is_root ACEXML_ENV_ARG_DECL)
00824 {
00825
00826 const ACEXML_Char *startname = this->parse_name ();
00827 if (startname == 0)
00828 {
00829 this->fatal_error (ACE_TEXT ("Unexpected end-of-file")
00830 ACEXML_ENV_ARG_PARAMETER);
00831 return;
00832 }
00833 if (is_root && this->doctype_ != 0
00834 && ACE_OS::strcmp (startname, this->doctype_) != 0)
00835 {
00836 this->fatal_error (ACE_TEXT ("Root element different from DOCTYPE")
00837 ACEXML_ENV_ARG_PARAMETER);
00838 return ;
00839 }
00840 ACEXML_AttributesImpl attributes;
00841 ACEXML_Char ch;
00842 int ns_flag = 0;
00843
00844
00845 const ACEXML_Char* ns_uri = 0;
00846 const ACEXML_Char* ns_lname = 0;
00847 for (int start_element_done = 0; start_element_done == 0;)
00848 {
00849 ch = this->skip_whitespace ();
00850
00851 switch (ch)
00852 {
00853 case 0:
00854 this->fatal_error(ACE_TEXT ("Internal Parser error")
00855 ACEXML_ENV_ARG_PARAMETER);
00856 return;
00857 case '/':
00858 if (this->get () != '>')
00859 {
00860 this->fatal_error(ACE_TEXT ("Expecting '>' at end of element ")
00861 ACE_TEXT ("definition")
00862 ACEXML_ENV_ARG_PARAMETER);
00863 return;
00864 }
00865 this->xml_namespace_.processName(startname, ns_uri,
00866 ns_lname, 0);
00867 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
00868 ns_uri, 1
00869 ACEXML_ENV_ARG_PARAMETER);
00870 ACEXML_CHECK;
00871 this->content_handler_->startElement(ns_uri, ns_lname,
00872 startname, &attributes
00873 ACEXML_ENV_ARG_PARAMETER);
00874 ACEXML_CHECK;
00875 this->content_handler_->endElement (ns_uri, ns_lname, startname
00876 ACEXML_ENV_ARG_PARAMETER);
00877 ACEXML_CHECK;
00878 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
00879 ns_uri, 0
00880 ACEXML_ENV_ARG_PARAMETER);
00881 ACEXML_CHECK;
00882 if (ns_flag)
00883 {
00884 this->xml_namespace_.popContext ();
00885 this->nested_namespace_--;
00886 }
00887 return;
00888 case '>':
00889 this->xml_namespace_.processName (startname, ns_uri,
00890 ns_lname, 0);
00891 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
00892 ns_uri, 1
00893 ACEXML_ENV_ARG_PARAMETER);
00894 ACEXML_CHECK;
00895 this->content_handler_->startElement(ns_uri, ns_lname, startname,
00896 &attributes
00897 ACEXML_ENV_ARG_PARAMETER);
00898 ACEXML_CHECK;
00899 start_element_done = 1;
00900 break;
00901 default:
00902 ACEXML_Char *attvalue = 0;
00903 ACEXML_Char *attname = this->parse_name (ch);
00904
00905 if (attname == 0 ||
00906 this->skip_equal () != 0 ||
00907 this->parse_attvalue (attvalue ACEXML_ENV_ARG_PARAMETER) != 0)
00908 {
00909 this->fatal_error(ACE_TEXT ("Error reading attribute value")
00910 ACEXML_ENV_ARG_PARAMETER);
00911 return;
00912 }
00913
00914
00915
00916 if (ACE_OS::strncmp (attname, ACE_TEXT("xmlns"), 5) == 0)
00917 {
00918 if (this->namespaces_)
00919 {
00920 if (!ns_flag)
00921 {
00922 this->xml_namespace_.pushContext ();
00923 this->nested_namespace_++;
00924 ns_flag = 1;
00925 }
00926
00927 ACEXML_Char* name = ACE_OS::strchr (attname, ':');
00928 const ACEXML_Char* ns_name = (name == 0)?
00929 empty_string:name+1;
00930 if (this->xml_namespace_.declarePrefix (ns_name,
00931 attvalue) == -1)
00932 {
00933 this->fatal_error(ACE_TEXT ("Duplicate definition of ")
00934 ACE_TEXT ("prefix")
00935 ACEXML_ENV_ARG_PARAMETER);
00936 return;
00937 }
00938 }
00939 if (this->namespace_prefixes_)
00940 {
00941
00942
00943 if (attributes.addAttribute (ACE_TEXT (""), ACE_TEXT (""),
00944 attname,
00945 default_attribute_type,
00946 attvalue) == -1)
00947 {
00948 this->fatal_error(ACE_TEXT ("Duplicate attribute ")
00949 ACE_TEXT ("definition. Hint: Try ")
00950 ACE_TEXT ("setting namespace_prefix")
00951 ACE_TEXT ("es feature to 0")
00952 ACEXML_ENV_ARG_PARAMETER);
00953 return;
00954 }
00955 }
00956 if (!this->namespaces_ && !this->namespace_prefixes_)
00957 {
00958 this->fatal_error(ACE_TEXT ("One of namespaces or ")
00959 ACE_TEXT ("namespace_prefixes should be")
00960 ACE_TEXT (" declared")
00961 ACEXML_ENV_ARG_PARAMETER);
00962 return;
00963 }
00964 }
00965 else
00966 {
00967 const ACEXML_Char *uri, *lName;
00968 this->xml_namespace_.processName (attname, uri, lName, 1);
00969 if (attributes.addAttribute (uri, lName, attname,
00970 default_attribute_type,
00971 attvalue) == -1)
00972 {
00973 this->fatal_error(ACE_TEXT ("Duplicate attribute ")
00974 ACE_TEXT ("definition")
00975 ACEXML_ENV_ARG_PARAMETER);
00976 return;
00977 }
00978 }
00979 break;
00980 }
00981 }
00982 if (this->parse_content (startname, ns_uri, ns_lname, ns_flag
00983 ACEXML_ENV_ARG_PARAMETER) != 0)
00984 return;
00985 }
00986
00987 int
00988 ACEXML_Parser::parse_content (const ACEXML_Char* startname,
00989 const ACEXML_Char*& ns_uri,
00990 const ACEXML_Char*& ns_lname, int ns_flag ACEXML_ENV_ARG_DECL)
00991 {
00992 ACEXML_Char *cdata;
00993 size_t cdata_length = 0;
00994
00995
00996 while (1)
00997 {
00998 ACEXML_Char ch = this->get ();
00999 switch (ch)
01000 {
01001 case 0:
01002 this->pop_context (1 ACEXML_ENV_ARG_PARAMETER);
01003 ACEXML_CHECK_RETURN (-1);
01004 break;
01005 case '<':
01006
01007 if (cdata_length != 0)
01008 {
01009 cdata = this->obstack_.freeze ();
01010 this->content_handler_->characters (cdata, 0, cdata_length
01011 ACEXML_ENV_ARG_PARAMETER);
01012 ACEXML_CHECK_RETURN (-1);
01013 this->obstack_.unwind (cdata);
01014 cdata_length = 0;
01015 }
01016 ch = this->peek();
01017 switch (ch)
01018 {
01019 case '!':
01020 this->get ();
01021 ch = this->peek ();
01022 if (ch == '-')
01023 {
01024 if (this->parse_comment () < 0)
01025 {
01026 this->fatal_error(ACE_TEXT ("Invalid comment in ")
01027 ACE_TEXT ("document")
01028 ACEXML_ENV_ARG_PARAMETER);
01029 ACEXML_CHECK_RETURN (-1);
01030 }
01031 }
01032 else if (ch == '[')
01033 {
01034 this->parse_cdata (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01035 ACEXML_CHECK_RETURN (-1);
01036 }
01037 else
01038 {
01039 this->fatal_error(ACE_TEXT ("Expecting a CDATA section ")
01040 ACE_TEXT ("or a comment section")
01041 ACEXML_ENV_ARG_PARAMETER);
01042 ACEXML_CHECK_RETURN (-1);
01043 }
01044 break;
01045 case '?':
01046 this->get();
01047 this->parse_processing_instruction
01048 (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01049 ACEXML_CHECK_RETURN (-1);
01050 break;
01051 case '/':
01052 {
01053 this->get ();
01054 ACEXML_Char* endname = this->parse_name ();
01055 if (endname == 0 ||
01056 ACE_OS::strcmp (startname, endname) != 0)
01057 {
01058 this->fatal_error(ACE_TEXT ("Name in ETag doesn't ")
01059 ACE_TEXT ("match name in STag")
01060 ACEXML_ENV_ARG_PARAMETER);
01061 ACEXML_CHECK_RETURN (-1);
01062 }
01063 if (this->skip_whitespace () != '>')
01064 {
01065 this->fatal_error(ACE_TEXT ("Expecting '>' at end ")
01066 ACE_TEXT ("of element")
01067 ACEXML_ENV_ARG_PARAMETER);
01068 return -1;
01069 }
01070 this->content_handler_->endElement (ns_uri, ns_lname,
01071 endname
01072 ACEXML_ENV_ARG_PARAMETER);
01073 ACEXML_CHECK_RETURN (-1);
01074 this->prefix_mapping (this->xml_namespace_.getPrefix(ns_uri),
01075 ns_uri, 0
01076 ACEXML_ENV_ARG_PARAMETER);
01077 ACEXML_CHECK_RETURN (-1);
01078 if (this->namespaces_ && ns_flag)
01079 {
01080 if (this->nested_namespace_ >= 1)
01081 {
01082 this->xml_namespace_.popContext ();
01083 this->nested_namespace_--;
01084 }
01085 }
01086 return 0;
01087 }
01088 default:
01089 this->parse_element (0 ACEXML_ENV_ARG_PARAMETER);
01090 ACEXML_CHECK_RETURN (-1);
01091 break;
01092 }
01093 break;
01094 case '&':
01095 if (this->peek () == '#')
01096 {
01097 ACEXML_Char buf[7];
01098 size_t len = 0;
01099 do
01100 {
01101 len = sizeof (buf);
01102 if (this->parse_char_reference (buf, len) != 0)
01103 {
01104
01105 this->fatal_error (ACE_TEXT ("Invalid CharRef")
01106 ACEXML_ENV_ARG_PARAMETER);
01107 ACEXML_CHECK_RETURN (-1);
01108 }
01109 } while (buf[0] == '&' && this->peek() == '#');
01110 for (size_t j = 0; j < len; ++j)
01111 this->obstack_.grow (buf[j]);
01112 cdata_length += len;
01113 }
01114 else
01115 {
01116 this->ref_state_ = ACEXML_ParserInt::IN_CONTENT;
01117 int length = this->parse_entity_reference(ACEXML_ENV_SINGLE_ARG_PARAMETER);
01118 ACEXML_CHECK_RETURN (-1);
01119 if (length == 1)
01120 cdata_length++;
01121 }
01122 break;
01123 case '\x20': case '\x0D': case '\x0A': case '\x09':
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
01152
01153
01154
01155
01156
01157
01158
01159
01160 default:
01161 ++cdata_length;
01162 this->obstack_.grow (ch);
01163 }
01164 }
01165 ACE_NOTREACHED (return 0;)
01166 }
01167
01168
01169 int
01170 ACEXML_Parser::parse_cdata (ACEXML_ENV_SINGLE_ARG_DECL)
01171 {
01172 if (this->parse_token (ACE_TEXT ("[CDATA[")) < 0)
01173 {
01174 this->fatal_error(ACE_TEXT ("Expecting '[CDATA[' at beginning of CDATA ")
01175 ACE_TEXT ("section")
01176 ACEXML_ENV_ARG_PARAMETER);
01177 ACEXML_CHECK_RETURN (-1);
01178 }
01179
01180 ACEXML_Char ch;
01181 int datalen = 0;
01182 ACEXML_Char *cdata = 0;
01183 while (1)
01184 {
01185 ch = this->get ();
01186
01187 if (ch == ']' && this->peek() == ']')
01188 {
01189 ACEXML_Char temp = ch;
01190 ch = this->get();
01191 if (ch == ']' && this->peek() == '>')
01192 {
01193 ch = this->get();
01194 cdata = this->obstack_.freeze ();
01195 this->content_handler_->characters (cdata, 0, datalen
01196 ACEXML_ENV_ARG_PARAMETER);
01197 ACEXML_CHECK_RETURN (-1);
01198 this->obstack_.unwind(cdata);
01199 return 0;
01200 }
01201 this->obstack_.grow (temp);
01202 ++datalen;
01203 }
01204 this->obstack_.grow (ch);
01205 ++datalen;
01206 };
01207 ACE_NOTREACHED (return -1);
01208 }
01209
01210
01211 int
01212 ACEXML_Parser::parse_entity_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01213 {
01214 ACEXML_Char nextch = 0;
01215
01216 if ((this->parse_token (ACE_TEXT ("NTITY")) < 0) ||
01217 this->skip_whitespace_count (&nextch) == 0)
01218 {
01219 this->fatal_error (ACE_TEXT ("Expecting keyword ENTITY followed by a ")
01220 ACE_TEXT ("space") ACEXML_ENV_ARG_PARAMETER);
01221 ACEXML_CHECK_RETURN (-1);
01222 }
01223
01224 int is_GEDecl = 1;
01225 if (nextch == '%')
01226 {
01227 is_GEDecl = 0;
01228 this->get ();
01229 if (this->skip_whitespace_count (&nextch) == 0)
01230 {
01231 this->fatal_error (ACE_TEXT ("Expecting space between % and ")
01232 ACE_TEXT ("entity name")
01233 ACEXML_ENV_ARG_PARAMETER);
01234 ACEXML_CHECK_RETURN (-1);
01235 }
01236 }
01237
01238 ACEXML_Char *entity_name = this->parse_name ();
01239 if (entity_name == 0)
01240 {
01241 this->fatal_error (ACE_TEXT ("Invalid entity name")
01242 ACEXML_ENV_ARG_PARAMETER);
01243 ACEXML_CHECK_RETURN (-1);
01244 }
01245
01246 if (this->skip_whitespace_count (&nextch) == 0)
01247 {
01248 this->fatal_error (ACE_TEXT ("Expecting space between entity name and ")
01249 ACE_TEXT ("entityDef")
01250 ACEXML_ENV_ARG_PARAMETER);
01251 ACEXML_CHECK_RETURN (-1);
01252 }
01253 int retval = 0;
01254 if (nextch == '\'' || nextch == '"')
01255 {
01256 ACEXML_Char *entity_value = 0;
01257 if (this->parse_entity_value (entity_value
01258 ACEXML_ENV_ARG_PARAMETER) != 0)
01259 {
01260 this->fatal_error(ACE_TEXT ("Invalid EntityValue")
01261 ACEXML_ENV_ARG_PARAMETER);
01262 ACEXML_CHECK_RETURN (-1);
01263 }
01264 if (is_GEDecl)
01265 retval = this->internal_GE_.add_entity (entity_name,
01266 entity_value);
01267 else
01268 retval = this->internal_PE_.add_entity (entity_name,
01269 entity_value);
01270 if (retval < 0)
01271 {
01272 this->fatal_error (ACE_TEXT ("Internal Parser Error in adding")
01273 ACE_TEXT ("Entity to map")
01274 ACEXML_ENV_ARG_PARAMETER);
01275 ACEXML_CHECK_RETURN (-1);
01276 }
01277 else if (retval == 1)
01278 {
01279 this->warning (ACE_TEXT ("Duplicate entity found")
01280 ACEXML_ENV_ARG_PARAMETER);
01281 ACEXML_CHECK_RETURN (-1);
01282 }
01283 }
01284 else
01285 {
01286 ACEXML_Char *systemid, *publicid;
01287
01288 this->parse_external_id (publicid, systemid
01289 ACEXML_ENV_ARG_PARAMETER);
01290 ACEXML_CHECK_RETURN (-1);
01291 if (systemid == 0)
01292 {
01293 this->fatal_error(ACE_TEXT ("Invalid SystemLiteral")
01294 ACEXML_ENV_ARG_PARAMETER);
01295 ACEXML_CHECK_RETURN (-1);
01296 }
01297 this->skip_whitespace_count (&nextch);
01298 if (nextch == 'N')
01299 {
01300 if (is_GEDecl == 0)
01301 {
01302 this->fatal_error(ACE_TEXT ("Invalid NDataDecl in PEDef")
01303 ACEXML_ENV_ARG_PARAMETER);
01304 ACEXML_CHECK_RETURN (-1);
01305 }
01306
01307 if ((this->parse_token (ACE_TEXT ("NDATA")) < 0) ||
01308 this->skip_whitespace_count (&nextch) == 0)
01309 {
01310 this->fatal_error(ACE_TEXT ("Expecting keyword NDATA followed ")
01311 ACE_TEXT ("by a space") ACEXML_ENV_ARG_PARAMETER);
01312 ACEXML_CHECK_RETURN (-1);
01313 }
01314
01315 ACEXML_Char *ndata = this->parse_name ();
01316 if (this->validate_)
01317 {
01318 if (!this->notations_.resolve_entity (ndata))
01319 {
01320 this->fatal_error (ACE_TEXT ("Undeclared Notation name")
01321 ACEXML_ENV_ARG_PARAMETER);
01322 ACEXML_CHECK_RETURN (-1);
01323 }
01324 this->dtd_handler_->unparsedEntityDecl(entity_name, publicid,
01325 systemid, ndata
01326 ACEXML_ENV_ARG_PARAMETER);
01327 ACEXML_CHECK_RETURN (-1);
01328 }
01329 }
01330 else
01331 {
01332 if (is_GEDecl)
01333 retval = this->external_GE_.add_entity (entity_name,
01334 systemid);
01335 else
01336 retval = this->external_PE_.add_entity (entity_name,
01337 systemid);
01338 if (retval < 0)
01339 {
01340 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01341 ACEXML_ENV_ARG_PARAMETER);
01342 ACEXML_CHECK_RETURN (-1);
01343 }
01344 else if (retval == 1)
01345 this->warning(ACE_TEXT ("Duplicate external entity")
01346 ACEXML_ENV_ARG_PARAMETER);
01347 if (is_GEDecl)
01348 retval = this->external_GE_.add_entity (entity_name,
01349 publicid);
01350 else
01351 retval = this->external_PE_.add_entity (entity_name,
01352 publicid);
01353 if (retval < 0)
01354 {
01355 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01356 ACEXML_ENV_ARG_PARAMETER);
01357 ACEXML_CHECK_RETURN (-1);
01358 }
01359 else if (retval == 1)
01360 this->warning (ACE_TEXT ("Duplicate entity definition")
01361 ACEXML_ENV_ARG_PARAMETER);
01362 }
01363 }
01364
01365
01366 if (this->skip_whitespace() != '>')
01367 {
01368 this->fatal_error(ACE_TEXT ("Expecting '>' at end of entityDef")
01369 ACEXML_ENV_ARG_PARAMETER);
01370 ACEXML_CHECK_RETURN (-1);
01371 }
01372 return 0;
01373 }
01374
01375 int
01376 ACEXML_Parser::parse_attlist_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01377 {
01378 if (this->parse_token (ACE_TEXT ("ATTLIST")) < 0)
01379 {
01380 this->fatal_error(ACE_TEXT ("Expecting keyword 'ATTLIST'")
01381 ACEXML_ENV_ARG_PARAMETER);
01382 ACEXML_CHECK_RETURN (-1);
01383 }
01384 int count = check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01385 ACEXML_CHECK_RETURN (-1);
01386 if (!count)
01387 {
01388 this->fatal_error(ACE_TEXT ("Expecting space between ATTLIST and ")
01389 ACE_TEXT ("element name") ACEXML_ENV_ARG_PARAMETER);
01390 ACEXML_CHECK_RETURN (-1);
01391 }
01392
01393 ACEXML_Char *element_name = this->parse_name ();
01394 if (element_name == 0)
01395 {
01396 this->fatal_error(ACE_TEXT ("Invalid element Name in attlistDecl")
01397 ACEXML_ENV_ARG_PARAMETER);
01398 ACEXML_CHECK_RETURN (-1);
01399 }
01400 ACEXML_Char fwd = 0;
01401 count = this->skip_whitespace_count (&fwd);
01402
01403 while (fwd != '>')
01404 {
01405 if (!this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER)
01406 && !count)
01407 this->fatal_error(ACE_TEXT ("Expecting space between element ")
01408 ACE_TEXT ("name and AttDef")
01409 ACEXML_ENV_ARG_PARAMETER);
01410 ACEXML_CHECK_RETURN (-1);
01411 this->skip_whitespace_count (&fwd);
01412 if (fwd == '>')
01413 break;
01414
01415 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01416 ACEXML_CHECK_RETURN (-1);
01417
01418 this->parse_attname (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01419 ACEXML_CHECK_RETURN (-1);
01420
01421 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01422 ACEXML_CHECK_RETURN (-1);
01423 if (!count)
01424 {
01425 this->fatal_error(ACE_TEXT ("Expecting space between AttName and ")
01426 ACE_TEXT ("AttType") ACEXML_ENV_ARG_PARAMETER);
01427 ACEXML_CHECK_RETURN (-1);
01428 }
01429 this->parse_atttype (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01430 ACEXML_CHECK_RETURN (-1);
01431
01432 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01433 ACEXML_CHECK_RETURN (-1);
01434 if (!count)
01435 {
01436 this->fatal_error(ACE_TEXT ("Expecting space between AttType and")
01437 ACE_TEXT (" DefaultDecl")
01438 ACEXML_ENV_ARG_PARAMETER);
01439 ACEXML_CHECK_RETURN (-1);
01440 }
01441 this->parse_defaultdecl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01442 ACEXML_CHECK_RETURN (-1);
01443
01444 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01445 ACEXML_CHECK_RETURN (-1);
01446 this->skip_whitespace_count(&fwd);
01447 }
01448 this->get ();
01449 return 0;
01450 }
01451
01452
01453 int
01454 ACEXML_Parser::check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_DECL)
01455 {
01456 ACEXML_Char fwd = '\xFF';
01457
01458 int count = this->skip_whitespace_count (&fwd);
01459 if (fwd == 0)
01460 {
01461 this->get();
01462 this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
01463 ACEXML_CHECK_RETURN (-1);
01464 fwd = this->peek();
01465 }
01466 if (fwd == '%')
01467 {
01468 this->get();
01469 if (this->external_subset_)
01470 {
01471 this->parse_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01472 ACEXML_CHECK_RETURN (-1);
01473 }
01474 else
01475 {
01476 this->fatal_error(ACE_TEXT ("Illegal PERef within markupDecl")
01477 ACEXML_ENV_ARG_PARAMETER);
01478 ACEXML_CHECK_RETURN (-1);
01479 }
01480 }
01481 if (count)
01482 {
01483
01484
01485 this->skip_whitespace_count();
01486 return count;
01487 }
01488 return this->skip_whitespace_count();
01489 }
01490
01491 ACEXML_Char*
01492 ACEXML_Parser::parse_attname (ACEXML_ENV_SINGLE_ARG_DECL)
01493 {
01494
01495 ACEXML_Char *att_name = this->parse_name ();
01496 if (att_name == 0)
01497 {
01498 this->fatal_error(ACE_TEXT ("Invalid AttName")
01499 ACEXML_ENV_ARG_PARAMETER);
01500 ACEXML_CHECK_RETURN (0);
01501 }
01502 return att_name;
01503 }
01504
01505 int
01506 ACEXML_Parser::parse_defaultdecl (ACEXML_ENV_SINGLE_ARG_DECL)
01507 {
01508
01509 ACEXML_Char nextch = this->peek ();
01510 ACEXML_Char *fixed_attr = 0;
01511 switch (nextch)
01512 {
01513 case '#':
01514 this->get ();
01515 switch (this->get ())
01516 {
01517 case 'R':
01518 if (this->parse_token (ACE_TEXT ("EQUIRED")) < 0)
01519 {
01520 this->fatal_error(ACE_TEXT ("Expecting keyword REQUIRED")
01521 ACEXML_ENV_ARG_PARAMETER);
01522 ACEXML_CHECK_RETURN (-1);
01523 }
01524
01525
01526 break;
01527 case 'I':
01528 if (this->parse_token (ACE_TEXT ("MPLIED")) < 0)
01529 {
01530 this->fatal_error(ACE_TEXT ("Expecting keyword IMPLIED")
01531 ACEXML_ENV_ARG_PARAMETER);
01532 ACEXML_CHECK_RETURN (-1);
01533 }
01534
01535
01536 break;
01537 case 'F':
01538 if (this->parse_token (ACE_TEXT ("IXED")) < 0 ||
01539 this->skip_whitespace_count () == 0)
01540 {
01541 this->fatal_error(ACE_TEXT ("Expecting keyword FIXED")
01542 ACEXML_ENV_ARG_PARAMETER);
01543 ACEXML_CHECK_RETURN (-1);
01544 }
01545
01546 if (this->parse_attvalue (fixed_attr
01547 ACEXML_ENV_ARG_PARAMETER) != 0)
01548 {
01549 this->fatal_error(ACE_TEXT ("Invalid Default AttValue")
01550 ACEXML_ENV_ARG_PARAMETER);
01551 ACEXML_CHECK_RETURN (-1);
01552 }
01553
01554 break;
01555 default:
01556 this->fatal_error (ACE_TEXT ("Invalid DefaultDecl")
01557 ACEXML_ENV_ARG_PARAMETER);
01558 ACEXML_CHECK_RETURN (-1);
01559 }
01560 break;
01561 case '\'':
01562 case '"':
01563 if (this->parse_attvalue (fixed_attr ACEXML_ENV_ARG_PARAMETER) != 0)
01564 {
01565 this->fatal_error(ACE_TEXT ("Invalid AttValue")
01566 ACEXML_ENV_ARG_PARAMETER);
01567 ACEXML_CHECK_RETURN (-1);
01568 }
01569
01570 break;
01571 default:
01572 this->fatal_error (ACE_TEXT ("Invalid DefaultDecl")
01573 ACEXML_ENV_ARG_PARAMETER);
01574 ACEXML_CHECK_RETURN (-1);
01575 break;
01576 }
01577 return 0;
01578 }
01579
01580 int
01581 ACEXML_Parser::parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_DECL)
01582 {
01583 ACEXML_Char ch = this->get();
01584 switch (ch)
01585 {
01586 case 'I':
01587 if (this->get () == 'D')
01588 {
01589 if (this->peek() != 'R' && this->is_whitespace (this->peek()))
01590 {
01591
01592
01593
01594 break;
01595 }
01596 if (this->parse_token (ACE_TEXT ("REF")) == 0)
01597 {
01598 if (this->peek() != 'S' && this->is_whitespace (this->peek()))
01599 {
01600
01601
01602
01603 break;
01604 }
01605 else if (this->peek() == 'S'
01606 && this->get()
01607 && this->is_whitespace (this->peek()))
01608 {
01609
01610
01611
01612 break;
01613 }
01614 }
01615 }
01616
01617 this->fatal_error(ACE_TEXT ("Expecting keyword `ID', `IDREF', or")
01618 ACE_TEXT ("`IDREFS'") ACEXML_ENV_ARG_PARAMETER);
01619 ACEXML_CHECK_RETURN (-1);
01620 case 'E':
01621 if (this->parse_token (ACE_TEXT ("NTIT")) == 0)
01622 {
01623 ACEXML_Char nextch = this->get ();
01624 if (nextch == 'Y')
01625 {
01626
01627
01628
01629 }
01630 else if (this->parse_token (ACE_TEXT ("IES")) == 0)
01631 {
01632
01633
01634
01635 }
01636 if (this->is_whitespace (this->peek()))
01637 {
01638
01639 break;
01640 }
01641 }
01642
01643 this->fatal_error(ACE_TEXT ("Expecting keyword `ENTITY', or")
01644 ACE_TEXT ("`ENTITIES'") ACEXML_ENV_ARG_PARAMETER);
01645 ACEXML_CHECK_RETURN (-1);
01646 case 'M':
01647 if (this->parse_token (ACE_TEXT ("TOKEN")) == 0)
01648 {
01649 if (this->is_whitespace (this->peek()))
01650 {
01651
01652
01653
01654 break;
01655 }
01656 else if (this->peek() == 'S'
01657 && this->get()
01658 && this->is_whitespace (this->peek()))
01659 {
01660
01661
01662
01663 break;
01664 }
01665 }
01666 this->fatal_error(ACE_TEXT ("Expecting keyword `NMTOKEN' or `NMTO")
01667 ACE_TEXT ("KENS'") ACEXML_ENV_ARG_PARAMETER);
01668 ACEXML_CHECK_RETURN (-1);
01669 break;
01670 default:
01671 this->fatal_error (ACE_TEXT ("Internal Parser Error")
01672 ACEXML_ENV_ARG_PARAMETER);
01673 ACEXML_CHECK_RETURN (-1);
01674 break;
01675 }
01676 return 0;
01677 }
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701 int
01702 ACEXML_Parser::parse_atttype (ACEXML_ENV_SINGLE_ARG_DECL)
01703 {
01704 ACEXML_Char nextch = this->peek();
01705 switch (nextch)
01706 {
01707 case 'C':
01708 if (this->parse_token (ACE_TEXT ("CDATA")) < 0)
01709 {
01710 this->fatal_error(ACE_TEXT ("Expecting keyword 'CDATA'")
01711 ACEXML_ENV_ARG_PARAMETER);
01712 ACEXML_CHECK_RETURN (-1);
01713 }
01714
01715
01716
01717 break;
01718 case 'I': case 'E':
01719 this->parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01720 ACEXML_CHECK_RETURN (-1);
01721 break;
01722 case 'N':
01723 this->get();
01724 nextch = this->peek();
01725 if (nextch != 'M' && nextch != 'O')
01726 {
01727 this->fatal_error (ACE_TEXT ("Expecting keyword 'NMTOKEN', ")
01728 ACE_TEXT ("'NMTOKENS' or 'NOTATION'")
01729 ACEXML_ENV_ARG_PARAMETER);
01730 ACEXML_CHECK_RETURN (-1);
01731 }
01732 if (nextch == 'M')
01733 {
01734 this->parse_tokenized_type (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01735 ACEXML_CHECK_RETURN (-1);
01736 break;
01737 }
01738 else
01739 {
01740 if (this->parse_token (ACE_TEXT ("OTATION")) < 0)
01741 {
01742 this->fatal_error(ACE_TEXT ("Expecting keyword `NOTATION'")
01743 ACEXML_ENV_ARG_PARAMETER);
01744 ACEXML_CHECK_RETURN (-1);
01745 }
01746 int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01747 ACEXML_CHECK_RETURN (-1);
01748 if (!count)
01749 {
01750 this->fatal_error (ACE_TEXT ("Expecting space between keyword ")
01751 ACE_TEXT ("NOTATION and '('")
01752 ACEXML_ENV_ARG_PARAMETER);
01753 ACEXML_CHECK_RETURN (-1);
01754 }
01755 if (this->get () != '(')
01756 {
01757 this->fatal_error(ACE_TEXT ("Expecting '(' in NotationType")
01758 ACEXML_ENV_ARG_PARAMETER);
01759 ACEXML_CHECK_RETURN (-1);
01760 }
01761 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01762 ACEXML_CHECK_RETURN (-1);
01763 do {
01764 this->skip_whitespace_count();
01765 ACEXML_Char *notation_name = this->parse_name ();
01766 if (notation_name == 0)
01767 {
01768 this->fatal_error(ACE_TEXT ("Invalid notation name")
01769 ACEXML_ENV_ARG_PARAMETER);
01770 ACEXML_CHECK_RETURN (-1);
01771 }
01772
01773 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01774 ACEXML_CHECK_RETURN (-1);
01775 nextch = this->get();
01776 } while (nextch == '|');
01777 if (nextch != ')')
01778 {
01779 this->fatal_error (ACE_TEXT ("Expecting a ')' after a ")
01780 ACE_TEXT ("NotationType declaration")
01781 ACEXML_ENV_ARG_PARAMETER);
01782 ACEXML_CHECK_RETURN (-1);
01783 }
01784 }
01785 break;
01786 case '(':
01787 this->get();
01788 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01789 ACEXML_CHECK_RETURN (-1);
01790 do {
01791 this->skip_whitespace_count();
01792 ACEXML_Char *token_name = this->parse_nmtoken ();
01793 if (token_name == 0)
01794 {
01795 this->fatal_error(ACE_TEXT ("Invalid enumeration name")
01796 ACEXML_ENV_ARG_PARAMETER);
01797 ACEXML_CHECK_RETURN (-1);
01798 }
01799
01800 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01801 ACEXML_CHECK_RETURN (-1);
01802 nextch = this->get();
01803 } while (nextch == '|');
01804 if (nextch != ')')
01805 {
01806 this->fatal_error (ACE_TEXT ("Expecting a ')' after a ")
01807 ACE_TEXT ("Enumeration declaration")
01808 ACEXML_ENV_ARG_PARAMETER);
01809 ACEXML_CHECK_RETURN (-1);
01810 }
01811 break;
01812 default:
01813 {
01814 this->fatal_error(ACE_TEXT ("Invalid AttType")
01815 ACEXML_ENV_ARG_PARAMETER);
01816 ACEXML_CHECK_RETURN (-1);
01817 }
01818 ACE_NOTREACHED (break);
01819 }
01820 return 0;
01821 }
01822
01823 int
01824 ACEXML_Parser::parse_notation_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01825 {
01826 if (this->parse_token (ACE_TEXT ("NOTATION")) < 0)
01827 {
01828 this->fatal_error(ACE_TEXT ("Expecting Keyword 'NOTATION'")
01829 ACEXML_ENV_ARG_PARAMETER);
01830 ACEXML_CHECK_RETURN (-1);
01831 }
01832 int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01833 ACEXML_CHECK_RETURN (-1);
01834 if (!count)
01835 {
01836 this->fatal_error (ACE_TEXT ("Expecting a space between keyword NOTATION")
01837 ACE_TEXT (" and notation name")
01838 ACEXML_ENV_ARG_PARAMETER);
01839 ACEXML_CHECK_RETURN (-1);
01840 }
01841 ACEXML_Char *notation = this->parse_name ();
01842 if (notation == 0)
01843 {
01844 this->fatal_error(ACE_TEXT ("Invalid Notation name")
01845 ACEXML_ENV_ARG_PARAMETER);
01846 ACEXML_CHECK_RETURN (-1);
01847 }
01848 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01849 ACEXML_CHECK_RETURN (-1);
01850 if (!count)
01851 {
01852 this->fatal_error (ACE_TEXT ("Expecting a space between notation name ")
01853 ACE_TEXT ("and ExternalID/PublicID")
01854 ACEXML_ENV_ARG_PARAMETER);
01855 ACEXML_CHECK_RETURN (-1);
01856 }
01857
01858 ACEXML_Char *systemid, *publicid;
01859
01860
01861
01862
01863 ACEXML_ParserInt::ReferenceState temp = this->ref_state_;
01864 this->ref_state_ = ACEXML_ParserInt::IN_NOTATION;
01865
01866 this->parse_external_id (publicid, systemid
01867 ACEXML_ENV_ARG_PARAMETER);
01868 ACEXML_CHECK_RETURN (-1);
01869
01870 this->ref_state_ = temp;
01871
01872
01873 if (systemid && this->notations_.add_entity (notation, systemid) != 0
01874 && this->validate_)
01875 {
01876 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01877 ACEXML_ENV_ARG_PARAMETER);
01878 ACEXML_CHECK_RETURN (-1);
01879 }
01880 if (publicid)
01881 {
01882 int retval = this->notations_.add_entity (notation, publicid);
01883 if (retval != 0 && !systemid && this->validate_)
01884 {
01885 this->fatal_error(ACE_TEXT ("Internal Parser Error")
01886 ACEXML_ENV_ARG_PARAMETER);
01887 ACEXML_CHECK_RETURN (-1);
01888 }
01889 }
01890
01891 if (this->skip_whitespace() != '>')
01892 {
01893 this->fatal_error(ACE_TEXT ("Expecting '>' at end of NotationDecl")
01894 ACEXML_ENV_ARG_PARAMETER);
01895 ACEXML_CHECK_RETURN (-1);
01896 }
01897
01898 if (this->validate_ && this->dtd_handler_)
01899 {
01900 this->dtd_handler_->notationDecl (notation,
01901 publicid,
01902 systemid ACEXML_ENV_ARG_PARAMETER);
01903 ACEXML_CHECK_RETURN (-1);
01904 }
01905 return 0;
01906 }
01907
01908 int
01909 ACEXML_Parser::parse_element_decl (ACEXML_ENV_SINGLE_ARG_DECL)
01910 {
01911 if (this->parse_token (ACE_TEXT ("LEMENT")) < 0)
01912 {
01913 this->fatal_error (ACE_TEXT ("Expecting keyword ELEMENT")
01914 ACEXML_ENV_ARG_PARAMETER);
01915 ACEXML_CHECK_RETURN (-1);
01916 }
01917 int count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01918 ACEXML_CHECK_RETURN (-1);
01919 if (!count)
01920 {
01921 this->fatal_error (ACE_TEXT ("Expecting a space between keyword ELEMENT")
01922 ACE_TEXT (" and element name")
01923 ACEXML_ENV_ARG_PARAMETER);
01924 ACEXML_CHECK_RETURN (-1);
01925 }
01926 ACEXML_Char *element_name = this->parse_name ();
01927 if (element_name == 0)
01928 {
01929 this->fatal_error (ACE_TEXT ("Invalid element name")
01930 ACEXML_ENV_ARG_PARAMETER);
01931 ACEXML_CHECK_RETURN (-1);
01932 }
01933 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01934 ACEXML_CHECK_RETURN (-1);
01935 if (!count)
01936 {
01937 this->fatal_error (ACE_TEXT ("Expecting a space between element name ")
01938 ACE_TEXT ("and element definition")
01939 ACEXML_ENV_ARG_PARAMETER);
01940 ACEXML_CHECK_RETURN (-1);
01941 }
01942 ACEXML_Char nextch = this->peek();
01943 switch (nextch)
01944 {
01945 case 'E':
01946 if (this->parse_token (ACE_TEXT ("EMPTY")) < 0)
01947 {
01948 this->fatal_error (ACE_TEXT ("Expecting keyword EMPTY")
01949 ACEXML_ENV_ARG_PARAMETER);
01950 ACEXML_CHECK_RETURN (-1);
01951 }
01952 break;
01953 case 'A':
01954 if (this->parse_token (ACE_TEXT ("ANY")) < 0)
01955 {
01956 this->fatal_error (ACE_TEXT ("Expecting keyword ANY")
01957 ACEXML_ENV_ARG_PARAMETER);
01958 ACEXML_CHECK_RETURN (-1);
01959 }
01960 break;
01961 case '(':
01962 this->parse_children_definition (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01963 ACEXML_CHECK_RETURN (-1);
01964 break;
01965 default:
01966 this->fatal_error (ACE_TEXT ("Invalid element definition")
01967 ACEXML_ENV_ARG_PARAMETER);
01968 ACEXML_CHECK_RETURN (-1);
01969 }
01970 count = this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01971 ACEXML_CHECK_RETURN (-1);
01972 if (this->skip_whitespace () != '>')
01973 {
01974 this->fatal_error (ACE_TEXT ("Expecting '>' after element defintion")
01975 ACEXML_ENV_ARG_PARAMETER);
01976 ACEXML_CHECK_RETURN (-1);
01977 }
01978 return 0;
01979 }
01980
01981
01982 int
01983 ACEXML_Parser::parse_children_definition (ACEXML_ENV_SINGLE_ARG_DECL)
01984 {
01985 this->get ();
01986 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
01987 ACEXML_CHECK_RETURN (-1);
01988 int subelement_number = 0;
01989 ACEXML_Char nextch = this->peek();
01990 switch (nextch)
01991 {
01992 case '#':
01993 if (this->parse_token (ACE_TEXT ("#PCDATA")) < 0)
01994 {
01995 this->fatal_error(ACE_TEXT ("Expecting keyword '#PCDATA'")
01996 ACEXML_ENV_ARG_PARAMETER);
01997 ACEXML_CHECK_RETURN (-1);
01998 }
01999 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02000 ACEXML_CHECK_RETURN (-1);
02001 nextch = this->get();
02002 while (nextch == '|')
02003 {
02004 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02005 ACEXML_CHECK_RETURN (-1);
02006 ACEXML_Char *name = this->parse_name ();
02007
02008 ACE_UNUSED_ARG (name);
02009 ++subelement_number;
02010
02011 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02012 ACEXML_CHECK_RETURN (-1);
02013 nextch = this->skip_whitespace();
02014 }
02015 if (nextch != ')' ||
02016 (subelement_number && this->get () != '*'))
02017 {
02018 this->fatal_error(ACE_TEXT ("Expecing ')' or ')*' at end of Mixed")
02019 ACE_TEXT (" element") ACEXML_ENV_ARG_PARAMETER);
02020 ACEXML_CHECK_RETURN (-1);
02021 }
02022
02023 break;
02024 default:
02025 int status = this->parse_child (1 ACEXML_ENV_ARG_PARAMETER);
02026 ACEXML_CHECK_RETURN (-1);
02027 if (status != 0)
02028 return -1;
02029 }
02030
02031
02032 nextch = this->peek ();
02033 switch (nextch)
02034 {
02035 case '?':
02036
02037 this->get ();
02038 break;
02039 case '*':
02040
02041 this->get ();
02042 break;
02043 case '+':
02044
02045 this->get ();
02046 break;
02047 default:
02048 break;
02049 }
02050
02051 return 0;
02052 }
02053
02054 int
02055 ACEXML_Parser::parse_child (int skip_open_paren ACEXML_ENV_ARG_DECL)
02056 {
02057
02058 if (skip_open_paren == 0 && this->get () != '(')
02059 {
02060 this->fatal_error(ACE_TEXT ("Expecting '(' at beginning of children")
02061 ACEXML_ENV_ARG_PARAMETER);
02062 ACEXML_CHECK_RETURN (-1);
02063 }
02064
02065 ACEXML_Char node_type = 0;
02066 ACEXML_Char nextch;
02067
02068 do {
02069 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02070 ACEXML_CHECK_RETURN (-1);
02071 this->skip_whitespace_count (&nextch);
02072 switch (nextch)
02073 {
02074 case '(':
02075 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02076 ACEXML_CHECK_RETURN (-1);
02077 this->parse_child (0 ACEXML_ENV_ARG_PARAMETER);
02078 ACEXML_CHECK_RETURN (-1);
02079 break;
02080 default:
02081 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02082 ACEXML_CHECK_RETURN (-1);
02083
02084 ACEXML_Char *subelement = this->parse_name ();
02085 if (subelement == 0)
02086 {
02087 this->fatal_error(ACE_TEXT ("Invalid subelement name")
02088 ACEXML_ENV_ARG_PARAMETER);
02089 ACEXML_CHECK_RETURN (-1);
02090 }
02091
02092 nextch = this->peek ();
02093 switch (nextch)
02094 {
02095 case '?':
02096
02097 this->get ();
02098 break;
02099 case '*':
02100
02101 this->get ();
02102 break;
02103 case '+':
02104
02105 this->get ();
02106 break;
02107 default:
02108 break;
02109 }
02110
02111
02112 break;
02113 }
02114 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02115 ACEXML_CHECK_RETURN (-1);
02116 this->skip_whitespace_count (&nextch);
02117 switch (nextch)
02118 {
02119 case '|':
02120 switch (node_type)
02121 {
02122 case 0:
02123 node_type = '|';
02124
02125 break;
02126 case '|':
02127 break;
02128 default:
02129 this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
02130 ACE_TEXT ("while defining an element")
02131 ACEXML_ENV_ARG_PARAMETER);
02132 ACEXML_CHECK_RETURN (-1);
02133 }
02134 break;
02135 case ',':
02136 switch (node_type)
02137 {
02138 case 0:
02139 node_type = ',';
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 break;
02151 case ')':
02152 break;
02153 default:
02154 this->fatal_error (ACE_TEXT ("Expecting `,', `|', or `)' ")
02155 ACE_TEXT ("while defining an element")
02156 ACEXML_ENV_ARG_PARAMETER);
02157 ACEXML_CHECK_RETURN (-1);
02158 }
02159 nextch = this->get();
02160 if (nextch == ')')
02161 break;
02162 this->check_for_PE_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02163 ACEXML_CHECK_RETURN (-1);
02164 this->skip_whitespace_count (&nextch);
02165 } while (nextch != ')');
02166
02167
02168 nextch = this->peek ();
02169 switch (nextch)
02170 {
02171 case '?':
02172
02173 this->get ();
02174 break;
02175 case '*':
02176
02177 this->get ();
02178 break;
02179 case '+':
02180
02181 this->get ();
02182 break;
02183 default:
02184 break;
02185 }
02186
02187
02188 return 0;
02189 }
02190
02191 int
02192 ACEXML_Parser::parse_char_reference (ACEXML_Char *buf, size_t& len)
02193 {
02194 if (len < 7)
02195 return -1;
02196 ACEXML_Char ch = this->get();
02197 if (ch != '#')
02198 return -1;
02199 int hex = 0;
02200 ch = this->peek();
02201 if (ch == 'x')
02202 {
02203 hex = 1;
02204 this->get ();
02205 }
02206 size_t i = 0;
02207 int more_digit = 0;
02208 ch = this->get ();
02209 for ( ; i < len &&
02210 (this->isNormalDigit (ch) || (hex ? this->isCharRef(ch): 0)); ++i)
02211 {
02212 buf[i] = ch;
02213 ch = this->get();
02214 ++more_digit;
02215 }
02216 if (ch != ';' || !more_digit)
02217 return -1;
02218 buf[i] = 0;
02219 ACEXML_UCS4 sum = (ACEXML_UCS4) ACE_OS::strtol (buf, 0, (hex ? 16 : 10));
02220
02221 if (!this->isChar (sum))
02222 return -1;
02223 int clen;
02224 #if defined (ACE_USES_WCHAR)
02225 # if (ACE_SIZEOF_WCHAR == 2) // UTF-16
02226 if ((clen = ACEXML_Transcoder::ucs42utf16 (sum, buf, len)) < 0)
02227 return -1;
02228 # elif (ACE_SIZEOF_WCHAR == 4) // UCS 4
02229 buf [0] = sum;
02230 buf [1] = 0;
02231 clen = 2;
02232 # endif
02233
02234 #else // or UTF-8
02235 if ((clen = ACEXML_Transcoder::ucs42utf8 (sum, buf, len)) < 0)
02236 return -1;
02237 #endif
02238 buf [clen] = 0;
02239 len = clen;
02240 return 0;
02241 }
02242
02243 ACEXML_Char*
02244 ACEXML_Parser::parse_reference_name (void)
02245 {
02246 ACEXML_Char ch = this->get ();
02247 if (!this->isLetter (ch) && (ch != '_' || ch != ':'))
02248 return 0;
02249 while (ch) {
02250 this->alt_stack_.grow (ch);
02251 ch = this->peek ();
02252 if (!this->isNameChar (ch))
02253 break;
02254 ch = this->get ();
02255 };
02256 if (ch != ';')
02257 return 0;
02258 ch = this->get();
02259 return this->alt_stack_.freeze ();
02260 }
02261
02262 int
02263 ACEXML_Parser::parse_attvalue (ACEXML_Char *&str ACEXML_ENV_ARG_DECL)
02264 {
02265 ACEXML_Char quote = this->get ();
02266 if (quote != '\'' && quote != '"')
02267 return -1;
02268 ACEXML_Char ch = this->get ();
02269 while (1)
02270 {
02271 if (ch == quote)
02272 {
02273 ACEXML_Char* temp = this->obstack_.freeze ();
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296 str = temp;
02297 return 0;
02298 }
02299 switch (ch)
02300 {
02301 case '&':
02302 if (this->peek () == '#')
02303 {
02304 ACEXML_Char buf[7];
02305 size_t len = sizeof (buf);
02306 if (this->parse_char_reference (buf, len) != 0)
02307 {
02308
02309 this->fatal_error (ACE_TEXT ("Invalid CharacterRef")
02310 ACEXML_ENV_ARG_PARAMETER);
02311 ACEXML_CHECK_RETURN (-1);
02312 }
02313 for (size_t j = 0; j < len; ++j)
02314 this->obstack_.grow (buf[j]);
02315 }
02316 else
02317 {
02318 this->ref_state_ = ACEXML_ParserInt::IN_ATT_VALUE;
02319 this->parse_entity_reference (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02320 ACEXML_CHECK_RETURN (-1);
02321 }
02322 break;
02323 case '\x20': case '\x0D': case '\x0A': case '\x09':
02324 this->obstack_.grow ('\x20');
02325 break;
02326 case '<':
02327 this->fatal_error (ACE_TEXT ("Illegal '<' in AttValue")
02328 ACEXML_ENV_ARG_PARAMETER);
02329 ACEXML_CHECK_RETURN (-1);
02330 break;
02331 case 0:
02332 this->pop_context (1 ACEXML_ENV_ARG_PARAMETER);
02333 ACEXML_CHECK_RETURN (-1);
02334 break;
02335 default:
02336 this->obstack_.grow (ch);
02337 break;
02338 }
02339 ch = this->get();
02340 }
02341 }
02342
02343
02344
02345 int
02346 ACEXML_Parser::parse_entity_reference (ACEXML_ENV_SINGLE_ARG_DECL)
02347 {
02348 ACEXML_Char* replace = this->parse_reference_name ();
02349 if (replace == 0)
02350 {
02351 this->fatal_error (ACE_TEXT ("Invalid Reference name")
02352 ACEXML_ENV_ARG_PARAMETER);
02353 ACEXML_CHECK_RETURN (-1);
02354 }
02355
02356
02357 if (this->unparsed_entities_.resolve_entity (replace)) {
02358 this->fatal_error (ACE_TEXT ("EntityRef refers to unparsed entity")
02359 ACEXML_ENV_ARG_PARAMETER);
02360 ACEXML_CHECK_RETURN (-1);
02361 }
02362
02363 const ACEXML_Char* entity = this->internal_GE_.resolve_entity(replace);
02364
02365
02366 if (!entity)
02367 {
02368 entity = this->predef_entities_.resolve_entity (replace);
02369 if (entity)
02370 {
02371
02372 this->obstack_.grow (*entity);
02373 return 1;
02374 }
02375 }
02376
02377 if (!this->validate_)
02378 {
02379 if (this->standalone_)
02380 {
02381
02382 this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
02383 ACEXML_ENV_ARG_PARAMETER);
02384 ACEXML_CHECK_RETURN (-1);
02385 }
02386 else
02387 {
02388 this->content_handler_->skippedEntity (replace
02389 ACEXML_ENV_ARG_PARAMETER);
02390 ACEXML_CHECK_RETURN (-1);
02391 return 0;
02392 }
02393 }
02394
02395
02396 if (!entity
02397
02398 && (!(this->internal_dtd_ || this->external_dtd_)
02399
02400 || (this->internal_dtd_ && !this->external_dtd_
02401 && !this->has_pe_refs_)
02402
02403 || this->standalone_))
02404 {
02405
02406 this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
02407 ACEXML_ENV_ARG_PARAMETER);
02408 ACEXML_CHECK_RETURN (-1);
02409 }
02410
02411 ACEXML_Char* systemId = 0;
02412 ACEXML_Char* publicId = 0;
02413 if (!entity)
02414 {
02415 if (this->external_GE_.resolve_entity (replace, systemId, publicId) < 0)
02416 {
02417 this->fatal_error (ACE_TEXT ("Undeclared Entity reference")
02418 ACEXML_ENV_ARG_PARAMETER);
02419 ACEXML_CHECK_RETURN (-1);
02420 }
02421 if (this->ref_state_ == ACEXML_ParserInt::IN_ATT_VALUE)
02422 {
02423 this->fatal_error (ACE_TEXT ("External EntityRef in Attribute Value")
02424 ACEXML_ENV_ARG_PARAMETER);
02425 ACEXML_CHECK_RETURN (-1);
02426 }
02427 this->external_entity_++;
02428 }
02429
02430
02431
02432 ACEXML_Char* ref_name = replace;
02433 int present = this->GE_reference_.insert (ref_name);
02434 if (present == 1 || present == -1)
02435 {
02436 while (this->GE_reference_.pop(ref_name) != -1)
02437 ;
02438 this->fatal_error (ACE_TEXT ("Recursion in resolving entity")
02439 ACEXML_ENV_ARG_PARAMETER);
02440 ACEXML_CHECK_RETURN (-1);
02441 }
02442
02443 if (!this->external_entity_)
02444 {
02445 ACEXML_StrCharStream* str = 0;
02446 ACE_NEW_RETURN (str, ACEXML_StrCharStream, -1);
02447 if (str->open (entity, replace) < 0
02448 || this->switch_input (str, replace) != 0)
02449 {
02450 this->fatal_error (ACE_TEXT ("Unable to create internal input ")
02451 ACE_TEXT ("stream")
02452 ACEXML_ENV_ARG_PARAMETER);
02453 ACEXML_CHECK_RETURN (-1);
02454 }
02455 return 0;
02456 }
02457 else
02458 {
02459 ACEXML_Char* uri = this->normalize_systemid (systemId);
02460 ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
02461 ACEXML_InputSource* ip = 0;
02462 if (this->entity_resolver_)
02463 {
02464 ip = this->entity_resolver_->resolveEntity (publicId,
02465 (uri ? uri : systemId)
02466 ACEXML_ENV_ARG_PARAMETER);
02467 ACEXML_CHECK_RETURN (-1);
02468 if (ip)
02469 {
02470 if (this->switch_input (ip, (uri ? uri : systemId),
02471 publicId) != 0)
02472 {
02473 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02474 ACEXML_ENV_ARG_PARAMETER);
02475 ACEXML_CHECK_RETURN (-1);
02476 }
02477 return 0;
02478 }
02479 }
02480 ACEXML_StreamFactory factory;
02481 ACEXML_CharStream* cstream = factory.create_stream (uri ? uri: systemId);
02482 if (!cstream) {
02483 this->fatal_error (ACE_TEXT ("Invalid input source")
02484 ACEXML_ENV_ARG_PARAMETER);
02485 ACEXML_CHECK_RETURN (-1);
02486 }
02487 if (this->switch_input (cstream, systemId, publicId) != 0)
02488 {
02489 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02490 ACEXML_ENV_ARG_PARAMETER);
02491 ACEXML_CHECK_RETURN (-1);
02492 }
02493 }
02494 return 0;
02495 }
02496
02497 int
02498 ACEXML_Parser::parse_PE_reference (ACEXML_ENV_SINGLE_ARG_DECL)
02499 {
02500 ACEXML_Char* replace = this->parse_reference_name ();
02501 if (replace == 0)
02502 {
02503 this->fatal_error (ACE_TEXT ("Invalid PEReference name")
02504 ACEXML_ENV_ARG_PARAMETER);
02505 ACEXML_CHECK_RETURN (-1);
02506 }
02507
02508
02509 const ACEXML_Char* entity = this->internal_PE_.resolve_entity(replace);
02510
02511 if (!entity &&
02512 (!this->external_dtd_ ||
02513 this->standalone_))
02514 {
02515
02516 this->fatal_error (ACE_TEXT ("Undefined Internal PEReference")
02517 ACEXML_ENV_ARG_PARAMETER);
02518 ACEXML_CHECK_RETURN (-1);
02519 }
02520
02521 ACEXML_Char* systemId = 0;
02522 ACEXML_Char* publicId = 0;
02523 if (!entity && this->validate_)
02524 {
02525 if (this->external_PE_.resolve_entity (replace, systemId, publicId) < 0)
02526 {
02527 this->fatal_error (ACE_TEXT ("Undefined PEReference")
02528 ACEXML_ENV_ARG_PARAMETER);
02529 ACEXML_CHECK_RETURN (-1);
02530 }
02531 this->external_entity_++;
02532 }
02533
02534
02535 ACEXML_Char* ref_name = replace;
02536 int present = this->PE_reference_.insert (ref_name);
02537 if (present == 1 || present == -1)
02538 {
02539 while (this->PE_reference_.pop(ref_name) != -1)
02540 ;
02541 this->fatal_error (ACE_TEXT ("Recursion in resolving entity")
02542 ACEXML_ENV_ARG_PARAMETER);
02543 ACEXML_CHECK_RETURN (-1);
02544 }
02545
02546 if (entity && !this->external_entity_)
02547 {
02548 ACEXML_StrCharStream* sstream = 0;
02549 ACEXML_String str (entity);
02550 if (this->ref_state_ != ACEXML_ParserInt::IN_ENTITY_VALUE)
02551 {
02552 const ACEXML_Char* ch = ACE_TEXT (" ");
02553 str = ch + str + ch;
02554 }
02555
02556
02557
02558 ACE_NEW_RETURN (sstream, ACEXML_StrCharStream, -1);
02559 if (sstream->open (str.c_str(), replace) < 0
02560 || this->switch_input (sstream, replace) != 0)
02561 {
02562 this->fatal_error (ACE_TEXT ("Error in switching InputSource")
02563 ACEXML_ENV_ARG_PARAMETER);
02564 ACEXML_CHECK_RETURN (-1);
02565 }
02566 return 0;
02567 }
02568 else if (this->external_entity_ && this->validate_)
02569 {
02570 ACEXML_Char* uri = this->normalize_systemid (systemId);
02571 ACE_Auto_Basic_Array_Ptr<ACEXML_Char> cleanup_uri (uri);
02572 ACEXML_InputSource* ip = 0;
02573 if (this->entity_resolver_)
02574 {
02575 ip = this->entity_resolver_->resolveEntity (publicId,
02576 (uri ? uri : systemId)
02577 ACEXML_ENV_ARG_PARAMETER);
02578 ACEXML_CHECK_RETURN (-1);
02579 }
02580 if (ip)
02581 {
02582 if (this->switch_input (ip, (uri ? uri : systemId), publicId) != 0)
02583 {
02584 this->fatal_error (ACE_TEXT ("Error in switching InputSource")
02585 ACEXML_ENV_ARG_PARAMETER);
02586 ACEXML_CHECK_RETURN (-1);
02587 }
02588 return 0;
02589 }
02590 else
02591 {
02592 ACEXML_StreamFactory factory;
02593 ACEXML_CharStream* cstream = factory.create_stream (uri ? uri: systemId);
02594 if (!cstream) {
02595 this->fatal_error (ACE_TEXT ("Invalid input source")
02596 ACEXML_ENV_ARG_PARAMETER);
02597 ACEXML_CHECK_RETURN (-1);
02598 }
02599 if (this->switch_input (cstream, systemId, publicId) != 0)
02600 {
02601 this->fatal_error (ACE_TEXT ("Error in switching InputSource")
02602 ACEXML_ENV_ARG_PARAMETER);
02603 ACEXML_CHECK_RETURN (-1);
02604 }
02605 if (this->ref_state_ == ACEXML_ParserInt::IN_ENTITY_VALUE)
02606 {
02607 ACEXML_Char less, mark;
02608 if (this->peek() == '<')
02609 {
02610 less = this->get();
02611 if (this->peek() == '?')
02612 {
02613 mark = this->get();
02614 if (this->peek() == 'x')
02615 {
02616 this->parse_text_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
02617 ACEXML_CHECK_RETURN (-1);
02618 }
02619 else
02620 {
02621 this->obstack_.grow (less);
02622 this->obstack_.grow (mark);
02623 }
02624 }
02625 this->obstack_.grow (less);
02626 }
02627 }
02628 return 0;
02629 }
02630 }
02631 this->fatal_error (ACE_TEXT ("Undefined PEReference")
02632 ACEXML_ENV_ARG_PARAMETER);
02633 ACEXML_CHECK_RETURN (-1);
02634 return -1;
02635 }
02636
02637 int
02638 ACEXML_Parser::parse_entity_value (ACEXML_Char *&str
02639 ACEXML_ENV_ARG_DECL)
02640 {
02641 ACEXML_ParserInt::ReferenceState temp = this->ref_state_;
02642 ACEXML_Char quote = this->get ();
02643 if (quote != '\'' && quote != '"')
02644 return -1;
02645 ACEXML_Char ch = this->get ();
02646 while (1)
02647 {
02648 if (ch == quote)
02649 {
02650 str = this->obstack_.freeze ();
02651 this->ref_state_ = temp;
02652 return 0;
02653 }
02654 switch (ch)
02655 {
02656 case '&':
02657 if (this->peek () == '#')
02658 {
02659 if (!this->external_entity_)
02660 {
02661 ACEXML_Char buf[7];
02662 size_t len = sizeof (buf);
02663 if (this->parse_char_reference (buf, len) != 0)
02664 {
02665
02666 this->fatal_error (ACE_TEXT ("Invalid character ")
02667 ACE_TEXT ("reference")
02668 ACEXML_ENV_ARG_PARAMETER);
02669 return -1;
02670 }
02671 for (size_t j = 0; j < len; ++j)
02672 this->obstack_.grow (buf[j]);
02673 break;
02674 }
02675 }
02676 this->obstack_.grow (ch);
02677 break;
02678 case '%':
02679 if (!this->external_entity_)
02680 {
02681 this->ref_state_ = ACEXML_ParserInt::IN_ENTITY_VALUE;
02682 this->parse_PE_reference(ACEXML_ENV_SINGLE_ARG_PARAMETER);
02683 ACEXML_CHECK_RETURN (-1);
02684 break;
02685 }
02686 this->obstack_.grow (ch);
02687 break;
02688 case 0:
02689 this->pop_context (0 ACEXML_ENV_ARG_PARAMETER);
02690 ACEXML_CHECK_RETURN (-1);
02691 break;
02692 default:
02693 this->obstack_.grow (ch);
02694 break;
02695 }
02696 ch = this->get();
02697 }
02698 }
02699
02700 ACEXML_Char *
02701 ACEXML_Parser::parse_name (ACEXML_Char ch)
02702 {
02703 if (ch == 0)
02704 ch = this->get ();
02705 if (!this->isLetter (ch) && ch != '_' && ch != ':')
02706 return 0;
02707 while (ch) {
02708 this->obstack_.grow (ch);
02709 ch = this->peek ();
02710 if (!this->isNameChar (ch))
02711 break;
02712 ch = this->get ();
02713 };
02714 return this->obstack_.freeze ();
02715 }
02716
02717 ACEXML_Char*
02718 ACEXML_Parser::parse_nmtoken (ACEXML_Char ch)
02719 {
02720 if (ch == 0)
02721 ch = this->get ();
02722 if (!this->isNameChar (ch))
02723 return 0;
02724 while (ch) {
02725 this->obstack_.grow (ch);
02726 ch = this->peek ();
02727 if (!this->isNameChar (ch))
02728 break;
02729 ch = this->get ();
02730 };
02731 return this->obstack_.freeze ();
02732 }
02733
02734 int
02735 ACEXML_Parser::parse_version_num (ACEXML_Char*& str)
02736 {
02737 ACEXML_Char quote = this->get ();
02738 if (quote != '\'' && quote != '"')
02739 return -1;
02740 int numchars = 0;
02741 while (1)
02742 {
02743 ACEXML_Char ch = this->get ();
02744 if (ch == quote && !numchars)
02745 return -1;
02746 else if (ch == quote)
02747 {
02748 str = this->obstack_.freeze ();
02749 return 0;
02750 }
02751
02752 if (ch == '-' || ((ch >= 'a' && ch <= 'z') ||
02753 (ch >= 'A' && ch <= 'Z') ||
02754 (ch >= '0' && ch <= '9') ||
02755 (ch == '_' || ch == '.' || ch == ':')))
02756 {
02757 this->obstack_.grow (ch);
02758 numchars++;
02759 }
02760 else
02761 return -1;
02762 }
02763 }
02764
02765 int
02766 ACEXML_Parser::parse_system_literal (ACEXML_Char*& str)
02767 {
02768 const ACEXML_Char quote = this->get();
02769 if (quote != '\'' && quote != '"')
02770 return -1;
02771 while (1)
02772 {
02773 ACEXML_Char ch = this->get ();
02774 if (ch == quote)
02775 {
02776 str = this->obstack_.freeze ();
02777 return 0;
02778 }
02779 switch (ch)
02780 {
02781 case '\x00': case '\x01': case '\x02': case '\x03': case '\x04':
02782 case '\x05': case '\x06': case '\x07': case '\x08': case '\x09':
02783 case '\x0A': case '\x0B': case '\x0C': case '\x0D': case '\x0E':
02784 case '\x0F': case '\x10': case '\x11': case '\x12': case '\x13':
02785 case '\x14': case '\x15': case '\x16': case '\x17': case '\x18':
02786 case '\x19': case '\x1A': case '\x1B': case '\x1C': case '\x1D':
02787 case '\x1E': case '\x1F': case '\x7F': case '\x20': case '<':
02788 case '>': case '#': case '%':
02789 ACE_ERROR ((LM_ERROR,
02790 ACE_TEXT ("Invalid char %c in SystemLiteral\n"), ch));
02791 return -1;
02792 default:
02793 this->obstack_.grow (ch);
02794 }
02795 }
02796 }
02797
02798 int
02799 ACEXML_Parser::parse_pubid_literal (ACEXML_Char*& str)
02800 {
02801 const ACEXML_Char quote = this->get();
02802 if (quote != '\'' && quote != '"')
02803 return -1;
02804 while (1)
02805 {
02806 ACEXML_Char ch = this->get ();
02807 if (ch == quote)
02808 {
02809 str = this->obstack_.freeze ();
02810 return 0;
02811 }
02812 else if (this->isPubidChar (ch))
02813 this->obstack_.grow (ch);
02814 else
02815 return -1;
02816 }
02817 }
02818
02819 int
02820 ACEXML_Parser::parse_encname (ACEXML_Char*& str)
02821 {
02822 const ACEXML_Char quote = this->get ();
02823 if (quote != '\'' && quote != '"')
02824 return -1;
02825 int numchars = 0;
02826 while (1)
02827 {
02828 ACEXML_Char ch = this->get ();
02829 if (ch == quote && !numchars)
02830 return -1;
02831 else if (ch == quote)
02832 {
02833 str = this->obstack_.freeze ();
02834 return 0;
02835 }
02836
02837 if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
02838 && !numchars)
02839 return -1;
02840 if (ch == '-' || ((ch >= 'a' && ch <= 'z') ||
02841 (ch >= 'A' && ch <= 'Z') ||
02842 (ch >= '0' && ch <= '9') ||
02843 (ch == '_' || ch == '.')))
02844 {
02845 this->obstack_.grow (ch);
02846 numchars++;
02847 }
02848 else
02849 return -1;
02850 }
02851 }
02852
02853 int
02854 ACEXML_Parser::parse_sddecl (ACEXML_Char*& str)
02855 {
02856 ACEXML_Char quote = this->get ();
02857 if (quote != '\'' && quote != '"')
02858 return -1;
02859 int numchars = 0;
02860 while (1)
02861 {
02862 ACEXML_Char ch = this->get ();
02863 if (ch == quote && numchars < 2)
02864 return -1;
02865 else if (ch == quote)
02866 {
02867 str = this->obstack_.freeze ();
02868 return 0;
02869 }
02870
02871
02872 switch (ch)
02873 {
02874 case 'y': case 'e': case 's': case 'n': case 'o':
02875 this->obstack_.grow (ch);
02876 numchars++;
02877 break;
02878 default:
02879 return -1;
02880 }
02881 }
02882 }
02883
02884 void
02885 ACEXML_Parser::prefix_mapping (const ACEXML_Char* prefix,
02886 const ACEXML_Char* uri,
02887 int start ACEXML_ENV_ARG_DECL)
02888 {
02889 if (this->namespaces_)
02890 {
02891 const ACEXML_Char* temp = (prefix == 0) ? empty_string : prefix;
02892 if (start) {
02893 this->content_handler_->startPrefixMapping (temp, uri
02894 ACEXML_ENV_ARG_PARAMETER);
02895 ACEXML_CHECK;
02896 }
02897 else
02898 {
02899 this->content_handler_->endPrefixMapping(temp
02900 ACEXML_ENV_ARG_PARAMETER);
02901 ACEXML_CHECK;
02902 }
02903 }
02904 }
02905
02906 int
02907 ACEXML_Parser::switch_input (ACEXML_CharStream* cstream,
02908 const ACEXML_Char* systemId,
02909 const ACEXML_Char* publicId)
02910 {
02911 ACEXML_InputSource* input = 0;
02912 ACE_NEW_RETURN (input, ACEXML_InputSource (cstream), -1);
02913 return this->switch_input (input, systemId, publicId);
02914 }
02915
02916 int
02917 ACEXML_Parser::switch_input (ACEXML_InputSource* input,
02918 const ACEXML_Char* systemId,
02919 const ACEXML_Char* publicId)
02920 {
02921 ACEXML_LocatorImpl* locator = 0;
02922 if (!systemId)
02923 systemId = input->getSystemId();
02924 ACE_NEW_RETURN (locator, ACEXML_LocatorImpl (systemId, publicId), -1);
02925 ACEXML_Parser_Context* new_context = 0;
02926 ACE_NEW_RETURN (new_context, ACEXML_Parser_Context(input, locator), -1);
02927 if (this->push_context (new_context) != 0)
02928 {
02929 ACE_ERROR ((LM_ERROR, "Unable to switch input streams"));
02930 delete new_context;
02931 return -1;
02932 }
02933 this->current_ = new_context;
02934 this->content_handler_->setDocumentLocator (this->current_->getLocator());
02935 return 0;
02936 }
02937
02938 int
02939 ACEXML_Parser::push_context (ACEXML_Parser_Context* context)
02940 {
02941 if (this->ctx_stack_.push (context) < 0)
02942 {
02943 ACE_ERROR ((LM_ERROR, "Unable to push input source onto the stack"));
02944 return -1;
02945 }
02946 return 0;
02947 }
02948
02949 size_t
02950 ACEXML_Parser::pop_context (int GE_ref ACEXML_ENV_ARG_DECL)
02951 {
02952 size_t nrelems = this->ctx_stack_.size();
02953 if (nrelems <= 1)
02954 {
02955 this->fatal_error(ACE_TEXT ("Unexpected end-of-file")
02956 ACEXML_ENV_ARG_PARAMETER);
02957 ACEXML_CHECK_RETURN (-1);
02958 }
02959
02960 ACEXML_Parser_Context* temp = 0;
02961 int retval = this->ctx_stack_.pop (temp);
02962 if (retval != 0)
02963 {
02964 this->fatal_error (ACE_TEXT ("Unable to pop element of the input stack")
02965 ACEXML_ENV_ARG_PARAMETER);
02966 ACEXML_CHECK_RETURN (-1);
02967 }
02968 delete temp;
02969 if (this->ctx_stack_.top (this->current_) != 0)
02970 {
02971 this->fatal_error (ACE_TEXT ("Unable to read top element of input stack")
02972 ACEXML_ENV_ARG_PARAMETER);
02973 ACEXML_CHECK_RETURN (-1);
02974 }
02975 ACEXML_Char* reference = 0;
02976 if (GE_ref == 1 && this->GE_reference_.size() > 0)
02977 {
02978 if (this->GE_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 else if (GE_ref == 0 && this->PE_reference_.size() > 0)
02986 {
02987 if (this->PE_reference_.pop (reference) < 0)
02988 {
02989 this->fatal_error (ACE_TEXT ("Internal Parser Error")
02990 ACEXML_ENV_ARG_PARAMETER);
02991 ACEXML_CHECK_RETURN (-1);
02992 }
02993 }
02994 nrelems = this->ctx_stack_.size();
02995
02996 if (this->external_entity_ && (GE_ref == 0 || GE_ref == 1))
02997 this->external_entity_--;
02998
02999 this->content_handler_->setDocumentLocator (this->current_->getLocator());
03000
03001 return nrelems;
03002 }
03003
03004 int
03005 ACEXML_Parser::getFeature (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
03006 {
03007 if (ACE_OS::strcmp (name, ACEXML_Parser::simple_parsing_feature_) == 0)
03008 {
03009 return this->simple_parsing_;
03010 }
03011 else if (ACE_OS::strcmp (name, ACEXML_Parser::namespaces_feature_) == 0)
03012 {
03013 return this->namespaces_;
03014 }
03015 else if (ACE_OS::strcmp (name,
03016 ACEXML_Parser::namespace_prefixes_feature_) == 0)
03017 {
03018 return this->namespace_prefixes_;
03019 }
03020 else if (ACE_OS::strcmp (name, ACEXML_Parser::validation_feature_) == 0)
03021 {
03022 return this->validate_;
03023 }
03024 ACEXML_THROW_RETURN (ACEXML_SAXNotRecognizedException (name), -1);
03025 }
03026
03027
03028
03029 void
03030 ACEXML_Parser::setFeature (const ACEXML_Char *name,
03031 int boolean_value ACEXML_ENV_ARG_DECL)
03032 {
03033 if (ACE_OS::strcmp (name, ACEXML_Parser::simple_parsing_feature_) == 0)
03034 {
03035 this->simple_parsing_ = (boolean_value == 0 ? 0 : 1);
03036 return;
03037 }
03038 else if (ACE_OS::strcmp (name, ACEXML_Parser::namespaces_feature_) == 0)
03039 {
03040 this->namespaces_ = (boolean_value == 0 ? 0 : 1);
03041 return;
03042 }
03043 else if (ACE_OS::strcmp (name,
03044 ACEXML_Parser::namespace_prefixes_feature_) == 0)
03045 {
03046 this->namespace_prefixes_ = (boolean_value == 0 ? 0 : 1);
03047 return;
03048 }
03049 else if (ACE_OS::strcmp (name, ACEXML_Parser::validation_feature_) == 0)
03050 {
03051 this->validate_ = (boolean_value == 0 ? 0 : 1);
03052 return;
03053 }
03054
03055 ACEXML_THROW (ACEXML_SAXNotRecognizedException (name));
03056 }
03057
03058 void *
03059 ACEXML_Parser::getProperty (const ACEXML_Char *name ACEXML_ENV_ARG_DECL)
03060 {
03061 ACEXML_THROW_RETURN (ACEXML_SAXNotSupportedException (name), 0);
03062 }
03063
03064 void
03065 ACEXML_Parser::setProperty (const ACEXML_Char *name,
03066 void *value ACEXML_ENV_ARG_DECL)
03067 {
03068 ACE_UNUSED_ARG (value);
03069
03070 ACEXML_THROW (ACEXML_SAXNotSupportedException (name));
03071 }
03072
03073 void
03074 ACEXML_Parser::error (const ACEXML_Char* msg ACEXML_ENV_ARG_DECL)
03075 {
03076 ACEXML_SAXParseException* exception = 0;
03077 ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
03078 if (this->error_handler_)
03079 this->error_handler_->error (*exception ACEXML_ENV_ARG_PARAMETER);
03080 else
03081 ACEXML_ENV_RAISE (exception);
03082 return;
03083 }
03084
03085 void
03086 ACEXML_Parser::warning (const ACEXML_Char* msg ACEXML_ENV_ARG_DECL)
03087 {
03088 ACEXML_SAXParseException* exception = 0;
03089 ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
03090 if (this->error_handler_)
03091 this->error_handler_->warning (*exception ACEXML_ENV_ARG_PARAMETER);
03092 delete exception;
03093 return;
03094 }
03095
03096 void
03097 ACEXML_Parser::fatal_error (const ACEXML_Char* msg ACEXML_ENV_ARG_DECL)
03098 {
03099 ACEXML_SAXParseException* exception = 0;
03100 ACE_NEW_NORETURN (exception, ACEXML_SAXParseException (msg));
03101 if (this->error_handler_)
03102 this->error_handler_->fatalError (*exception ACEXML_ENV_ARG_PARAMETER);
03103 this->reset();
03104 ACEXML_ENV_RAISE (exception);
03105 return;
03106 }
03107
03108 void
03109 ACEXML_Parser::parse_version_info (ACEXML_ENV_SINGLE_ARG_DECL)
03110 {
03111 ACEXML_Char* astring;
03112 if (this->parse_token (ACE_TEXT("ersion")) < 0
03113 || this->skip_equal () != 0
03114 || this->parse_version_num (astring) != 0)
03115 {
03116 this->fatal_error (ACE_TEXT ("Invalid VersionInfo specification")
03117 ACEXML_ENV_ARG_PARAMETER);
03118 return;
03119 }
03120 if (ACE_OS::strcmp (astring, ACE_TEXT ("1.0")) != 0)
03121 {
03122 this->fatal_error (ACE_TEXT ("ACEXML Parser supports XML version 1.0 ")
03123 ACE_TEXT ("documents only") ACEXML_ENV_ARG_PARAMETER);
03124 return;
03125 }
03126 }
03127
03128 void
03129 ACEXML_Parser::parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_DECL)
03130 {
03131 ACEXML_Char* astring = 0;
03132 if ((this->parse_token (ACE_TEXT("ncoding")) < 0)
03133 || this->skip_equal () != 0
03134 || this->parse_encname (astring) != 0)
03135 {
03136 this->fatal_error (ACE_TEXT ("Invalid EncodingDecl specification")
03137 ACEXML_ENV_ARG_PARAMETER);
03138 ACEXML_CHECK;
03139 }
03140 const ACEXML_Char* encoding = this->current_->getInputSource()->getEncoding();
03141 if (encoding != 0 && ACE_OS::strcasecmp (astring, encoding) != 0)
03142 {
03143 ACE_ERROR ((LM_ERROR, ACE_TEXT ("Detected Encoding is %s ")
03144 ACE_TEXT (": Declared Encoding is %s\n"),
03145 encoding, astring));
03146 this->warning (ACE_TEXT ("Declared encoding differs from detected ")
03147 ACE_TEXT ("encoding") ACEXML_ENV_ARG_PARAMETER);
03148 }
03149 }
03150
03151 int
03152 ACEXML_Parser::parse_text_decl (ACEXML_ENV_SINGLE_ARG_DECL)
03153 {
03154
03155 if (this->parse_token (ACE_TEXT("xml")) < 0)
03156 {
03157 this->fatal_error(ACE_TEXT ("Expecting keyword 'xml' in TextDecl")
03158 ACEXML_ENV_ARG_PARAMETER);
03159 ACEXML_CHECK_RETURN (-1);
03160 }
03161
03162 ACEXML_Char fwd = this->skip_whitespace();
03163
03164 if (fwd == 'v')
03165 {
03166 this->parse_version_info (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03167 ACEXML_CHECK_RETURN (-1);
03168 fwd = this->skip_whitespace();
03169 }
03170
03171 if (fwd == 'e')
03172 {
03173 this->parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03174 ACEXML_CHECK_RETURN (-1);
03175 fwd = this->skip_whitespace();
03176 }
03177 else
03178 {
03179 this->fatal_error (ACE_TEXT ("Missing encodingDecl in TextDecl")
03180 ACEXML_ENV_ARG_PARAMETER);
03181 ACEXML_CHECK_RETURN (-1);
03182 }
03183
03184 if (fwd == '?' && this->get() == '>')
03185 return 0;
03186
03187 this->fatal_error (ACE_TEXT ("Invalid TextDecl") ACEXML_ENV_ARG_PARAMETER);
03188 ACEXML_CHECK_RETURN (-1);
03189 return -1;
03190 }
03191
03192 void
03193 ACEXML_Parser::parse_xml_decl (ACEXML_ENV_SINGLE_ARG_DECL)
03194 {
03195
03196 if (this->parse_token (ACE_TEXT("xml")) < 0)
03197 {
03198 this->fatal_error(ACE_TEXT ("Expecting keyword xml in XMLDecl")
03199 ACEXML_ENV_ARG_PARAMETER);
03200 ACEXML_CHECK;
03201 }
03202
03203 ACEXML_Char fwd = this->skip_whitespace();
03204
03205
03206 if (fwd != 'v')
03207 {
03208 this->fatal_error (ACE_TEXT ("Expecting VersionInfo declaration")
03209 ACEXML_ENV_ARG_PARAMETER);
03210 ACEXML_CHECK;
03211 }
03212
03213 this->parse_version_info (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03214 ACEXML_CHECK;
03215
03216 fwd = this->skip_whitespace();
03217 if (fwd != '?')
03218 {
03219 if (fwd == 'e')
03220 {
03221 this->parse_encoding_decl (ACEXML_ENV_SINGLE_ARG_PARAMETER);
03222 ACEXML_CHECK;
03223 fwd = this->skip_whitespace();
03224 }
03225 if (fwd == 's')
03226 {
03227 ACEXML_Char* astring;
03228 if ((this->parse_token (ACE_TEXT("tandalone")) == 0) &&
03229 this->skip_equal () == 0 &&
03230 this->parse_sddecl (astring) == 0)
03231 {
03232 if (ACE_OS::strcmp (astring, ACE_TEXT ("yes")) == 0)
03233 this->standalone_ = 1;
03234 fwd = this->skip_whitespace();
03235 }
03236 }
03237 }
03238 if (fwd == '?' && this->get() == '>')
03239 return;
03240
03241 this->fatal_error (ACE_TEXT ("Invalid XMLDecl declaration")
03242 ACEXML_ENV_ARG_PARAMETER);
03243 ACEXML_CHECK;
03244 }
03245
03246 int
03247 ACEXML_Parser::parse_comment (void)
03248 {
03249 int state = 0;
03250
03251 if (this->get () != '-' ||
03252 this->get () != '-' ||
03253 this->get () == '-')
03254 return -1;
03255
03256 while (state < 3)
03257
03258
03259
03260 {
03261 ACEXML_Char fwd = this->get ();
03262 if ((fwd == '-' && state < 2) ||
03263 (fwd == '>' && state == 2))
03264 state += 1;
03265 else
03266 state = 0;
03267 }
03268 return 0;
03269 }
03270
03271 int
03272 ACEXML_Parser::parse_processing_instruction (ACEXML_ENV_SINGLE_ARG_DECL)
03273 {
03274 const ACEXML_Char *pitarget = this->parse_name ();
03275 ACEXML_Char *instruction = 0;
03276
03277 if (!ACE_OS::strcasecmp (ACE_TEXT ("xml"), pitarget))
03278 {
03279
03280 this->fatal_error(ACE_TEXT ("PI can't have 'xml' in PITarget")
03281 ACEXML_ENV_ARG_PARAMETER);
03282 ACEXML_CHECK_RETURN (-1);
03283 }
03284
03285 int state = 0;
03286
03287 ACEXML_Char ch = this->skip_whitespace();
03288 while (state < 2)
03289 {
03290 switch (ch)
03291 {
03292 case '?':
03293 if (state == 0)
03294 state = 1;
03295 break;
03296 case '>':
03297 if (state == 1)
03298 {
03299 instruction = this->obstack_.freeze ();
03300 this->content_handler_->processingInstruction (pitarget,
03301 instruction
03302 ACEXML_ENV_ARG_PARAMETER);
03303 ACEXML_CHECK_RETURN (-1);
03304 this->obstack_.unwind (const_cast<ACEXML_Char*> (pitarget));
03305 return 0;
03306 }
03307 break;
03308 case 0x0A:
03309
03310 default:
03311 if (state == 1)
03312 this->obstack_.grow ('?');
03313 this->obstack_.grow (ch);
03314 state = 0;
03315 }
03316 ch = this->get ();
03317 }
03318 return -1;
03319 }
03320
03321 void
03322 ACEXML_Parser::reset (void)
03323 {
03324 this->doctype_ = 0;
03325 if (this->ctx_stack_.pop (this->current_) == -1)
03326 ACE_ERROR ((LM_ERROR,
03327 ACE_TEXT ("Mismatched push/pop of Context stack")));
03328 if (this->current_)
03329 {
03330 this->current_->getInputSource()->getCharStream()->rewind();
03331
03332 this->current_->setInputSource (0);
03333 delete this->current_;
03334 this->current_ = 0;
03335 }
03336
03337 ACEXML_Char* temp = 0;
03338 while (this->GE_reference_.pop (temp) != -1)
03339 ;
03340 while (this->PE_reference_.pop (temp) != -1)
03341 ;
03342 this->obstack_.release();
03343 this->alt_stack_.release();
03344 this->xml_namespace_.reset();
03345 this->nested_namespace_ = 0;
03346 this->internal_GE_.reset();
03347 this->external_GE_.reset();
03348 this->unparsed_entities_.reset();
03349 this->predef_entities_.reset();
03350 this->internal_PE_.reset();
03351 this->external_PE_.reset();
03352 this->notations_.reset();
03353 this->ref_state_ = ACEXML_ParserInt::INVALID;
03354 this->external_subset_ = 0;
03355 this->external_entity_ = 0;
03356 this->has_pe_refs_ = 0;
03357 this->standalone_ = 0;
03358 this->external_dtd_ = 0;
03359 this->internal_dtd_ = 0;
03360 }
03361