mirror of
https://git.gfz-potsdam.de/naaice/iphreeqc.git
synced 2025-12-16 16:44:49 +01:00
indent -bli0 -i4 -ts4 -npcs -nbc *.cxx git-svn-id: svn://136.177.114.72/svn_GW/phreeqcpp/trunk@3168 1feff8c3-07ed-0310-ac33-dd36852eb9cd
1137 lines
31 KiB
C++
1137 lines
31 KiB
C++
// SAXPhreeqc.cpp
|
|
#ifdef _DEBUG
|
|
#pragma warning(disable : 4786) // disable truncation warning (Only used by debugger)
|
|
#endif
|
|
|
|
#include <float.h> // DBL_DIG
|
|
#include <stdio.h> // sprintf
|
|
#include <wctype.h> // iswspace
|
|
|
|
#include <cassert> // assert
|
|
//#include <strstream> // std::ostrstream
|
|
#include <sstream>
|
|
#include <iostream> // std::cerr
|
|
#ifdef SKIP
|
|
#endif
|
|
#ifdef _DEBUG
|
|
#define _CRTDBG_MAP_ALLOC
|
|
#include <crtdbg.h>
|
|
#endif
|
|
|
|
|
|
#include <xercesc/framework/StdInInputSource.hpp>
|
|
#include <xercesc/framework/MemoryManager.hpp>
|
|
#include <xercesc/framework/XMLGrammarPool.hpp>
|
|
#include <xercesc/internal/XMLGrammarPoolImpl.hpp>
|
|
#include <xercesc/internal/MemoryManagerImpl.hpp>
|
|
#include <xercesc/validators/common/Grammar.hpp>
|
|
|
|
//#include <xercesc/parsers/SAXParser.hpp> // SAXParser
|
|
#include <xercesc/sax/AttributeList.hpp> // AttributeList
|
|
#include <xercesc/util/XMLUniDefs.hpp> // Unicode definitions
|
|
#include <xercesc/framework/MemBufInputSource.hpp> // MemBufInputSource
|
|
#include <xercesc/framework/MemoryManager.hpp>
|
|
#include <xercesc/internal/MemoryManagerImpl.hpp>
|
|
#include <xercesc/util/PlatformUtils.hpp> // XMLPlatformUtils::getCurrentMillis
|
|
#include <xercesc/util/XMLUni.hpp>
|
|
|
|
#include <xercesc/sax2/SAX2XMLReader.hpp>
|
|
#include <xercesc/sax2/XMLReaderFactory.hpp>
|
|
|
|
#include "SAXPhreeqc.h" // SAX_ functions
|
|
#include "SaxPhreeqcHandlers.h" // SaxPhreeqcHandlers
|
|
|
|
//XERCES_CPP_NAMESPACE_USE
|
|
#define xns XERCES_CPP_NAMESPACE
|
|
|
|
///static char buffer[300000];
|
|
///static std::ostrstream s_oss(buffer, 300000); // must never go out of scope
|
|
static
|
|
std::ostringstream
|
|
s_oss; // must never go out of scope
|
|
static bool
|
|
s_bSysIsOpen = false; // must never go out of scope
|
|
|
|
#include <math.h>
|
|
// extern routines
|
|
#include "phqalloc.h"
|
|
#include "global.h"
|
|
#include "phrqproto.h"
|
|
#include "output.h"
|
|
#ifdef SKIP
|
|
int
|
|
conc_init(struct conc *conc_ptr);
|
|
void *
|
|
free_check_null(void *ptr);
|
|
int
|
|
pe_data_store(struct pe_data **pe, const char *token);
|
|
struct phase *
|
|
phase_bsearch(char *ptr, int *j, int print);
|
|
struct solution *
|
|
solution_alloc(void);
|
|
struct solution *
|
|
solution_bsearch(int k, int *n, int print);
|
|
int
|
|
solution_free(struct solution *solution_ptr);
|
|
void
|
|
space(void **ptr, int i, int *max, int struct_size);
|
|
char *
|
|
string_duplicate(const char *token);
|
|
char *
|
|
string_hsave(const char *str);
|
|
int
|
|
error_msg(const char *err_str, const int stop);
|
|
struct master *
|
|
master_bsearch(const char *ptr);
|
|
void
|
|
malloc_error(void);
|
|
#endif
|
|
//}
|
|
|
|
|
|
class
|
|
Initializer
|
|
{
|
|
public:
|
|
Initializer()
|
|
{
|
|
#if defined(_DEBUG)
|
|
int
|
|
tmpDbgFlag;
|
|
|
|
/*
|
|
* Set the debug-heap flag to keep freed blocks in the
|
|
* heap's linked list - This will allow us to catch any
|
|
* inadvertent use of freed memory
|
|
*/
|
|
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
|
|
//tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
|
|
tmpDbgFlag |=
|
|
_CRTDBG_LEAK_CHECK_DF;
|
|
//tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF;
|
|
_CrtSetDbgFlag(tmpDbgFlag);
|
|
#endif
|
|
|
|
xns::XMLPlatformUtils::Initialize();
|
|
}
|
|
};
|
|
|
|
static Initializer
|
|
sInit; // initialize xerces once
|
|
static SaxPhreeqcHandlers
|
|
s_handler; // one and only instance
|
|
|
|
void
|
|
SAX_StartSystem()
|
|
{
|
|
|
|
assert(!s_bSysIsOpen); // system already open and has not been closed
|
|
|
|
// init stream
|
|
//s_oss.freeze(false);
|
|
s_oss.seekp(0);
|
|
|
|
// write stream
|
|
// s_oss << "<system>";
|
|
s_oss << "<?xml version=\"1.0\" ?>";
|
|
s_oss << "<phast_state nx=\"2\">";
|
|
s_oss << " <system system_number=\"1\">";
|
|
s_bSysIsOpen = true;
|
|
|
|
}
|
|
|
|
char *
|
|
stringify_null(char *string)
|
|
{
|
|
if (string == NULL)
|
|
return (string_hsave(""));
|
|
return (string);
|
|
}
|
|
|
|
int
|
|
SAX_AddSolution(struct solution *solution_ptr)
|
|
{
|
|
//const char ERR_MESSAGE[] = "Packing solution message: %s, element not found\n";
|
|
int
|
|
i,
|
|
newd;
|
|
assert(s_bSysIsOpen); // must call SAX_StartSystem first
|
|
s_oss.precision(DBL_DIG - 1);
|
|
// Solution element and attributes
|
|
newd = solution_ptr->new_def;
|
|
s_oss << " <solution " << std::endl;
|
|
s_oss << " soln_new_def=\"" << solution_ptr->
|
|
new_def << "\"" << std::endl;
|
|
s_oss << " soln_n_user=\"" << solution_ptr->
|
|
n_user << "\" " << std::endl;
|
|
s_oss << " soln_n_user_end=\"" << solution_ptr->
|
|
n_user_end << "\"" << std::endl;
|
|
s_oss << " soln_description=\"" << solution_ptr->
|
|
description << "\"" << std::endl;
|
|
s_oss << " soln_tc=\"" << solution_ptr->tc << "\"" << std::endl;
|
|
s_oss << " soln_ph=\"" << solution_ptr->ph << "\"" << std::endl;
|
|
s_oss << " soln_solution_pe=\"" << solution_ptr->
|
|
solution_pe << "\"" << std::endl;
|
|
s_oss << " soln_mu=\"" << solution_ptr->mu << "\"" << std::endl;
|
|
s_oss << " soln_ah2o=\"" << solution_ptr->ah2o << "\"" << std::endl;
|
|
s_oss << " soln_density=\"" << solution_ptr->
|
|
density << "\"" << std::endl;
|
|
s_oss << " soln_total_h=\"" << solution_ptr->
|
|
total_h << "\"" << std::endl;
|
|
s_oss << " soln_total_o=\"" << solution_ptr->
|
|
total_o << "\"" << std::endl;
|
|
s_oss << " soln_cb=\"" << solution_ptr->cb << "\"" << std::endl;
|
|
s_oss << " soln_mass_water=\"" << solution_ptr->
|
|
mass_water << "\"" << std::endl;
|
|
s_oss << " soln_total_alkalinity=\"" << solution_ptr->
|
|
total_alkalinity << "\"" << std::endl;
|
|
//s_oss << " soln_total_co2=\"" << solution_ptr->total_co2 << "\"" << std::endl;
|
|
s_oss << " soln_units=\"" << solution_ptr->units << "\"" << std::endl;
|
|
s_oss << " soln_default_pe=\"" << solution_ptr->
|
|
default_pe << "\"" << std::endl;
|
|
s_oss << " soln_count_master_activity=\"" << solution_ptr->
|
|
count_master_activity << "\"" << std::endl;
|
|
s_oss << " soln_count_isotopes=\"" << solution_ptr->
|
|
count_isotopes << "\"" << std::endl;
|
|
s_oss << " soln_count_species_gamma=\"" << solution_ptr->
|
|
count_species_gamma << "\">" << std::endl;
|
|
// end of solution attributes
|
|
// pe structures
|
|
for (i = 0; solution_ptr->pe[i].name != NULL; i++)
|
|
{
|
|
s_oss << " <soln_pe soln_pe_name=\"" << solution_ptr->pe[i].
|
|
name << "\"/>" << std::endl;
|
|
}
|
|
// soln_total conc structures
|
|
for (i = 0; solution_ptr->totals[i].description != NULL; i++)
|
|
{
|
|
struct conc *
|
|
c = &(solution_ptr->totals[i]);
|
|
s_oss << " <soln_total " << std::endl;
|
|
s_oss << " conc_desc=\"" << c->description << "\"" << std::endl;
|
|
s_oss << " conc_moles=\"" << c->moles << "\"" << std::endl;
|
|
if (newd == TRUE)
|
|
{
|
|
s_oss << " conc_input_conc=\"" << c->
|
|
input_conc << "\"" << std::endl;
|
|
if (c->units != NULL)
|
|
s_oss << " conc_units=\"" << c->
|
|
units << "\"" << std::endl;
|
|
if (c->equation_name != NULL)
|
|
{
|
|
s_oss << " conc_equation_name=\"" << stringify_null(c->
|
|
equation_name)
|
|
<< "\"" << std::endl;
|
|
s_oss << " conc_phase_si=\"" << c->
|
|
phase_si << "\"" << std::endl;
|
|
}
|
|
if (c->as != NULL)
|
|
s_oss << " conc_as=\"" << stringify_null(c->
|
|
as) << "\"" <<
|
|
std::endl;
|
|
s_oss << " conc_gfw=\"" << c->gfw << "\"" << std::endl;
|
|
}
|
|
s_oss << " conc_n_pe=\"" << c->n_pe << "\"" << std::endl;
|
|
s_oss << " />" << std::endl;
|
|
}
|
|
// master_activity, master_activity structure
|
|
|
|
for (i = 0; i < solution_ptr->count_master_activity; i++)
|
|
{
|
|
s_oss << " <soln_m_a m_a_desc=\"" << stringify_null(solution_ptr->
|
|
master_activity
|
|
[i].
|
|
description) <<
|
|
"\" m_a_la=\"" << solution_ptr->master_activity[i].
|
|
la << "\"/>" << std::endl;
|
|
}
|
|
/*
|
|
if (solution_ptr->count_master_activity > 0) {
|
|
s_oss << " <soln_m_a m_a_list=\"" << std::endl;
|
|
for (i=0; i < solution_ptr->count_master_activity; i++) {
|
|
if (solution_ptr->master_activity[i].description != NULL) {
|
|
s_oss << stringify_null(solution_ptr->master_activity[i].description) << " ";
|
|
s_oss << solution_ptr->master_activity[i].la << std::endl;
|
|
} else {
|
|
s_oss << "null 0.0" << std::endl;
|
|
}
|
|
}
|
|
s_oss << "\"/>" << std::endl;
|
|
}
|
|
*/
|
|
// species_gamma, mater_activity structure
|
|
for (i = 0; i < solution_ptr->count_species_gamma; i++)
|
|
{
|
|
s_oss << " <soln_s_g m_a_desc=\"" << stringify_null(solution_ptr->
|
|
species_gamma
|
|
[i].
|
|
description) <<
|
|
"\" m_a_la=\"" << solution_ptr->species_gamma[i].
|
|
la << "\"/>" << std::endl;
|
|
}
|
|
// isotopes, isotope structure
|
|
for (i = 0; solution_ptr->count_isotopes; i++)
|
|
{
|
|
s_oss << " <soln_isotope " << std::endl;
|
|
s_oss << " iso_isotope_number=\"" << solution_ptr->isotopes[i].
|
|
isotope_number << "\"" << std::endl;
|
|
s_oss << " iso_elt_name=\"" << solution_ptr->isotopes[i].
|
|
elt_name << "\"" << std::endl;
|
|
s_oss << " iso_isotope_name=\"" << solution_ptr->isotopes[i].
|
|
isotope_name << "\"" << std::endl;
|
|
s_oss << " iso_total=\"" << solution_ptr->isotopes[i].
|
|
total << "\"" << std::endl;
|
|
s_oss << " iso_ratio=\"" << solution_ptr->isotopes[i].
|
|
ratio << "\"" << std::endl;
|
|
s_oss << " iso_ratio_uncertainty=\"" << solution_ptr->isotopes[i].
|
|
ratio_uncertainty << "\"" << std::endl;
|
|
s_oss << " iso_coef=\"" << solution_ptr->isotopes[i].
|
|
coef << "\"" << std::endl;
|
|
}
|
|
// End of solution
|
|
s_oss << " </solution>" << std::endl;
|
|
|
|
return (OK);
|
|
}
|
|
|
|
void
|
|
SAX_EndSystem()
|
|
{
|
|
assert(s_bSysIsOpen); // must call SAX_StartSystem first
|
|
|
|
s_oss << " </system>" << std::endl;
|
|
s_oss << "</phast_state>" << std::endl;
|
|
s_oss << '\0';
|
|
|
|
s_bSysIsOpen = false;
|
|
//delete[] s_handler;
|
|
return;
|
|
}
|
|
|
|
int
|
|
SAX_GetXMLLength()
|
|
{
|
|
assert(!s_bSysIsOpen); // must call SAX_EndSystem first
|
|
//return s_oss.pcount();
|
|
return s_oss.str().size();
|
|
}
|
|
|
|
const char *
|
|
SAX_GetXMLStr()
|
|
{
|
|
assert(!s_bSysIsOpen); // must call SAX_EndSystem first
|
|
return s_oss.str().c_str();
|
|
}
|
|
|
|
void
|
|
SAX_cleanup()
|
|
{
|
|
//delete s_handler;
|
|
//s_oss.freeze(false);
|
|
}
|
|
|
|
// utility routines
|
|
|
|
int
|
|
XMLCh2Int(const XMLCh * const attValue)
|
|
{
|
|
char *
|
|
string = xns::XMLString::transcode(attValue);
|
|
int
|
|
i = strtol(string, NULL, 10);
|
|
xns::XMLString::release(&string);
|
|
return i;
|
|
//return (xns::XMLString::parseInt(attValue));
|
|
}
|
|
|
|
double
|
|
XMLCh2Double(const XMLCh * const attValue)
|
|
{
|
|
char *
|
|
string = xns::XMLString::transcode(attValue);
|
|
double
|
|
d = strtod(string, NULL);
|
|
xns::XMLString::release(&string);
|
|
return d;
|
|
}
|
|
|
|
char *
|
|
XMLCh2String(const XMLCh * const attValue)
|
|
{
|
|
char *
|
|
string = xns::XMLString::transcode(attValue);
|
|
char *
|
|
s = string_duplicate(string);
|
|
xns::XMLString::release(&string);
|
|
return s;
|
|
}
|
|
|
|
char *
|
|
XMLCh_hsave(const XMLCh * const attValue, bool allow_null)
|
|
{
|
|
char *
|
|
string = xns::XMLString::transcode(attValue);
|
|
char *
|
|
s = string_hsave(string);
|
|
if (allow_null && strlen(s) == 0)
|
|
s = NULL;
|
|
xns::XMLString::release(&string);
|
|
return s;
|
|
}
|
|
|
|
|
|
int
|
|
SAX_UnpackSolutions(void *pvBuffer, int buf_size)
|
|
{
|
|
// Create MemBufferInputSource from the buffer containing the XML
|
|
// statements.
|
|
xns::MemBufInputSource memBufIS((const XMLByte *) pvBuffer, buf_size,
|
|
"solution_id", false);
|
|
fprintf(stderr, "%s", (char *) pvBuffer);
|
|
return 0;
|
|
//
|
|
// Create a SAX2 parser object.
|
|
//
|
|
xns::SAX2XMLReader * parser = xns::XMLReaderFactory::createXMLReader();
|
|
parser->setFeature(xns::XMLUni::fgXercesSchemaFullChecking, false);
|
|
parser->setFeature(xns::XMLUni::fgSAX2CoreNameSpaces, false);
|
|
parser->setFeature(xns::XMLUni::fgXercesSchema, false);
|
|
parser->setFeature(xns::XMLUni::fgXercesIdentityConstraintChecking,
|
|
false);
|
|
//
|
|
// Create the handler object and install it as the document and error
|
|
// handler for the parser. Then parse the MemBufferInputSource and
|
|
// catch any exceptions that propogate out
|
|
//
|
|
try
|
|
{
|
|
unsigned long
|
|
duration = 0;
|
|
parser->setContentHandler(&s_handler);
|
|
parser->setErrorHandler(&s_handler);
|
|
int
|
|
t = 0;
|
|
for (; t < 1000; ++t)
|
|
{
|
|
const unsigned long
|
|
startMillis = xns::XMLPlatformUtils::getCurrentMillis();
|
|
parser->parse(memBufIS);
|
|
const unsigned long
|
|
endMillis = xns::XMLPlatformUtils::getCurrentMillis();
|
|
duration += endMillis - startMillis;
|
|
}
|
|
std::cerr << "\nSaxParse time = " << duration << " millis\n";
|
|
}
|
|
catch(const xns::SAXException & toCatch)
|
|
{
|
|
char *
|
|
psz = xns::XMLString::transcode(toCatch.getMessage());
|
|
input_error++;
|
|
sprintf(error_string, "SAX_UnpackSolutions: %s\n", psz);
|
|
error_msg(error_string, CONTINUE);
|
|
xns::XMLString::release(&psz);
|
|
return ERROR;
|
|
}
|
|
catch(const xns::XMLException & toCatch)
|
|
{
|
|
char *
|
|
psz = xns::XMLString::transcode(toCatch.getMessage());
|
|
input_error++;
|
|
sprintf(error_string, "SAX_UnpackSolutions: %s\n", psz);
|
|
error_msg(error_string, CONTINUE);
|
|
xns::XMLString::release(&psz);
|
|
return ERROR;
|
|
}
|
|
catch(...)
|
|
{
|
|
input_error++;
|
|
sprintf(error_string, "SAX_UnpackSolutions: %s\n",
|
|
"Unknown error occured.");
|
|
error_msg(error_string, CONTINUE);
|
|
return ERROR;
|
|
}
|
|
|
|
return (OK);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// element names
|
|
|
|
SaxPhreeqcHandlers::SaxPhreeqcHandlers():eltType(typeNULL), attType(attNULL), totals(), acts(),
|
|
solution_ptr(NULL)
|
|
{
|
|
int
|
|
i;
|
|
|
|
int
|
|
count_elementInfo,
|
|
count_attributeInfo;
|
|
struct mapElementInfo
|
|
{
|
|
char *
|
|
key;
|
|
enum elementType
|
|
type;
|
|
};
|
|
struct mapAttributeInfo
|
|
{
|
|
enum attributeType
|
|
type;
|
|
char *
|
|
key;
|
|
};
|
|
struct mapElementInfo
|
|
elementInfo[] = {
|
|
{"phast_state", typePHAST_STATE},
|
|
{"system", typeSYSTEM},
|
|
{"solution", typeSOLUTION},
|
|
{"soln_pe", typeSOLN_PE},
|
|
{"soln_total", typeSOLN_TOTAL},
|
|
{"soln_m_a", typeSOLN_MASTER_ACTIVITY},
|
|
{"soln_isotope", typeSOLN_ISOTOPE},
|
|
{"soln_s_g", typeSOLN_SPECIES_GAMMA}
|
|
};
|
|
count_elementInfo = sizeof(elementInfo) / sizeof(struct mapElementInfo);
|
|
struct mapAttributeInfo
|
|
attributeInfo[] = {
|
|
// Solution structure
|
|
{attSOLN_new_def, "soln_new_def"},
|
|
{attSOLN_n_user, "soln_n_user"},
|
|
{attSOLN_n_user_end, "soln_n_user_end"},
|
|
{attSOLN_description, "soln_description"},
|
|
{attSOLN_tc, "soln_tc"},
|
|
{attSOLN_ph, "soln_ph"},
|
|
{attSOLN_solution_pe, "soln_solution_pe"},
|
|
{attSOLN_mu, "soln_mu"},
|
|
{attSOLN_ah2o, "soln_ah2o"},
|
|
{attSOLN_density, "soln_density"},
|
|
{attSOLN_total_h, "soln_total_h"},
|
|
{attSOLN_total_o, "soln_total_o"},
|
|
{attSOLN_cb, "soln_cb"},
|
|
{attSOLN_mass_water, "soln_mass_water"},
|
|
{attSOLN_total_alkalinity, "soln_total_alkalinity"},
|
|
{attSOLN_total_co2, "soln_total_co2"},
|
|
{attSOLN_units, "soln_units"},
|
|
{attSOLN_default_pe, "soln_default_pe"},
|
|
{attSOLN_count_master_activity, "soln_count_master_activity"},
|
|
{attSOLN_count_isotopes, "soln_count_isotopes"},
|
|
{attSOLN_count_species_gamma, "soln_count_species_gamma"},
|
|
{attSOLN_PE_name, "soln_pe_name"},
|
|
// master_activity structure
|
|
{attM_A_description, "m_a_desc"},
|
|
{attM_A_la, "m_a_la"},
|
|
{attM_A_list, "m_a_list"},
|
|
// isotope structure
|
|
{attISO_isotope_number, "iso_isotope_number"},
|
|
{attISO_elt_name, "iso_elt_name"},
|
|
{attISO_isotope_name, "iso_isotope_name"},
|
|
{attISO_total, "iso_total"},
|
|
{attISO_ratio, "iso_ratio"},
|
|
{attISO_ratio_uncertainty, "iso_ratio_uncertainty"},
|
|
{attISO_x_ratio_uncertainty, "iso_x_ratio_uncertainty"},
|
|
{attISO_coef, "iso_coef"},
|
|
// conc structure
|
|
{attCONC_description, "conc_desc"},
|
|
{attCONC_moles, "conc_moles"},
|
|
{attCONC_input_conc, "conc_input_conc"},
|
|
{attCONC_units, "conc_units"},
|
|
{attCONC_equation_name, "conc_equation_name"},
|
|
{attCONC_phase_si, "conc_phase_si"},
|
|
{attCONC_n_pe, "conc_n_pe"},
|
|
{attCONC_as, "conc_as"},
|
|
{attCONC_gfw, "conc_gfw"},
|
|
|
|
};
|
|
|
|
count_attributeInfo =
|
|
sizeof(attributeInfo) / sizeof(struct mapAttributeInfo);
|
|
for (i = 0; i < count_elementInfo; i++)
|
|
{
|
|
// memory freed in destructor
|
|
this->mapXMLCh2Type[xns::XMLString::transcode(elementInfo[i].key)] =
|
|
elementInfo[i].type;
|
|
}
|
|
for (i = 0; i < count_attributeInfo; i++)
|
|
{
|
|
// memory freed in destructor
|
|
this->
|
|
mapXMLCh2AttType[xns::XMLString::
|
|
transcode(attributeInfo[i].key)] =
|
|
attributeInfo[i].type;
|
|
}
|
|
|
|
this->totals.reserve(50);
|
|
this->acts.reserve(50);
|
|
}
|
|
|
|
SaxPhreeqcHandlers::~SaxPhreeqcHandlers()
|
|
{
|
|
std::map < const XMLCh *, elementType, XMLCH_LESS >::iterator it =
|
|
this->mapXMLCh2Type.begin();
|
|
for (; it != this->mapXMLCh2Type.end(); ++it)
|
|
{
|
|
XMLCh *p = (XMLCh *) it->first;
|
|
xns::XMLString::release(&p);
|
|
}
|
|
this->mapXMLCh2Type.clear();
|
|
std::map < const XMLCh *, attributeType, XMLCH_LESS >::iterator ita =
|
|
this->mapXMLCh2AttType.begin();
|
|
for (; ita != this->mapXMLCh2AttType.end(); ++ita)
|
|
{
|
|
XMLCh *p = (XMLCh *) ita->first;
|
|
xns::XMLString::release(&p);
|
|
}
|
|
this->mapXMLCh2AttType.clear();
|
|
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Implementations of the SAX DocumentHandler interface
|
|
// -----------------------------------------------------------------------
|
|
|
|
void
|
|
SaxPhreeqcHandlers::endDocument()
|
|
{
|
|
}
|
|
|
|
void
|
|
SaxPhreeqcHandlers::endElement(const XMLCh * const uri,
|
|
const XMLCh * const name,
|
|
const XMLCh * const qname)
|
|
{
|
|
switch (this->mapXMLCh2Type[name])
|
|
{
|
|
case typeSOLUTION:
|
|
// solution is finished now copy into solutions array
|
|
{
|
|
int n;
|
|
// copy vector of conc's to solution
|
|
this->solution_ptr->totals =
|
|
(struct conc *) PHRQ_realloc(this->solution_ptr->totals,
|
|
(size_t) (this->totals.size() +
|
|
1) *
|
|
sizeof(struct conc));
|
|
std::copy(this->totals.begin(), this->totals.end(),
|
|
this->solution_ptr->totals);
|
|
this->solution_ptr->totals[this->totals.size()].description =
|
|
NULL;
|
|
this->totals.clear();
|
|
assert(this->totals.size() == 0);
|
|
|
|
// copy vector of master_activities's to solution
|
|
this->solution_ptr->master_activity =
|
|
(struct master_activity *) free_check_null(this->
|
|
solution_ptr->
|
|
master_activity);
|
|
if (this->acts.size() > 0)
|
|
{
|
|
this->solution_ptr->master_activity =
|
|
(struct master_activity *) PHRQ_realloc(this->
|
|
solution_ptr->
|
|
master_activity,
|
|
(size_t) (this->
|
|
acts.
|
|
size())
|
|
*
|
|
sizeof(struct
|
|
master_activity));
|
|
std::copy(this->acts.begin(), this->acts.end(),
|
|
this->solution_ptr->master_activity);
|
|
}
|
|
this->solution_ptr->count_master_activity = this->acts.size();
|
|
this->acts.clear();
|
|
assert(this->acts.size() == 0);
|
|
|
|
// copy vector of s_gamma's to solution
|
|
this->solution_ptr->species_gamma =
|
|
(struct master_activity *) free_check_null(this->
|
|
solution_ptr->
|
|
species_gamma);
|
|
if (this->s_gammas.size() > 0)
|
|
{
|
|
this->solution_ptr->species_gamma =
|
|
(struct master_activity *) PHRQ_realloc(this->
|
|
solution_ptr->
|
|
species_gamma,
|
|
(size_t) (this->
|
|
s_gammas.
|
|
size())
|
|
*
|
|
sizeof(struct
|
|
master_activity));
|
|
std::copy(this->s_gammas.begin(), this->s_gammas.end(),
|
|
this->solution_ptr->species_gamma);
|
|
}
|
|
this->solution_ptr->count_species_gamma = this->s_gammas.size();
|
|
this->s_gammas.clear();
|
|
assert(this->s_gammas.size() == 0);
|
|
|
|
// copy vector of isotopes's to solution
|
|
this->solution_ptr->isotopes =
|
|
(struct isotope *) free_check_null(this->solution_ptr->
|
|
isotopes);
|
|
if (this->isotopes.size() > 0)
|
|
{
|
|
this->solution_ptr->isotopes =
|
|
(struct isotope *) PHRQ_realloc(this->solution_ptr->
|
|
isotopes,
|
|
(size_t) (this->isotopes.
|
|
size()) *
|
|
sizeof(struct isotope));
|
|
std::copy(this->isotopes.begin(), this->isotopes.end(),
|
|
this->solution_ptr->isotopes);
|
|
}
|
|
this->solution_ptr->count_isotopes = this->isotopes.size();
|
|
this->isotopes.clear();
|
|
assert(this->isotopes.size() == 0);
|
|
|
|
|
|
// store solution for now
|
|
if (solution_bsearch(this->solution_ptr->n_user, &n, FALSE) !=
|
|
NULL)
|
|
{
|
|
solution_free(solution[n]);
|
|
solution[n] = this->solution_ptr;
|
|
}
|
|
else
|
|
{
|
|
n = count_solution++;
|
|
if (count_solution >= max_solution)
|
|
{
|
|
space((void **) &(solution), count_solution,
|
|
&max_solution, sizeof(struct solution *));
|
|
}
|
|
solution[n] = this->solution_ptr;
|
|
}
|
|
this->solution_ptr = NULL;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
SaxPhreeqcHandlers::characters(const XMLCh * const chars,
|
|
const unsigned int length)
|
|
{
|
|
// skip whitespace
|
|
|
|
//XMLCh* pChar = (XMLCh*)chars;
|
|
//while(pChar && iswspace(*pChar)) ++pChar;
|
|
//if (*pChar)
|
|
// {
|
|
/*
|
|
switch(this->eltType)
|
|
{
|
|
case typeSOLN_MASTER_ACTIVITY:
|
|
//xns::BaseRefVectorOf<XMLCh> *arg = xns::XMLString::tokenizeString(chars);
|
|
for ( i = 0; i < arg->size() - 1; i+=2 ) {
|
|
struct master_activity *ma = new master_activity();
|
|
ma->description = XMLCh_hsave( arg->elementAt(i), true);
|
|
ma->la = XMLCh2Double( arg->elementAt(i + 1));
|
|
this->acts.push_back(*ma);
|
|
}
|
|
//struct master_activity *ma = new master_activity();
|
|
//ma->description = NULL;
|
|
//this->acts.push_back(*ma);
|
|
break;
|
|
}
|
|
*/
|
|
|
|
}
|
|
|
|
void
|
|
SaxPhreeqcHandlers::ignorableWhitespace(const XMLCh * const chars,
|
|
const unsigned int length)
|
|
{
|
|
}
|
|
|
|
void
|
|
SaxPhreeqcHandlers::processingInstruction(const XMLCh * const target,
|
|
const XMLCh * const data)
|
|
{
|
|
}
|
|
|
|
void
|
|
SaxPhreeqcHandlers::startDocument()
|
|
{
|
|
}
|
|
|
|
void
|
|
SaxPhreeqcHandlers::startElement(const XMLCh * const uri,
|
|
const XMLCh * const name,
|
|
const XMLCh * const qname,
|
|
const xns::Attributes & attributes)
|
|
{
|
|
//const char ERR_MSG[] = "Unpacking solution message: %s, element not found\n";
|
|
char *string;
|
|
|
|
int i;
|
|
|
|
string = xns::XMLString::transcode(name);
|
|
this->eltType = this->mapXMLCh2Type[name];
|
|
xns::XMLString::release(&string);
|
|
switch (this->eltType)
|
|
{
|
|
case typePHAST_STATE:
|
|
XMLCh * x;
|
|
x = xns::XMLString::transcode("nx");
|
|
i = XMLCh2Int(attributes.getValue(x));
|
|
xns::XMLString::release(&x);
|
|
break;
|
|
case typeSOLUTION:
|
|
assert(this->solution_ptr == NULL);
|
|
assert(this->totals.size() == 0);
|
|
assert(this->acts.size() == 0);
|
|
|
|
// allocate space for solution
|
|
this->solution_ptr = solution_alloc();
|
|
|
|
// process attributes for solution
|
|
processSolutionAttributes(attributes);
|
|
break;
|
|
case typeSOLN_PE:
|
|
assert(this->solution_ptr->pe != NULL);
|
|
// store pe, no need to clean up at end of solution
|
|
if ((attributes.getLength() >= 1)
|
|
&& (this->mapXMLCh2AttType[attributes.getLocalName(0)] ==
|
|
attSOLN_PE_name))
|
|
{
|
|
string =
|
|
xns::XMLString::transcode(attributes.
|
|
getValue((unsigned int) 0));
|
|
pe_data_store(&(this->solution_ptr->pe), string);
|
|
xns::XMLString::release(&string);
|
|
}
|
|
else
|
|
{
|
|
++input_error;
|
|
sprintf(error_string, "No attribute data for SOLN_PE.\n");
|
|
error_msg(error_string, CONTINUE);
|
|
}
|
|
break;
|
|
case typeSOLN_TOTAL:
|
|
{
|
|
// store in c, push_back on totals
|
|
// need to copy and clean up at end of </solution>
|
|
struct conc c;
|
|
processSolutionTotalAttributes(attributes, &c);
|
|
this->totals.push_back(c);
|
|
}
|
|
break;
|
|
case typeSOLN_MASTER_ACTIVITY:
|
|
{
|
|
// store in ma, push_back on acts
|
|
// need to copy and clean up at end of </solution>
|
|
struct master_activity ma;
|
|
processMasterActivityAttributes(attributes, &ma);
|
|
this->acts.push_back(ma);
|
|
//processMasterActivityAttributes(attributes, &this->acts);
|
|
}
|
|
break;
|
|
case typeSOLN_SPECIES_GAMMA:
|
|
{
|
|
// store in ma, push_back on s_gammas
|
|
// need to copy and clean up at end of </solution>
|
|
struct master_activity ma;
|
|
processMasterActivityAttributes(attributes, &ma);
|
|
this->s_gammas.push_back(ma);
|
|
}
|
|
break;
|
|
case typeSOLN_ISOTOPE:
|
|
{
|
|
// store in iso, push_back on isotopes
|
|
// need to copy and clean up at end of </solution>
|
|
struct isotope iso;
|
|
processIsotopeAttributes(attributes, &iso);
|
|
this->isotopes.push_back(iso);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
int
|
|
SaxPhreeqcHandlers::processSolutionAttributes(const xns::
|
|
Attributes & attributes)
|
|
{
|
|
const char ERR_MSG[] =
|
|
"Unpacking solution attributes: %s, attribute not found\n";
|
|
unsigned int i;
|
|
char *string;
|
|
attributeType attType;
|
|
assert(this->eltType == typeSOLUTION);
|
|
assert(this->solution_ptr != NULL);
|
|
|
|
// Get attribute name, map to attribute type, process
|
|
|
|
for (i = 0; i < attributes.getLength(); i++)
|
|
{
|
|
attType = this->mapXMLCh2AttType[attributes.getLocalName(i)];
|
|
switch (attType)
|
|
{
|
|
case attSOLN_new_def:
|
|
this->solution_ptr->new_def = XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_n_user:
|
|
this->solution_ptr->n_user = XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_n_user_end:
|
|
this->solution_ptr->n_user_end =
|
|
XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_description:
|
|
this->solution_ptr->description =
|
|
XMLCh2String(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_tc:
|
|
this->solution_ptr->tc = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_ph:
|
|
this->solution_ptr->ph = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_solution_pe:
|
|
this->solution_ptr->solution_pe =
|
|
XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_mu:
|
|
this->solution_ptr->mu = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_ah2o:
|
|
this->solution_ptr->ah2o = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_density:
|
|
this->solution_ptr->density =
|
|
XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_total_h:
|
|
this->solution_ptr->total_h =
|
|
XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_total_o:
|
|
this->solution_ptr->total_o =
|
|
XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_cb:
|
|
this->solution_ptr->cb = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_mass_water:
|
|
this->solution_ptr->mass_water =
|
|
XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_total_alkalinity:
|
|
this->solution_ptr->total_alkalinity =
|
|
XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
//case attSOLN_total_co2:
|
|
//this->solution_ptr->total_co2 = XMLCh2Double(attributes.getValue(i));
|
|
//break;
|
|
case attSOLN_units:
|
|
this->solution_ptr->units =
|
|
XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attSOLN_default_pe:
|
|
this->solution_ptr->default_pe =
|
|
XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_count_master_activity:
|
|
this->solution_ptr->count_master_activity =
|
|
XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_count_isotopes:
|
|
this->solution_ptr->count_isotopes =
|
|
XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attSOLN_count_species_gamma:
|
|
this->solution_ptr->count_species_gamma =
|
|
XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
default:
|
|
++input_error;
|
|
string = xns::XMLString::transcode(attributes.getLocalName(i));
|
|
sprintf(error_string, ERR_MSG, string);
|
|
error_msg(error_string, CONTINUE);
|
|
xns::XMLString::release(&string);
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
SaxPhreeqcHandlers::processSolutionTotalAttributes(const xns::
|
|
Attributes & attributes,
|
|
struct conc *c)
|
|
{
|
|
const char ERR_MSG[] =
|
|
"Unpacking solution totals attributes: %s, attribute not found\n";
|
|
unsigned int i;
|
|
char *string;
|
|
conc_init(c);
|
|
attributeType attType;
|
|
assert(this->eltType == typeSOLN_TOTAL);
|
|
|
|
|
|
// Get attribute name, map to attribute type, process
|
|
|
|
for (i = 0; i < attributes.getLength(); i++)
|
|
{
|
|
attType = this->mapXMLCh2AttType[attributes.getLocalName(i)];
|
|
switch (attType)
|
|
{
|
|
case attCONC_description:
|
|
c->description = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attCONC_moles:
|
|
c->moles = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attCONC_input_conc:
|
|
c->input_conc = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attCONC_units:
|
|
c->units = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attCONC_equation_name:
|
|
c->equation_name = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
c->phase = NULL;
|
|
break;
|
|
case attCONC_phase_si:
|
|
c->phase_si = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attCONC_n_pe:
|
|
c->n_pe = XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attCONC_as:
|
|
c->as = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attCONC_gfw:
|
|
c->gfw = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
|
|
default:
|
|
++input_error;
|
|
string = xns::XMLString::transcode(attributes.getLocalName(i));
|
|
sprintf(error_string, ERR_MSG, string);
|
|
error_msg(error_string, CONTINUE);
|
|
xns::XMLString::release(&string);
|
|
break;
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|
|
|
|
int
|
|
SaxPhreeqcHandlers::processMasterActivityAttributes(const xns::
|
|
Attributes & attributes,
|
|
struct master_activity
|
|
*ma)
|
|
//int SaxPhreeqcHandlers::processMasterActivityAttributes(const xns::Attributes& attributes, std::vector<struct master_activity> *v)
|
|
{
|
|
int i;
|
|
char *string;
|
|
const char ERR_MSG[] =
|
|
"Unpacking master activity attributes: %s, attribute not found\n";
|
|
ma->description = NULL;
|
|
ma->la = 0.0;
|
|
attributeType attType;
|
|
for (i = 0; i < (int) attributes.getLength(); i++)
|
|
{
|
|
attType = this->mapXMLCh2AttType[attributes.getLocalName(i)];
|
|
|
|
switch (attType)
|
|
{
|
|
|
|
case attM_A_description:
|
|
ma->description = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attM_A_la:
|
|
ma->la = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
/*
|
|
case attM_A_list:
|
|
{
|
|
struct master_activity ma;
|
|
xns::BaseRefVectorOf<XMLCh> *arg = xns::XMLString::tokenizeString(attributes.getValue((unsigned int) 0));
|
|
|
|
for ( i = 0; i < arg->size(); i+=2 ) {
|
|
ma.description = XMLCh_hsave( arg->elementAt(i), TRUE);
|
|
if (strcmp(ma.description, "null") == 0) {
|
|
ma.description = NULL;
|
|
}
|
|
ma.la = XMLCh2Double( arg->elementAt(i+1));
|
|
//this->acts.push_back(ma);
|
|
(*v).push_back(ma);
|
|
}
|
|
}
|
|
break;
|
|
*/
|
|
default:
|
|
++input_error;
|
|
string = xns::XMLString::transcode(attributes.getLocalName(i));
|
|
sprintf(error_string, ERR_MSG, string);
|
|
error_msg(error_string, CONTINUE);
|
|
xns::XMLString::release(&string);
|
|
break;
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|
|
|
|
int
|
|
SaxPhreeqcHandlers::processIsotopeAttributes(const xns::
|
|
Attributes & attributes,
|
|
struct isotope *iso)
|
|
{
|
|
int i;
|
|
char *string;
|
|
const char ERR_MSG[] =
|
|
"Unpacking isotope attributes: %s, attribute not found\n";
|
|
|
|
iso->primary = iso->master = NULL;
|
|
iso->elt_name = iso->isotope_name = NULL;
|
|
attributeType attType;
|
|
for (i = 0; i < (int) attributes.getLength(); i++)
|
|
{
|
|
attType = this->mapXMLCh2AttType[attributes.getLocalName(i)];
|
|
switch (attType)
|
|
{
|
|
case attISO_isotope_number:
|
|
iso->isotope_number = XMLCh2Int(attributes.getValue(i));
|
|
break;
|
|
case attISO_elt_name:
|
|
iso->elt_name = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attISO_isotope_name:
|
|
iso->isotope_name = XMLCh_hsave(attributes.getValue(i), TRUE);
|
|
break;
|
|
case attISO_total:
|
|
iso->total = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attISO_ratio:
|
|
iso->ratio = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attISO_ratio_uncertainty:
|
|
iso->ratio_uncertainty = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
case attISO_coef:
|
|
iso->coef = XMLCh2Double(attributes.getValue(i));
|
|
break;
|
|
|
|
default:
|
|
++input_error;
|
|
string = xns::XMLString::transcode(attributes.getLocalName(i));
|
|
sprintf(error_string, ERR_MSG, string);
|
|
error_msg(error_string, CONTINUE);
|
|
xns::XMLString::release(&string);
|
|
break;
|
|
}
|
|
}
|
|
return (OK);
|
|
}
|