2013-03-22 15:35:40 +01:00
|
|
|
/*
|
|
|
|
|
Copyright 2013 Statoil ASA.
|
|
|
|
|
|
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
|
|
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
2013-03-25 17:17:09 +01:00
|
|
|
#include <iostream>
|
2013-03-26 14:31:05 +01:00
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <boost/algorithm/string.hpp>
|
|
|
|
|
|
2013-12-08 19:17:33 +01:00
|
|
|
#include <opm/parser/eclipse/RawDeck/RawRecord.hpp>
|
|
|
|
|
#include <opm/parser/eclipse/RawDeck/RawConsts.hpp>
|
2013-04-08 10:31:54 +02:00
|
|
|
|
|
|
|
|
using namespace Opm;
|
2013-03-22 15:35:40 +01:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
namespace Opm {
|
|
|
|
|
|
2013-05-06 12:13:49 +02:00
|
|
|
/*
|
|
|
|
|
* It is assumed that after a record is terminated, there is no quote marks
|
|
|
|
|
* in the subsequent comment. This is in accordance with the Eclipse user
|
|
|
|
|
* manual.
|
2014-12-08 16:34:28 +01:00
|
|
|
*
|
2013-05-06 12:13:49 +02:00
|
|
|
* If a "non-complete" record string is supplied, an invalid_argument
|
|
|
|
|
* exception is thrown.
|
2014-12-08 16:34:28 +01:00
|
|
|
*
|
2013-05-06 12:13:49 +02:00
|
|
|
*/
|
2013-11-07 12:32:07 +01:00
|
|
|
RawRecord::RawRecord(const std::string& singleRecordString, const std::string& fileName, const std::string& keywordName) : m_fileName(fileName), m_keywordName(keywordName){
|
2013-05-06 12:13:49 +02:00
|
|
|
if (isTerminatedRecordString(singleRecordString)) {
|
|
|
|
|
setRecordString(singleRecordString);
|
2013-05-07 21:55:49 +02:00
|
|
|
splitSingleRecordString();
|
2013-05-06 12:13:49 +02:00
|
|
|
} else {
|
|
|
|
|
throw std::invalid_argument("Input string is not a complete record string,"
|
|
|
|
|
" offending string: " + singleRecordString);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-08 16:34:28 +01:00
|
|
|
|
2013-11-07 12:32:07 +01:00
|
|
|
const std::string& RawRecord::getFileName() const {
|
|
|
|
|
return m_fileName;
|
|
|
|
|
}
|
2014-12-08 16:34:28 +01:00
|
|
|
|
2013-11-07 12:32:07 +01:00
|
|
|
const std::string& RawRecord::getKeywordName() const {
|
|
|
|
|
return m_keywordName;
|
|
|
|
|
}
|
2014-12-08 16:34:28 +01:00
|
|
|
|
2013-05-06 12:13:49 +02:00
|
|
|
|
2013-05-08 14:31:20 +02:00
|
|
|
std::string RawRecord::pop_front() {
|
2013-05-08 15:29:58 +02:00
|
|
|
std::string front = m_recordItems.front();
|
|
|
|
|
m_recordItems.pop_front();
|
|
|
|
|
return front;
|
2013-05-08 14:31:20 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-10 13:55:00 +02:00
|
|
|
|
|
|
|
|
void RawRecord::push_front(std::string token) {
|
|
|
|
|
m_recordItems.push_front( token );
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 21:37:22 +02:00
|
|
|
|
|
|
|
|
size_t RawRecord::size() const {
|
|
|
|
|
return m_recordItems.size();
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-11 12:36:16 +02:00
|
|
|
void RawRecord::dump() const {
|
|
|
|
|
std::cout << "RecordDump: ";
|
|
|
|
|
for (size_t i = 0; i < m_recordItems.size(); i++)
|
|
|
|
|
std::cout << m_recordItems[i] << "/" << getItem(i) << " ";
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 21:37:22 +02:00
|
|
|
|
2013-06-03 15:54:16 +02:00
|
|
|
const std::string& RawRecord::getItem(size_t index) const {
|
2013-05-10 13:55:00 +02:00
|
|
|
if (index < m_recordItems.size())
|
|
|
|
|
return m_recordItems[index];
|
|
|
|
|
else
|
|
|
|
|
throw std::out_of_range("Lookup index out of range");
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-06 12:13:49 +02:00
|
|
|
const std::string& RawRecord::getRecordString() const {
|
|
|
|
|
return m_sanitizedRecordString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RawRecord::isTerminatedRecordString(const std::string& candidateRecordString) {
|
|
|
|
|
unsigned int terminatingSlash = findTerminatingSlash(candidateRecordString);
|
|
|
|
|
bool hasTerminatingSlash = (terminatingSlash < candidateRecordString.size());
|
|
|
|
|
int numberOfQuotes = std::count(candidateRecordString.begin(), candidateRecordString.end(), RawConsts::quote);
|
|
|
|
|
bool hasEvenNumberOfQuotes = (numberOfQuotes % 2) == 0;
|
|
|
|
|
return hasTerminatingSlash && hasEvenNumberOfQuotes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RawRecord::splitSingleRecordString() {
|
|
|
|
|
char currentChar;
|
2013-08-21 14:29:46 +02:00
|
|
|
char tokenStartCharacter=' ';
|
2013-05-06 12:13:49 +02:00
|
|
|
std::string currentToken = "";
|
2014-09-18 14:47:05 +02:00
|
|
|
bool inQuote = false;
|
2013-05-06 12:13:49 +02:00
|
|
|
for (unsigned i = 0; i < m_sanitizedRecordString.size(); i++) {
|
|
|
|
|
currentChar = m_sanitizedRecordString[i];
|
2014-09-18 14:47:05 +02:00
|
|
|
if (!inQuote && charIsSeparator(currentChar)) {
|
2013-05-06 12:13:49 +02:00
|
|
|
processSeparatorCharacter(currentToken, currentChar, tokenStartCharacter);
|
|
|
|
|
} else if (currentChar == RawConsts::quote) {
|
2014-09-18 14:47:05 +02:00
|
|
|
inQuote = !inQuote;
|
|
|
|
|
processNonSpecialCharacters(currentToken, currentChar);
|
2013-05-06 12:13:49 +02:00
|
|
|
} else {
|
|
|
|
|
processNonSpecialCharacters(currentToken, currentChar);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (currentToken.size() > 0) {
|
|
|
|
|
m_recordItems.push_back(currentToken);
|
|
|
|
|
currentToken.clear();
|
|
|
|
|
}
|
2013-04-04 13:30:50 +02:00
|
|
|
}
|
2013-05-06 12:13:49 +02:00
|
|
|
|
|
|
|
|
void RawRecord::processSeparatorCharacter(std::string& currentToken, const char& currentChar, char& tokenStartCharacter) {
|
|
|
|
|
if (tokenStartCharacter == RawConsts::quote) {
|
|
|
|
|
currentToken += currentChar;
|
|
|
|
|
} else {
|
|
|
|
|
if (currentToken.size() > 0) {
|
|
|
|
|
m_recordItems.push_back(currentToken);
|
|
|
|
|
currentToken.clear();
|
|
|
|
|
}
|
|
|
|
|
tokenStartCharacter = currentChar;
|
|
|
|
|
}
|
2013-04-04 13:30:50 +02:00
|
|
|
}
|
2013-05-06 12:13:49 +02:00
|
|
|
|
|
|
|
|
void RawRecord::processNonSpecialCharacters(std::string& currentToken, const char& currentChar) {
|
|
|
|
|
currentToken += currentChar;
|
2013-03-26 14:31:05 +01:00
|
|
|
}
|
2013-05-06 12:13:49 +02:00
|
|
|
|
|
|
|
|
bool RawRecord::charIsSeparator(char candidate) {
|
|
|
|
|
return std::string::npos != RawConsts::separators.find(candidate);
|
2013-04-02 15:42:19 +02:00
|
|
|
}
|
|
|
|
|
|
2013-05-06 12:13:49 +02:00
|
|
|
void RawRecord::setRecordString(const std::string& singleRecordString) {
|
|
|
|
|
unsigned terminatingSlash = findTerminatingSlash(singleRecordString);
|
|
|
|
|
m_sanitizedRecordString = singleRecordString.substr(0, terminatingSlash);
|
|
|
|
|
boost::trim(m_sanitizedRecordString);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int RawRecord::findTerminatingSlash(const std::string& singleRecordString) {
|
|
|
|
|
unsigned int terminatingSlash = singleRecordString.find_first_of(RawConsts::slash);
|
|
|
|
|
unsigned int lastQuotePosition = singleRecordString.find_last_of(RawConsts::quote);
|
|
|
|
|
|
2014-12-08 16:34:28 +01:00
|
|
|
// Checks lastQuotePosition vs terminatingSlashPosition,
|
|
|
|
|
// since specifications of WELLS, FILENAMES etc can include slash, but
|
2013-05-06 12:13:49 +02:00
|
|
|
// these are always in quotes (and there are no quotes after record-end).
|
|
|
|
|
if (terminatingSlash < lastQuotePosition && lastQuotePosition < singleRecordString.size()) {
|
|
|
|
|
terminatingSlash = singleRecordString.find_first_of(RawConsts::slash, lastQuotePosition);
|
|
|
|
|
}
|
|
|
|
|
return terminatingSlash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RawRecord::~RawRecord() {
|
|
|
|
|
}
|
2013-03-22 15:35:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|