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 bool found = false;
00238 map < string, string >::iterator i;
00239 for (i = attributes.begin(); i != attributes.end(); ++i)
00240 if (i->first == attr)
00241 found = true;
00242
00243 if (!found)
00244 ddx_fatal_error(this, "Required attribute '%s' not found.",
00245 attr.c_str());
00246
00247 return found;
00248 }
00249
00255 void DDXParser::process_attribute_element(const char **attrs)
00256 {
00257
00258 transfer_attrs(attrs);
00259 bool error = !(check_required_attribute(string("name"))
00260 && check_required_attribute(string("type")));
00261 if (error)
00262 return;
00263
00264 if (attributes["type"] == "Container") {
00265 set_state(inside_attribute_container);
00266
00267 AttrTable *child;
00268 AttrTable *parent = at_stack.top();
00269
00270 child = parent->append_container(attributes["name"]);
00271 at_stack.push(child);
00272 DBG2(cerr << "Pushing at" << endl);
00273 }
00274 else {
00275 set_state(inside_attribute);
00276
00277 dods_attr_name = attributes["name"];
00278 dods_attr_type = attributes["type"];
00279 }
00280 }
00281
00285 void DDXParser::process_attribute_alias(const char **attrs)
00286 {
00287 transfer_attrs(attrs);
00288 if (check_required_attribute(string("name"))
00289 && check_required_attribute(string("attribute"))) {
00290 set_state(inside_alias);
00291 at_stack.top()->attr_alias(attributes["name"],
00292 attributes["attribute"]);
00293 }
00294 }
00295
00303 void DDXParser::process_variable(Type t, ParseState s, const char **attrs)
00304 {
00305 transfer_attrs(attrs);
00306
00307 set_state(s);
00308 BaseType *btp = factory(t, attributes["name"]);
00309 if (!btp)
00310 ddx_fatal_error(this,
00311 "Internal parser error; could not instantiate the variable '%s'.",
00312 attributes["name"].c_str());
00313
00314
00315
00316
00317
00318 bt_stack.push(btp);
00319 at_stack.push(&btp->get_attr_table());
00320 }
00321
00325 void DDXParser::process_dimension(const char **attrs)
00326 {
00327 transfer_attrs(attrs);
00328 if (check_required_attribute(string("size"))) {
00329 set_state(inside_dimension);
00330 Array *ap = dynamic_cast < Array * >(bt_stack.top());
00331 if (!ap)
00332 ddx_fatal_error(this, "Parse error: Expected an array variable.");
00333
00334 ap->append_dim(atoi(attributes["size"].c_str()),
00335 attributes["name"]);
00336 }
00337 }
00338
00343 void DDXParser::process_blob(const char **attrs)
00344 {
00345 transfer_attrs(attrs);
00346 if (check_required_attribute(string("href"))) {
00347 set_state(inside_blob_href);
00348 *blob_href = attributes["href"];
00349 }
00350 }
00351
00358 inline bool
00359 DDXParser::is_attribute_or_alias(const char *name, const char **attrs)
00360 {
00361 if (strcmp(name, "Attribute") == 0) {
00362 process_attribute_element(attrs);
00363
00364 return true;
00365 }
00366 else if (strcmp(name, "Alias") == 0) {
00367 process_attribute_alias(attrs);
00368
00369 return true;
00370 }
00371
00372 return false;
00373 }
00374
00380 inline bool DDXParser::is_variable(const char *name, const char **attrs)
00381 {
00382 Type t;
00383 if ((t = is_simple_type(name)) != dods_null_c) {
00384 process_variable(t, inside_simple_type, attrs);
00385 return true;
00386 }
00387 else if (strcmp(name, "Array") == 0) {
00388 process_variable(dods_array_c, inside_array, attrs);
00389 return true;
00390 }
00391 else if (strcmp(name, "Structure") == 0) {
00392 process_variable(dods_structure_c, inside_structure, attrs);
00393 return true;
00394 }
00395 else if (strcmp(name, "Sequence") == 0) {
00396 process_variable(dods_sequence_c, inside_sequence, attrs);
00397 return true;
00398 }
00399 else if (strcmp(name, "Grid") == 0) {
00400 process_variable(dods_grid_c, inside_grid, attrs);
00401 return true;
00402 }
00403
00404 return false;
00405 }
00406
00407 void DDXParser::finish_variable(const char *tag, Type t,
00408 const char *expected)
00409 {
00410 if (strcmp(tag, expected) != 0) {
00411 DDXParser::ddx_fatal_error(this,
00412 "Expected an end tag for a %s; found '%s' instead.",
00413 expected, tag);
00414 return;
00415 }
00416
00417 pop_state();
00418
00419 BaseType *btp = bt_stack.top();
00420
00421 bt_stack.pop();
00422 at_stack.pop();
00423
00424 if (btp->type() != t) {
00425 DDXParser::ddx_fatal_error(this,
00426 "Internal error: Expected a %s variable.",
00427 expected);
00428 return;
00429 }
00430
00431 if (t == dods_array_c
00432 && dynamic_cast < Array * >(btp)->dimensions() == 0) {
00433 DDXParser::ddx_fatal_error(this,
00434 "No dimension element included in the Array '%s'.",
00435 btp->name().c_str());
00436 return;
00437 }
00438
00439 BaseType *parent = bt_stack.top();
00440
00441 if (!(parent->is_vector_type() || parent->is_constructor_type())) {
00442 DDXParser::ddx_fatal_error(this,
00443 "Tried to add the array variable '%s' to a non-constructor type (%s %s).",
00444 tag,
00445 bt_stack.top()->type_name().c_str(),
00446 bt_stack.top()->name().c_str());
00447 return;
00448 }
00449
00450 parent->add_var(btp);
00451 }
00452
00459
00464 void DDXParser::ddx_start_document(DDXParser * parser)
00465 {
00466 parser->error_msg = "";
00467 parser->char_data = "";
00468
00469
00470 parser->at_stack.push(&parser->dds->get_attr_table());
00471
00472
00473
00474
00475 parser->bt_stack.push(new Structure("dummy_dds"));
00476
00477 parser->set_state(parser_start);
00478
00479 DBG2(cerr << "Parser state: " << states[parser->get_state()] << endl);
00480 }
00481
00484 void DDXParser::ddx_end_document(DDXParser * parser)
00485 {
00486 DBG2(cerr << "Ending state == " << states[parser->get_state()] <<
00487 endl);
00488
00489 if (parser->get_state() != parser_start)
00490 DDXParser::ddx_fatal_error(parser,
00491 "The document contained unbalanced tags.");
00492
00493
00494
00495 if (parser->get_state() == parser_error)
00496 return;
00497
00498
00499
00500 Constructor *cp =
00501 dynamic_cast < Constructor * >(parser->bt_stack.top());
00502 if (!cp)
00503 ddx_fatal_error(parser, "Parse error: Expected a Structure, Sequence or Grid variable.");
00504
00505 for (Constructor::Vars_iter i = cp->var_begin(); i != cp->var_end();
00506 ++i)
00507 parser->dds->add_var(*i);
00508
00509 parser->bt_stack.pop();
00510 delete cp;
00511 }
00512
00519 void DDXParser::ddx_start_element(DDXParser * parser, const char *name,
00520 const char **attrs)
00521 {
00522 DBG2(cerr << "start element: " << name << ", states: "
00523 << states[parser->get_state()]);
00524
00525 switch (parser->get_state()) {
00526 case parser_start:
00527 if (strcmp(name, "Dataset") == 0) {
00528 parser->set_state(inside_dataset);
00529
00530 parser->transfer_attrs(attrs);
00531 if (parser->check_required_attribute(string("name")))
00532 parser->dds->set_dataset_name(parser->attributes["name"]);
00533 }
00534 else
00535 DDXParser::ddx_fatal_error(parser,
00536 "Expected response to start with a Dataset element; found '%s' instead.",
00537 name);
00538 break;
00539
00540 case inside_dataset:
00541 if (parser->is_attribute_or_alias(name, attrs))
00542 break;
00543 else if (parser->is_variable(name, attrs))
00544 break;
00545 else if (strcmp(name, "dataBLOB") == 0) {
00546 parser->process_blob(attrs);
00547
00548 }
00549 else
00550 DDXParser::ddx_fatal_error(parser,
00551 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00552 name);
00553 break;
00554
00555 case inside_attribute_container:
00556 if (parser->is_attribute_or_alias(name, attrs))
00557 break;
00558 else
00559 DDXParser::ddx_fatal_error(parser,
00560 "Expected an Attribute or Alias element; found '%s' instead.",
00561 name);
00562 break;
00563
00564 case inside_attribute:
00565 if (parser->is_attribute_or_alias(name, attrs))
00566 break;
00567 else if (strcmp(name, "value") == 0)
00568 parser->set_state(inside_attribute_value);
00569 else
00570 ddx_fatal_error(parser,
00571 "Expected an 'Attribute', 'Alias' or 'value' element; found '%s' instead.",
00572 name);
00573 break;
00574
00575 case inside_attribute_value:
00576 ddx_fatal_error(parser,
00577 "Internal parser error; unexpected state, inside value while processing element '%s'.",
00578 name);
00579 break;
00580
00581 case inside_alias:
00582 ddx_fatal_error(parser,
00583 "Internal parser error; unexpected state, inside alias while processing element '%s'.",
00584 name);
00585 break;
00586
00587 case inside_simple_type:
00588 if (parser->is_attribute_or_alias(name, attrs))
00589 break;
00590 else
00591 ddx_fatal_error(parser,
00592 "Expected an 'Attribute' or 'Alias' element; found '%s' instead.",
00593 name);
00594 break;
00595
00596 case inside_array:
00597 if (parser->is_attribute_or_alias(name, attrs))
00598 break;
00599 else if (is_not(name, "Array") && parser->is_variable(name, attrs))
00600 break;
00601 else if (strcmp(name, "dimension") == 0) {
00602 parser->process_dimension(attrs);
00603
00604 }
00605 else
00606 ddx_fatal_error(parser,
00607 "Expected an 'Attribute' or 'Alias' element; found '%s' instead.",
00608 name);
00609 break;
00610
00611 case inside_dimension:
00612 ddx_fatal_error(parser,
00613 "Internal parser error; unexpected state, inside dimension while processing element '%s'.",
00614 name);
00615 break;
00616
00617 case inside_structure:
00618 if (parser->is_attribute_or_alias(name, attrs))
00619 break;
00620 else if (parser->is_variable(name, attrs))
00621 break;
00622 else
00623 DDXParser::ddx_fatal_error(parser,
00624 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00625 name);
00626 break;
00627
00628 case inside_sequence:
00629 if (parser->is_attribute_or_alias(name, attrs))
00630 break;
00631 else if (parser->is_variable(name, attrs))
00632 break;
00633 else
00634 DDXParser::ddx_fatal_error(parser,
00635 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00636 name);
00637 break;
00638
00639 case inside_grid:
00640 if (parser->is_attribute_or_alias(name, attrs))
00641 break;
00642 else if (strcmp(name, "Array") == 0)
00643 parser->process_variable(dods_array_c, inside_array, attrs);
00644 else if (strcmp(name, "Map") == 0)
00645 parser->process_variable(dods_array_c, inside_map, attrs);
00646 else
00647 DDXParser::ddx_fatal_error(parser,
00648 "Expected an Attribute, Alias or variable element; found '%s' instead.",
00649 name);
00650 break;
00651
00652 case inside_map:
00653 if (parser->is_attribute_or_alias(name, attrs))
00654 break;
00655 else if (is_not(name, "Array") && is_not(name, "Sequence")
00656 && is_not(name, "Grid")
00657 && parser->is_variable(name, attrs))
00658 break;
00659 else if (strcmp(name, "dimension") == 0) {
00660 parser->process_dimension(attrs);
00661
00662 }
00663 else
00664 ddx_fatal_error(parser,
00665 "Expected an 'Attribute', 'Alias', variable or 'dimension' element; found '%s' instead.",
00666 name);
00667 break;
00668
00669 case inside_blob_href:
00670 ddx_fatal_error(parser,
00671 "Internal parser error; unexpected state, inside blob href while processing element '%s'.",
00672 name);
00673 break;
00674
00675 case parser_unknown:
00676 parser->set_state(parser_unknown);
00677 break;
00678
00679 case parser_error:
00680 break;
00681 }
00682
00683 DBGN(cerr << " ... " << states[parser->get_state()] << endl);
00684 }
00685
00691 void DDXParser::ddx_end_element(DDXParser * parser, const char *name)
00692 {
00693 DBG2(cerr << "End element " << name << " (state "
00694 << states[parser->get_state()] << ")" << endl);
00695
00696 switch (parser->get_state()) {
00697 case parser_start:
00698 ddx_fatal_error(parser,
00699 "Internal parser error; unexpected state, inside start state while processing element '%s'.",
00700 name);
00701 break;
00702
00703 case inside_dataset:
00704 if (strcmp(name, "Dataset") == 0)
00705 parser->pop_state();
00706 else
00707 DDXParser::ddx_fatal_error(parser,
00708 "Expected an end Dataset tag; found '%s' instead.",
00709 name);
00710 break;
00711
00712 case inside_attribute_container:
00713 if (strcmp(name, "Attribute") == 0) {
00714 parser->pop_state();
00715 parser->at_stack.pop();
00716 }
00717 else
00718 DDXParser::ddx_fatal_error(parser,
00719 "Expected an end Attribute tag; found '%s' instead.",
00720 name);
00721 break;
00722
00723 case inside_attribute:
00724 if (strcmp(name, "Attribute") == 0)
00725 parser->pop_state();
00726 else
00727 DDXParser::ddx_fatal_error(parser,
00728 "Expected an end Attribute tag; found '%s' instead.",
00729 name);
00730 break;
00731
00732 case inside_attribute_value:
00733 if (strcmp(name, "value") == 0) {
00734 parser->pop_state();
00735 AttrTable *atp = parser->at_stack.top();
00736 atp->append_attr(parser->dods_attr_name,
00737 parser->dods_attr_type, parser->char_data);
00738 parser->char_data = "";
00739 }
00740 else
00741 DDXParser::ddx_fatal_error(parser,
00742 "Expected an end value tag; found '%s' instead.",
00743 name);
00744
00745 break;
00746
00747
00748 case inside_alias:
00749 parser->pop_state();
00750 break;
00751
00752 case inside_simple_type:
00753 if (is_simple_type(name) != dods_null_c) {
00754 parser->pop_state();
00755 BaseType *btp = parser->bt_stack.top();
00756 parser->bt_stack.pop();
00757 parser->at_stack.pop();
00758
00759 BaseType *parent = parser->bt_stack.top();
00760
00761 if (parent->is_vector_type() || parent->is_constructor_type())
00762 parent->add_var(btp);
00763 else
00764 DDXParser::ddx_fatal_error(parser,
00765 "Tried to add the simple-type variable '%s' to a non-constructor type (%s %s).",
00766 name,
00767 parser->bt_stack.top()->
00768 type_name().c_str(),
00769 parser->bt_stack.top()->name().
00770 c_str());
00771 }
00772 else
00773 DDXParser::ddx_fatal_error(parser,
00774 "Expected an end tag for a simple type; found '%s' instead.",
00775 name);
00776 break;
00777
00778 case inside_array:
00779 parser->finish_variable(name, dods_array_c, "Array");
00780 break;
00781
00782 case inside_dimension:
00783 if (strcmp(name, "dimension") == 0)
00784 parser->pop_state();
00785 else
00786 DDXParser::ddx_fatal_error(parser,
00787 "Expected an end dimension tag; found '%s' instead.",
00788 name);
00789 break;
00790
00791 case inside_structure:
00792 parser->finish_variable(name, dods_structure_c, "Structure");
00793 break;
00794
00795 case inside_sequence:
00796 parser->finish_variable(name, dods_sequence_c, "Sequence");
00797 break;
00798
00799 case inside_grid:
00800 parser->finish_variable(name, dods_grid_c, "Grid");
00801 break;
00802
00803 case inside_map:
00804 parser->finish_variable(name, dods_array_c, "Map");
00805 break;
00806
00807 case inside_blob_href:
00808 if (strcmp(name, "dataBLOB") == 0)
00809 parser->pop_state();
00810 else
00811 DDXParser::ddx_fatal_error(parser,
00812 "Expected an end dataBLOB tag; found '%s' instead.",
00813 name);
00814 break;
00815
00816 case parser_unknown:
00817 parser->pop_state();
00818 break;
00819
00820 case parser_error:
00821 break;
00822 }
00823 }
00824
00828 void DDXParser::characters(DDXParser * parser, const xmlChar * ch, int len)
00829 {
00830 switch (parser->get_state()) {
00831 case inside_attribute_value:
00832 parser->char_data.append((const char *)(ch), len);
00833 DBG2(cerr << "Characters: '" << parser->char_data << "'" << endl);
00834 break;
00835
00836 default:
00837 break;
00838 }
00839 }
00840
00845 xmlEntityPtr DDXParser::ddx_get_entity(DDXParser *, const xmlChar * name)
00846 {
00847 return xmlGetPredefinedEntity(name);
00848 }
00849
00857 void DDXParser::ddx_fatal_error(DDXParser * parser, const char *msg, ...)
00858 {
00859 va_list args;
00860
00861 parser->set_state(parser_error);
00862
00863 va_start(args, msg);
00864 char str[1024];
00865 vsnprintf(str, 1024, msg, args);
00866 va_end(args);
00867
00868 #ifdef LIBXML2_6_16
00869
00870 int line = xmlSAX2GetLineNumber(parser->ctxt);
00871 #else
00872 int line = getLineNumber(parser->ctxt);
00873 #endif
00874 parser->error_msg += "At line " + long_to_string(line) + ": ";
00875 parser->error_msg += string(str) + string("\n");
00876 }
00877
00879
00882 static xmlSAXHandler ddx_sax_parser =
00883 {
00884 0,
00885 0,
00886 0,
00887 0,
00888 0,
00889 (getEntitySAXFunc) DDXParser::ddx_get_entity,
00890 0,
00891 0,
00892 0,
00893 0,
00894 0,
00895 0,
00896 (startDocumentSAXFunc) DDXParser::ddx_start_document,
00897 (endDocumentSAXFunc) DDXParser::ddx_end_document,
00898 (startElementSAXFunc) DDXParser::ddx_start_element,
00899 (endElementSAXFunc) DDXParser::ddx_end_element,
00900 0,
00901 (charactersSAXFunc) DDXParser::characters,
00902 0,
00903 0,
00904 0,
00905 (warningSAXFunc) DDXParser::ddx_fatal_error,
00906 (errorSAXFunc) DDXParser::ddx_fatal_error,
00907 (fatalErrorSAXFunc) DDXParser::ddx_fatal_error,
00908 #ifdef LIBXML2_5_10
00909 0,
00910 0,
00911 0,
00912 0,
00913 #endif
00914 #ifdef LIBXML2_6_16
00915 0,
00916 0,
00917 0,
00918 0
00919 #endif
00920 };
00921
00922 void DDXParser::cleanup_parse(xmlParserCtxtPtr & context) const
00923 {
00924 if (!context->wellFormed) {
00925 context->sax = NULL;
00926 xmlFreeParserCtxt(context);
00927 throw
00928 DDXParseFailed(string
00929 ("\nThe DDX is not a well formed XML document.\n")
00930 + error_msg);
00931 }
00932
00933 if (!context->valid) {
00934 context->sax = NULL;
00935 xmlFreeParserCtxt(context);
00936 throw DDXParseFailed(string("\nThe DDX is not a valid document.\n")
00937 + error_msg);
00938 }
00939
00940 if (get_state() == parser_error) {
00941 context->sax = NULL;
00942 xmlFreeParserCtxt(context);
00943 throw DDXParseFailed(string("\nError parsing DDX response.\n") +
00944 error_msg);
00945 }
00946
00947 context->sax = NULL;
00948 xmlFreeParserCtxt(context);
00949 }
00950
00953 void DDXParser::intern_stream(FILE * in, DDS * dest_dds, string * blob)
00954 {
00955
00956
00957 if (!in || feof(in) || ferror(in))
00958 throw InternalErr(__FILE__, __LINE__,
00959 "Input stream not open or read error");
00960
00961 dds = dest_dds;
00962 blob_href = blob;
00963
00964 int size = 1024;
00965 char chars[1024];
00966
00967 int res = fread(chars, 1, 4, in);
00968 if (res > 0) {
00969 xmlParserCtxtPtr context =
00970 xmlCreatePushParserCtxt(NULL, NULL, chars, res,
00971 "stream");
00972
00973 ctxt = context;
00974
00975 context->sax = &ddx_sax_parser;
00976 context->userData = this;
00977 context->validate = true;
00978
00979 while ((res = fread(chars, 1, size, in)) > 0) {
00980 xmlParseChunk(ctxt, chars, res, 0);
00981 }
00982 xmlParseChunk(ctxt, chars, 0, 1);
00983
00984 cleanup_parse(context);
00985 }
00986 }
00987
00988
01000 void DDXParser::intern(const string & document, DDS * dest_dds,
01001 string * blob)
01002 {
01003
01004
01005
01006
01007
01008
01009
01010 xmlParserCtxtPtr context = xmlCreateFileParserCtxt(document.c_str());
01011 if (!context)
01012 throw
01013 DDXParseFailed(string
01014 ("Could not initialize the parser with the file: '")
01015 + document + string("'."));
01016
01017 dds = dest_dds;
01018 blob_href = blob;
01019 ctxt = context;
01020
01021 context->sax = &ddx_sax_parser;
01022 context->userData = this;
01023 context->validate = true;
01024
01025 xmlParseDocument(context);
01026
01027 cleanup_parse(context);
01028 }
01029
01030 }