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