forked from heremaps/flatdata
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for reading from TAR archives to flatdata-cpp (heremaps#182)
Signed-off-by: Christian Ocker <[email protected]>
- Loading branch information
Showing
7 changed files
with
590 additions
and
1 deletion.
There are no files selected for viewing
75 changes: 75 additions & 0 deletions
75
flatdata-cpp/include/flatdata/MemoryMappedTarFileStorage.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* Copyright (c) 2021 HERE Europe B.V. | ||
* See the LICENSE file in the root of this project for license details. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "MemoryDescriptor.h" | ||
#include "internal/TarReader.h" | ||
|
||
#include <boost/interprocess/file_mapping.hpp> | ||
#include <boost/interprocess/mapped_region.hpp> | ||
|
||
#include <cstdio> | ||
#include <map> | ||
#include <memory> | ||
|
||
namespace flatdata | ||
{ | ||
class MemoryMappedTarFileStorage | ||
{ | ||
public: | ||
explicit MemoryMappedTarFileStorage( const char* tar_path ); | ||
|
||
MemoryDescriptor read( const char* path ) const; | ||
|
||
private: | ||
boost::interprocess::mapped_region m_region; | ||
std::map< std::string, MemoryDescriptor > m_files; | ||
}; | ||
|
||
inline MemoryMappedTarFileStorage::MemoryMappedTarFileStorage( const char* tar_path ) | ||
{ | ||
try | ||
{ | ||
boost::interprocess::file_mapping file( tar_path, boost::interprocess::read_only ); | ||
boost::interprocess::mapped_region region( file, boost::interprocess::read_only ); | ||
if ( region.get_size( ) == 0 ) | ||
{ | ||
return; | ||
} | ||
|
||
m_region = std::move( region ); | ||
} | ||
catch ( boost::interprocess::interprocess_exception& ) | ||
{ | ||
return; | ||
} | ||
|
||
auto files = internal::read_tar_files( tar_path ); | ||
|
||
for ( const auto& file : files ) | ||
{ | ||
std::string path = file.name.substr( 0, 2 ) == "./" ? file.name.substr( 2 ) : file.name; | ||
m_files.emplace( | ||
std::move( path ), | ||
MemoryDescriptor( | ||
static_cast< const unsigned char* >( m_region.get_address( ) ) + file.offset, | ||
std::min( file.size, m_region.get_size( ) - file.offset ) ) ); | ||
} | ||
} | ||
|
||
inline MemoryDescriptor | ||
MemoryMappedTarFileStorage::read( const char* path ) const | ||
{ | ||
auto found = m_files.find( path ); | ||
if ( found != m_files.end( ) ) | ||
{ | ||
return found->second; | ||
} | ||
|
||
return MemoryDescriptor( ); | ||
} | ||
|
||
} // namespace flatdata |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/** | ||
* Copyright (c) 2021 HERE Europe B.V. | ||
* See the LICENSE file in the root of this project for license details. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "MemoryMappedTarFileStorage.h" | ||
#include "ResourceStorage.h" | ||
|
||
#include <boost/filesystem.hpp> | ||
|
||
#include <fstream> | ||
|
||
namespace flatdata | ||
{ | ||
/** | ||
* @brief Read-only resource storage for reading flatdata archives inside a TAR file. | ||
*/ | ||
class TarFileResourceStorage : public ResourceStorage | ||
{ | ||
public: | ||
/** | ||
* @brief Create resource storage for a TAR file | ||
* @param tar_path The path to the TAR file | ||
* @param tar_path The path inside the TAR file | ||
* @throws std::runtime_error if the reading of the TAR file fails | ||
* @return TarFileResourceStorage or nullptr on error | ||
*/ | ||
static std::unique_ptr< TarFileResourceStorage > create( const char* tar_path, | ||
const char* sub_path = "" ); | ||
|
||
std::unique_ptr< ResourceStorage > create_directory( const char* key ) override; | ||
std::unique_ptr< ResourceStorage > directory( const char* key ) override; | ||
bool exists( const char* key ) override; | ||
|
||
protected: | ||
std::shared_ptr< std::ostream > create_output_stream( const char* key ) override; | ||
MemoryDescriptor read_resource( const char* key ) override; | ||
|
||
private: | ||
TarFileResourceStorage( std::shared_ptr< const MemoryMappedTarFileStorage > storage, | ||
const std::string& tar_path, | ||
const std::string& sub_path ); | ||
std::string get_path( const char* key ) const; | ||
|
||
private: | ||
std::shared_ptr< const MemoryMappedTarFileStorage > m_storage; | ||
std::string m_tar_path; | ||
std::string m_sub_path; | ||
}; | ||
|
||
// ------------------------------------------------------------------------------------------------- | ||
|
||
inline std::unique_ptr< TarFileResourceStorage > | ||
TarFileResourceStorage::create( const char* tar_path, const char* sub_path ) | ||
{ | ||
std::shared_ptr< const MemoryMappedTarFileStorage > storage( | ||
new MemoryMappedTarFileStorage( tar_path ) ); | ||
|
||
return std::unique_ptr< TarFileResourceStorage >( | ||
new TarFileResourceStorage( storage, tar_path, sub_path ) ); | ||
} | ||
|
||
inline std::shared_ptr< std::ostream > | ||
TarFileResourceStorage::create_output_stream( const char* ) | ||
{ | ||
// Writing to TAR files is not supported | ||
return nullptr; | ||
} | ||
|
||
inline TarFileResourceStorage::TarFileResourceStorage( | ||
std::shared_ptr< const MemoryMappedTarFileStorage > storage, | ||
const std::string& tar_path, | ||
const std::string& sub_path ) | ||
: m_storage( std::move( storage ) ) | ||
, m_tar_path( tar_path ) | ||
, m_sub_path( sub_path ) | ||
{ | ||
} | ||
|
||
inline std::string | ||
TarFileResourceStorage::get_path( const char* key ) const | ||
{ | ||
const char TAR_PATH_SEPARATOR = '/'; | ||
|
||
return m_sub_path.empty( ) ? std::string( key ) : m_sub_path + TAR_PATH_SEPARATOR + key; | ||
} | ||
|
||
inline MemoryDescriptor | ||
TarFileResourceStorage::read_resource( const char* key ) | ||
{ | ||
if ( !exists( key ) ) | ||
{ | ||
return MemoryDescriptor( ); | ||
} | ||
return m_storage->read( get_path( key ).c_str( ) ); | ||
} | ||
|
||
inline std::unique_ptr< ResourceStorage > | ||
TarFileResourceStorage::create_directory( const char* key ) | ||
{ | ||
return directory( key ); | ||
} | ||
|
||
inline std::unique_ptr< ResourceStorage > | ||
TarFileResourceStorage::directory( const char* key ) | ||
{ | ||
return std::unique_ptr< TarFileResourceStorage >( | ||
new TarFileResourceStorage( m_storage, m_tar_path, get_path( key ) ) ); | ||
} | ||
|
||
inline bool | ||
TarFileResourceStorage::exists( const char* key ) | ||
{ | ||
return m_storage->read( get_path( key ).c_str( ) ).data( ) != nullptr; | ||
} | ||
|
||
} // namespace flatdata |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* Copyright (c) 2021 HERE Europe B.V. | ||
* See the LICENSE file in the root of this project for license details. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <stddef.h> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace flatdata | ||
{ | ||
namespace internal | ||
{ | ||
struct TarFileEntry | ||
{ | ||
std::string name; | ||
size_t offset = 0; | ||
size_t size = 0; | ||
}; | ||
|
||
std::vector< TarFileEntry > read_tar_files( const char* tar_path ); | ||
} // namespace internal | ||
} // namespace flatdata |
Oops, something went wrong.