diff --git a/SelectedOutput.cpp b/CSelectedOutput.cpp similarity index 98% rename from SelectedOutput.cpp rename to CSelectedOutput.cpp index 0da49140..95ab2aed 100644 --- a/SelectedOutput.cpp +++ b/CSelectedOutput.cpp @@ -13,7 +13,7 @@ #include #include "Debug.h" // ASSERT -#include "SelectedOutput.hxx" // CSelectedOutput +#include "CSelectedOutput.hxx" // CSelectedOutput const size_t RESERVE_ROWS = 80; const size_t RESERVE_COLS = 80; diff --git a/SelectedOutput.hxx b/CSelectedOutput.hxx similarity index 100% rename from SelectedOutput.hxx rename to CSelectedOutput.hxx diff --git a/IPhreeqc.cpp b/IPhreeqc.cpp index 9c26dc46..6c14abb4 100644 --- a/IPhreeqc.cpp +++ b/IPhreeqc.cpp @@ -1,25 +1,29 @@ -#include // auto_ptr +#include // auto_ptr +#include #include -#include "IPhreeqc.hpp" // IPhreeqc -#include "Phreeqc.h" // Phreeqc +#include "IPhreeqc.hpp" // IPhreeqc +#include "Phreeqc.h" // Phreeqc #include "thread.h" -#include "Debug.h" // ASSERT -#include "ErrorReporter.hxx" // CErrorReporter -#include "SelectedOutput.hxx" // CSelectedOutput -#include "dumper.h" // dumper +#include "Debug.h" // ASSERT +#include "ErrorReporter.hxx" // CErrorReporter +#include "CSelectedOutput.hxx" // CSelectedOutput +#include "phreeqcpp/SelectedOutput.h" // SelectedOutput +#include "dumper.h" // dumper const char OUTPUT_FILENAME_FORMAT[] = "phreeqc.%d.out"; const char ERROR_FILENAME_FORMAT[] = "phreeqc.%d.err"; const char LOG_FILENAME_FORMAT[] = "phreeqc.%d.log"; -const char PUNCH_FILENAME_FORMAT[] = "selected.%d.out"; +const char PUNCH_FILENAME_FORMAT[] = "selected_%d.%d.out"; const char DUMP_FILENAME_FORMAT[] = "dump.%d.out"; // statics std::map IPhreeqc::Instances; size_t IPhreeqc::InstancesIndex = 0; +static const char empty[] = ""; + IPhreeqc::IPhreeqc(void) : DatabaseLoaded(false) @@ -37,7 +41,7 @@ IPhreeqc::IPhreeqc(void) , ErrorReporter(0) , WarningStringOn(true) , WarningReporter(0) -, SelectedOutput(0) +, CurrentSelectedOutputUserNumber(1) , SelectedOutputStringOn(false) , PhreeqcPtr(0) , input_file(0) @@ -47,7 +51,6 @@ IPhreeqc::IPhreeqc(void) this->ErrorReporter = new CErrorReporter; this->WarningReporter = new CErrorReporter; - this->SelectedOutput = new CSelectedOutput(); this->PhreeqcPtr = new Phreeqc(this); ASSERT(this->PhreeqcPtr->phast == 0); @@ -59,8 +62,7 @@ IPhreeqc::IPhreeqc(void) std::pair::iterator, bool> pr = IPhreeqc::Instances.insert(instance); mutex_unlock(&map_lock); - ::sprintf(buffer, PUNCH_FILENAME_FORMAT, this->Index); - this->SelectedOutputFileName = buffer; + this->SelectedOutputFileNameMap[1] = this->sel_file_name(1); ::sprintf(buffer, OUTPUT_FILENAME_FORMAT, this->Index); this->OutputFileName = buffer; @@ -82,10 +84,17 @@ IPhreeqc::~IPhreeqc(void) this->OutputFileOn = false; #endif delete this->PhreeqcPtr; - delete this->SelectedOutput; delete this->WarningReporter; delete this->ErrorReporter; + std::map< int, CSelectedOutput* >::iterator sit = this->SelectedOutputMap.begin(); + for (; sit != this->SelectedOutputMap.end(); ++sit) + { + delete (*sit).second; + } + this->SelectedOutputMap.clear(); + this->CurrentSelectedOutputMap.clear(); + mutex_lock(&map_lock); std::map::iterator it = IPhreeqc::Instances.find(this->Index); if (it != IPhreeqc::Instances.end()) @@ -328,12 +337,23 @@ bool IPhreeqc::GetOutputStringOn(void)const int IPhreeqc::GetSelectedOutputColumnCount(void)const { - return (int)this->SelectedOutput->GetColCount(); + std::map< int, CSelectedOutput* >::const_iterator ci = this->SelectedOutputMap.find(this->CurrentSelectedOutputUserNumber); + if (ci != this->SelectedOutputMap.end()) + { + return (int)(*ci).second->GetColCount(); + } + return 0; } const char* IPhreeqc::GetSelectedOutputFileName(void)const { - return this->SelectedOutputFileName.c_str(); + static const char empty[] = ""; + std::map< int, std::string >::const_iterator ci = this->SelectedOutputFileNameMap.find(this->CurrentSelectedOutputUserNumber); + if (ci != this->SelectedOutputFileNameMap.end()) + { + return (*ci).second.c_str(); + } + return empty; } bool IPhreeqc::GetSelectedOutputFileOn(void)const @@ -343,7 +363,12 @@ bool IPhreeqc::GetSelectedOutputFileOn(void)const int IPhreeqc::GetSelectedOutputRowCount(void)const { - return (int)this->SelectedOutput->GetRowCount(); + std::map< int, CSelectedOutput* >::const_iterator ci = this->SelectedOutputMap.find(this->CurrentSelectedOutputUserNumber); + if (ci != this->SelectedOutputMap.end()) + { + return (int)(*ci).second->GetRowCount(); + } + return 0; } const char* IPhreeqc::GetSelectedOutputString(void)const @@ -353,7 +378,12 @@ const char* IPhreeqc::GetSelectedOutputString(void)const { return err_msg; } - return this->SelectedOutputString.c_str(); + std::map< int, std::string >::const_iterator cit = this->SelectedOutputStringMap.find(this->CurrentSelectedOutputUserNumber); + if (cit != this->SelectedOutputStringMap.end()) + { + return (*cit).second.c_str(); + } + return empty; } const char* IPhreeqc::GetSelectedOutputStringLine(int n) @@ -363,12 +393,17 @@ const char* IPhreeqc::GetSelectedOutputStringLine(int n) { return empty; } - return this->SelectedOutputLines[n].c_str(); + return this->SelectedOutputLinesMap[this->CurrentSelectedOutputUserNumber][n].c_str(); } int IPhreeqc::GetSelectedOutputStringLineCount(void)const { - return (int)this->SelectedOutputLines.size(); + std::map< int, std::vector < std::string > >::const_iterator cit = this->SelectedOutputLinesMap.find(this->CurrentSelectedOutputUserNumber); + if (cit != this->SelectedOutputLinesMap.end()) + { + return (*cit).second.size(); + } + return (int)0; } bool IPhreeqc::GetSelectedOutputStringOn(void)const @@ -386,7 +421,7 @@ VRESULT IPhreeqc::GetSelectedOutputValue(int row, int col, VAR* pVAR) return VR_INVALIDARG; } - VRESULT v = this->SelectedOutput->Get(row, col, pVAR); + VRESULT v = this->SelectedOutputMap[this->CurrentSelectedOutputUserNumber]->Get(row, col, pVAR); switch (v) { case VR_OK: @@ -494,7 +529,13 @@ int IPhreeqc::LoadDatabase(const char* filename) // cleanup // this->UnLoadDatabase(); - this->SelectedOutput->Clear(); + std::map< int, CSelectedOutput* >::iterator it = this->SelectedOutputMap.begin(); + for (; it != this->SelectedOutputMap.end(); ++it) + { + delete (*it).second; + } + this->SelectedOutputMap.clear(); + this->CurrentSelectedOutputMap.clear(); // open file // @@ -543,8 +584,13 @@ int IPhreeqc::LoadDatabaseString(const char* input) // cleanup // this->UnLoadDatabase(); - - this->SelectedOutput->Clear(); + std::map< int, CSelectedOutput* >::iterator it = this->SelectedOutputMap.begin(); + for (; it != this->SelectedOutputMap.end(); ++it) + { + delete (*it).second; + } + this->SelectedOutputMap.clear(); + this->CurrentSelectedOutputMap.clear(); std::string s(input); std::istringstream iss(s); @@ -738,6 +784,11 @@ void IPhreeqc::SetBasicFortranCallback(double (*fcn)(double *x1, double *x2, cha this->PhreeqcPtr->register_fortran_basic_callback(fcn); } +void IPhreeqc::SetCurrentSelectedOutputUserNumber(int n) +{ + this->CurrentSelectedOutputUserNumber = n; +} + void IPhreeqc::SetDumpFileName(const char *filename) { if (filename && ::strlen(filename)) @@ -815,7 +866,9 @@ void IPhreeqc::SetSelectedOutputFileName(const char *filename) { if (filename && ::strlen(filename)) { - this->SelectedOutputFileName = filename; + // Can't use this->PhreeqcPtr->SelectedOutput_map since it's necessary + // to override the default filename "selected_output_%d.%d.sel" + this->SelectedOutputFileNameMap[1] = std::string(filename); } } @@ -851,10 +904,25 @@ void IPhreeqc::UnLoadDatabase(void) // clear selectedoutput // - ASSERT(this->SelectedOutput); - this->SelectedOutput->Clear(); - this->SelectedOutputString.clear(); - this->SelectedOutputLines.clear(); + std::map< int, CSelectedOutput* >::iterator itt = this->SelectedOutputMap.begin(); + for (; itt != this->SelectedOutputMap.end(); ++itt) + { + delete (*itt).second; + } + this->SelectedOutputMap.clear(); + this->CurrentSelectedOutputMap.clear(); + + std::map< int, std::string >::iterator mit = this->SelectedOutputStringMap.begin(); + for (; mit != this->SelectedOutputStringMap.begin(); ++mit) + { + (*mit).second.clear(); + } + std::map< int, std::vector< std::string > >::iterator it = this->SelectedOutputLinesMap.begin(); + for (; it != this->SelectedOutputLinesMap.begin(); ++it) + { + (*it).second.clear(); + } + // clear dump string // @@ -872,22 +940,52 @@ void IPhreeqc::UnLoadDatabase(void) int IPhreeqc::EndRow(void) { - if (this->SelectedOutput->GetRowCount() <= 1) + if (this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->GetRowCount() <= 1) { // ensure all user_punch headings are included ASSERT(this->PhreeqcPtr->n_user_punch_index >= 0); - for (int i = this->PhreeqcPtr->n_user_punch_index; i < this->PhreeqcPtr->user_punch_count_headings; ++i) + if (this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output] != NULL) { - this->SelectedOutput->PushBackEmpty(this->PhreeqcPtr->user_punch_headings[i]); + if (this->PhreeqcPtr->current_user_punch) + { + for (size_t i = this->PhreeqcPtr->n_user_punch_index; i < this->PhreeqcPtr->current_user_punch->Get_headings().size(); ++i) + { + this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackEmpty(this->PhreeqcPtr->current_user_punch->Get_headings()[i].c_str()); + } + } } } - return this->SelectedOutput->EndRow(); + return this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->EndRow(); } void IPhreeqc::check_database(const char* sz_routine) { this->ErrorReporter->Clear(); - this->SelectedOutput->Clear(); + + std::map< int, CSelectedOutput* >::iterator it = this->SelectedOutputMap.begin(); + for (; it != this->SelectedOutputMap.end(); ++it) + { + delete (*it).second; + } + this->SelectedOutputMap.clear(); + this->CurrentSelectedOutputMap.clear(); + + // release + this->LogString.clear(); + this->LogLines.clear(); + this->OutputString.clear(); + this->OutputLines.clear(); + + std::map< int, std::string >::iterator mit = SelectedOutputStringMap.begin(); + for (; mit != SelectedOutputStringMap.begin(); ++mit) + { + (*mit).second.clear(); + } + std::map< int, std::vector< std::string > >::iterator lit = this->SelectedOutputLinesMap.begin(); + for (; lit != this->SelectedOutputLinesMap.begin(); ++lit) + { + (*lit).second.clear(); + } if (!this->DatabaseLoaded) { @@ -910,14 +1008,6 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL pfn_pre(cookie); } - // release - this->LogString.clear(); - this->LogLines.clear(); - this->OutputString.clear(); - this->OutputLines.clear(); - this->SelectedOutputString.clear(); - this->SelectedOutputLines.clear(); - /* * set read callback */ @@ -945,18 +1035,43 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL #endif ::sprintf(token, "Reading input data for simulation %d.", this->PhreeqcPtr->simulation); - int save_punch_in = this->PhreeqcPtr->punch.in; + bool save_punch_in = this->PhreeqcPtr->SelectedOutput_map.size() > 0; this->PhreeqcPtr->dup_print(token, TRUE); if (this->PhreeqcPtr->read_input() == EOF) break; - if (this->PhreeqcPtr->simulation > 1 && save_punch_in == TRUE && this->PhreeqcPtr->punch.new_def == TRUE) + bool bWarning = false; + std::map< int, SelectedOutput >::iterator mit = this->PhreeqcPtr->SelectedOutput_map.begin(); + for (; mit != this->PhreeqcPtr->SelectedOutput_map.end(); ++mit) { - std::ostringstream oss; - oss << sz_routine << ": Warning SELECTED_OUTPUT has been redefined.\n"; - this->PhreeqcPtr->warning_msg(oss.str().c_str()); + if (this->CurrentSelectedOutputMap.find(&(*mit).second) == this->CurrentSelectedOutputMap.end()) + { + // int -> CSelectedOutput* + std::map< int, CSelectedOutput* >::value_type item((*mit).first, new CSelectedOutput()); + this->SelectedOutputMap.insert(item); + // SelectedOutput* -> CSelectedOutput* + this->CurrentSelectedOutputMap.insert( + std::map< SelectedOutput*, CSelectedOutput* >::value_type( + &(*mit).second, item.second)); + + // SelectedOutput* -> std::string* + this->CurrentToStringMap.insert( + std::map< SelectedOutput*, std::string* >::value_type( + &(*mit).second, &this->SelectedOutputStringMap[(*mit).first])); + } + else + { + ASSERT(this->SelectedOutputMap[(*mit).first] == this->CurrentSelectedOutputMap[&(*mit).second]); + } + if (this->PhreeqcPtr->simulation > 1 && save_punch_in && (*mit).second.Get_new_def() && !bWarning) + { + std::ostringstream oss; + oss << sz_routine << ": Warning SELECTED_OUTPUT has been redefined.\n"; + this->PhreeqcPtr->warning_msg(oss.str().c_str()); + bWarning = true; + } } if (this->PhreeqcPtr->simulation > 1 && this->PhreeqcPtr->keycount[Keywords::KEY_USER_PUNCH] > 0) { @@ -977,7 +1092,7 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL } #ifdef SWIG_SHARED_OBJ - if (this->PhreeqcPtr->punch.in == TRUE) + if (this->PhreeqcPtr->SelectedOutput_map.size() > 0) { // // (punch.in == TRUE) when any "RUN" has contained @@ -997,7 +1112,15 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL // if (!this->SelectedOutputFileOn) { - ASSERT(!this->punch_ostream); + std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin(); + for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it) + { + ASSERT((*it).second.Get_punch_ostream() == 0); + } + } + else + { + ASSERT(TRUE); } if (this->PhreeqcPtr->pr.punch == FALSE) @@ -1007,20 +1130,24 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL // PRINT; -selected_output false // is given as input // Note: this also disables the CSelectedOutput object + ASSERT(TRUE); } else { - if (this->PhreeqcPtr->punch.new_def == FALSE) + std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin(); + for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it) { - if (this->SelectedOutputFileOn && !this->punch_ostream) + if (this->SelectedOutputFileOn && !(*it).second.Get_punch_ostream()) { // // LoadDatabase // do_run -- containing SELECTED_OUTPUT ****TODO**** check -file option // another do_run without SELECTED_OUTPUT // - std::string filename = this->SelectedOutputFileName; - if (!this->punch_open(filename.c_str())) + ASSERT(!this->SelectedOutputFileNameMap[(*it).first].empty()); + ASSERT(this->SelectedOutputFileNameMap[(*it).first] == this->PhreeqcPtr->SelectedOutput_map[(*it).first].Get_file_name()); + std::string filename = this->SelectedOutputFileNameMap[(*it).first]; + if (!punch_open(filename.c_str(), std::ios_base::out, (*it).first)) { std::ostringstream oss; oss << sz_routine << ": Unable to open:" << "\"" << filename << "\".\n"; @@ -1028,42 +1155,39 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL } else { + ASSERT(this->Get_punch_ostream() != NULL); + ASSERT((*it).second.Get_punch_ostream() == NULL); + + int n_user = (*it).first; + this->PhreeqcPtr->SelectedOutput_map[n_user].Set_punch_ostream(this->Get_punch_ostream()); + this->Set_punch_ostream(NULL); + // output selected_output headings - this->PhreeqcPtr->punch.new_def = TRUE; - this->PhreeqcPtr->tidy_punch(); - } - } - } - else - { - if (this->SelectedOutputFileOn && !this->punch_ostream) - { - // This is a special case which could not occur in - // phreeqc - // - // LoadDatabase - // do_run -- containing SELECTED_OUTPUT ****TODO**** check -file option - // another do_run with SELECTED_OUTPUT - // - std::string filename = this->SelectedOutputFileName; - if (!this->punch_open(filename.c_str())) - { - std::ostringstream oss; - oss << sz_routine << ": Unable to open:" << "\"" << filename << "\".\n"; - this->PhreeqcPtr->warning_msg(oss.str().c_str()); - } - else - { - // output selected_output headings - ASSERT(this->PhreeqcPtr->punch.new_def == TRUE); + (*it).second.Set_new_def(TRUE); this->PhreeqcPtr->tidy_punch(); } } } } } + else + { + ASSERT(TRUE); + } + - if (!this->SelectedOutputFileOn) ASSERT(!this->punch_ostream); + std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin(); + for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it) + { + if (this->SelectedOutputFileOn) + { + ASSERT((*it).second.Get_punch_ostream()); + } + else + { + ASSERT(!(*it).second.Get_punch_ostream()); + } + } // Consider this addition { @@ -1230,12 +1354,16 @@ void IPhreeqc::do_run(const char* sz_routine, std::istream* pis, PFN_PRERUN_CALL if (this->SelectedOutputStringOn) { - // output lines - std::istringstream iss(this->SelectedOutputString); - std::string line; - while (std::getline(iss, line)) + std::map< int, std::string >::iterator mit = this->SelectedOutputStringMap.begin(); + for (; mit != this->SelectedOutputStringMap.end(); ++mit) { - this->SelectedOutputLines.push_back(line); + // output lines + std::istringstream iss((*mit).second); + std::string line; + while (std::getline(iss, line)) + { + this->SelectedOutputLinesMap[(*mit).first].push_back(line); + } } } } @@ -1273,13 +1401,13 @@ void IPhreeqc::log_msg(const char * str) { this->LogString += str; } - ASSERT(!(this->LogFileOn ^ (this->log_ostream != 0))); + ASSERT(!(this->LogFileOn != (this->log_ostream != 0))); this->PHRQ_io::log_msg(str); } void IPhreeqc::error_msg(const char *str, bool stop) { - ASSERT(!(this->ErrorFileOn ^ (this->error_ostream != 0))); + ASSERT(!(this->ErrorFileOn != (this->error_ostream != 0))); if (this->error_ostream != NULL && this->error_on) { @@ -1307,7 +1435,7 @@ void IPhreeqc::error_msg(const char *str, bool stop) void IPhreeqc::warning_msg(const char *str) { - ASSERT(!(this->ErrorFileOn ^ (this->error_ostream != 0))); + ASSERT(!(this->ErrorFileOn != (this->error_ostream != 0))); if (this->error_ostream != NULL && this->error_on) { @@ -1332,7 +1460,7 @@ void IPhreeqc::output_msg(const char * str) { this->OutputString += str; } - ASSERT(!(this->OutputFileOn ^ (this->output_ostream != 0))); + ASSERT(!(this->OutputFileOn != (this->output_ostream != 0))); this->PHRQ_io::output_msg(str); } @@ -1345,9 +1473,9 @@ void IPhreeqc::punch_msg(const char *str) { if (this->SelectedOutputStringOn && this->punch_on) { - this->SelectedOutputString += str; + *(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output]) += str; } - ASSERT(!(this->SelectedOutputFileOn ^ (this->punch_ostream != 0))); + ASSERT(!(this->SelectedOutputFileOn != (this->PhreeqcPtr->current_selected_output->Get_punch_ostream() != 0))); this->PHRQ_io::punch_msg(str); } @@ -1418,10 +1546,16 @@ int IPhreeqc::close_output_files(void) delete this->output_ostream; delete this->log_ostream; - delete this->punch_ostream; delete this->dump_ostream; delete this->error_ostream; + std::map< int, SelectedOutput >::iterator it = this->PhreeqcPtr->SelectedOutput_map.begin(); + for (; it != this->PhreeqcPtr->SelectedOutput_map.end(); ++it) + { + delete (*it).second.Get_punch_ostream(); + (*it).second.Set_punch_ostream(NULL); + } + this->error_ostream = 0; this->output_ostream = 0; this->log_ostream = 0; @@ -1438,9 +1572,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, double d) this->PHRQ_io::fpunchf(name, format, d); if (this->SelectedOutputStringOn && this->punch_on) { - PHRQ_io::fpunchf_helper(&this->SelectedOutputString, format, d); + PHRQ_io::fpunchf_helper(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output], format, d); } - this->SelectedOutput->PushBackDouble(name, d); + this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackDouble(name, d); } catch (std::bad_alloc) { @@ -1455,9 +1589,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, char *s) this->PHRQ_io::fpunchf(name, format, s); if (this->SelectedOutputStringOn && this->punch_on) { - PHRQ_io::fpunchf_helper(&this->SelectedOutputString, format, s); + PHRQ_io::fpunchf_helper(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output], format, s); } - this->SelectedOutput->PushBackString(name, s); + this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackString(name, s); } catch (std::bad_alloc) { @@ -1472,9 +1606,9 @@ void IPhreeqc::fpunchf(const char *name, const char *format, int i) this->PHRQ_io::fpunchf(name, format, i); if (this->SelectedOutputStringOn && this->punch_on) { - PHRQ_io::fpunchf_helper(&this->SelectedOutputString, format, i); + PHRQ_io::fpunchf_helper(this->CurrentToStringMap[this->PhreeqcPtr->current_selected_output], format, i); } - this->SelectedOutput->PushBackLong(name, (long)i); + this->CurrentSelectedOutputMap[this->PhreeqcPtr->current_selected_output]->PushBackLong(name, (long)i); } catch (std::bad_alloc) { @@ -1487,15 +1621,22 @@ void IPhreeqc::fpunchf_end_row(const char *format) this->EndRow(); } -bool IPhreeqc::punch_open(const char *file_name, std::ios_base::openmode mode) +bool IPhreeqc::punch_open(const char *file_name, std::ios_base::openmode mode, int n_user) { - if (file_name && this->PhreeqcPtr->have_punch_name) + if (this->PhreeqcPtr->SelectedOutput_map[n_user].Get_have_punch_name() && + !this->PhreeqcPtr->SelectedOutput_map[n_user].Get_file_name().empty()) { - this->SelectedOutputFileName = file_name; + this->SelectedOutputFileNameMap[n_user] = this->PhreeqcPtr->SelectedOutput_map[n_user].Get_file_name(); + } + else if (this->SelectedOutputFileNameMap[n_user].empty()) + { + this->SelectedOutputFileNameMap[n_user] = this->sel_file_name(n_user); } if (this->SelectedOutputFileOn) { - return this->PHRQ_io::punch_open(this->SelectedOutputFileName.c_str(), mode); + ASSERT(!this->SelectedOutputFileNameMap[n_user].empty()); + this->PhreeqcPtr->SelectedOutput_map[n_user].Set_file_name(this->SelectedOutputFileNameMap[n_user]); + return this->ofstream_open(&punch_ostream, this->SelectedOutputFileNameMap[n_user].c_str(), mode); } return true; } @@ -1508,3 +1649,10 @@ bool IPhreeqc::output_open(const char *file_name, std::ios_base::openmode mode) } return true; } + +std::string IPhreeqc::sel_file_name(int n_user) +{ + char buffer[80]; + ::sprintf(buffer, PUNCH_FILENAME_FORMAT, n_user, this->Index); + return std::string(buffer); +} diff --git a/IPhreeqc.hpp b/IPhreeqc.hpp index fcdc4d55..da0f48c1 100644 --- a/IPhreeqc.hpp +++ b/IPhreeqc.hpp @@ -23,6 +23,7 @@ class Phreeqc; class IErrorReporter; class CSelectedOutput; +class SelectedOutput; /** * @class IPhreeqcStop @@ -325,7 +326,7 @@ public: /** * Retrieves the number of columns in the selected-output buffer. * @return The number of columns. - * @see GetSelectedOutputRowCount, GetSelectedOutputValue + * @see GetSelectedOutputRowCount, GetSelectedOutputValue, SetCurrentSelectedOutputUserNumber */ int GetSelectedOutputColumnCount(void)const; @@ -334,7 +335,7 @@ public: * Retrieves the name of the selected output file. This file name is used if not specified within SELECTED_OUTPUT input. * The default value is selected.id.out, where id is obtained from \ref GetId. * @return filename The name of the file to write to. - * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringOn, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, SetSelectedOutputFileName, SetSelectedOutputFileOn, SetSelectedOutputStringOn + * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringOn, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileName, SetSelectedOutputFileOn, SetSelectedOutputStringOn */ const char* GetSelectedOutputFileName(void)const; @@ -349,7 +350,7 @@ public: /** * Retrieves the number of rows in the selected-output buffer. * @return The number of rows. - * @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputValue, SetSelectedOutputFileOn + * @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputValue, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn */ int GetSelectedOutputRowCount(void)const; @@ -358,7 +359,7 @@ public: * @return A null terminated string containing SELECTED_OUTPUT. * @pre * \ref SetSelectedOutputStringOn must have been set to true in order to receive SELECTED_OUTPUT. - * @see GetSelectedOutputStringLine, GetSelectedOutputFileOn, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, SetSelectedOutputFileOn, SetSelectedOutputStringOn + * @see GetSelectedOutputStringLine, GetSelectedOutputFileOn, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, GetSelectedOutputString, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn, SetSelectedOutputStringOn */ const char* GetSelectedOutputString(void)const; @@ -368,7 +369,7 @@ public: * @return A null terminated string containing the given line. * Returns an empty string if n is out of range. * @pre \ref SetSelectedOutputStringOn must have been set to true. - * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, SetSelectedOutputFileOn, SetSelectedOutputStringOn + * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLineCount, GetSelectedOutputStringOn, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn, SetSelectedOutputStringOn */ const char* GetSelectedOutputStringLine(int n); @@ -376,7 +377,7 @@ public: * Retrieves the number of lines in the current selected output string buffer. * @return The number of lines. * @pre \ref SetSelectedOutputStringOn must have been set to true. - * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLine, GetSelectedOutputStringOn, SetSelectedOutputFileOn, SetSelectedOutputStringOn + * @see GetSelectedOutputFileOn, GetSelectedOutputString, GetSelectedOutputStringLine, GetSelectedOutputStringOn, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn, SetSelectedOutputStringOn */ int GetSelectedOutputStringLineCount(void)const; @@ -398,7 +399,7 @@ public: * @retval VR_INVALIDCOL The given column is out of range. * @retval VR_OUTOFMEMORY Memory could not be allocated. * @retval VR_BADINSTANCE The given id is invalid. - * @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputRowCount, GetSelectedOutputValue2, SetSelectedOutputFileOn + * @see GetSelectedOutputColumnCount, GetSelectedOutputFileOn, GetSelectedOutputRowCount, GetSelectedOutputValue2, SetCurrentSelectedOutputUserNumber, SetSelectedOutputFileOn * @remarks * Row 0 contains the column headings to the selected_ouput. * @par Examples: @@ -811,6 +812,16 @@ public: void SetSelectedOutputStringOn(bool bValue); + /** + * Sets the given user number for use in subsequent calls to GetSelectedOutputXXX routines. + * The initial setting is 1. + * @param n The user number as specified in the SELECTED_OUTPUT block. + * @see GetSelectedOutputColumnCount, GetSelectedOutputFileName, GetSelectedOutputRowCount, GetSelectedOutputString, GetSelectedOutputStringLine, GetSelectedOutputStringLineCount, GetSelectedOutputValue + */ + void SetCurrentSelectedOutputUserNumber(int n); + + + public: // overrides virtual void error_msg(const char *str, bool stop=false); @@ -826,7 +837,7 @@ public: virtual void fpunchf_end_row(const char *format); virtual bool output_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out); - virtual bool punch_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out); + virtual bool punch_open(const char *file_name, std::ios_base::openmode mode = std::ios_base::out, int n_user = 1); protected: int EndRow(void); @@ -842,6 +853,7 @@ protected: void update_errors(void); + std::string sel_file_name(int n_user); protected: #if defined(_MSC_VER) @@ -879,23 +891,27 @@ protected: std::string WarningString; std::vector< std::string > WarningLines; - CSelectedOutput *SelectedOutput; - std::string StringInput; + int CurrentSelectedOutputUserNumber; + std::map< int, CSelectedOutput* > SelectedOutputMap; + std::map< SelectedOutput*, CSelectedOutput* > CurrentSelectedOutputMap; + std::map< SelectedOutput*, std::string* > CurrentToStringMap; + std::string StringInput; std::string DumpString; std::vector< std::string > DumpLines; std::list< std::string > Components; - std::string SelectedOutputFileName; + std::map< int, std::string > SelectedOutputFileNameMap; + std::string OutputFileName; std::string ErrorFileName; std::string LogFileName; std::string DumpFileName; - bool SelectedOutputStringOn; - std::string SelectedOutputString; - std::vector< std::string > SelectedOutputLines; + bool SelectedOutputStringOn; + std::map< int, std::string > SelectedOutputStringMap; + std::map< int, std::vector< std::string > > SelectedOutputLinesMap; protected: Phreeqc* PhreeqcPtr; diff --git a/Makefile.am b/Makefile.am index ae3ee373..dce00187 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,8 +30,8 @@ libiphreeqc_la_SOURCES=\ ErrorReporter.hxx\ IPhreeqc.cpp\ IPhreeqcLib.cpp\ - SelectedOutput.cpp\ - SelectedOutput.hxx\ + CSelectedOutput.cpp\ + CSelectedOutput.hxx\ thread.h\ Var.c\ phreeqcpp/cxxKinetics.cxx\ @@ -81,6 +81,8 @@ libiphreeqc_la_SOURCES=\ phreeqcpp/ReadClass.cxx\ phreeqcpp/runner.cpp\ phreeqcpp/runner.h\ + phreeqcpp/SelectedOutput.cpp\ + phreeqcpp/SelectedOutput.h\ phreeqcpp/Solution.cxx\ phreeqcpp/Solution.h\ phreeqcpp/SolutionIsotope.cxx\ @@ -107,6 +109,8 @@ libiphreeqc_la_SOURCES=\ phreeqcpp/Temperature.h\ phreeqcpp/Use.cpp\ phreeqcpp/Use.h\ + phreeqcpp/UserPunch.cpp\ + phreeqcpp/UserPunch.h\ phreeqcpp/Utils.cxx\ phreeqcpp/Utils.h\ phreeqcpp/advection.cpp\