25 #include "openPMD/IO/AbstractFilePosition.hpp"
26 #include "openPMD/IO/AbstractIOHandler.hpp"
27 #include "openPMD/IO/AbstractIOHandlerImpl.hpp"
28 #include "openPMD/IO/InvalidatableFile.hpp"
29 #include "openPMD/auxiliary/StringManip.hpp"
30 #include "openPMD/backend/Writable.hpp"
32 #include <unordered_map>
33 #include <unordered_set>
39 template <
typename FilePositionType = AbstractFilePosition >
40 class AbstractIOHandlerImplCommon :
public AbstractIOHandlerImpl
44 explicit AbstractIOHandlerImplCommon( AbstractIOHandler * handler );
46 ~AbstractIOHandlerImplCommon( )
override;
53 std::unordered_map< Writable *, InvalidatableFile >
m_files;
54 std::unordered_set< InvalidatableFile > m_dirty;
58 PE_InvalidatableFile = 0,
64 std::unordered_map< Writable *, InvalidatableFile >::iterator,
66 > getPossiblyExisting( std::string file );
98 std::shared_ptr< FilePositionType >
107 virtual std::shared_ptr< FilePositionType >
119 virtual std::shared_ptr< FilePositionType >
124 template <
typename FilePositionType >
125 AbstractIOHandlerImplCommon< FilePositionType >::AbstractIOHandlerImplCommon(
126 AbstractIOHandler * handler )
127 : AbstractIOHandlerImpl{handler}
132 template <
typename FilePositionType >
133 AbstractIOHandlerImplCommon<
134 FilePositionType >::~AbstractIOHandlerImplCommon( ) =
default;
137 template <
typename FilePositionType >
138 std::tuple< InvalidatableFile,
139 std::unordered_map< Writable *, InvalidatableFile >::iterator,
141 AbstractIOHandlerImplCommon< FilePositionType >::getPossiblyExisting(
145 auto it = std::find_if(
146 m_files.begin( ), m_files.end( ),
147 [file]( std::unordered_map<
148 Writable *, InvalidatableFile >::value_type
const & entry ) {
149 return *entry.second == file && entry.second.valid( );
153 InvalidatableFile name;
154 if ( it == m_files.end( ) )
162 newlyCreated =
false;
166 std::unordered_map< Writable *, InvalidatableFile >::iterator,
bool >(
167 std::move( name ), it, newlyCreated );
171 template <
typename FilePositionType >
172 void AbstractIOHandlerImplCommon< FilePositionType >::associateWithFile(
173 Writable * writable, InvalidatableFile file )
176 m_files[writable] = std::move( file );
180 template <
typename FilePositionType >
184 return fullPath( *fileName );
188 template <
typename FilePositionType >
190 std::string fileName )
192 if ( auxiliary::ends_with( m_handler->directory,
"/" ) )
194 return m_handler->directory + fileName;
198 return m_handler->directory +
"/" + fileName;
202 template<
typename FilePositionType >
205 Writable * writable,
bool preferParentFile )
207 auto getFileFromParent = [ writable, this ]() {
208 auto file = m_files.find( writable->parent )->second;
209 associateWithFile( writable, file );
212 if( preferParentFile && writable->parent )
214 return getFileFromParent();
218 auto it = m_files.find( writable );
219 if( it != m_files.end() )
221 return m_files.find( writable )->second;
223 else if( writable->parent )
225 return getFileFromParent();
229 throw std::runtime_error(
230 "Internal error: Root object must be opened explicitly." );
235 template<
typename FilePositionType >
236 std::shared_ptr< FilePositionType >
240 std::shared_ptr< AbstractFilePosition > res;
242 if ( writable->abstractFilePosition )
244 res = writable->abstractFilePosition;
246 else if ( writable->parent )
248 res = writable->parent->abstractFilePosition;
252 res = std::make_shared< FilePositionType >( );
256 writable->abstractFilePosition = res;
258 return std::dynamic_pointer_cast< FilePositionType >( res );
262 template <
typename FilePositionType >
263 std::shared_ptr< FilePositionType >
265 Writable * writable, std::string extend )
267 if ( !auxiliary::starts_with( extend,
'/' ) )
269 extend =
"/" + extend;
271 auto oldPos = setAndGetFilePosition( writable,
false );
272 auto res = extendFilePosition( oldPos, extend );
274 writable->abstractFilePosition = res;