From 9cf4c16e9a7eef9292b852fe64eb340806da9015 Mon Sep 17 00:00:00 2001 From: Andre Rummler Date: Sun, 3 Dec 2023 13:28:25 +0100 Subject: [PATCH 1/5] Replacing in-built sio with FetchContent mechanism (full build; can be stripped down). --- CMakeLists.txt | 17 +- sio/CMakeLists.txt | 50 --- sio/include/sio/api.h | 479 ----------------------- sio/include/sio/block.h | 77 ---- sio/include/sio/buffer.h | 481 ----------------------- sio/include/sio/compression/zlib.h | 58 --- sio/include/sio/definitions.h | 350 ----------------- sio/include/sio/exception.h | 147 ------- sio/include/sio/io_device.h | 383 ------------------ sio/include/sio/memcpy.h | 119 ------ sio/include/sio/version.h | 47 --- sio/src/api.cc | 596 ----------------------------- sio/src/block.cc | 27 -- sio/src/buffer.cc | 399 ------------------- sio/src/compression/zlib.cc | 73 ---- sio/src/exception.cc | 81 ---- sio/src/io_device.cc | 164 -------- sio/src/memcpy.cc | 24 -- sio/src/version.cc | 22 -- tests/CMakeLists.txt | 2 +- 20 files changed, 10 insertions(+), 3586 deletions(-) delete mode 100644 sio/CMakeLists.txt delete mode 100644 sio/include/sio/api.h delete mode 100644 sio/include/sio/block.h delete mode 100644 sio/include/sio/buffer.h delete mode 100644 sio/include/sio/compression/zlib.h delete mode 100644 sio/include/sio/definitions.h delete mode 100644 sio/include/sio/exception.h delete mode 100644 sio/include/sio/io_device.h delete mode 100644 sio/include/sio/memcpy.h delete mode 100644 sio/include/sio/version.h delete mode 100644 sio/src/api.cc delete mode 100644 sio/src/block.cc delete mode 100644 sio/src/buffer.cc delete mode 100644 sio/src/compression/zlib.cc delete mode 100644 sio/src/exception.cc delete mode 100644 sio/src/io_device.cc delete mode 100644 sio/src/memcpy.cc delete mode 100644 sio/src/version.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index a3e14b59b..49ac5ff9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,15 @@ FIND_PACKAGE( SIO QUIET ) IF( NOT SIO_FOUND ) MESSAGE( STATUS "SIO not found on your system. Using builtin sio" ) - ADD_SUBDIRECTORY( sio ) + include(FetchContent) + FetchContent_Declare(sio_extern + GIT_REPOSITORY https://github.com/iLCSoft/SIO.git + GIT_TAG master + GIT_SHALLOW 1 +# FIND_PACKAGE_ARGS +) + + FetchContent_MakeAvailable(sio_extern) ENDIF() MESSAGE( STATUS "Using SIO (${SIO_VERSION})" ) @@ -320,10 +328,3 @@ install(EXPORT ${PROJECT_NAME}Targets DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/" ) -IF( NOT SIO_FOUND ) -install(EXPORT SIOTargets - NAMESPACE SIO:: - FILE "SIOTargets.cmake" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/SIO/" - ) -ENDIF() diff --git a/sio/CMakeLists.txt b/sio/CMakeLists.txt deleted file mode 100644 index 85d48e1ac..000000000 --- a/sio/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# -# CMakeLists.txt for building the SIO library only -# For the full SIO package (library, includes, binaries, examples) -# please visit https:/github.com/iLCSoft/SIO -# -# @author: Remi Ete, DESY -# - -PROJECT( SIO ) - -# project version -SET( SIO_VERSION_MAJOR 0 ) -SET( SIO_VERSION_MINOR 0 ) -SET( SIO_VERSION_PATCH 4 ) -SET( SIO_VERSION "${SIO_VERSION_MAJOR}.${SIO_VERSION_MINOR}.${SIO_VERSION_PATCH}" ) -SET( SIO_SOVERSION "${SIO_VERSION_MAJOR}.${SIO_VERSION_MINOR}" ) - -FIND_PACKAGE( ZLIB REQUIRED ) - -# SIO care about endianess -INCLUDE( TestBigEndian ) -TEST_BIG_ENDIAN( BIG_ENDIAN ) - -IF( NOT BIG_ENDIAN ) - ADD_DEFINITIONS( "-D__LITTLE_ENDIAN__" ) -ENDIF() - -# Build the SIO library -FILE( GLOB_RECURSE SIO_SRCS src/*.cc ) - -ADD_DEFINITIONS( "-DSIO_LOGLVL=0" ) -ADD_SHARED_LIBRARY( sio ${SIO_SRCS} ) -ADD_LIBRARY( SIO::sio ALIAS sio ) -TARGET_INCLUDE_DIRECTORIES( sio PUBLIC - $ - $ -) -TARGET_LINK_LIBRARIES( sio PUBLIC ZLIB::ZLIB ) -INSTALL_SHARED_LIBRARY( sio DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT SIOTargets ) -ADD_LIBRARY( SIO::sio ALIAS sio ) - -# Install the sio headers as well. Necessary for the python bindings and also -# for cases where others want to link against LCIO / this version of SIO -INSTALL(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/sio DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - -# mimic the SIOConfig.cmake variables for the LCIO project -SET( SIO_VERSION "${SIO_VERSION}" CACHE STRING "The SIO version" ) -SET( SIO_LIBRARIES "sio" CACHE STRING "The SIO library" ) -SET( SIO_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" CACHE STRING "The path to SIO include directories" ) -SET( CHECK_PACKAGE_SIO_LIBRARY "sio" CACHE STRING "The name of the builtin SIO library to check when searching for LCIO package" ) diff --git a/sio/include/sio/api.h b/sio/include/sio/api.h deleted file mode 100644 index 2f5745f20..000000000 --- a/sio/include/sio/api.h +++ /dev/null @@ -1,479 +0,0 @@ -#pragma once - -// -- sio headers -#include -#include - -// -- std headers -#include -#include -#include -#include -#include - -namespace sio { - - class buffer ; - class buffer_span ; - class block ; - class write_device ; - - /** - * @brief api class. - * Helper class to perform high level operation on sio objects - */ - class api { - public: - // static API only - api() = delete ; - - /** - * @name Pointer relocation - */ - ///@{ - /** - * @brief Perform the pointer relocation after the record has been read. - * - * @param pointed_at the map of pointers "pointed at" - * @param pointer_to the map of pointers "pointer to" - */ - static void read_relocation( pointed_at_map& pointed_at, pointer_to_map& pointer_to ) ; - - /** - * @brief Perform the pointer relocation after the record has been written. - * This operation requires to know the beginning of the record buffer - * address to compute the address shift - * - * @param rec_start the address of the start of the record - * @param pointed_at the map of pointers "pointed at" - * @param pointer_to the map of pointers "pointer to" - */ - static void write_relocation( const sio::byte* rec_start, pointed_at_map& pointed_at, pointer_to_map& pointer_to ) ; - ///@} - - /** - * @name Buffer I/O - */ - ///@{ - /** - * @brief Read data from the buffer. The template form allows - * for using either a sio::buffer or a sio::buffer_span object - * - * @param buffer the buffer to read from - * @param ptr the address of the variable to receive - * @param position the position in the buffer - * @param count the number of bytes to read - * @return the actual number of bytes read out - */ - template - static typename bufT::size_type read( const bufT &buffer, T *ptr, typename bufT::index_type position, typename bufT::size_type count ) ; - - /** - * @brief Read data from the buffer. The template form allows - * for using either a sio::buffer or a sio::buffer_span object - * - * @param buffer the buffer to read from - * @param ptr the address of the variable to receive - * @param length the length of the variable - * @param position the position in the buffer - * @param count the number of bytes to read - * @return the actual number of bytes read out - */ - template - static typename bufT::size_type read( const bufT &buffer, typename bufT::pointer ptr, typename bufT::size_type length, typename bufT::index_type position, typename bufT::size_type count ) ; - - /** - * @brief Write data to the buffer. The template form allows - * for using either a sio::buffer or a sio::buffer_span object - * - * @param buffer the buffer to write to - * @param ptr the address of the variable to write - * @param position the position in the buffer - * @param count the number of bytes to write - * @return the actual number of bytes written out - */ - template - static typename bufT::size_type write( bufT &buffer, const T *const ptr, typename bufT::index_type position, typename bufT::size_type count ) ; - - /** - * @brief Write data to the buffer. The template form allows - * for using either a sio::buffer or a sio::buffer_span object - * - * @param buffer the buffer to write to - * @param ptr the address of the variable to write - * @param length the length of the variable - * @param position the position in the buffer - * @param count the number of bytes to write - * @return the actual number of bytes written out - */ - template - static typename bufT::size_type write( bufT &buffer, typename bufT::const_pointer const ptr, typename bufT::size_type length, typename bufT::index_type position, typename bufT::size_type count ) ; - ///@} - - /** - * @name Record I/O - */ - ///@{ - /** - * @brief Read the next record header from the input stream. - * On exit, the stream cursor is set after the record header, ready - * to read the incoming record data bytes. The record header bytes - * read out from the stream are stored in the buffer passed as third - * argument. If the buffer is not large enough to contain all bytes, - * it is expanded. - * - * @param stream the input stream - * @param rec_info the record info to receive - * @param outbuf the buffer containing the record info bytes - */ - static void read_record_info( sio::ifstream &stream, record_info &rec_info, buffer &outbuf ) ; - - /** - * @brief Read out the record data from the input stream. The record data - * bytes are written in the buffer passed by reference. By default, the - * bytes are written at the beginning of the buffer. The last argument - * allows for specifying a shift from the start of the buffer. - * - * @param stream the input stream - * @param rec_info the record info - * @param outbuf the buffer to receive the record data bytes - * @param buffer_shift an optional shift from the start of the buffer - */ - static void read_record_data( sio::ifstream &stream, const record_info &rec_info, buffer &outbuf, std::size_t buffer_shift = 0 ) ; - - /** - * @brief Read out the record (header + data) from the input stream. - * Simple combination of the functions above. - * - * @param stream the input stream - * @param rec_info the record info to receive - * @param outbuf the record header + data bytes to receive - */ - static void read_record( sio::ifstream &stream, record_info &rec_info, buffer &outbuf ) ; - - /** - * @brief Read out the next record (header + data) from the input stream. - * The 'valid' arguments is used for validating the record info. - * You might want to skip a record before extracting the full data - * buffer. In this case the 'valid' function should return false. - * If the record info is validated, the record data is extracted - * out from the stream and passed to a second callback function - * to process it. This function also returns a boolean value - * specifying whether the next record should be read out. - * Example reading out a single specific record: - * @code{cpp} - * sio::buffer buf( 32*sio::kbyte ) ; - * sio::ifstream stream ; - * // ... open the stream ... - * sio::api::read_records( stream, buf, - * []( const sio::record_info &recinfo ) { - * // looking for a specific record - * return (recinfo._name == "MyRecord") ; - * }, - * []( const sio::record_info &recinfo, buffer_span recdata ){ - * // do something the record data - * // return false saying stop reading records - * return false ; - * }) ; - * @endcode - * - * @param stream the input stream - * @param rec_info the record info to receive - * @param outbuf the record header + data bytes to receive - */ - template - static void read_records( sio::ifstream &stream, buffer &outbuf, ValidPred valid, ReadFunc func ) ; - - /** - * @brief Read out the record (header + data) from the input stream. - * Simple combination of the functions above. Returns the record - * info and the buffer. The initial buffer size is set to 1 Mo and - * might be expanded while reading out the record data if required. - * - * @param stream the input stream - */ - static std::pair read_record( sio::ifstream &stream ) ; - - /** - * @brief Skip the next records while the unary predicate is true. - * The predicate must be of the following form : - * 'bool predicate(const record_info&)'. - * - * @param stream the input stream - * @param pred the unary predicate - */ - template - static void skip_records( sio::ifstream &stream, UnaryPredicate pred ) ; - - /** - * @brief Skip the N next records from the input stream - * - * @param stream the input stream - * @param nskip the number of record to skip - */ - static void skip_n_records( sio::ifstream &stream, std::size_t nskip ) ; - - /** - * @brief Skip the N next records with a specific name. - * If a record with a different name is encountered, it is also skipped. - * - * @param stream the input stream - * @param nskip the number of record to skip - * @param name the record name to skip (only) - */ - static void skip_records( sio::ifstream &stream, std::size_t nskip, const std::string &name ) ; - - /** - * @brief Got to the next record with the spcified name - * - * @param stream the input stream - * @param name the target record name - */ - static void go_to_record( sio::ifstream &stream, const std::string &name ) ; - - /** - * @brief Extract all the block info from the buffer. Skip block reading - * - * @param buf the input block buffer - */ - static std::vector read_block_infos( const buffer_span &buf ) ; - - /** - * @brief Extract the block info and get a buffer span of the block at the given index - * - * @param rec_buf the record buffer - * @param index the index of block header start in the record buffer - */ - static std::pair extract_block( const buffer_span &rec_buf, buffer_span::index_type index ) ; - - /** - * @brief Decode the record buffer using the block decoder. - * Loop over the blocks found in the buffer and try to decode it. - * If the block decoder is not available, it is skipped - * - * @param rec_buf the record buffer pointing on the first block to decode - * @param blocks the list of block decoder to use - */ - static void read_blocks( const buffer_span &rec_buf, const block_list &blocks ) ; - - /** - * @brief Dump the records from the input stream to the console. - * Note that if you use a detailed printout, the record - * is first uncompressed using zlib and the block infos - * are printed out too. - * - * @param stream the input stream - * @param skip the number of records to skip from the current position - * @param count the number of record to printout - * @param detailed whether to printout detailed information (block info) - */ - static void dump_records( sio::ifstream &stream, std::size_t skip, std::size_t count, bool detailed ) ; - - /** - * @brief Write the blocks in the buffer contained in the write_device. - * For each block, a block header and the block data is written - * - * @param device the write device to write to - * @param blocks the block encoder - */ - static void write_blocks( write_device &device, const block_list &blocks ) ; - - /** - * @brief Write a record in a buffer. A record_info object is returned. - * Note that in the returned structure the fields _file_start and - * _file_end are not filled since the writting is only done in the - * buffer at this step. Note also that this function doesn't call - * any compression algorithm. See overloads to get a compressed - * buffer. - * - * @param name the record name - * @param rec_buf the record buffer to receive - * @param blocks the block list for writting - * @param opts the record options - */ - static record_info write_record( const std::string &name, buffer &rec_buf, const block_list& blocks, sio::options_type opts ) ; - - /** - * @brief Compress the record buffer. Note that several operation are done - * in this function: - * - the record buffer is compressed and receive in the comp_buf - * - the record info is updated with the compressed record data length - * - the record header is overwritten in the record buffer - * - * @param rec_info the record info instance - * @param rec_buf the record buffer - * @param comp_buf the compressed buffer to receive - */ - template - static void compress_record( record_info &rec_info, buffer &rec_buf, buffer &comp_buf, compT &compressor ) ; - - /** - * @brief Write the full record buffer in the output stream. The stream - * is flushed after writing the buffer - * - * @param stream the output stream - * @param rec_buf the full record buffer (header + data) - * @param rec_info the record info to update (file start and end positions) - */ - static void write_record( sio::ofstream &stream, const buffer_span &rec_buf, record_info &rec_info ) ; - - /** - * @brief Write the record buffer in two step from two buffers. The first - * buffer contains the record header buffer and the second the - * record data, either compressed or uncompressed. The stream is - * flushed after writing the two buffers - * - * @param stream the output stream - * @param hdr_span the record header buffer span - * @param data_span the record data buffer span - * @param rec_info the record info to update (file start and end positions) - */ - static void write_record( sio::ofstream &stream, const buffer_span &hdr_span, const buffer_span &data_span, record_info &rec_info ) ; - ///@} - - /** - * @name Compression - */ - ///@{ - /** - * @brief Extract the compression bit from the option word - * - * @param opts the options word - */ - static bool is_compressed( options_type opts ) ; - - /** - * @brief Turn on/off the compression bit in the options word - * - * @param opts the option word - * @param value whether to set on/off the compression bit - * @return the old compression bit value - */ - static bool set_compression( options_type &opts, bool value ) ; - ///@} - }; - -} - -#include -#include -#include - -namespace sio { - - template - inline typename bufT::size_type api::read( const bufT &buffer, T *ptr, typename bufT::index_type position, typename bufT::size_type count ) { - if( not buffer.valid() ) { - SIO_THROW( sio::error_code::bad_state, "Buffer is invalid." ) ; - } - const auto bytelen = sizeof_helper::size*count ; - const auto padlen = (bytelen + sio::padding) & sio::padding_mask ; - SIO_DEBUG( "Reading... len: " << sizeof_helper::size << ", count: " << count << ", padlen: " << padlen << ", position: " << position ) ; - if( position + padlen > buffer.size() ) { - std::stringstream ss ; - ss << "Can't read " << padlen << " bytes out of buffer (pos=" << position << ")" ; - SIO_THROW( sio::error_code::invalid_argument, ss.str() ) ; - } - auto ptr_read = buffer.ptr( position ) ; - sio::memcpy::read( ptr_read, ptr, count ) ; - return padlen ; - } - - //-------------------------------------------------------------------------- - - template - inline typename bufT::size_type api::write( bufT &buffer, const T *const ptr, typename bufT::index_type position, typename bufT::size_type count ) { - if( not buffer.valid() ) { - SIO_THROW( sio::error_code::bad_state, "Buffer is invalid." ) ; - } - const auto bytelen = sizeof_helper::size*count ; - const auto padlen = (bytelen + sio::padding) & sio::padding_mask ; - if( position + padlen >= buffer.size() ) { - auto expand_size = std::max( buffer.size(), padlen ) ; - buffer.expand( expand_size ) ; - } - auto ptr_write = buffer.ptr( position ) ; - SIO_DEBUG( "Writing... len=" << sizeof_helper::size << ", count=" << count << ", bytelen=" << bytelen << ", padlen=" << padlen << ", position:" << position ) ; - sio::memcpy::write( ptr, ptr_write, count ) ; - for( auto bytcnt = bytelen; bytcnt < padlen; bytcnt++ ) { - *(ptr_write + bytcnt) = sio::null_byte ; - } - return padlen ; - } - - //-------------------------------------------------------------------------- - - template - inline void api::read_records( sio::ifstream &stream, buffer &outbuf, ValidPred valid, ReadFunc func ) { - bool continue_extract = true ; - while( continue_extract ) { - sio::record_info rec_info {} ; - api::read_record_info( stream, rec_info, outbuf ) ; - // if user validates the record info object, we extract the record data - auto val = valid( rec_info ) ; - if( val ) { - // extract the record data - api::read_record_data( stream, rec_info, outbuf, rec_info._header_length ) ; - // pass the record data buffer to the user (as a span) - // stop extracting records if the function returns false - continue_extract = func( rec_info, outbuf.span( rec_info._header_length, rec_info._data_length ) ) ; - } - else { - // if not, seek to the next record - stream.seekg( rec_info._file_end ) ; - } - } - } - - //-------------------------------------------------------------------------- - - template - inline void api::skip_records( sio::ifstream &stream, UnaryPredicate pred ) { - sio::record_info rec_info ; - sio::buffer rec_buffer( sio::max_record_info_len ) ; - while( 1 ) { - // read record header - api::read_record_info( stream, rec_info, rec_buffer ) ; - // skip record data - stream.seekg( rec_info._file_end ) ; - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state after a seek operation!" ) ; - } - if( not pred( rec_info ) ) { - break ; - } - } - } - - //-------------------------------------------------------------------------- - - template - inline void api::compress_record( record_info &rec_info, buffer &rec_buf, buffer &comp_buf, compT &compressor ) { - if( not rec_buf.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "Record buffer is invalid" ) ; - } - if( not comp_buf.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "Compression buffer is invalid" ) ; - } - try { - // set the compression bit in the record options - sio::api::set_compression( rec_info._options, true ) ; - // compress the record buffer (but not the record header) - auto rec_span = rec_buf.span( rec_info._header_length ) ; - compressor.compress( rec_span, comp_buf ) ; - rec_info._data_length = comp_buf.size() ; - write_device device ( std::move(rec_buf) ) ; - // fill back the record buffer with updated information on header - device.data( rec_info._header_length ) ; - device.data( sio::record_marker ) ; - device.data( rec_info._options ) ; - device.data( rec_info._data_length ) ; - // get back the buffer - rec_buf = device.take_buffer() ; - } - catch( sio::exception &e ) { - SIO_RETHROW( e, sio::error_code::io_failure, "Couldn't compress record buffer" ) ; - } - } - -} diff --git a/sio/include/sio/block.h b/sio/include/sio/block.h deleted file mode 100644 index 09c28875d..000000000 --- a/sio/include/sio/block.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -// -- sio headers -#include - -// -- std headers -#include - -namespace sio { - - class read_device ; - class write_device ; - - /** - * @brief block class. - * - * Implements to reading (writing) of record blocks from (to) a buffer. - * Blocks are versioned and the version is written out in the block header, - * so that on read operation, the version can be use to perform a proper - * decoding of data. - */ - class block { - public: - /// No default constructor - block() = delete ; - /// No copy constructor - block( const block& ) = delete ; - /// No move constructor - block( block&& ) = delete ; - /// No copy assignement - block& operator=( const block& ) = delete ; - /// No move assignement - block& operator=( block&& ) = delete ; - /// Default destructor - virtual ~block() = default ; - - /** - * @brief Constructor - * - * @param nam the block name - * @param vers the block version - */ - block( const std::string &nam, sio::version_type vers ) ; - - /** - * @brief Get the block name - */ - const std::string &name() const noexcept ; - - /** - * @brief Get the block version - */ - sio::version_type version() const noexcept ; - - /** - * @brief Perform decoding of block buffer using the device - * - * @param device the read device containing the block buffer - * @param vers the block version read out from the stream - */ - virtual void read( sio::read_device &device, sio::version_type vers ) = 0 ; - - /** - * @brief Perform encoding of block data in a buffer using the device - * - * @param device the write device containing the block buffer - */ - virtual void write( sio::write_device &device ) = 0 ; - - private: - ///< The block version - const sio::version_type _version ; - ///< The block name - const std::string _name ; - }; - -} \ No newline at end of file diff --git a/sio/include/sio/buffer.h b/sio/include/sio/buffer.h deleted file mode 100644 index 304fd4d0c..000000000 --- a/sio/include/sio/buffer.h +++ /dev/null @@ -1,481 +0,0 @@ -#pragma once - -// -- sio headers -#include - -// -- std headers -#include - -namespace sio { - - /** - * @brief buffer_span class. - * - * Implements a view on a byte array without owning it. - * A buffer_span can be obtained directly from a byte_array - * or from a buffer using the buffer::span() methods. - * The buffer_span class provides only const methods to - * work with the underlying byte array, except for the - * assignement operator which allow to change the underlying - * byte array span. Note that the implementation stores a - * pair of const_iterator on a byte_array. Thus the validity - * of the buffer_span object relies on the validity of these - * iterators. - */ - class buffer_span { - public: - // traits - using container = sio::byte_array ; - using element_type = container::value_type ; - using const_iterator = container::const_iterator ; - using index_type = std::size_t ; - using size_type = std::size_t ; - using reference = container::reference ; - using const_reference = container::const_reference ; - using pointer = container::pointer ; - using const_pointer = container::const_pointer ; - - public: - /// Default copy constructor - buffer_span( const buffer_span& ) = default ; - /// Default move constructor - buffer_span( buffer_span&& ) = default ; - /// Default destructor - ~buffer_span() = default ; - /// Default assignement operator - buffer_span& operator=( const buffer_span& ) = default ; - /// Default move assignment operator - buffer_span& operator=( buffer_span&& ) = default ; - - /** - * @brief Default constructor - */ - buffer_span() ; - - /** - * @brief Constructor from a byte_array - * - * @param bytes the byte_array on which to construct the span - */ - buffer_span( const container &bytes ) ; - - /** - * @brief Constructor with two iterators - * - * @param first the start of the span - * @param last the end of the span (not included) - */ - buffer_span( const_iterator first, const_iterator last ) ; - - /** - * @brief Constructor with iterator and bytes count - * - * @param first the start of the span - * @param count the number of bytes to the end of the span - */ - buffer_span( const_iterator first, size_type count ) ; - - /** - * @name Iterators - */ - ///{@ - /** - * @brief Get the iterator to the start of the span - */ - const_iterator begin() const ; - - /** - * @brief Get the iterator to the end of the span - */ - const_iterator end() const ; - ///@} - - /** - * @name Element access - */ - ///{@ - /** - * @brief Get the data buffer - */ - const element_type *data() const ; - - /** - * @brief Get the front element (if valid) - */ - const_reference front() const ; - - /** - * @brief Get the back element (if valid) - */ - const_reference back() const ; - - /** - * @brief Data access operator (no range check) - * - * @param index the index of a byte access - */ - const_reference operator[]( index_type index ) const ; - - /** - * @brief Data access operator (range check!) - * - * @param index the index of a byte access - */ - const_reference at( index_type index ) const ; - - /** - * @brief Get a pointer on the raw bytes at the given index - * - * @param index the index access - */ - const_pointer ptr( index_type index ) const ; - ///@} - - /** - * @name Capacity - */ - ///{@ - /** - * @brief Get the size of the span - */ - size_type size() const ; - - /** - * @brief Whether the span is empty - */ - bool empty() const ; - - /** - * @brief Whether the span is valid, meaning not default constructed - */ - bool valid() const ; - - /** - * @brief boolean operator. Returns true if the span is valid - */ - operator bool() const noexcept ; - ///@} - - /** - * @name Operations - */ - ///{@ - /** - * @brief Get a sub span from a new start, untill the end - * - * @param start the subspan new start - */ - buffer_span subspan( index_type start ) const ; - - /** - * @brief Get a sub span from a new start and new end - * - * - * @param start the subspan new start - * @param count the size of the subspan - */ - buffer_span subspan( index_type start, std::size_t count ) const ; - - /** - * @brief Dump the buffer into standard output - * - * @param base the numeric base of the output data (default octal) - * @param line_split the number of bytes to print before a line break - * @param max_bytes the maximum number of bytes to printout - */ - void dump( int base = 8, unsigned int line_split = 20, size_type max_bytes = std::numeric_limits::max() ) ; - ///@} - - private: - ///< An iterator to the begin of a byte_array - const_iterator _first{} ; - ///< An iterator to the end of a byte_array - const_iterator _last{} ; - ///< Whether the span is null (invalid) - bool _isnull {false} ; - }; - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - /** - * @brief buffer class - */ - class buffer { - public: - using container = sio::byte_array ; - using element_type = container::value_type ; - using iterator = container::iterator ; - using const_iterator = container::const_iterator ; - using reverse_iterator = container::reverse_iterator ; - using const_reverse_iterator = container::const_reverse_iterator ; - using index_type = std::size_t ; - using size_type = std::size_t ; - using reference = container::reference ; - using const_reference = container::const_reference ; - using pointer = container::pointer ; - using const_pointer = container::const_pointer ; - - public: - /// No default constructor - buffer() = delete ; - /// No copy constructor - buffer( const buffer& ) = delete ; - /// No assignment by copy - buffer& operator=( const buffer& ) = delete ; - - /** - * @brief Constructor with buffer size - * - * @param len the buffer size to allocate - */ - buffer( size_type len ) ; - - /** - * @brief Constructor with byte array (move!) - * - * @param bytes the byte array - */ - buffer( container &&bytes ) ; - - /** - * @brief Move constructor - * - * @param rhs the other buffer object to move - */ - buffer( buffer&& rhs ) ; - - /** - * @brief Move assignment operator - * - * @param rhs the other buffer object to move - */ - buffer& operator=( buffer&& rhs ) ; - - /** - * @name Iterators - */ - ///@{ - /** - * @brief Get an iterator to the beginning of the byte array - */ - const_iterator begin() const ; - - /** - * @brief Get an iterator to the end of the byte array - */ - const_iterator end() const ; - - /** - * @brief Get an iterator to the beginning of the byte array - */ - iterator begin() ; - - /** - * @brief Get an iterator to the end of the byte array - */ - iterator end() ; - - /** - * @brief Get an iterator to the reverse beginning (end) of the byte array - */ - const_reverse_iterator rbegin() const ; - - /** - * @brief Get an iterator to the reverse end (begin) of the byte array - */ - const_reverse_iterator rend() const ; - - /** - * @brief Get an iterator to the reverse beginning (end) of the byte array - */ - reverse_iterator rbegin() ; - - /** - * @brief Get an iterator to the reverse end (begin) of the byte array - */ - reverse_iterator rend() ; - ///@} - - /** - * @name Element access - */ - ///@{ - /** - * @brief Get a byte at the specified position - * - * @param index the index access - */ - const_reference operator[]( index_type index ) const ; - - /** - * @brief Get a byte at the specified position - * - * @param index the index access - */ - reference operator[]( index_type index ) ; - - /** - * @brief Get a byte at the specified position - * - * @param index the index access - */ - const_reference at( index_type index ) const ; - - /** - * @brief Get a byte at the specified position - * - * @param index the index access - */ - reference at( index_type index ) ; - - /** - * @brief Get a byte at the front position - */ - const_reference front() const ; - - /** - * @brief Get a byte at the front position - */ - reference front() ; - - /** - * @brief Get a byte at the back position - */ - const_reference back() const ; - - /** - * @brief Get a byte at the back position - */ - reference back() ; - - /** - * @brief Get the raw buffer bytes as an array - */ - const_pointer data() const ; - - /** - * @brief Get the raw buffer bytes as an array - */ - pointer data() ; - - /** - * @brief Get a pointer on the raw bytes at the given index - * - * @param index the index access - */ - const_pointer ptr( index_type index ) const ; - - /** - * @brief Get a pointer on the raw bytes at the given index - * - * @param index the index access - */ - pointer ptr( index_type index ) ; - ///@} - - /** - * @name Capacity - */ - ///@{ - /** - * @brief Get the buffer size - */ - size_type size() const ; - - /** - * @brief Whether the buffer is empty - */ - bool empty() const ; - - /** - * @brief Get the underlying current buffer capacity - */ - size_type capacity() const ; - ///@} - - /** - * @name Modifiers - */ - ///@{ - /** - * @brief Resize the buffer to the specified size - * - * @param newsize the new buffer size - */ - void resize( size_type newsize ) ; - - /** - * @brief Expand the buffer by adding new bytes - * - * @param nbytes the number of bytes to add - * @return the new buffer size - */ - size_type expand( size_type nbytes = 32*sio::kbyte*sio::kbyte ) ; - - /** - * @brief Shrink the internal buffer to its size. - * This doesn't modify the buffer size. - */ - void shrink() ; - - /** - * @brief Clear the buffer. - * Note that the memory is not released until the buffer - * gets deleted. To release the buffer memory, use shrink = true - * - * @param shrink whether to shrink the buffer after the clear operation - */ - void clear( bool shrink = false ) ; - ///@} - - /** - * @name Operations - */ - ///@{ - /** - * @brief Re-use the buffer bytes. Creates a new buffer object - * and move the byte container in the new buffer object. - * The current buffer is invalidated - */ - buffer reuse() ; - - /** - * @brief Whether the buffer is valid - * - * The buffer may be invalidated after a move operation - * occuring when: - * - std::move is called - * - buffer::reuse() is called - */ - bool valid() const ; - - /** - * @brief Get a the entire buffer as buffer_span - */ - buffer_span span() const ; - - /** - * @brief Get a sub span of the buffer - * - * @param start where the span starts - */ - buffer_span span( index_type start ) const ; - - /** - * @brief Get a sub span of the buffer - * - * @param start where the sub span starts - * @param count the length of the sub span - */ - buffer_span span( index_type start, size_type count ) const ; - ///@} - - private: - ///< The byte array container - container _bytes {} ; - ///< Whether the buffer is in a valid state - bool _valid {true} ; - }; - -} diff --git a/sio/include/sio/compression/zlib.h b/sio/include/sio/compression/zlib.h deleted file mode 100644 index 46e106c07..000000000 --- a/sio/include/sio/compression/zlib.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -// -- sio headers -#include - -namespace sio { - - class buffer ; - class buffer_span ; - - class zlib_compression { - public: - /// Default constructor - zlib_compression() = default ; - /// Default destructor - ~zlib_compression() = default ; - - /** - * @brief Set the compression level. - * - Z_DEFAULT_COMPRESSION: default zlib compression level - * - 0: no commpression - * - [1-9] various levels - * Note that above 9, the level is set to 9 - * - * @param level the compression level to use - */ - void set_level( int level ) ; - - /** - * @brief Get the compression level - */ - int level() const ; - - /** - * @brief Uncompress the buffer and return a new buffer (reference). - * The uncpmpressed buffer must have been resized correctly - * before calling this function. - * - * @param inbuf the input buffer to uncompress - * @param outbuf the uncompressed buffer to receive - */ - void uncompress( const buffer_span &inbuf, buffer &outbuf ) ; - - /** - * @brief Compress the buffer and return a new buffer - * - * @param inbuf the input buffer to compress - * @param outbuf the output buffer to receive - */ - void compress( const buffer_span &inbuf, buffer &outbuf ) ; - - private: - ///< The compression level (on compress) - default: Z_DEFAULT_COMPRESSION (-1) - int _level {-1} ; - }; - -} - diff --git a/sio/include/sio/definitions.h b/sio/include/sio/definitions.h deleted file mode 100644 index b29214459..000000000 --- a/sio/include/sio/definitions.h +++ /dev/null @@ -1,350 +0,0 @@ -#pragma once - -// -- std headers -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __APPLE__ -#include <_types.h> -#include <_types/_uint16_t.h> -#include <_types/_uint32_t.h> -#include <_types/_uint64_t.h> -#include <_types/_uint8_t.h> -#include -#include -#else -#include -#endif - -// ---------------------------------------------------------------------------- -// Deal with 'endian-ness'. Try to base this on the processor type (because -// the operating system doesn't guarantee endian-ness ... Linux runs happily -// on both x86 CPUs (little endian) and PPC CPUs (big endian)). -// -// Branch on flag provided by compiler: -// -// OS CPU Macro Provided by Endian-ness -// ------------ ------------ ------------ ------------ ----------- -// AIX PPC(?) _AIX GNU compiler Big -// OSF1 Alpha __alpha__ GNU compiler Little -// Linux x86 __i386__ GNU compiler Little -// Linux Opteron _LP64 GNU compiler Little -// Linux itanium _LP64 GNU compiler Little -// SunOS Sparc __sparc__ GNU compiler Big -// Windows/NT Alpha _M_ALPHA VC compiler Little -// Windows/NT x86 _M_IX86 VC compiler Little -// Windows/NT MIPS _M_MRX000 VC compiler ? -// Windows/NT PPC _M_PPC VC compiler Big -// ---------------------------------------------------------------------------- -#if defined(__alpha__) || defined(__i386__) || defined(_M_ALPHA) || defined(_M_IX86) || defined(_LP64) || defined(__LITTLE_ENDIAN__) -#define SIO_LITTLE_ENDIAN -#endif - -#if defined(_AIX) || defined(__sparc__) || defined(_M_PPC) || ( defined(__APPLE_CC__) && !defined(__LITTLE_ENDIAN__) ) -#define SIO_BIG_ENDIAN -#endif - -#if !defined(SIO_LITTLE_ENDIAN) && !defined(SIO_BIG_ENDIAN) -#error "Couldn't determine endianess on this plateform!" -#endif - -/** - * sio (simple io) namespace. - * Holds a persistency implementation using sio - */ -namespace sio { - - // ---------------------------------------------------------------------------- - // Deal with pointer length. Currently, the only problem is alpha which uses - // 64 bit pointers. - // - // OS CPU Macro Provided by Pointer size - // ------------ ------------ ------------ ------------ ----------- - // AIX PPC(?) _AIX GNU compiler 4 bytes - // OSF1 Alpha __alpha__ GNU compiler 8 bytes - // Linux x86 __i386__ GNU compiler 4 bytes - // Linux Opteron _LP64 _ GNU compiler 8 bytes - // Linux Itanium _LP64 GNU compiler 8 bytes - // SunOS Sparc __sparc__ GNU compiler 4 bytes - // Windows/NT Alpha _M_ALPHA VC compiler 8 bytes - // Windows/NT x86 _M_IX86 VC compiler 4 bytes - // Windows/NT MIPS _M_MRX000 VC compiler ? bytes - // Windows/NT PPC _M_PPC VC compiler 4 bytes - // ---------------------------------------------------------------------------- - // Old check was problematic because both macros could evaluate to true, and it would - // also be possible that sio::ptr_type was not defined at all. Change as needed. - // --JM -#if defined(__alpha__) || defined(_M_ALPHA) || defined(_LP64) - using ptr_type = std::size_t ; -#else - using ptr_type = unsigned int ; -#endif - - class block ; - class read_device ; - class write_device ; - class buffer ; - class buffer_span ; - - // Bytes related types - using byte = char ; - using byte_array = std::vector ; - using byte_traits = std::char_traits ; - // Other types - using index_type = std::size_t ; - using options_type = unsigned int ; - using version_type = uint32_t ; - using pointed_at_map = std::map< void*, void* > ; - using pointer_to_map = std::multimap< void*, void* > ; - using ifstream = std::ifstream ; - using ofstream = std::ofstream ; - using fstream = std::fstream ; - using block_ptr = std::shared_ptr ; - using block_list = std::vector ; - - /// The null byte definition - static constexpr byte null_byte = '\0' ; - - static constexpr byte padding_bytes [4] = {null_byte} ; - /// Kilo byte unit - static constexpr std::size_t kbyte = 0x00000400 ; - /// Mega byte unit - static constexpr std::size_t mbyte = 0x00100000 ; - /// The compression bit mask - static constexpr unsigned int compression_bit = 0x00000001 ; - /// The bit alignment mask - static constexpr unsigned int bit_align = 0x00000003 ; - /// The additional padding added in buffer IO - static constexpr unsigned int padding = 3 ; - /// The additional padding mask - static constexpr unsigned int padding_mask = 0xfffffffc ; - /// The record marker - static constexpr unsigned int record_marker = 0xabadcafe ; - /// The block marker - static constexpr unsigned int block_marker = 0xdeadbeef ; - /// The maximum length of a record name - static constexpr std::size_t max_record_name_len = 64 ; - /// The maximum length of a record_info in memory - static constexpr std::size_t max_record_info_len = 2*sizeof(sio::ifstream::pos_type) + 5*sizeof(unsigned int) + max_record_name_len ; - - // TODO: Do we still need all of this ?? - static constexpr std::size_t single_len = 1 ; - static constexpr std::size_t double_len = 2 ; - static constexpr std::size_t quad_len = 4 ; - static constexpr std::size_t octo_len = 8 ; - - /** - * @brief record_info struct. - * - * Holds simple descriptive fields on record - */ - struct record_info { - ///< Position of the record start in the file - sio::ifstream::pos_type _file_start {0} ; - ///< Position of the record end in the file - sio::ifstream::pos_type _file_end {0} ; - ///< The size of the record header in memory - unsigned int _header_length {0} ; - ///< The record options - unsigned int _options {0} ; - ///< The size of the record data read out from the file - unsigned int _data_length {0} ; - ///< The size of the record data after uncompression (if compressed) - unsigned int _uncompressed_length {0} ; - ///< The record name - std::string _name {} ; - }; - - /** - * @brief block_info struct. - * - * Holds simple descriptive fields on block - */ - struct block_info { - ///< The start position of the block in the record buffer - unsigned int _record_start {0} ; - ///< The end position of the block in the record buffer - unsigned int _record_end {0} ; - ///< The size of the block header in memory - unsigned int _header_length {0} ; - ///< The block version - unsigned int _version {0} ; - ///< The size of the block data - unsigned int _data_length {0} ; - ///< The block name - std::string _name {} ; - }; - - /** - * @brief Streaming operator for record_info - */ - inline std::ostream &operator<<( std::ostream &stream, const record_info &info ) { - stream << "- name: " << info._name << std::endl ; - stream << "- file pos: " << info._file_start << " - " << info._file_end << std::endl ; - stream << "- header len: " << info._header_length << std::endl ; - stream << "- options: " << info._options << std::endl ; - stream << "- compressed len: " << info._data_length << std::endl ; - stream << "- uncompressed len: " << info._uncompressed_length << std::endl ; - return stream ; - } - - /** - * @brief Streaming operator for block_info - */ - inline std::ostream &operator<<( std::ostream &stream, const block_info &info ) { - stream << "- name: " << info._name << std::endl ; - stream << "- record pos: " << info._record_start << " - " << info._record_end << std::endl ; - stream << "- header len: " << info._header_length << std::endl ; - stream << "- version: " << info._version << std::endl ; - stream << "- data len: " << info._data_length << std::endl ; - return stream ; - } - - /** - * @brief Validate a name. - * - * SIO only accepts names starting with (regular expression) [A-Za-z_] - * and continuing with [A-Za-z0-9_] (which most people will recognize - * as the definition of a C/C++ variable name). - * - * @param name the string name to test - */ - inline bool validate( const std::string &name ) { - auto cname = name.c_str() ; - if( *cname < 0 ) { - return false; - } - if( !isalpha( (int)*cname ) && *cname != '_' ) { - return false; - } - for( cname += 1; *cname != '\0'; cname++ ) { - if( *cname < 0 ) { - return false; - } - if( !isalnum( (int)*cname ) && *cname != '_' ) { - return false; - } - } - return true; - } - - /** - * @brief Validate a record name - * - * @param name the record name to validate - */ - inline bool valid_record_name( const std::string &name ) { - if( not sio::validate( name ) ) { - return false ; - } - if( name.size() > sio::max_record_name_len ) { - return false ; - } - return true ; - } -} - -// SIO_LOGLVL defines the log level. The verbosity is fixed -// at compile time to avoid performance issue due to logging -// Log levels: -// - silent: 0 -// - debug: 1 -// - info: 2 -// - warning: 3 -// - error: 4 -#ifndef SIO_LOGLVL -#define SIO_LOGLVL 2 -#endif - -#if SIO_LOGLVL > 3 -#define SIO_DEBUG( message ) std::cout << "[SIO DEBUG] " << __FUNCTION__ << " - " << message << std::endl -#else -#define SIO_DEBUG( message ) -#endif - -#if SIO_LOGLVL > 2 -#define SIO_INFO( message ) std::cout << "[SIO INFO] - " << __FUNCTION__ << " - " << message << std::endl -#else -#define SIO_INFO( message ) -#endif - -#if SIO_LOGLVL > 1 -#define SIO_WARNING( message ) std::cout << "[SIO WARNING] - " << __FUNCTION__ << " - " << message << std::endl -#else -#define SIO_WARNING( message ) -#endif - -#if SIO_LOGLVL > 0 -#define SIO_ERROR( message ) std::cout << "[SIO ERROR] - " << __FUNCTION__ << " - " << message << std::endl -#else -#define SIO_ERROR( message ) -#endif - -// address cast -#define SIO_BYTE_CAST(pntr) (reinterpret_cast((pntr))) -#define SIO_CBYTE_CAST(pntr) (reinterpret_cast((pntr))) -#define SIO_UCHAR_CAST(pntr) (reinterpret_cast((pntr))) -#define SIO_CUCHAR_CAST(pntr) (reinterpret_cast((pntr))) - -// version decoding/encoding for backward compatibility -#define SIO_VERSION_MAJOR( v ) sio::version::major_version( v ) -#define SIO_VERSION_MINOR( v ) sio::version::minor_version( v ) -#define SIO_VERSION_ENCODE( maj, min ) sio::version::encode_version( maj, min ) - -#ifdef SIO_MACROS_WITH_EXCEPTION -#warning "SIO_MACROS_WITH_EXCEPTION activated!" -// Read or write data -#define SIO_DATA( dev, pnt, cnt ) \ - try { \ - SIO_DEBUG( "Reading/writing " << #pnt << " of size " << cnt ); \ - dev.data( pnt, cnt ) ; \ - } \ - catch( sio::exception &e ) { \ - SIO_RETHROW( e, sio::error_code::io_failure, "Failed to read or write data!" ) ; \ - } - -// Specialized macro for simple data reading/writing -#define SIO_SDATA( dev, dat ) \ - try { \ - SIO_DEBUG( "Simple reading/writing " << #dat ); \ - dev.data( dat ) ; \ - } \ - catch( sio::exception &e ) { \ - SIO_RETHROW( e, sio::error_code::io_failure, "Failed to read or write data!" ) ; \ - } - -// Read or write a pointer (pointer to) -#define SIO_PNTR( dev, pnt ) \ - try { \ - SIO_DEBUG( "Reading/writing pointer to" << #pnt ); \ - dev.pointer_to( (sio::ptr_type*)pnt ) ; \ - } \ - catch( sio::exception &e ) { \ - SIO_RETHROW( e, sio::error_code::io_failure, "Failed to read or write pointer to!" ) ; \ - } - -// Read or write a pointer tag (pointed at) -#define SIO_PTAG( dev, pnt ) \ - try { \ - SIO_DEBUG( "Reading/writing pointed at" << #pnt ); \ - dev.pointed_at( (sio::ptr_type*)pnt ) ; \ - } \ - catch( sio::exception &e ) { \ - SIO_RETHROW( e, sio::error_code::io_failure, "Failed to read or write pointed at!" ) ; \ - } -#else -// Read or write data -#define SIO_DATA( dev, pnt, cnt ) dev.data( pnt, cnt ) -// Specialized macro for simple data reading/writing -#define SIO_SDATA( dev, dat ) dev.data( dat ) -// Read or write a pointer (pointer to) -#define SIO_PNTR( dev, pnt ) dev.pointer_to( (sio::ptr_type*)pnt ) -// Read or write a pointer tag (pointed at) -#define SIO_PTAG( dev, pnt ) dev.pointed_at( (sio::ptr_type*)pnt ) - -#endif diff --git a/sio/include/sio/exception.h b/sio/include/sio/exception.h deleted file mode 100644 index c00f44868..000000000 --- a/sio/include/sio/exception.h +++ /dev/null @@ -1,147 +0,0 @@ -#pragma once - -// -- std headers -#include -#include - -// exception helper macros -#define SIO_THROW( code, message ) throw sio::exception( code, __LINE__, __FUNCTION__, __FILE__, message ) -#define SIO_RETHROW( orig, code, message ) throw sio::exception( orig, code, __LINE__, __FUNCTION__, __FILE__, message ) - -namespace sio { - - /** - * @brief error_code enumerator - */ - enum class error_code : unsigned int { - invalid_argument, - not_found, - already_open, - open_fail, - not_open, - eof, - io_failure, - no_marker, - compress_error, - bad_state, - bad_alloc, - out_of_range - }; - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - /** - * @brief error_code_helper class. - * - * Helper class for error_code manipulation - */ - class error_code_helper { - public: - // static API only - error_code_helper() = delete ; - - public: - /** - * @brief Convert error_code to string - * - * @param code the code to convert - */ - static std::string to_string( error_code code ) noexcept ; - }; - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - /** - * @brief exception class - * - * Main sio exception class. - */ - class exception : public std::exception { - public: - exception() = delete ; - exception( const exception & ) = default ; - ~exception() = default ; - - /** - * @brief Constructor - * - * @param code the error code - * @param line the exception line number - * @param func the function name in which the exception has been thrown - * @param fname the file in which the exception has been thrown - * @param msg the exception message - */ - exception( error_code code, unsigned int line, const std::string &func, const std::string &fname, const std::string &msg ) ; - - /** - * @brief Constructor - * - * @param rhs any possible class having a method what() returning a string - * @param code the error code - * @param line the exception line number - * @param func the function name in which the exception has been thrown - * @param fname the file in which the exception has been thrown - * @param msg the exception message - */ - template - exception( const T &rhs, error_code code, unsigned int line, const std::string &func, const std::string &fname, const std::string &msg ) ; - - /** - * @brief Get the full exception message - */ - const char* what() const noexcept override ; - - /** - * @brief Get the associated error code - */ - sio::error_code code() const ; - - protected: - /** - * @brief Helper function creating the full exception message - * - * @param code the error code - * @param line the exception line number - * @param func the function name in which the exception has been thrown - * @param fname the file in which the exception has been thrown - * @param msg the exception message - */ - std::string message( error_code code, unsigned int line, const std::string &func, const std::string &fname, const std::string &msg ) const ; - - /** - * @brief Helper function creating the full exception message - * - * @param a previous message to prepend in the message (plus a line break) - * @param code the error code - * @param line the exception line number - * @param func the function name in which the exception has been thrown - * @param fname the file in which the exception has been thrown - * @param msg the exception message - */ - std::string message( const std::string &previous, error_code code, unsigned int line, const std::string &func, const std::string &fname, const std::string &msg ) const ; - - protected: - ///< The associated error code - const error_code _code ; - ///< The full exception message - const std::string _message ; - }; - - //-------------------------------------------------------------------------- - - template - inline exception::exception( - const T &rhs, - error_code code, - unsigned int line, - const std::string &func, - const std::string &fname, - const std::string &msg ) : - _code( code ) , - _message( message(rhs.what(), code, line, func, fname, msg) ) { - /* nop */ - } - -} diff --git a/sio/include/sio/io_device.h b/sio/include/sio/io_device.h deleted file mode 100644 index f877bb0ec..000000000 --- a/sio/include/sio/io_device.h +++ /dev/null @@ -1,383 +0,0 @@ -#pragma once - -// -- sio headers -#include -#include - -namespace sio { - - class buffer ; - class buffer_span ; - - /** - * @brief read_device class. - * - * Holds a buffer_span and a cursor allowing to read - * data sequentially, moving the cursor after reading. - */ - class read_device { - public: - using cursor_type = std::size_t ; - using size_type = std::size_t ; - - public: - /// Default constructor - read_device() = default ; - /// Default copy constructor - read_device( const read_device & ) = default ; - /// Default move constructor - read_device( read_device && ) = default ; - /// Default assignement operator - read_device& operator=( const read_device & ) = default ; - /// Default move assignement operator - read_device& operator=( read_device && ) = default ; - /// Default destructor - ~read_device() = default ; - - /** - * @brief Constructor with buffer span - * - * @param buf the input buffer span - */ - read_device( buffer_span buf ) ; - - /** - * @name Buffer - */ - ///{@ - /** - * @brief Set the buffer span to use (move) - * - * @param buf the buffer to use - */ - void set_buffer( buffer_span &&buf ) ; - - /** - * @brief Set the buffer span to use (copy) - * - * @param buf the buffer to use - */ - void set_buffer( const buffer_span &buf ) ; - ///@} - - /** - * @name Cursor - */ - ///{@ - /** - * @brief Get the cursor position - */ - cursor_type position() const ; - - /** - * @brief Seek the cursor at a given position - * - * @param pos the new cursor position - */ - void seek( cursor_type pos ) ; - ///@} - - /** - * @name I/O operations - */ - ///{@ - /** - * @brief Read out a variable from the buffer. Move the cursor accordingly - * - * @param var the variable to receive - */ - template - void data( T &var ) ; - - /** - * @brief Read out a vector from the buffer. Move the cursor accordingly - * - * @param vars the vector to receive - */ - template - void data( std::vector &vars ) ; - - /** - * @brief Read out an array of variables from the buffer. Move the cursor accordingly - * - * @param var the address of the array - * @param count the number of element to read out - */ - template - void data( T *var, size_type count ) ; - - /** - * @brief Read out a "pointer to" pointer from the buffer. - * A new entry is created for a future relocation. - * The pointer relocation is performed at the end of record reading - * - * @param ptr the address to register - */ - void pointer_to( ptr_type *ptr ) ; - - /** - * @brief Read out a "pointed at" pointer from the buffer. - * A new entry is created for a future relocation. - * The pointer relocation is performed at the end of record reading - * - * @param ptr the address to register - */ - void pointed_at( ptr_type *ptr ) ; - - /** - * @brief Perform the pointer relocation after the whole record has - * been read. The pointers are relocated and the pointer maps - * are cleared - */ - void pointer_relocation() ; - ///@} - - private: - ///< The buffer span - buffer_span _buffer {} ; - ///< The device cursor - cursor_type _cursor {0} ; - ///< The map of pointer "pointed at" - pointed_at_map _pointed_at {} ; - ///< The map of pointer "pointer to" - pointer_to_map _pointer_to {} ; - }; - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - /** - * @brief write_device class. - * - * Holds a buffer and provide a api to write data sequentially - * to this buffer by using a cursor - */ - class write_device { - public: - using cursor_type = std::size_t ; - using size_type = std::size_t ; - - public: - /// No default constructor - write_device() = delete ; - /// Default copy constructor - write_device( const write_device & ) = delete ; - /// Default move constructor - write_device( write_device && ) = default ; - /// Default assignement operator - write_device& operator=( const write_device & ) = delete ; - /// Default move assignement operator - write_device& operator=( write_device && ) = default ; - /// Default destructor - ~write_device() = default ; - /// Constructor with buffer - write_device( buffer&& buf ) ; - - /** - * @name Buffer - */ - ///{@ - /** - * @brief Set the buffer to use (move) - * - * @param buf the buffer to use - */ - void set_buffer( buffer&& buf ) ; - - /** - * @brief Take out the buffer from the device. - * The buffer in the device becomes invalid - */ - buffer take_buffer() ; - ///@} - - /** - * @name Cursor - */ - ///{@ - /** - * @brief Get the cursor position - */ - cursor_type position() const ; - - /** - * @brief Seek the cursor at a given position - * - * @param pos the new cursor position - */ - void seek( cursor_type pos ) ; - ///@} - - /** - * @name I/O operations - */ - ///{@ - /** - * @brief Write out a variable to the buffer. Move the cursor accordingly - * - * @param var the variable to write - */ - template - void data( const T &var ) ; - - /** - * @brief Write out a vector to the buffer. Move the cursor accordingly - * - * @param vars the vector to write - */ - template - void data( const std::vector &vars ) ; - - /** - * @brief Write out an array of variables to the buffer. Move the cursor accordingly - * - * @param var the address of the array - * @param count the number of element to write out - */ - template - void data( const T *const var, size_type count ) ; - - /** - * @brief Write out a "pointer to" pointer to the buffer. - * A new entry is created for a future relocation. - * The pointer relocation is performed at the end of record writting - * - * @param ptr the address to register - */ - void pointer_to( ptr_type *ptr ) ; - - /** - * @brief Write out a "pointed at" pointer to the buffer. - * A new entry is created for a future relocation. - * The pointer relocation is performed at the end of record writting - * - * @param ptr the address to register - */ - void pointed_at( ptr_type *ptr ) ; - - /** - * @brief Perform the pointer relocation after the whole record has - * been written. The pointers are relocated and the pointer maps - * are cleared - */ - void pointer_relocation() ; - ///@} - - private: - ///< The buffer in which to write - buffer _buffer ; - ///< The device cursor - cursor_type _cursor {0} ; - ///< The map of pointer "pointed at" - pointed_at_map _pointed_at {} ; - ///< The map of pointer "pointer to" - pointer_to_map _pointer_to {} ; - }; - -} - -#include - -namespace sio { - - //-------------------------------------------------------------------------- - - // specialization of string - template <> - inline void read_device::data( std::string &var ) { - int len(0) ; - data( len ) ; - var.resize( len ) ; - data( &var[0], len ) ; - } - - //-------------------------------------------------------------------------- - - // specialization of vector of strings - template <> - inline void read_device::data( std::vector &vars ) { - int len (0) ; - data( len ) ; - if( len > 0 ) { - vars.resize( len ) ; - for( std::string &str : vars ) { - data( str ) ; - } - } - } - - //-------------------------------------------------------------------------- - - template - inline void read_device::data( T &var ) { - data( &var, 1 ) ; - } - - //-------------------------------------------------------------------------- - - template - inline void read_device::data( std::vector &vars ) { - int len (0) ; - data( len ) ; - if( len > 0 ) { - vars.resize( len ) ; - data( &vars[0], len ) ; - } - } - - //-------------------------------------------------------------------------- - - template - inline void read_device::data( T *var, size_type count ) { - _cursor += sio::api::read( _buffer, var, _cursor, count ) ; - } - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - // specialization for string - template <> - inline void write_device::data( const std::string &var ) { - int len = var.size() ; - data( len ) ; - data( var.data(), len ) ; - } - - //-------------------------------------------------------------------------- - - // specialization for vector of strings - template <> - inline void write_device::data( const std::vector &vars ) { - data( static_cast(vars.size()) ) ; - if( not vars.empty() ) { - for( auto &str : vars ) { - data( str ) ; - } - } - } - - //-------------------------------------------------------------------------- - - template - inline void write_device::data( const T &var ) { - data( &var, 1 ) ; - } - - //-------------------------------------------------------------------------- - - template - inline void write_device::data( const std::vector &vars ) { - data( (int)vars.size() ) ; - if( not vars.empty() ) { - data( &vars[0], vars.size() ) ; - } - } - - //-------------------------------------------------------------------------- - - template - inline void write_device::data( const T *const var, size_type count ) { - _cursor += sio::api::write( _buffer, var, _cursor, count ) ; - } - -} diff --git a/sio/include/sio/memcpy.h b/sio/include/sio/memcpy.h deleted file mode 100644 index 93bf79cd0..000000000 --- a/sio/include/sio/memcpy.h +++ /dev/null @@ -1,119 +0,0 @@ -#pragma once - -// -- sio headers -#include - -// -- std headers -#include // std::memcpy, std::size_t - -namespace sio { - - /** - * @brief sizeof_helper struct. - * Helper structure to hardcode the size of some types. - * This is there to ensure backward compatibility with - * the old SIO implementation - */ - template - struct sizeof_helper { - static constexpr std::size_t size = sizeof(T) ; - }; - -#define SIO_FORCE_SIZEOF( TYPE, SIZE ) \ - template <> \ - struct sizeof_helper { \ - static constexpr std::size_t size = SIZE ; \ - } - - SIO_FORCE_SIZEOF( char, 1 ) ; - SIO_FORCE_SIZEOF( unsigned char, 1 ) ; - SIO_FORCE_SIZEOF( short, 2 ) ; - SIO_FORCE_SIZEOF( unsigned short, 2 ) ; - SIO_FORCE_SIZEOF( int , 4 ) ; - SIO_FORCE_SIZEOF( unsigned int , 4 ) ; -#if defined(_AIX) || defined(__alpha__) || defined(__i386__) || defined(__sparc__) || defined(__APPLE_CC__) || defined(_LP64) - SIO_FORCE_SIZEOF( long long , 8 ) ; - SIO_FORCE_SIZEOF( unsigned long long , 8 ) ; -#else - SIO_FORCE_SIZEOF( __int64 , 8 ) ; - SIO_FORCE_SIZEOF( unsigned __int64 , 8 ) ; -#endif - SIO_FORCE_SIZEOF( float , 4 ) ; - SIO_FORCE_SIZEOF( double , 8 ) ; - -#undef SIO_FORCE_SIZEOF - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - /** - * @brief memcpy class - * - * Perform raw data copy and deals with plateform endian-ness - */ - class memcpy { - public: - // static API only - memcpy() = delete ; - - /** - * @brief Perform a reverse byte copy - * - * @param from the input bytes address to copy - * @param dest the output destination of copied bytes - * @param size the size of the element in the bytes - * @param count the number of elements to copy - */ - static void reverse_copy( const sio::byte *const from, sio::byte *dest, std::size_t size, std::size_t count ) ; - - /** - * @brief Perform a byte array copy - * - * @param from the input bytes address to copy - * @param dest the output destination of copied bytes - * @param size the size of the element in the bytes - * @param count the number of elements to copy - */ - static void copy( const sio::byte *const from, sio::byte *dest, std::size_t size, std::size_t count ) ; - - /** - * @brief Template overload of raw copy (see above) for writing. - * The size of the template parameter is evaluated using the - * helper structure sizeof_helper. - * - * @param from the array to copy - * @param dest the destination byte pointer - * @param count the number of elements to copy - */ - template - static void write( const T *const from, sio::byte *dest, std::size_t count ) ; - - /** - * @brief Template overload of raw copy (see above) for reading. - * The size of the template parameter is evaluated using the - * helper structure sizeof_helper. - * - * @param from the bytes to copy - * @param dest the destination array - * @param count the number of elements to copy - */ - template - static void read( const sio::byte *const from, T *dest, std::size_t count ) ; - }; - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - template - inline void memcpy::write( const T *const from, sio::byte *dest, std::size_t count ) { - sio::memcpy::copy( reinterpret_cast(from), dest, sizeof_helper::size, count ) ; - } - - //-------------------------------------------------------------------------- - - template - inline void memcpy::read( const sio::byte *const from, T *dest, std::size_t count ) { - sio::memcpy::copy( from, reinterpret_cast(dest), sizeof_helper::size, count ) ; - } - -} diff --git a/sio/include/sio/version.h b/sio/include/sio/version.h deleted file mode 100644 index e8e564e26..000000000 --- a/sio/include/sio/version.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// -- sio headers -#include - -namespace sio { - - /** - * @brief version class. - * - * Helper class to encode or decode version in a single variable - */ - class version { - public: - using version_type = sio::version_type ; - using major_type = uint16_t ; - using minor_type = uint16_t ; - - public: - // static API only - version() = delete ; - - /** - * @brief Encode a version from a major and minor version number - * - * @param major the major version number - * @param minor the minor version number - */ - static version_type encode_version( major_type major, minor_type minor ) noexcept ; - - /** - * @brief Decode a minor version number from the version number - * - * @param version the full version number - */ - static minor_type minor_version( version_type version ) noexcept ; - - /** - * @brief Decode a major version number from the version number - * - * @param version the full version number - */ - static major_type major_version( version_type version ) noexcept ; - }; - -} - diff --git a/sio/src/api.cc b/sio/src/api.cc deleted file mode 100644 index a55aa3646..000000000 --- a/sio/src/api.cc +++ /dev/null @@ -1,596 +0,0 @@ -// -- sio headers -#include -#include -#include -#include -#include -#include -#include -#include - -// -- std headers -#include -#include -#include -#include -#include - -namespace sio { - - void api::read_relocation( pointed_at_map& pointed_at, pointer_to_map& pointer_to ) { - // Pointer relocation on read. - // Some of these variables are a little terse! Expanded meanings: - // ptol: Iterator pointing to lower bound in the 'pointer to' multimap - // ptoh: Iterator pointing to upper bound in the 'pointer to' multimap - // ptoi: Iterator for the 'pointer to' multimap (runs [ptol, ptoh) ) - // pati: Iterator in the 'pointed at' map (search map for ptol->first) - auto ptol = pointer_to.begin() ; - while( ptol != pointer_to.end() ) { - auto ptoh = pointer_to.upper_bound( ptol->first ) ; - auto pati = pointed_at.find( ptol->first ) ; - bool pat_found( pati != pointed_at.end() ) ; - // if the pointed at object is not found we set the pointer to null - for( auto ptoi = ptol; ptoi != ptoh; ptoi++ ) { - auto pointer = static_cast( ptoi->second ) ; - *pointer = ( pat_found ? reinterpret_cast( pati->second ) : 0 ) ; - } - ptol = ptoh ; - } - } - - //-------------------------------------------------------------------------- - - void api::write_relocation( buffer::const_pointer rec_start, pointed_at_map& pointed_at, pointer_to_map& pointer_to ) { - // Pointer relocation on write. - // Some of these variables are a little terse! Expanded meanings: - // ptol: Iterator pointing to lower bound in the 'pointer to' multimap - // ptoh: Iterator pointing to upper bound in the 'pointer to' multimap - // ptoi: Iterator for the 'pointer to' multimap (runs [ptol, ptoh) ) - // pati: Iterator in the 'pointed at' map (search map for ptol->first) - unsigned int match = 0x00000001 ; - auto ptol = pointer_to.begin() ; - while( ptol != pointer_to.end() ) { - auto ptoh = pointer_to.upper_bound( ptol->first ) ; - auto pati = pointed_at.find( ptol->first ) ; - if( pati != pointed_at.end() ) { - auto pointer = rec_start + reinterpret_cast( pati->second ) ; - sio::memcpy::write( &match, (sio::byte*)pointer, 1 ) ; - for( auto ptoi = ptol; ptoi != ptoh; ptoi++ ) { - pointer = rec_start + reinterpret_cast( ptoi->second ) ; - sio::memcpy::write( &match, (sio::byte*)pointer, 1 ) ; - } - } - match++ ; - ptol = ptoh ; - } - } - - //-------------------------------------------------------------------------- - - void api::read_record_info( sio::ifstream &stream, record_info &rec_info, buffer &outbuf ) { - if( not stream.is_open() ) { - SIO_THROW( sio::error_code::not_open, "ifstream is not open!" ) ; - } - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state!" ) ; - } - rec_info._file_start = stream.tellg() ; - outbuf.resize( sio::max_record_info_len ) ; - SIO_DEBUG( "Reading first record bytes of input stream at position: " << stream.tellg() ) ; - stream.read( outbuf.data(), 8 ) ; - if( stream.eof() ) { - SIO_THROW( sio::error_code::eof, "Reached end of file !" ) ; - } - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state after reading first record bytes!" ) ; - } - unsigned int marker(0) ; - read_device device( outbuf.span() ) ; - // Interpret: 1) The length of the record header. - // 2) The record marker. - device.data( rec_info._header_length ) ; - device.data( marker ) ; - if( marker != sio::record_marker ) { - stream.setstate( sio::ifstream::failbit ) ; - SIO_THROW( sio::error_code::no_marker, "Record marker not found!" ) ; - } - // Interpret: 3) The options word. - // 4) The length of the record data (compressed). - // 5) The length of the record name (uncompressed). - // 6) The length of the record name. - // 7) The record name. - stream.read( outbuf.ptr(8), rec_info._header_length-8 ) ; - device.seek( 8 ) ; - device.data( rec_info._options ) ; - device.data( rec_info._data_length ) ; - device.data( rec_info._uncompressed_length ) ; - unsigned int name_length(0) ; - device.data( name_length ) ; - if( name_length > sio::max_record_name_len ) { - SIO_THROW( sio::error_code::no_marker, "Invalid record name size (limited)" ) ; - } - rec_info._name.assign( name_length, '\0' ) ; - device.data( &(rec_info._name[0]), name_length ) ; - const auto compressed = sio::api::is_compressed( rec_info._options ) ; - // if the record is compressed skip the read pointer over - // any padding bytes that may have been inserted to make - // the next record header start on a four byte boundary in the file. - auto tot_len = rec_info._data_length + rec_info._header_length ; - SIO_DEBUG( "Total len before: " << tot_len ) ; - if( compressed ) { - tot_len += ((4 - (rec_info._data_length & sio::bit_align)) & sio::bit_align) ; - } - SIO_DEBUG( "Total len after padding: " << tot_len ) ; - rec_info._file_end = rec_info._file_start ; - rec_info._file_end += tot_len ; - // a bit of debugging ... - SIO_DEBUG( "=== Read record info ====" ) ; - SIO_DEBUG( rec_info ) ; - SIO_DEBUG( "read_record_info: Resizing buffer to " << rec_info._header_length ) ; - outbuf.resize( rec_info._header_length ) ; - } - - //-------------------------------------------------------------------------- - - void api::read_record_data( sio::ifstream &stream, const record_info &rec_info, buffer &outbuf, std::size_t buffer_shift ) { - if( not stream.is_open() ) { - SIO_THROW( sio::error_code::not_open, "ifstream is not open!" ) ; - } - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state!" ) ; - } - // resize the buffer to the expected read size. - // this may not re-allocate the buffer internally - // if it was large enough - outbuf.resize( buffer_shift + rec_info._data_length ) ; - // go to record start - auto seek_pos = rec_info._file_start ; - seek_pos += rec_info._header_length ; - stream.seekg( seek_pos ) ; - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state after a seek operation!" ) ; - } - stream.read( outbuf.ptr( buffer_shift ), rec_info._data_length ) ; - if( not stream.good() ) { - SIO_THROW( sio::error_code::io_failure, "ifstream is in a bad state after a read operation!" ) ; - } - if( not stream.seekg( rec_info._file_end ).good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state after a seek operation!" ) ; - } - SIO_DEBUG( "read_record_data: Resizing buffer to " << buffer_shift + rec_info._data_length ) ; - outbuf.resize( buffer_shift + rec_info._data_length ) ; - } - - //-------------------------------------------------------------------------- - - void api::read_record( sio::ifstream &stream, record_info &rec_info, buffer &outbuf ) { - // read out the record info - api::read_record_info( stream, rec_info, outbuf ) ; - // read out the record data in the buffer. Shift the buffer position by the - // size of the record header to keep the record header bytes in the buffer too. - api::read_record_data( stream, rec_info, outbuf, rec_info._header_length ) ; - } - - //-------------------------------------------------------------------------- - - std::pair api::read_record( sio::ifstream &stream ) { - record_info rec_info ; - buffer outbuf( sio::mbyte ) ; - api::read_record( stream, rec_info, outbuf ) ; - return std::make_pair( rec_info, std::move( outbuf ) ) ; - } - - //-------------------------------------------------------------------------- - - void api::skip_n_records( sio::ifstream &stream, std::size_t nskip ) { - std::size_t counter = 0 ; - api::skip_records( stream, [&]( const record_info & ) { - ++ counter ; - return ( counter < nskip ) ; - }) ; - } - - //-------------------------------------------------------------------------- - - void api::skip_records( sio::ifstream &stream, std::size_t nskip, const std::string &name ) { - std::size_t counter = 0 ; - api::skip_records( stream, [&]( const record_info &rec_info ) { - if( name == rec_info._name ) { - ++ counter ; - } - return ( counter < nskip ) ; - }) ; - } - - //-------------------------------------------------------------------------- - - void api::go_to_record( sio::ifstream &stream, const std::string &name ) { - record_info goto_info ; - api::skip_records( stream, [&]( const record_info &rec_info ) { - if( name == rec_info._name ) { - goto_info = rec_info ; - return false ; - } - return true ; - }) ; - stream.seekg( goto_info._file_start ) ; - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ifstream is in a bad state after a seek operation!" ) ; - } - } - - //-------------------------------------------------------------------------- - - std::vector api::read_block_infos( const buffer_span &buf ) { - if( not buf.valid() ) { - SIO_THROW( sio::error_code::bad_state, "Buffer is invalid." ) ; - } - std::vector block_infos ; - buffer_span::index_type current_pos (0) ; - while( 1 ) { - // end of block buffer ? - if( current_pos >= buf.size() ) { - break ; - } - auto block_data = sio::api::extract_block( buf, current_pos ) ; - current_pos = block_data.first._record_end ; - block_infos.push_back( block_data.first ) ; - } - return block_infos ; - } - - //-------------------------------------------------------------------------- - - std::pair api::extract_block( const buffer_span &rec_buf, buffer_span::index_type index ) { - if( index >= rec_buf.size() ) { - SIO_THROW( sio::error_code::invalid_argument, "Start of block pointing after end of record!" ) ; - } - block_info info ; - SIO_DEBUG( "Block buffer size is " << rec_buf.size() ) ; - SIO_DEBUG( "Block index is " << index ) ; - read_device device( rec_buf.subspan( index ) ) ; - info._record_start = index ; - unsigned int marker(0), block_len(0) ; - device.data( block_len ) ; - SIO_DEBUG( "Block len is " << block_len ) ; - device.data( marker ) ; - // check for a block marker - if( sio::block_marker != marker ) { - std::stringstream ss ; - ss << "Block marker not found (block marker: " << sio::block_marker <<", record marker: " << sio::record_marker << ", got " << marker << ")" ; - SIO_THROW( sio::error_code::no_marker, ss.str() ) ; - } - device.data( info._version ) ; - unsigned int name_len(0) ; - device.data( name_len ) ; - info._name.assign( name_len, '\0' ) ; - device.data( &(info._name[0]), name_len ) ; - info._header_length = device.position() ; - info._data_length = block_len - info._header_length ; - device.seek( block_len ) ; - info._record_end = index + block_len ; - return std::make_pair( info, rec_buf.subspan( index, block_len ) ) ; - } - - //-------------------------------------------------------------------------- - - void api::read_blocks( const buffer_span &rec_buf, const std::vector>& blocks ) { - if( not rec_buf.valid() ) { - SIO_THROW( sio::error_code::bad_state, "Buffer is invalid." ) ; - } - buffer_span::index_type current_pos (0) ; - read_device device ; - while( 1 ) { - // end of block buffer ? - if( current_pos >= rec_buf.size() ) { - break ; - } - auto block_data = sio::api::extract_block( rec_buf, current_pos ) ; - current_pos = block_data.first._record_end ; - // look for the block decoder - auto block_iter = std::find_if( blocks.begin(), blocks.end(), [&]( std::shared_ptr blk ) { - return ( blk->name() == block_data.first._name ) ; - }) ; - // skip the block if no decoder - if( blocks.end() == block_iter ) { - continue ; - } - // prepare the read device - device.set_buffer( block_data.second ) ; - device.seek( block_data.first._header_length ) ; - try { - (*block_iter)->read( device, block_data.first._version ) ; - } - catch( sio::exception &e ) { - SIO_RETHROW( e, sio::error_code::io_failure, "Failed to decode block buffer (" + block_data.first._name + ")" ) ; - } - } - device.pointer_relocation() ; - } - - //-------------------------------------------------------------------------- - - void api::dump_records( sio::ifstream &stream, std::size_t skip, std::size_t count, bool detailed ) { - try { - // skip records first - if( skip > 0 ) { - sio::api::skip_n_records( stream, skip ) ; - } - sio::record_info rec_info ; - sio::buffer info_buffer( sio::max_record_info_len ) ; - sio::buffer rec_buffer( sio::mbyte ) ; - sio::buffer uncomp_rec_buffer( sio::mbyte ) ; - unsigned int record_counter (0) ; - const unsigned int tab_len = 117 ; - if( not detailed ) { - std::cout << std::string( tab_len, '-' ) << std::endl ; - std::cout << - std::setw(30) << std::left << "Record name " << " | " << - std::setw(15) << "Start" << " | " << - std::setw(15) << "End" << " | " << - std::setw(12) << "Options" << " | " << - std::setw(10) << "Header len" << " | " << - std::setw(15) << "Data len" << - std::endl ; - std::cout << std::string( tab_len, '-' ) << std::endl ; - } - while(1) { - if( record_counter >= count ) { - break ; - } - SIO_DEBUG( "Start reading next record info from stream" ) ; - sio::api::read_record_info( stream, rec_info, info_buffer ) ; - if( detailed ) { - SIO_DEBUG( "Detailed: Start reading next record data from stream" ) ; - sio::api::read_record_data( stream, rec_info, rec_buffer ) ; - } - // seek after the record to read the next record info - stream.seekg( rec_info._file_end ) ; - ++ record_counter ; - if( detailed ) { - std::cout << std::string( tab_len, '-' ) << std::endl ; - std::cout << - std::setw(30) << std::left << "Record name " << " | " << - std::setw(15) << "Start" << " | " << - std::setw(15) << "End" << " | " << - std::setw(12) << "Options" << " | " << - std::setw(10) << "Header len" << " | " << - std::setw(15) << "Data len" << - std::endl ; - } - std::stringstream size_str ; - size_str << rec_info._data_length << " (" << rec_info._uncompressed_length << ")" ; - std::cout << - std::setw(30) << std::left << rec_info._name << " | " << - std::setw(15) << rec_info._file_start << " | " << - std::setw(15) << rec_info._file_end << " | " << - std::setw(12) << rec_info._options << " | " << - std::setw(10) << rec_info._header_length << " | " << - std::setw(15) << size_str.str() << - std::endl ; - if( detailed ) { - std::cout << std::string( tab_len, '-' ) << std::endl ; - std::cout << - std::setw(30) << std::left << "Block name " << " | " << - std::setw(15) << "Start" << " | " << - std::setw(15) << "End" << " | " << - std::setw(12) << "Version" << " | " << - std::setw(10) << "Header len" << " | " << - std::setw(15) << "Data len" << - std::endl ; - std::cout << std::string( tab_len, '-' ) << std::endl ; - const bool compressed = sio::api::is_compressed( rec_info._options ) ; - if( compressed ) { - // FIXME use zlib by default ?? - sio::zlib_compression compressor ; - uncomp_rec_buffer.resize( rec_info._uncompressed_length ) ; - compressor.uncompress( rec_buffer.span(), uncomp_rec_buffer ) ; - } - sio::buffer_span device_buffer = compressed ? uncomp_rec_buffer.span() : rec_buffer.span( 0, rec_info._data_length ) ; - SIO_DEBUG( "Start extracting block infos" ) ; - auto block_infos = sio::api::read_block_infos( device_buffer ) ; - SIO_DEBUG( "Number of blocks found: " << block_infos.size() ) ; - for( auto binfo : block_infos ) { - std::stringstream version_str ; - version_str << sio::version::major_version( binfo._version ) << "." << sio::version::minor_version( binfo._version ) ; - std::cout << - std::setw(30) << std::left << binfo._name << " | " << - std::setw(15) << binfo._record_start << " | " << - std::setw(15) << binfo._record_end << " | " << - std::setw(12) << version_str.str() << " | " << - std::setw(10) << binfo._header_length << " | " << - std::setw(15) << binfo._data_length << - std::endl ; - } - std::cout << std::endl ; - } - } - } - catch( sio::exception &e ) { - // we are finished ! - if( e.code() == sio::error_code::eof ) { - return ; - } - throw e ; - } - } - - //-------------------------------------------------------------------------- - - void api::write_blocks( write_device &device, const block_list &blocks ) { - for( auto blk : blocks ) { - auto blk_ptr = blk ; - try { - auto block_start = device.position() ; - auto block_name = blk_ptr->name() ; - unsigned int blkname_len = block_name.size() ; - // write the block header. It will be updated after - // the block has been written - device.data( sio::block_marker ) ; - device.data( sio::block_marker ) ; - device.data( blk_ptr->version() ) ; - device.data( blkname_len ) ; - device.data( block_name.c_str(), blkname_len ) ; - // write the block data - blk_ptr->write( device ) ; - // fill back the block length in block header - auto blk_end = device.position() ; - unsigned int blklen = blk_end - block_start ; - SIO_DEBUG( "Block len :" << blklen ) ; - device.seek( block_start ) ; - device.data( blklen ) ; - device.seek( blk_end ) ; - } - catch( sio::exception &e ) { - SIO_RETHROW( e, sio::error_code::io_failure, "Couldn't write block to buffer (" + blk_ptr->name() + ")" ) ; - } - } - device.pointer_relocation() ; - } - - //-------------------------------------------------------------------------- - - record_info api::write_record( const std::string &name, buffer &rec_buf, const block_list& blocks, sio::options_type opts ) { - if( not sio::valid_record_name( name ) ) { - SIO_THROW( sio::error_code::invalid_argument, "Record name '" + name + "' is invalid" ) ; - } - if( not rec_buf.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "Buffer is invalid" ) ; - } - try { - sio::api::set_compression( opts, false ) ; - record_info info ; - info._options = opts ; - info._name = name ; - write_device device( std::move(rec_buf) ) ; - // Output: 1) A placeholder for the record header length. - // 2) A 'framing' marker (to help in debugging). - // 3) An options word. - // 4) A placeholder for the record data length (compressed). - // 5) A placeholder for the record data length (uncompressed). - // 6) The length of the record name. - // 7) The record name. - device.data( sio::record_marker ) ; - device.data( sio::record_marker ) ; - device.data( opts ) ; - auto datalen_pos = device.position() ; - device.data( sio::record_marker ) ; - device.data( sio::record_marker ) ; - unsigned int name_len = name.size() ; - device.data( name_len ) ; - device.data( &(name[0]), name_len ) ; - // write back the header len - info._header_length = device.position() ; - device.seek( 0 ) ; - device.data( info._header_length ) ; - device.seek( info._header_length ) ; - // write the blocks - sio::api::write_blocks( device, blocks ) ; - // fill the data length and uncompressed record length - auto end_pos = device.position() ; - device.seek( datalen_pos ) ; - info._data_length = end_pos - info._header_length ; - info._uncompressed_length = end_pos - info._header_length ; - device.data( info._data_length ) ; - device.data( info._uncompressed_length ) ; - // get back the buffer - rec_buf = std::move( device.take_buffer() ) ; - rec_buf.resize( end_pos ) ; - return info ; - } - catch( sio::exception &e ) { - SIO_RETHROW( e, sio::error_code::io_failure, "Couldn't write record into buffer" ) ; - } - } - - //-------------------------------------------------------------------------- - - void api::write_record( sio::ofstream &stream, const buffer_span &rec_buf, record_info &rec_info ) { - if( not stream.is_open() ) { - SIO_THROW( sio::error_code::not_open, "ofstream is not open!" ) ; - } - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ofstream is in a bad state!" ) ; - } - if( not rec_buf.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "The record buffer is not valid" ) ; - } - rec_info._file_start = stream.tellp() ; - // write data - if( not stream.write( rec_buf.data(), rec_buf.size() ).good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't write record buffer to output stream" ) ; - } - // always add some padding bytes at the end - auto padlen = (4 - (rec_buf.size() & sio::bit_align)) & sio::bit_align; - if( padlen > 0 ) { - SIO_DEBUG( "Writing " << padlen << " bytes for padding ..." ) ; - if( not stream.write( sio::padding_bytes, padlen ).good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't write record buffer padding to output stream" ) ; - } - } - // flush the stream - if( not stream.flush().good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't flush output stream" ) ; - } - rec_info._file_end = stream.tellp() ; - SIO_DEBUG( "Written record with info :\n" << rec_info ) ; - } - - //-------------------------------------------------------------------------- - - void api::write_record( sio::ofstream &stream, const buffer_span &hdr_span, const buffer_span &data_span, record_info &rec_info ) { - if( not stream.is_open() ) { - SIO_THROW( sio::error_code::not_open, "ofstream is not open!" ) ; - } - if( not stream.good() ) { - SIO_THROW( sio::error_code::bad_state, "ofstream is in a bad state!" ) ; - } - if( not hdr_span.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "The record header buffer is not valid" ) ; - } - if( not data_span.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "The record data buffer is not valid" ) ; - } - rec_info._file_start = stream.tellp() ; - // write record header - if( not stream.write( hdr_span.data(), hdr_span.size() ).good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't write record header buffer to output stream" ) ; - } - // write record data - if( not stream.write( data_span.data(), data_span.size() ).good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't write record data buffer to output stream" ) ; - } - // always add some padding bytes at the end - auto padlen = (4 - (data_span.size() & sio::bit_align)) & sio::bit_align; - if( padlen > 0 ) { - SIO_DEBUG( "Writing " << padlen << " bytes for padding ..." ) ; - if( not stream.write( sio::padding_bytes, padlen ).good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't write record buffer padding to output stream" ) ; - } - } - // flush the stream - if( not stream.flush().good() ) { - SIO_THROW( sio::error_code::io_failure, "Couldn't flush output stream" ) ; - } - rec_info._file_end = stream.tellp() ; - SIO_DEBUG( "Written record with info :\n" << rec_info ) ; - } - - //-------------------------------------------------------------------------- - - bool api::is_compressed( options_type opts ) { - return static_cast( opts & sio::compression_bit ) ; - } - - //-------------------------------------------------------------------------- - - bool api::set_compression( options_type &opts, bool value ) { - bool out = sio::api::is_compressed( opts ) ; - opts &= ~sio::compression_bit ; - if( value ) { - opts |= sio::compression_bit ; - } - return out ; - } - -} diff --git a/sio/src/block.cc b/sio/src/block.cc deleted file mode 100644 index b213e9ecd..000000000 --- a/sio/src/block.cc +++ /dev/null @@ -1,27 +0,0 @@ -// -- sio headers -#include -#include - -namespace sio { - - block::block( const std::string &nam, sio::version_type vers ) : - _version(vers), - _name(nam) { - if( not sio::validate( _name ) ) { - SIO_THROW( sio::error_code::invalid_argument, "Block name '" + _name + "' is invalid!" ) ; - } - } - - //-------------------------------------------------------------------------- - - const std::string &block::name() const noexcept { - return _name ; - } - - //-------------------------------------------------------------------------- - - sio::version_type block::version() const noexcept { - return _version ; - } - -} \ No newline at end of file diff --git a/sio/src/buffer.cc b/sio/src/buffer.cc deleted file mode 100644 index a20fd7aae..000000000 --- a/sio/src/buffer.cc +++ /dev/null @@ -1,399 +0,0 @@ -// -- sio headers -#include -#include - -// -- std headers -#include -#include - -namespace sio { - - buffer_span::buffer_span() : - _isnull(true) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - buffer_span::buffer_span( const container &bytes ) : - _first( bytes.begin() ), - _last( bytes.end() ) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - buffer_span::buffer_span( const_iterator first, const_iterator last ) : - _first(first), - _last(last) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - buffer_span::buffer_span( const_iterator first, std::size_t count ) : - _first(first), - _last(std::next(first, count)) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - buffer_span::const_iterator buffer_span::begin() const { - return _first ; - } - - //-------------------------------------------------------------------------- - - buffer_span::const_iterator buffer_span::end() const { - return _last ; - } - - //-------------------------------------------------------------------------- - - const buffer_span::element_type *buffer_span::data() const { - return _isnull ? nullptr : &(*_first) ; - } - - //-------------------------------------------------------------------------- - - buffer_span::const_reference buffer_span::front() const { - return (*_first) ; - } - - //-------------------------------------------------------------------------- - - buffer_span::const_reference buffer_span::back() const { - return *(_last-1) ; - } - - //-------------------------------------------------------------------------- - - buffer_span::const_reference buffer_span::operator[]( index_type index ) const { - return data() [ index ] ; - } - - //-------------------------------------------------------------------------- - - buffer_span::const_reference buffer_span::at( index_type index ) const { - if( index >= size() ) { - std::stringstream ss ; - ss << "index: " << index << ", size: " << size() ; - SIO_THROW( error_code::out_of_range, ss.str() ) ; - } - return data() [ index ] ; - } - - //-------------------------------------------------------------------------- - - buffer_span::const_pointer buffer_span::ptr( index_type index ) const { - return data() + index ; - } - - //-------------------------------------------------------------------------- - - std::size_t buffer_span::size() const { - return _isnull ? 0 : std::distance( _first, _last ) ; - } - - //-------------------------------------------------------------------------- - - bool buffer_span::empty() const { - return (size() == 0) ; - } - - //-------------------------------------------------------------------------- - - bool buffer_span::valid() const { - return (not _isnull) ; - } - - //-------------------------------------------------------------------------- - - buffer_span::operator bool() const noexcept { - return valid() ; - } - - //-------------------------------------------------------------------------- - - buffer_span buffer_span::subspan( index_type start ) const { - if( start > size() ) { - std::stringstream ss ; - ss << "start: " << start << ", size: " << size() ; - SIO_THROW( error_code::out_of_range, ss.str() ) ; - } - return buffer_span( std::next(_first, start) , _last ) ; - } - - //-------------------------------------------------------------------------- - - buffer_span buffer_span::subspan( index_type start, std::size_t count ) const { - if( start+count > size() ) { - std::stringstream ss ; - ss << "start: " << start << ", count: " << count << ", size: " << size() ; - SIO_THROW( error_code::out_of_range, ss.str() ) ; - } - return buffer_span( std::next(_first, start) , std::next(_first, start+count) ) ; - } - - //-------------------------------------------------------------------------- - - void buffer_span::dump( int base, unsigned int line_split, size_type max_bytes ) { - std::ios_base::fmtflags f( std::cout.flags() ); - for( size_type i=0 ; i max_bytes ) { - break ; - } - } - std::cout << std::endl ; - std::cout.flags( f ); - } - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - buffer::buffer( size_type len ) : - _bytes( len, sio::null_byte ) { - if( 0 == len ) { - SIO_THROW( sio::error_code::invalid_argument, "Can't construct a buffer with length of 0!" ) ; - } - } - - //-------------------------------------------------------------------------- - - buffer::buffer( container &&bytes ) : - _bytes( std::move( bytes ) ) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - buffer::buffer( buffer&& rhs ) { - _bytes = std::move( rhs._bytes ) ; - _valid = rhs._valid ; - rhs._valid = false ; - } - - //-------------------------------------------------------------------------- - - buffer& buffer::operator=( buffer&& rhs ) { - _bytes = std::move( rhs._bytes ) ; - _valid = rhs._valid ; - rhs._valid = false ; - return *this ; - } - - //-------------------------------------------------------------------------- - - buffer::const_iterator buffer::begin() const { - return _bytes.begin() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_iterator buffer::end() const { - return _bytes.end() ; - } - - //-------------------------------------------------------------------------- - - buffer::iterator buffer::begin() { - return _bytes.begin() ; - } - - //-------------------------------------------------------------------------- - - buffer::iterator buffer::end() { - return _bytes.end() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_reverse_iterator buffer::rbegin() const { - return _bytes.rbegin() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_reverse_iterator buffer::rend() const { - return _bytes.rend() ; - } - - //-------------------------------------------------------------------------- - - buffer::reverse_iterator buffer::rbegin() { - return _bytes.rbegin() ; - } - - //-------------------------------------------------------------------------- - - buffer::reverse_iterator buffer::rend() { - return _bytes.rend() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_reference buffer::operator[]( index_type index ) const { - return _bytes [ index ] ; - } - - //-------------------------------------------------------------------------- - - buffer::reference buffer::operator[]( index_type index ) { - return _bytes [ index ] ; - } - - //-------------------------------------------------------------------------- - - buffer::const_reference buffer::at( index_type index ) const { - return _bytes.at( index ) ; - } - - //-------------------------------------------------------------------------- - - buffer::reference buffer::at( index_type index ) { - return _bytes.at( index ) ; - } - - //-------------------------------------------------------------------------- - - buffer::const_reference buffer::front() const { - return _bytes.front() ; - } - - //-------------------------------------------------------------------------- - - buffer::reference buffer::front() { - return _bytes.front() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_reference buffer::back() const { - return _bytes.back() ; - } - - //-------------------------------------------------------------------------- - - buffer::reference buffer::back() { - return _bytes.back() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_pointer buffer::data() const { - return _bytes.data() ; - } - - //-------------------------------------------------------------------------- - - buffer::pointer buffer::data() { - return _bytes.data() ; - } - - //-------------------------------------------------------------------------- - - buffer::const_pointer buffer::ptr( index_type index ) const { - return &(_bytes[ index ]) ; - } - - //-------------------------------------------------------------------------- - - buffer::pointer buffer::ptr( index_type index ) { - return &(_bytes[ index ]) ; - } - - //-------------------------------------------------------------------------- - - buffer::size_type buffer::size() const { - return _bytes.size() ; - } - - //-------------------------------------------------------------------------- - - bool buffer::empty() const { - return _bytes.empty() ; - } - - //-------------------------------------------------------------------------- - - buffer::size_type buffer::capacity() const { - return _bytes.capacity() ; - } - - //-------------------------------------------------------------------------- - - void buffer::resize( size_type newsize ) { - _bytes.resize( newsize ) ; - } - - //-------------------------------------------------------------------------- - - buffer::size_type buffer::expand( std::size_t nbytes ) { - auto len = size() ; - resize( len + nbytes ) ; - return len ; - } - - //-------------------------------------------------------------------------- - - void buffer::shrink() { - _bytes.shrink_to_fit() ; - } - - //-------------------------------------------------------------------------- - - void buffer::clear( bool shrink ) { - _bytes.clear() ; - if( shrink ) { - _bytes.shrink_to_fit() ; - } - } - - //-------------------------------------------------------------------------- - - buffer buffer::reuse() { - buffer new_buffer( std::move( _bytes ) ) ; - _valid = false ; - return new_buffer ; - } - - //-------------------------------------------------------------------------- - - bool buffer::valid() const { - return _valid ; - } - - //-------------------------------------------------------------------------- - - buffer_span buffer::span() const { - return buffer_span( begin() , end() ) ; - } - - //-------------------------------------------------------------------------- - - buffer_span buffer::span( index_type start ) const { - if( start > size() ) { - std::stringstream ss ; - ss << "start: " << start << ", size: " << size() ; - SIO_THROW( error_code::out_of_range, ss.str() ) ; - } - return buffer_span( std::next(begin(), start) , end() ) ; - } - - //-------------------------------------------------------------------------- - - buffer_span buffer::span( index_type start, size_type count ) const { - if( start+count > size() ) { - std::stringstream ss ; - ss << "start: " << start << ", count: " << count << ", size: " << size() ; - SIO_THROW( error_code::out_of_range, ss.str() ) ; - } - return buffer_span( std::next(begin(), start) , std::next(begin(), start+count) ) ; - } - -} diff --git a/sio/src/compression/zlib.cc b/sio/src/compression/zlib.cc deleted file mode 100644 index 56f828e88..000000000 --- a/sio/src/compression/zlib.cc +++ /dev/null @@ -1,73 +0,0 @@ -#include - -// -- sio headers -#include -#include - -// -- zlib headers -#include - -// -- std headers -#include - -namespace sio { - - void zlib_compression::set_level( int level ) { - if(level < 0) { - _level = Z_DEFAULT_COMPRESSION; - } - else if(level > 9) { - _level = 9; - } - else { - _level = level; - } - } - - //-------------------------------------------------------------------------- - - int zlib_compression::level() const { - return _level ; - } - - //-------------------------------------------------------------------------- - - void zlib_compression::uncompress( const buffer_span &inbuf, buffer &outbuf ) { - if( not inbuf.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "Buffer is not valid" ) ; - } - // zlib uncompress requires to pass an address of uLongf type ... - uLongf outsize = outbuf.size() ; - auto zstat = ::uncompress( (Bytef*)outbuf.data(), &outsize, (const Bytef*)inbuf.data(), inbuf.size() ) ; - if( Z_OK != zstat ) { - std::stringstream ss ; - ss << "Zlib uncompression failed with status " << zstat ; - SIO_THROW( sio::error_code::compress_error, ss.str() ) ; - } - SIO_DEBUG( "ZLIB uncompress OK!" ) ; - } - - //-------------------------------------------------------------------------- - - void zlib_compression::compress( const buffer_span &inbuf, buffer &outbuf ) { - if( not inbuf.valid() ) { - SIO_THROW( sio::error_code::invalid_argument, "Buffer is not valid" ) ; - } - // comp_bound is a first estimate of the compressed size. - // After compression, the real output size is returned, - // this is why the buffer is resized after calling compress2(). - auto comp_bound = ::compressBound( inbuf.size() ) ; - if( outbuf.size() < comp_bound ) { - outbuf.resize( comp_bound ) ; - } - auto zstat = ::compress2( reinterpret_cast(outbuf.data()), &comp_bound, reinterpret_cast(inbuf.data()), inbuf.size(), _level ) ; - if( Z_OK != zstat ) { - std::stringstream ss ; - ss << "Zlib compression failed with status " << zstat ; - SIO_THROW( sio::error_code::compress_error, ss.str() ) ; - } - outbuf.resize( comp_bound ) ; - SIO_DEBUG( "ZLIB compress OK!" ) ; - } - -} diff --git a/sio/src/exception.cc b/sio/src/exception.cc deleted file mode 100644 index a82cb3e87..000000000 --- a/sio/src/exception.cc +++ /dev/null @@ -1,81 +0,0 @@ -// -- std headers -#include - -namespace sio { - - inline std::string error_code_helper::to_string( error_code code ) noexcept { - switch( code ) { - case error_code::invalid_argument: return "invalid_argument" ; - case error_code::not_found: return "not_found" ; - case error_code::already_open: return "already_open" ; - case error_code::open_fail: return "open_fail" ; - case error_code::not_open: return "not_open" ; - case error_code::eof: return "eof" ; - case error_code::io_failure: return "io_failure" ; - case error_code::no_marker: return "no_marker" ; - case error_code::compress_error: return "compress_error" ; - case error_code::bad_state: return "bad_state" ; - case error_code::bad_alloc: return "bad_alloc" ; - case error_code::out_of_range: return "out_of_range" ; - default: return "unknown" ; - } - } - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - exception::exception( - error_code code, - unsigned int line, - const std::string &func, - const std::string &fname, - const std::string &msg ) : - _code( code ), - _message( message(code, line, func, fname, msg) ) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - const char* exception::what() const noexcept { - return _message.c_str() ; - } - - //-------------------------------------------------------------------------- - - sio::error_code exception::code() const { - return _code ; - } - - //-------------------------------------------------------------------------- - - std::string exception::message( - error_code code, - unsigned int line, - const std::string &func, - const std::string &fname, - const std::string &msg ) const { - return fname + - " (l." + std::to_string(line) + ") in " + - func + ": " + msg + - " [" + error_code_helper::to_string( code ) + "]" ; - } - - //-------------------------------------------------------------------------- - - std::string exception::message( - const std::string &previous, - error_code code, - unsigned int line, - const std::string &func, - const std::string &fname, - const std::string &msg ) const { - if( previous.empty() ) { - return message(code, line, func, fname, msg) ; - } - else { - return previous + "\n" + message(code, line, func, fname, msg) ; - } - } - -} diff --git a/sio/src/io_device.cc b/sio/src/io_device.cc deleted file mode 100644 index 420e63653..000000000 --- a/sio/src/io_device.cc +++ /dev/null @@ -1,164 +0,0 @@ -// -- sio headers -#include -#include - -namespace sio { - - read_device::read_device( buffer_span buf ) : - _buffer(std::move(buf)) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - void read_device::set_buffer( const buffer_span &buf ) { - _buffer = buf ; - } - - //-------------------------------------------------------------------------- - - void read_device::set_buffer( buffer_span &&buf ) { - _buffer = buf ; - } - - //-------------------------------------------------------------------------- - - read_device::cursor_type read_device::position() const { - return _cursor ; - } - - //-------------------------------------------------------------------------- - - void read_device::seek( cursor_type pos ) { - if( pos > _buffer.size() ) { - SIO_THROW( sio::error_code::out_of_range, "Can't seek device cursor: out of range!" ) ; - } - _cursor = pos ; - } - - //-------------------------------------------------------------------------- - - void read_device::pointer_to( ptr_type *ptr ) { - // Read. Keep a record of the "match" quantity read from the buffer and - // the location in memory which will need relocating. - // Placeholder value for 'pointer to' - unsigned int match = 0 ; - data( match ) ; - // Ignore match = 0x00000000. This is basically a null pointer which can - // never be relocated, so don't fill the multimap with a lot of useless - // information. - if( match != 0x00000000 ) { - sio::pointer_to_map::value_type entry = { reinterpret_cast(match), ptr } ; - _pointer_to.insert( entry ) ; - } - *ptr = static_cast( match ) ; - } - - //-------------------------------------------------------------------------- - - void read_device::pointed_at( ptr_type *ptr ) { - // Read. Keep a record of the "match" quantity read from the buffer and - // the location in memory which will need relocating. - unsigned int match = 0 ; - data( match ) ; - // Ignore match = SIO_ptag. This is basically a pointer target which was - // never relocated when the record was written. i.e. nothing points to it! - // Don't clutter the maps with information that can never be used. - if( match != 0xffffffff ) { - pointed_at_map::value_type entry = { reinterpret_cast( match ), ptr } ; - _pointed_at.insert( entry ) ; - } - } - - //-------------------------------------------------------------------------- - - void read_device::pointer_relocation() { - sio::api::read_relocation( _pointed_at, _pointer_to ) ; - _pointer_to.clear() ; - _pointed_at.clear() ; - } - - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - - write_device::write_device( buffer&& buf ) : - _buffer( std::move( buf ) ) { - /* nop */ - } - - //-------------------------------------------------------------------------- - - void write_device::set_buffer( buffer&& buf ) { - _buffer = std::move( buf ) ; - } - - //-------------------------------------------------------------------------- - - buffer write_device::take_buffer() { - return std::move( _buffer ) ; - } - - //-------------------------------------------------------------------------- - - write_device::cursor_type write_device::position() const { - return _cursor ; - } - - //-------------------------------------------------------------------------- - - void write_device::seek( cursor_type pos ) { - if( pos > _buffer.size() ) { - SIO_THROW( sio::error_code::out_of_range, "Can't seek device cursor: out of range!" ) ; - } - _cursor = pos ; - } - - //-------------------------------------------------------------------------- - - void write_device::pointer_to( ptr_type *ptr ) { - // Write. Keep a record of the "match" quantity (i.e. the value of the - // pointer (which may be different lengths on different machines!)) and - // the current offset in the output buffer. Put a placeholder in the - // output buffer (it will be overwritten at the "output relocation" stage). - // - // Placeholder value for 'pointer to' - unsigned int SIO_pntr = 0x00000000 ; - // ptr is really a pointer-to-a-pointer. This routine is most interested - // in the value of *xfer when treated as a pointer. C++ tends to object - // to this as being 'not type safe'. To keep the compiler happy (and purists - // miserable), do one 'reinterpret_cast' immediately to make later code - // easier to read. - // Indirect ptr (actually **ptr) - void *ifer = reinterpret_cast(*ptr) ; - // Ignore NULL pointers. These are always recorded in the buffer with a - // zero match word (and are treated specially when read back). There's no - // point in putting useless information in the maps. - if( nullptr != ifer ) { - sio::pointer_to_map::value_type entry = { ifer, reinterpret_cast( _buffer.ptr(_cursor) - _buffer.data() ) } ; - _pointer_to.insert( entry ) ; - } - data( SIO_pntr ) ; - } - - //-------------------------------------------------------------------------- - - void write_device::pointed_at( ptr_type *ptr ) { - // Write. Save the memory location of this object along with the offset - // in the output buffer where the generated match quantity must go. Put - // a placeholder in the output buffer (it will be overwritten at the "output - // relocation" stage). - unsigned int SIO_ptag = 0xffffffff ; - sio::pointed_at_map::value_type entry = { ptr, reinterpret_cast( _buffer.ptr(_cursor) - _buffer.data() ) } ; - _pointed_at.insert( entry ) ; - data( SIO_ptag ) ; - } - - //-------------------------------------------------------------------------- - - void write_device::pointer_relocation() { - sio::api::write_relocation( _buffer.data(), _pointed_at, _pointer_to ) ; - _pointer_to.clear() ; - _pointed_at.clear() ; - } - -} diff --git a/sio/src/memcpy.cc b/sio/src/memcpy.cc deleted file mode 100644 index 60f6a4f9f..000000000 --- a/sio/src/memcpy.cc +++ /dev/null @@ -1,24 +0,0 @@ -// -- sio headers -#include - -namespace sio { - - void memcpy::reverse_copy( const sio::byte *const from, sio::byte * dest, std::size_t size, std::size_t count ) { - for( std::size_t s=0 ; s - -namespace sio { - - version::version_type version::encode_version( major_type major, minor_type minor ) noexcept { - return (((major) << 16) + (minor)) ; - } - - //-------------------------------------------------------------------------- - - version::minor_type version::minor_version( version_type version ) noexcept { - return ((version) & 0x0000ffff) ; - } - - //-------------------------------------------------------------------------- - - version::major_type version::major_version( version_type version ) noexcept { - return (((version) & 0xffff0000) >> 16) ; - } - -} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ba94ec539..9cfb5f90a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -201,7 +201,7 @@ MACRO( ADD_LCIO_TEST file ) ADD_EXECUTABLE( ${file} EXCLUDE_FROM_ALL ../src/cpp/src/TESTS/${file}.cc ) ENDIF() ADD_DEPENDENCIES( tests ${file} ) - TARGET_LINK_LIBRARIES( ${file} lcio ) + TARGET_LINK_LIBRARIES( ${file} lcio sio) ADD_TEST( t_${file} "${EXECUTABLE_OUTPUT_PATH}/${file}" ) SET_TESTS_PROPERTIES( t_${file} PROPERTIES PASS_REGULAR_EXPRESSION "TEST_PASSED" ) ENDMACRO() From 7a4f947a2e00af26d2b329133a684e2119f17a2b Mon Sep 17 00:00:00 2001 From: Andre Rummler Date: Mon, 4 Dec 2023 13:52:51 +0100 Subject: [PATCH 2/5] Pinning SIO version at v00-01. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49ac5ff9e..dd75bf1ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,7 +170,7 @@ IF( NOT SIO_FOUND ) include(FetchContent) FetchContent_Declare(sio_extern GIT_REPOSITORY https://github.com/iLCSoft/SIO.git - GIT_TAG master + GIT_TAG v00-01 GIT_SHALLOW 1 # FIND_PACKAGE_ARGS ) From 96e24962af196da80918d2bd2aedb1eaf74d763d Mon Sep 17 00:00:00 2001 From: arummler Date: Mon, 4 Dec 2023 13:55:32 +0100 Subject: [PATCH 3/5] Fix tests dependencies after move to use FetchContent to retrieve SIO. Co-authored-by: Thomas Madlener --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9cfb5f90a..d915849f0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -201,7 +201,7 @@ MACRO( ADD_LCIO_TEST file ) ADD_EXECUTABLE( ${file} EXCLUDE_FROM_ALL ../src/cpp/src/TESTS/${file}.cc ) ENDIF() ADD_DEPENDENCIES( tests ${file} ) - TARGET_LINK_LIBRARIES( ${file} lcio sio) + TARGET_LINK_LIBRARIES( ${file} LCIO::lcio SIO::sio) ADD_TEST( t_${file} "${EXECUTABLE_OUTPUT_PATH}/${file}" ) SET_TESTS_PROPERTIES( t_${file} PROPERTIES PASS_REGULAR_EXPRESSION "TEST_PASSED" ) ENDMACRO() From 46bd3c194425910ebb30043188f7158cbb64d69f Mon Sep 17 00:00:00 2001 From: Andre Rummler Date: Mon, 4 Dec 2023 14:42:16 +0100 Subject: [PATCH 4/5] Fix dependency for rootDict generation. --- src/cpp/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 7f73ae2a7..d59001c0f 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -375,7 +375,7 @@ IF( BUILD_ROOTDICT ) INCLUDE_DIRECTORIES( SYSTEM "${ROOT_INCLUDE_DIRS}" ) ADD_SHARED_LIBRARY( lcioDict ${lcio_rootdict_sources} ) - TARGET_LINK_LIBRARIES( lcioDict ${ROOT_LIBRARIES} lcio ) + TARGET_LINK_LIBRARIES( lcioDict ${ROOT_LIBRARIES} LCIO::lcio SIO::sio) IF( APPLE ) From 2e8f10af0794b0acb43f039a507408275da17666 Mon Sep 17 00:00:00 2001 From: Andre Rummler Date: Tue, 5 Dec 2023 23:11:26 +0100 Subject: [PATCH 5/5] Workaround for rootDict depending on SIO variables being populated after pulling SIO through FetchContent. TODO: use modern ROOT macros and targets. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd75bf1ee..0dde79204 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,9 @@ IF( NOT SIO_FOUND ) ) FetchContent_MakeAvailable(sio_extern) + + get_target_property(SIO_VERSION SIO::sio VERSION) + get_target_property(SIO_INCLUDE_DIRS SIO::sio INCLUDE_DIRECTORIES) ENDIF() MESSAGE( STATUS "Using SIO (${SIO_VERSION})" )