iphreeqc/src/phreeqcpp/StorageBinList.cpp

359 lines
7.8 KiB
C++

#include <algorithm> // std::replace
#include "StorageBinList.h"
#include "Parser.h"
#if defined(PHREEQCI_GUI)
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif
StorageBinListItem::StorageBinListItem(void)
{
this->defined = false;
}
StorageBinListItem::~StorageBinListItem(void)
{
}
StorageBinListItem::StorageBinListItem(CParser & parser)
{
this->Clear();
// Read list of numbers or number ranges
for (;;)
{
//read lines
PHRQ_io::LINE_TYPE l = parser.check_line("read StorageBinListLtem", false, true, true, true);
std::istream::pos_type next_char = 0;
if (l == PHRQ_io::LT_EOF) break;
for (;;)
{
std::string token;
CParser::TOKEN_TYPE j = parser.copy_token(token, next_char);
if (j == CParser::TT_DIGIT)
{
this->Augment(token);
}
else if (j == CParser::TT_EMPTY)
{
break;
}
}
}
}
void StorageBinListItem::Augment(std::string token)
{
this->defined = true;
if (token.size() == 0) return;
// split string accounting for possible negative numbers
size_t pos;
if ((pos = token.find("--")) != std::string::npos)
{
token.replace(pos,2," &");
}
std::replace(token.begin() + 1, token.end(), '-', ' ');
std::replace(token.begin() + 1, token.end(), '&', '-');
// parse string into 1 or 2 numbers
std::istringstream iss(token);
std::set < int > temp_set;
int i;
if (iss >> i)
{
// add first
temp_set.insert(i);
if (iss >> i)
{
// add second if defined
temp_set.insert(i);
}
}
// add single number or range to StorageBinListItem
if (temp_set.size() == 1)
{
this->numbers.insert(*(temp_set.begin()));
}
else if (temp_set.size() == 2)
{
int i1, i2;
std::set <int>::iterator it;
it = temp_set.begin();
i1 = *it;
it++;
i2 = *it;
for (i = i1; i <= i2; i++)
{
this->numbers.insert(i);
}
}
}
void StorageBinListItem::Augment(int i)
{
// Skip if all are defined
if (this->defined == true && this->numbers.size() == 0) return;
this->defined = true;
this->numbers.insert(i);
}
//
//Class definitions for StorageBinList
//
StorageBinList::StorageBinList(PHRQ_io *io)
:
PHRQ_base(io)
{
}
StorageBinList::StorageBinList(CParser & parser, PHRQ_io *io)
:
PHRQ_base(io)
{
this->Read(parser);
}
StorageBinList::~StorageBinList(void)
{
}
std::set<StorageBinListItem *> StorageBinList::GetAllItems(void)
{
// don't include this->cell
std::set<StorageBinListItem *> items;
items.insert(&this->solution);
items.insert(&this->pp_assemblage);
items.insert(&this->exchange);
items.insert(&this->surface);
items.insert(&this->ss_assemblage);
items.insert(&this->gas_phase);
items.insert(&this->kinetics);
items.insert(&this->mix);
items.insert(&this->reaction);
items.insert(&this->temperature);
items.insert(&this->pressure);
return items;
}
void StorageBinList::SetAll(bool tf)
{
std::set<StorageBinListItem *> all = this->GetAllItems();
std::set<StorageBinListItem *>::iterator it = all.begin();
for (; it != all.end(); ++it)
{
(*it)->Clear();
(*it)->Set_defined(tf);
}
}
bool StorageBinList::Read(CParser & parser)
{
bool return_value(true);
std::istream::pos_type next_char;
std::string token;
int opt_save;
opt_save = CParser::OPT_DEFAULT;
// reset cells
this->cell.Clear();
this->cell.Set_defined(false);
for (;;)
{
int opt;
opt = parser.get_option(vopts, next_char);
if (opt == CParser::OPT_DEFAULT)
{
opt = opt_save;
}
else
{
opt_save = opt;
}
// Select StorageBinListItem
StorageBinListItem *item = NULL;
switch (opt)
{
case 0:
item = &(this->Get_solution());
break;
case 1:
case 2:
item = &(this->Get_pp_assemblage());
break;
case 3:
item = &(this->Get_exchange());
break;
case 4:
item = &(this->Get_surface());
break;
case 5:
case 6:
case 7:
item = &(this->Get_ss_assemblage());
break;
case 8:
item = &(this->Get_gas_phase());
break;
case 9:
item = &(this->Get_kinetics());
break;
case 10:
item = &(this->Get_mix());
break;
case 11:
item = &(this->Get_reaction());
break;
case 12:
case 16:
item = &(this->Get_temperature());
break;
case 14:
case 15:
item = &(this->Get_cell());
break;
case 17:
case 18:
item = &(this->Get_pressure());
break;
default:
break;
}
// Read dump entity list of numbers or number ranges for line, store in item
if ((opt >= 0 && opt <= 12) || (opt >= 14))
{
for (;;)
{
CParser::TOKEN_TYPE j = parser.copy_token(token, next_char);
if (item)
{
if (j == CParser::TT_DIGIT)
{
item->Augment(token);
}
else if (j == CParser::TT_EMPTY)
{
item->Augment(token);
break;
}
else
{
parser.error_msg("Expected single number or range of numbers.",
PHRQ_io::OT_CONTINUE);
break;
}
}
else
{
parser.error_msg("Dump entity type not defined.",
PHRQ_io::OT_CONTINUE);
break;
}
}
}
// Process other identifiers
switch (opt)
{
case CParser::OPT_EOF:
break;
case CParser::OPT_KEYWORD:
break;
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 16:
case 17:
case 18:
break;
case 13: //all
this->SetAll(true);
break;
case 14:
case 15:
//if (cell_list.Get_numbers().empty())
//{
// this->SetAll(true);
//}
//else
//{
//this->TransferAll(cell_list);
//}
break;
default:
case CParser::OPT_DEFAULT:
case CParser::OPT_ERROR:
opt = CParser::OPT_EOF;
parser.error_msg("Unknown input reading DELETE definition.",
PHRQ_io::OT_CONTINUE);
parser.error_msg(parser.line().c_str(), PHRQ_io::OT_CONTINUE);
return_value = false;
break;
}
if (opt == CParser::OPT_EOF || opt == CParser::OPT_KEYWORD)
break;
}
// Now check to see if cell_list defined
if (this->Get_cell().Get_defined())
{
if (this->Get_cell().Get_numbers().empty())
{
this->SetAll(true);
}
else
{
this->TransferAll(this->Get_cell());
}
}
return(return_value);
}
void StorageBinList::TransferAll(StorageBinListItem &source)
{
std::set<StorageBinListItem *> items = this->GetAllItems();
std::set < int >::iterator it;
for (it = source.Get_numbers().begin(); it != source.Get_numbers().end(); it++)
{
std::set<StorageBinListItem *>::iterator item = items.begin();
for (; item != items.end(); ++item)
{
(*item)->Augment(*it);
}
}
}
const std::vector< std::string >::value_type temp_vopts[] = {
std::vector< std::string >::value_type("solution"), // 0
std::vector< std::string >::value_type("pp_assemblage"), // 1
std::vector< std::string >::value_type("equilibrium_phases"), // 2
std::vector< std::string >::value_type("exchange"), // 3
std::vector< std::string >::value_type("surface"), // 4
std::vector< std::string >::value_type("ss_assemblage"), // 5
std::vector< std::string >::value_type("solid_solution"), // 6
std::vector< std::string >::value_type("solid_solutions"), // 7
std::vector< std::string >::value_type("gas_phase"), // 8
std::vector< std::string >::value_type("kinetics"), // 9
std::vector< std::string >::value_type("mix"), // 10
std::vector< std::string >::value_type("reaction"), // 11
std::vector< std::string >::value_type("temperature"), // 12
std::vector< std::string >::value_type("all"), // 13
std::vector< std::string >::value_type("cell"), // 14
std::vector< std::string >::value_type("cells"), // 15
std::vector< std::string >::value_type("reaction_temperature"), // 16
std::vector< std::string >::value_type("pressure"), // 17
std::vector< std::string >::value_type("reaction_pressure") // 18
};
const std::vector< std::string > StorageBinList::vopts(temp_vopts, temp_vopts + sizeof temp_vopts / sizeof temp_vopts[0]);