From da74a4f0d6d711e9360433c7e154ce52c3500bdd Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 26 Oct 2021 21:11:39 +0200 Subject: [PATCH] #8196 GRDECL import : Handle multiple items of same value --- .../RifEclipseTextFileReader.cpp | 47 +++++++++++++++---- .../FileInterface/RifEclipseTextFileReader.h | 6 +-- .../RifEclipseTextFileReader-Test.cpp | 22 +++++++++ 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.cpp b/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.cpp index 76d0018127..255ae2a9e0 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.cpp @@ -26,6 +26,7 @@ #include "mio/mio.hpp" #include "RiaPreferencesSystem.h" +#include "RiaStdStringTools.h" #include #include @@ -89,9 +90,9 @@ std::pair> const auto commentChar = '-'; - std::string keywordName; - std::string line; - bool isEndTokenKeywordRead = false; + std::string keywordName; + std::string_view line; + bool isEndTokenKeywordRead = false; bytesRead = 0; float value = 0.0f; @@ -134,14 +135,36 @@ std::pair> size_t start = 0; size_t end = 0; + // Index in token for the '*' character used to define a multiplier for the float value + // + size_t multiplierIndex = 0; + while ( ( start = line.find_first_not_of( RifEclipseTextFileReader::m_whiteSpace, end ) ) != std::string::npos ) { end = line.find_first_of( RifEclipseTextFileReader::m_whiteSpace, start ); + int multiplier = 1; + + multiplierIndex = line.find_first_of( '*', start ); + if ( multiplierIndex < end ) + { + int multiplierCandidate = 1; + + if ( RiaStdStringTools::toInt( line.substr( start, multiplierIndex - start ), multiplierCandidate ) ) + { + multiplier = multiplierCandidate; + } + + start = multiplierIndex + 1; + } + auto resultObject = fast_float::from_chars( line.data() + start, line.data() + end, value ); if ( resultObject.ec == std::errc() ) { - values.emplace_back( value ); + for ( size_t i = 0; i < static_cast( multiplier ); i++ ) + { + values.emplace_back( value ); + } } } } @@ -226,24 +249,30 @@ std::string_view RifEclipseTextFileReader::readLine( const std::string_view& sou //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifEclipseTextFileReader::rtrim( std::string& s, const char* t /*= ws */ ) +void RifEclipseTextFileReader::rtrim( std::string_view& s, const char* t /*= ws */ ) { - s.erase( s.find_last_not_of( t ) + 1 ); + if ( s.empty() ) return; + + s = s.substr( 0, s.find_last_not_of( t ) + 1 ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifEclipseTextFileReader::ltrim( std::string& s, const char* t /*= ws */ ) +void RifEclipseTextFileReader::ltrim( std::string_view& s, const char* t /*= ws */ ) { - s.erase( 0, s.find_first_not_of( t ) ); + if ( s.empty() ) return; + + s = s.substr( s.find_first_not_of( t ), s.size() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifEclipseTextFileReader::trim( std::string& s, const char* t /*= ws */ ) +void RifEclipseTextFileReader::trim( std::string_view& s, const char* t /*= ws */ ) { + if ( s.empty() ) return; + rtrim( s, t ); ltrim( s, t ); } diff --git a/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.h b/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.h index f31fe5a5f5..259a49e9d9 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.h +++ b/ApplicationLibCode/FileInterface/RifEclipseTextFileReader.h @@ -51,13 +51,13 @@ public: static std::string_view readLine( const std::string_view& source, const size_t offset, size_t& bytesRead ); // trim from end of string (right) - static void rtrim( std::string& s, const char* t = m_whiteSpace ); + static void rtrim( std::string_view& s, const char* t = m_whiteSpace ); // trim from beginning of string (left) - static void ltrim( std::string& s, const char* t = m_whiteSpace ); + static void ltrim( std::string_view& s, const char* t = m_whiteSpace ); // trim from both ends of string (right then left) - static void trim( std::string& s, const char* t = m_whiteSpace ); + static void trim( std::string_view& s, const char* t = m_whiteSpace ); // Parse string data for Eclipse keywords static std::vector parseStringData( const std::string_view& stringData ); diff --git a/ApplicationLibCode/UnitTests/RifEclipseTextFileReader-Test.cpp b/ApplicationLibCode/UnitTests/RifEclipseTextFileReader-Test.cpp index 663466a67a..592b91d085 100644 --- a/ApplicationLibCode/UnitTests/RifEclipseTextFileReader-Test.cpp +++ b/ApplicationLibCode/UnitTests/RifEclipseTextFileReader-Test.cpp @@ -159,3 +159,25 @@ TEST( RifEclipseTextFileReader, ReadLine_TwoLinesWithLineBreak ) EXPECT_EQ( size_t( 10 ), bytesRead ); EXPECT_EQ( size_t( 9 ), secondLine.size() ); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RifEclipseTextFileReader, ValueMultiplier ) +{ + std::string fileContent = "ZCORN\n" + "2*2.21 0.5 3*12345.12\n" + "/\n"; + + auto keywordDataItems = RifEclipseTextFileReader::parseStringData( fileContent ); + + EXPECT_EQ( size_t( 1 ), keywordDataItems.size() ); + + auto firstKeyword = keywordDataItems.front(); + + EXPECT_EQ( size_t( 6 ), firstKeyword.values.size() ); + EXPECT_FLOAT_EQ( 2.21f, firstKeyword.values[0] ); + EXPECT_FLOAT_EQ( 2.21f, firstKeyword.values[1] ); + EXPECT_FLOAT_EQ( 0.5f, firstKeyword.values[2] ); + EXPECT_FLOAT_EQ( 12345.12f, firstKeyword.values[3] ); +}