00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027
00028 #include <cstring>
00029
00030 #include "BaseType.h"
00031 #include "Constructor.h"
00032 #include "DDXParser.h"
00033
00034 #include "util.h"
00035 #include "debug.h"
00036
00037 namespace libdap {
00038
00039 static const not_used char *states[] =
00040 {
00041 "start",
00042
00043 "dataset",
00044
00045 "attribute_container",
00046 "attribute",
00047 "attribute_value",
00048
00049 "alias",
00050
00051 "simple_type",
00052
00053 "array",
00054 "dimension",
00055
00056 "grid",
00057 "map",
00058
00059 "structure",
00060 "sequence",
00061
00062 "blob href",
00063
00064 "unknown",
00065 "error"
00066 };
00067
00068
00069
00070 BaseType *DDXParser::factory(Type t, const string & name)
00071 {
00072 switch (t) {
00073 case dods_byte_c:
00074 return d_factory->NewByte(name);
00075 break;
00076
00077 case dods_int16_c:
00078 return d_factory->NewInt16(name);
00079 break;
00080
00081 case dods_uint16_c:
00082 return d_factory->NewUInt16(name);
00083 break;
00084
00085 case dods_int32_c:
00086 return d_factory->NewInt32(name);
00087 break;
00088
00089 case dods_uint32_c:
00090 return d_factory->NewUInt32(name);
00091 break;
00092
00093 case dods_float32_c:
00094 return d_factory->NewFloat32(name);
00095 break;
00096
00097 case dods_float64_c:
00098 return d_factory->NewFloat64(name);
00099 break;
00100
00101 case dods_str_c:
00102 return d_factory->NewStr(name);
00103 break;
00104
00105 case dods_url_c:
00106 return d_factory->NewUrl(name);
00107 break;
00108
00109 case dods_array_c:
00110 return d_factory->NewArray(name);
00111 break;
00112
00113 case dods_structure_c:
00114 return d_factory->NewStructure(name);
00115 break;
00116
00117 case dods_sequence_c:
00118 return d_factory->NewSequence(name);
00119 break;
00120
00121 case dods_grid_c:
00122 return d_factory->NewGrid(name);
00123 break;
00124
00125 default:
00126 return 0;
00127 }
00128 }
00129
00131 static Type get_type(const char *name)
00132 {
00133 if (strcmp(name, "Byte") == 0)
00134 return dods_byte_c;
00135
00136 if (strcmp(name, "Int16") == 0)
00137 return dods_int16_c;
00138
00139 if (strcmp(name, "UInt16") == 0)
00140 return dods_uint16_c;
00141
00142 if (strcmp(name, "Int32") == 0)
00143 return dods_int32_c;
00144
00145 if (strcmp(name, "UInt32") == 0)
00146 return dods_uint32_c;
00147
00148 if (strcmp(name, "Float32") == 0)
00149 return dods_float32_c;
00150
00151 if (strcmp(name, "Float64") == 0)
00152 return dods_float64_c;
00153
00154 if (strcmp(name, "String") == 0)
00155 return dods_str_c;
00156
00157 if (strcmp(name, "Url") == 0)
00158 return dods_url_c;
00159
00160 if (strcmp(name, "Array") == 0)
00161 return dods_array_c;
00162
00163 if (strcmp(name, "Structure") == 0)
00164 return dods_structure_c;
00165
00166 if (strcmp(name, "Sequence") == 0)
00167 return dods_sequence_c;
00168
00169 if (strcmp(name, "Grid") == 0)
00170 return dods_grid_c;
00171
00172 return dods_null_c;
00173 }
00174
00175 static Type is_simple_type(const char *name)
00176 {
00177 Type t = get_type(name);
00178 switch (t) {
00179 case dods_byte_c:
00180 case dods_int16_c:
00181 case dods_uint16_c:
00182 case dods_int32_c:
00183 case dods_uint32_c:
00184 case dods_float32_c:
00185 case dods_float64_c:
00186 case dods_str_c:
00187 case dods_url_c:
00188 return t;
00189 default:
00190 return dods_null_c;
00191 }
00192 }
00193
00194 static bool is_not(const char *name, const char *tag)
00195 {
00196 return strcmp(name, tag) != 0;
00197 }
00198
00199 void DDXParser::set_state(DDXParser::ParseState state)
00200 {
00201 s.push(state);
00202 }
00203
00204 DDXParser::ParseState DDXParser::get_state() const
00205 {
00206 return s.top();
00207 }
00208
00209 void DDXParser::pop_state()
00210 {
00211 s.pop();
00212 }
00213
00217 void DDXParser::transfer_attrs(const char **attrs)
00218 {
00219 attributes.clear();
00220
00221 if (!attrs)
00222 return;
00223
00224 for (int i = 0; attrs[i] != 0; i += 2) {
00225 string attr_i = attrs[i];
00226 downcase(attr_i);
00227 attributes[attr_i] = string(attrs[i + 1]);
00228 }
00229 }
00230
00235 bool DDXParser::check_required_attribute(const string & attr)
00236 {
00237 #if 0
00238 bool found = false;
00239 map < string, string >::iterator i;
00240 for (i = attributes.begin(); i != attributes.end(); ++i)
00241 if (i->first == attr)
00242 found = true;
00243
00244 if (!found)
00245 ddx_fatal_error(this, "Required attribute '%s' not found.",
00246 attr.c_str());
00247
00248 return found;
00249 #endif
00250 #if 1
00251 map < string, string >::iterator i = attributes.find(attr);
00252 if (i == attributes.end())
00253 ddx_fatal_error(this, "Required attribute '%s' not found.",
00254 attr.c_str());
00255 return true;
00256 #endif
00257 }
00258
00264 bool DDXParser::check_attribute(const string & attr)
00265 {
00266 return (attributes.find(attr) != attributes.end());
00267 }
00268
00274 void DDXParser::process_attribute_element(const char **attrs)
00275 {
00276
00277 transfer_attrs(attrs);
00278 bool error = !(check_required_attribute(string("name"))
00279 && check_required_attribute(string("type")));
00280 if (error)
00281 return;
00282
00283 if (attributes["type"] == "Container") {
00284 set_state(inside_attribute_container);
00285
00286 AttrTable *child;
00287 AttrTable *parent = at_stack.top();
00288
00289 child = parent->append_container(attributes["name"]);
00290 at_stack.push(child);
00291 DBG2(cerr << "Pushing at" << endl);
00292 }
00293 else {
00294 set_state(inside_attribute);
00295
00296 dods_attr_name = attributes["name"];
00297 dods_attr_type = attributes["type"];
00298 }
00299 }
00300
00304 void DDXParser::process_attribute_alias(const char **attrs)
00305 {
00306 transfer_attrs(attrs);
00307 if (check_required_attribute(string("name"))
00308 && check_required_attribute(string("attribute"))) {
00309 set_state(inside_alias);
00310 at_stack.top()->attr_alias(attributes["name"],
00311 attributes["attribute"]);
00312 }
00313 }
00314
00322 void DDXParser::process_variable(Type t, ParseState s, const char **attrs)
00323 {
00324 transfer_attrs(attrs);
00325
00326 set_state(s);
00327 if (bt_stack.top()->type() == dods_array_c
00328 || check_required_attribute("name")) {
00329 BaseType *btp = factory(t, attributes["name"]);
00330 if (!btp)
00331 ddx_fatal_error(
00332 this,
00333 "Internal parser error; could not instantiate the variable '%s'.",
00334 attributes["name"].c_str());
00335
00336
00337
00338
00339
00340 bt_stack.push(btp);
00341 at_stack.push(&btp->get_attr_table());
00342 }
00343 }
00344
00348 void DDXParser::process_dimension(const char **attrs)
00349 {
00350 transfer_attrs(attrs);
00351 if (check_required_attribute(string("size"))) {
00352 set_state(inside_dimension);
00353 Array *ap = dynamic_cast<Array *> (bt_stack.top());
00354 if (!ap)
00355 ddx_fatal_error(this, "Parse error: Expected an array variable.");
00356 else
00357 ap->append_dim(atoi(attributes["size"].c_str()),
00358 attributes["name"]);
00359 }
00360 }
00361
00367 void DDXParser::process_blob(const char **attrs)
00368 {
00369 if (dds->get_dap_major() > 2 && dds->get_dap_major() > 1)
00370 ddx_fatal_error(this,
00371 "Found a dataBLOB element in a 3.2 or greater response.");
00372
00373 transfer_attrs(attrs);
00374 if (check_required_attribute(string("href"))) {
00375 set_state(inside_blob_href);
00376 #if 0
00377 *blob_href = attributes["href"];
00378 #endif
00379 }
00380 }
00381
00388 inline bool
00389 DDXParser::is_attribute_or_alias(const char *name, const char **attrs)
00390 {
00391 if (strcmp(name, "Attribute") == 0) {
00392 process_attribute_element(attrs);
00393
00394 return true;
00395 }
00396 else if (strcmp(name, "Alias") == 0) {
00397 process_attribute_alias(attrs);
00398
00399 return true;
00400 }
00401
00402 return false;
00403 }
00404
00410 inline bool DDXParser::is_variable(const char *name, const char **attrs)
00411 {
00412 Type t;
00413 if ((t = is_simple_type(name)) != dods_null_c) {
00414 process_variable(t, inside_simple_type, attrs);
00415 return true;
00416 }
00417 else if (strcmp(name, "Array") == 0) {
00418 process_variable(dods_array_c, inside_array, attrs);
00419 return true;
00420 }
00421 else if (strcmp(name, "Structure") == 0) {
00422 process_variable(dods_structure_c, inside_structure, attrs);
00423 return true;
00424 }
00425 else if (strcmp(name, "Sequence") == 0) {
00426 process_variable(dods_sequence_c, inside_sequence, attrs);
00427 return true;
00428 }
00429 else if (strcmp(name, "Grid") == 0) {
00430 process_variable(dods_grid_c, inside_grid, attrs);
00431 return true;
00432 }
00433
00434 return false;
00435 }
00436
00437 void DDXParser::finish_variable(const char *tag, Type t,
00438 const char *expected)
00439 {
00440 if (strcmp(tag, expected) != 0) {
00441 DDXParser::ddx_fatal_error(this,
00442 "Expected an end tag for a %s; found '%s' instead.",
00443 expected, tag);
00444 return;
00445 }
00446
00447 pop_state();
00448
00449 BaseType *btp = bt_stack.top();
00450
00451 bt_stack.pop();
00452 at_stack.pop();
00453
00454 if (btp && btp->type() != t) {
00455 DDXParser::ddx_fatal_error(this,
00456 "Internal error: Expected a %s variable.",
00457 expected);
00458 return;
00459 }
00460
00461 if (t == dods_array_c
00462 && dynamic_cast < Array * >(btp)->dimensions() == 0) {
00463 DDXParser::ddx_fatal_error(this,
00464 "No dimension element included in the Array '%s'.",
00465 btp->name().c_str());
00466 return;
00467 }
00468
00469 BaseType *parent = bt_stack.top();
00470
00471 if (!(parent->is_vector_type() || parent->is_constructor_type())) {
00472 DDXParser::ddx_fatal_error(this,
00473 "Tried to add the array variable '%s' to a non-constructor type (%s %s).",
00474 tag,
00475 bt_stack.top()->type_name().c_str(),
00476 bt_stack.top()->name().c_str());
00477 return;
00478 }
00479
00480 parent->add_var(btp);
00481 }
00482
00489
00494 void DDXParser::ddx_start_document(DDXParser * parser)
00495 {
00496 parser->error_msg = "";
00497 parser->char_data = "";
00498
00499
00500 parser->at_stack.push(&parser->dds->get_attr_table());
00501
00502
00503
00504
00505 parser->bt_stack.push(new Structure("dummy_dds"));
00506
00507 parser->set_state(parser_start);
00508
00509 DBG2(cerr << "Parser state: " << states[parser->get_state()] << endl);
00510 }
00511
00514 void DDXParser::ddx_end_document(DDXParser * parser)
00515 {
00516 DBG2(cerr << "Ending state == " << states[parser->get_state()] <<
00517 endl);
00518
00519 if (parser->get_state() != parser_start)
00520 DDXParser::ddx_fatal_error(parser,
00521 "The document contained unbalanced tags.");
00522
00523
00524
00525 if (parser->get_state() == parser_error)
00526 return;
00527
00528
00529
00530 Constructor *cp = dynamic_cast < Constructor * >(parser->bt_stack.top());
00531 if (!cp)
00532 ddx_fatal_error(parser,
00533 "Parse error: Expected a Structure, Sequence or Grid variable.");
00534 else {
00535 for (Constructor::Vars_iter i = cp->var_begin(); i != cp->var_end(); ++i)
00536 parser->dds->add_var(*i);
00537
00538 parser->bt_stack.pop();
00539 delete cp;
00540 }
00541 }
00542
00549 void DDXParser::ddx_start_element(DDXParser * parser, const char *name,
00550 const char **attrs)
00551 {
00552 DBG2(cerr << "start element: " << name << ", states: "
00553 << states[parser->get_state()]);
00554
00555 switch (parser->get_state()) {
00556 case parser_start:
00557 if (strcmp(name, "Dataset") == 0) {
00558 parser->set_state(inside_dataset);
00559
00560 parser->transfer_attrs(attrs);
00561
00562 if (parser->check_required_attribute(string("name")))
00563 parser->dds->set_dataset_name(parser->attributes["name"]);
00564
00565 if (parser->check_attribute("dap_version"))
00566 parser->dds->set_dap_version(parser->attributes["dap_version"]);
00567 }
00568 else
00569 DDXParser::ddx_fatal_error(parser,
00570 "Expected response to start with a Dataset element; found '%s' instead.",
00571 name);
00572 break;
00573
00574 case inside_dataset:
00575 if (parser->is_attribute_or_alias(name, attrs))
00576 break;
00577 else if (parser->is_variable(name, attrs))
00578 break;
00579 else if (strcmp(name, "dataBLOB") == 0) {
00580 parser->process_blob(attrs);
00581
00582 }
00583 else
00584 DDXParser::ddx_fatal_error(parser,
00585 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00586 name);
00587 break;
00588
00589 case inside_attribute_container:
00590 if (parser->is_attribute_or_alias(name, attrs))
00591 break;
00592 else
00593 DDXParser::ddx_fatal_error(parser,
00594 "Expected an Attribute or Alias element; found '%s' instead.",
00595 name);
00596 break;
00597
00598 case inside_attribute:
00599 if (parser->is_attribute_or_alias(name, attrs))
00600 break;
00601 else if (strcmp(name, "value") == 0)
00602 parser->set_state(inside_attribute_value);
00603 else
00604 ddx_fatal_error(parser,
00605 "Expected an 'Attribute', 'Alias' or 'value' element; found '%s' instead.",
00606 name);
00607 break;
00608
00609 case inside_attribute_value:
00610 ddx_fatal_error(parser,
00611 "Internal parser error; unexpected state, inside value while processing element '%s'.",
00612 name);
00613 break;
00614
00615 case inside_alias:
00616 ddx_fatal_error(parser,
00617 "Internal parser error; unexpected state, inside alias while processing element '%s'.",
00618 name);
00619 break;
00620
00621 case inside_simple_type:
00622 if (parser->is_attribute_or_alias(name, attrs))
00623 break;
00624 else
00625 ddx_fatal_error(parser,
00626 "Expected an 'Attribute' or 'Alias' element; found '%s' instead.",
00627 name);
00628 break;
00629
00630 case inside_array:
00631 if (parser->is_attribute_or_alias(name, attrs))
00632 break;
00633 else if (is_not(name, "Array") && parser->is_variable(name, attrs))
00634 break;
00635 else if (strcmp(name, "dimension") == 0) {
00636 parser->process_dimension(attrs);
00637
00638 }
00639 else
00640 ddx_fatal_error(parser,
00641 "Expected an 'Attribute' or 'Alias' element; found '%s' instead.",
00642 name);
00643 break;
00644
00645 case inside_dimension:
00646 ddx_fatal_error(parser,
00647 "Internal parser error; unexpected state, inside dimension while processing element '%s'.",
00648 name);
00649 break;
00650
00651 case inside_structure:
00652 if (parser->is_attribute_or_alias(name, attrs))
00653 break;
00654 else if (parser->is_variable(name, attrs))
00655 break;
00656 else
00657 DDXParser::ddx_fatal_error(parser,
00658 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00659 name);
00660 break;
00661
00662 case inside_sequence:
00663 if (parser->is_attribute_or_alias(name, attrs))
00664 break;
00665 else if (parser->is_variable(name, attrs))
00666 break;
00667 else
00668 DDXParser::ddx_fatal_error(parser,
00669 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00670 name);
00671 break;
00672
00673 case inside_grid:
00674 if (parser->is_attribute_or_alias(name, attrs))
00675 break;
00676 else if (strcmp(name, "Array") == 0)
00677 parser->process_variable(dods_array_c, inside_array, attrs);
00678 else if (strcmp(name, "Map") == 0)
00679 parser->process_variable(dods_array_c, inside_map, attrs);
00680 else
00681 DDXParser::ddx_fatal_error(parser,
00682 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00683 name);
00684 break;
00685
00686 case inside_map:
00687 if (parser->is_attribute_or_alias(name, attrs))
00688 break;
00689 else if (is_not(name, "Array") && is_not(name, "Sequence")
00690 && is_not(name, "Grid")
00691 && parser->is_variable(name, attrs))
00692 break;
00693 else if (strcmp(name, "dimension") == 0) {
00694 parser->process_dimension(attrs);
00695
00696 }
00697 else
00698 ddx_fatal_error(parser,
00699 "Expected an 'Attribute', 'Alias', variable or 'dimension' element; found '%s' instead.",
00700 name);
00701 break;
00702
00703 case inside_blob_href:
00704 ddx_fatal_error(parser,
00705 "Internal parser error; unexpected state, inside blob href while processing element '%s'.",
00706 name);
00707 break;
00708
00709 case parser_unknown:
00710 parser->set_state(parser_unknown);
00711 break;
00712
00713 case parser_error:
00714 break;
00715 }
00716
00717 DBGN(cerr << " ... " << states[parser->get_state()] << endl);
00718 }
00719
00725 void DDXParser::ddx_end_element(DDXParser * parser, const char *name)
00726 {
00727 DBG2(cerr << "End element " << name << " (state "
00728 << states[parser->get_state()] << ")" << endl);
00729
00730 switch (parser->get_state()) {
00731 case parser_start:
00732 ddx_fatal_error(parser,
00733 "Internal parser error; unexpected state, inside start state while processing element '%s'.",
00734 name);
00735 break;
00736
00737 case inside_dataset:
00738 if (strcmp(name, "Dataset") == 0)
00739 parser->pop_state();
00740 else
00741 DDXParser::ddx_fatal_error(parser,
00742 "Expected an end Dataset tag; found '%s' instead.",
00743 name);
00744 break;
00745
00746 case inside_attribute_container:
00747 if (strcmp(name, "Attribute") == 0) {
00748 parser->pop_state();
00749 parser->at_stack.pop();
00750 }
00751 else
00752 DDXParser::ddx_fatal_error(parser,
00753 "Expected an end Attribute tag; found '%s' instead.",
00754 name);
00755 break;
00756
00757 case inside_attribute:
00758 if (strcmp(name, "Attribute") == 0)
00759 parser->pop_state();
00760 else
00761 DDXParser::ddx_fatal_error(parser,
00762 "Expected an end Attribute tag; found '%s' instead.",
00763 name);
00764 break;
00765
00766 case inside_attribute_value:
00767 if (strcmp(name, "value") == 0) {
00768 parser->pop_state();
00769 AttrTable *atp = parser->at_stack.top();
00770 atp->append_attr(parser->dods_attr_name,
00771 parser->dods_attr_type, parser->char_data);
00772 parser->char_data = "";
00773 }
00774 else
00775 DDXParser::ddx_fatal_error(parser,
00776 "Expected an end value tag; found '%s' instead.",
00777 name);
00778
00779 break;
00780
00781
00782 case inside_alias:
00783 parser->pop_state();
00784 break;
00785
00786 case inside_simple_type:
00787 if (is_simple_type(name) != dods_null_c) {
00788 parser->pop_state();
00789 BaseType *btp = parser->bt_stack.top();
00790 parser->bt_stack.pop();
00791 parser->at_stack.pop();
00792
00793 BaseType *parent = parser->bt_stack.top();
00794
00795 if (parent->is_vector_type() || parent->is_constructor_type())
00796 parent->add_var(btp);
00797 else
00798 DDXParser::ddx_fatal_error(parser,
00799 "Tried to add the simple-type variable '%s' to a non-constructor type (%s %s).",
00800 name,
00801 parser->bt_stack.top()->
00802 type_name().c_str(),
00803 parser->bt_stack.top()->name().
00804 c_str());
00805 }
00806 else
00807 DDXParser::ddx_fatal_error(parser,
00808 "Expected an end tag for a simple type; found '%s' instead.",
00809 name);
00810 break;
00811
00812 case inside_array:
00813 parser->finish_variable(name, dods_array_c, "Array");
00814 break;
00815
00816 case inside_dimension:
00817 if (strcmp(name, "dimension") == 0)
00818 parser->pop_state();
00819 else
00820 DDXParser::ddx_fatal_error(parser,
00821 "Expected an end dimension tag; found '%s' instead.",
00822 name);
00823 break;
00824
00825 case inside_structure:
00826 parser->finish_variable(name, dods_structure_c, "Structure");
00827 break;
00828
00829 case inside_sequence:
00830 parser->finish_variable(name, dods_sequence_c, "Sequence");
00831 break;
00832
00833 case inside_grid:
00834 parser->finish_variable(name, dods_grid_c, "Grid");
00835 break;
00836
00837 case inside_map:
00838 parser->finish_variable(name, dods_array_c, "Map");
00839 break;
00840
00841 case inside_blob_href:
00842 if (strcmp(name, "dataBLOB") == 0)
00843 parser->pop_state();
00844 else
00845 DDXParser::ddx_fatal_error(parser,
00846 "Expected an end dataBLOB tag; found '%s' instead.",
00847 name);
00848 break;
00849
00850 case parser_unknown:
00851 parser->pop_state();
00852 break;
00853
00854 case parser_error:
00855 break;
00856 }
00857 }
00858
00862 void DDXParser::characters(DDXParser * parser, const xmlChar * ch, int len)
00863 {
00864 switch (parser->get_state()) {
00865 case inside_attribute_value:
00866 parser->char_data.append((const char *)(ch), len);
00867 DBG2(cerr << "Characters: '" << parser->char_data << "'" << endl);
00868 break;
00869
00870 default:
00871 break;
00872 }
00873 }
00874
00879 xmlEntityPtr DDXParser::ddx_get_entity(DDXParser *, const xmlChar * name)
00880 {
00881 return xmlGetPredefinedEntity(name);
00882 }
00883
00891 void DDXParser::ddx_fatal_error(DDXParser * parser, const char *msg, ...)
00892 {
00893 va_list args;
00894
00895 parser->set_state(parser_error);
00896
00897 va_start(args, msg);
00898 char str[1024];
00899 vsnprintf(str, 1024, msg, args);
00900 va_end(args);
00901
00902 #ifdef LIBXML2_6_16
00903
00904 int line = xmlSAX2GetLineNumber(parser->ctxt);
00905 #else
00906 int line = getLineNumber(parser->ctxt);
00907 #endif
00908 parser->error_msg += "At line " + long_to_string(line) + ": ";
00909 parser->error_msg += string(str) + string("\n");
00910 }
00911
00913
00916 static xmlSAXHandler ddx_sax_parser =
00917 {
00918 0,
00919 0,
00920 0,
00921 0,
00922 0,
00923 (getEntitySAXFunc) DDXParser::ddx_get_entity,
00924 0,
00925 0,
00926 0,
00927 0,
00928 0,
00929 0,
00930 (startDocumentSAXFunc) DDXParser::ddx_start_document,
00931 (endDocumentSAXFunc) DDXParser::ddx_end_document,
00932 (startElementSAXFunc) DDXParser::ddx_start_element,
00933 (endElementSAXFunc) DDXParser::ddx_end_element,
00934 0,
00935 (charactersSAXFunc) DDXParser::characters,
00936 0,
00937 0,
00938 0,
00939 (warningSAXFunc) DDXParser::ddx_fatal_error,
00940 (errorSAXFunc) DDXParser::ddx_fatal_error,
00941 (fatalErrorSAXFunc) DDXParser::ddx_fatal_error,
00942 #ifdef LIBXML2_5_10
00943 0,
00944 0,
00945 0,
00946 0,
00947 #endif
00948 #ifdef LIBXML2_6_16
00949 0,
00950 0,
00951 0,
00952 0
00953 #endif
00954 };
00955
00956 void DDXParser::cleanup_parse(xmlParserCtxtPtr & context) const
00957 {
00958 if (!context->wellFormed) {
00959 context->sax = NULL;
00960 xmlFreeParserCtxt(context);
00961 throw
00962 DDXParseFailed(string
00963 ("\nThe DDX is not a well formed XML document.\n")
00964 + error_msg);
00965 }
00966
00967 if (!context->valid) {
00968 context->sax = NULL;
00969 xmlFreeParserCtxt(context);
00970 throw DDXParseFailed(string("\nThe DDX is not a valid document.\n")
00971 + error_msg);
00972 }
00973
00974 if (get_state() == parser_error) {
00975 context->sax = NULL;
00976 xmlFreeParserCtxt(context);
00977 throw DDXParseFailed(string("\nError parsing DDX response.\n") +
00978 error_msg);
00979 }
00980
00981 context->sax = NULL;
00982 xmlFreeParserCtxt(context);
00983 }
00984
00987 void DDXParser::intern_stream(FILE * in, DDS * dest_dds)
00988 {
00989
00990
00991 if (!in || feof(in) || ferror(in))
00992 throw InternalErr(__FILE__, __LINE__,
00993 "Input stream not open or read error");
00994
00995 dds = dest_dds;
00996 #if 0
00997 blob_href = blob;
00998 #endif
00999 int size = 1024;
01000 char chars[1024];
01001
01002 int res = fread(chars, 1, 4, in);
01003 if (res > 0) {
01004 xmlParserCtxtPtr context =
01005 xmlCreatePushParserCtxt(NULL, NULL, chars, res,
01006 "stream");
01007
01008 ctxt = context;
01009
01010 context->sax = &ddx_sax_parser;
01011 context->userData = this;
01012 context->validate = true;
01013
01014 while ((res = fread(chars, 1, size, in)) > 0) {
01015 xmlParseChunk(ctxt, chars, res, 0);
01016 }
01017 xmlParseChunk(ctxt, chars, 0, 1);
01018
01019 cleanup_parse(context);
01020 }
01021 }
01022
01023
01036 void DDXParser::intern(const string & document, DDS * dest_dds)
01037 {
01038
01039
01040
01041
01042
01043
01044
01045 xmlParserCtxtPtr context = xmlCreateFileParserCtxt(document.c_str());
01046 if (!context)
01047 throw
01048 DDXParseFailed(string
01049 ("Could not initialize the parser with the file: '")
01050 + document + string("'."));
01051
01052 dds = dest_dds;
01053 #if 0
01054 blob_href = blob;
01055 #endif
01056 ctxt = context;
01057
01058 context->sax = &ddx_sax_parser;
01059 context->userData = this;
01060 context->validate = true;
01061
01062 xmlParseDocument(context);
01063
01064 cleanup_parse(context);
01065 }
01066
01067 }