From c3628129d44a7167f2cbad54721b58424cc3fb54 Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Tue, 23 Sep 2014 18:09:37 +0200 Subject: [PATCH] -(add) now it is possible to override libarchive location from cmake -(add) added git ignore file -(mod) merged archive reader and archive writer entries -(fix) fixed memory leaks reported by valgrind -(fix) archives are no longer zero padded --- .gitignore | 2 + CMakeLists.txt | 18 +- archive_entry.cpp | 258 ++++++++++++++++++ archive_writer_entry.hpp => archive_entry.hpp | 37 ++- archive_reader.cpp | 15 +- archive_reader.hpp | 10 +- archive_reader_entry.cpp | 84 ------ archive_reader_entry.hpp | 68 ----- archive_reader_entry_buffer.cpp | 3 +- archive_reader_entry_buffer.hpp | 13 +- archive_reader_filter.hpp | 3 +- archive_reader_format.hpp | 3 +- archive_reader_iterator.cpp | 6 +- archive_reader_iterator.hpp | 8 +- archive_writer.cpp | 27 +- archive_writer.hpp | 13 +- archive_writer.ipp | 10 +- archive_writer_entry.cpp | 152 ----------- archive_writer_filter.hpp | 3 +- archive_writer_format.hpp | 3 +- 20 files changed, 361 insertions(+), 375 deletions(-) create mode 100644 .gitignore create mode 100644 archive_entry.cpp rename archive_writer_entry.hpp => archive_entry.hpp (72%) delete mode 100644 archive_reader_entry.cpp delete mode 100644 archive_reader_entry.hpp delete mode 100644 archive_writer_entry.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2995a63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a3a7c3..e13af2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,20 +28,28 @@ cmake_minimum_required( VERSION 2.8.12 ) project(archive_cpp_wrapper) +if(NOT libarchive_LIBRARIES) + # set defaults for ubuntu + set( libarchive_LIBRARIES "/usr/lib/x86_64-linux-gnu/libarchive.so" ) + set( libarchive_INCLUDE_DIRS "" ) +endif() + set(CMAKE_CXX_FLAGS "-Wall -std=c++11") file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp") file(GLOB template_implementations "${CMAKE_CURRENT_SOURCE_DIR}/*.ipp") +include_directories( ${libarchive_INCLUDE_DIRS} ) + add_library( ${PROJECT_NAME} SHARED + archive_entry.cpp + archive_reader.cpp - archive_reader_entry.cpp archive_reader_iterator.cpp archive_reader_entry_buffer.cpp archive_writer.cpp - archive_writer_entry.cpp archive_exception.cpp @@ -49,7 +57,8 @@ add_library( ${PROJECT_NAME} SHARED ${template_implementations} ) -target_link_libraries( ${PROJECT_NAME} /usr/lib/x86_64-linux-gnu/libarchive.so.13 ) +target_link_libraries( ${PROJECT_NAME} ${libarchive_LIBRARIES} ) + set_target_properties( ${PROJECT_NAME} PROPERTIES VERSION "0.0.1" SOVERSION "1" ) install( @@ -64,12 +73,11 @@ install( archive_reader.hpp archive_writer_format.hpp archive_exception.hpp - archive_writer_entry.hpp archive_reader_iterator.hpp archive_reader_format.hpp archive_writer_filter.hpp archive_reader_filter.hpp - archive_reader_entry.hpp + archive_entry.hpp archive_writer.hpp archive_reader.ipp archive_writer.ipp diff --git a/archive_entry.cpp b/archive_entry.cpp new file mode 100644 index 0000000..86516a8 --- /dev/null +++ b/archive_entry.cpp @@ -0,0 +1,258 @@ +/* +BSD 2-Clause license + +Copyright (c) 2014, Domen Vrankar +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "archive_entry.hpp" +#include "archive_exception.hpp" + +namespace ns_archive { + +entry::entry(archive_entry* entry, ns_reader::entry_buffer& entry_buffer) : + _entry( entry, []( archive_entry* entry ){ /* do nothing as this entry is owned by a reader */ } ), + _stream(&entry_buffer), + _has_stream(true) +{ + // +} + +entry::entry(std::istream& stream) : + _entry( archive_entry_new(), []( archive_entry* entry ){ archive_entry_free( entry ); } ), + _stream( stream.rdbuf() ), + _has_stream(true) +{ + auto* pbuf = _stream.rdbuf(); + std::size_t stream_size = pbuf->pubseekoff( 0, _stream.end, _stream.in ); + pbuf->pubseekpos( 0, _stream.in ); + + archive_entry_set_mode( _entry.get(), S_IFREG ); + archive_entry_set_size( _entry.get(), stream_size ); +} + +void entry::clear_entry(std::istream& stream) +{ + archive_entry_clear( _entry.get() ); + _stream.rdbuf( stream.rdbuf() ); + _has_stream = true; + + auto* pbuf = _stream.rdbuf(); + std::size_t stream_size = pbuf->pubseekoff( 0, _stream.end, _stream.in ); + pbuf->pubseekpos( 0, _stream.in ); + + archive_entry_set_mode( _entry.get(), S_IFREG ); + archive_entry_set_size( _entry.get(), stream_size ); +} + +//-------------------------getters---------------------------// +int64_t entry::get_header_value_gid() +{ + return archive_entry_gid(_entry.get()); +} + +int64_t entry::get_header_value_ino() +{ + return archive_entry_ino(_entry.get()); +} + +int64_t entry::get_header_value_ino64() +{ + return archive_entry_ino64(_entry.get()); +} + +int64_t entry::get_header_value_size() +{ + return archive_entry_size(_entry.get()); +} + +int64_t entry::get_header_value_uid() +{ + return archive_entry_uid(_entry.get()); +} + +mode_t entry::get_header_value_mode() +{ + return archive_entry_mode(_entry.get()); +} + +mode_t entry::get_header_value_perm() +{ + return archive_entry_perm(_entry.get()); +} + +dev_t entry::get_header_value_rdev() +{ + return archive_entry_rdev(_entry.get()); +} + +dev_t entry::get_header_value_rdevmajor() +{ + return archive_entry_rdevmajor(_entry.get()); +} + +dev_t entry::get_header_value_rdevminor() +{ + return archive_entry_rdevminor(_entry.get()); +} + +std::string entry::get_header_value_gname() +{ + return archive_entry_gname(_entry.get()); +} + +std::string entry::get_header_value_hardlink() +{ + return archive_entry_hardlink(_entry.get()); +} + +std::string entry::get_header_value_pathname() +{ + return archive_entry_pathname(_entry.get()); +} + +std::string entry::get_header_value_symlink() +{ + return archive_entry_symlink(_entry.get()); +} + +std::string entry::get_header_value_uname() +{ + return archive_entry_uname(_entry.get()); +} + +unsigned int entry::get_header_value_nlink() +{ + return archive_entry_nlink(_entry.get()); +} + +//-------------------------setters---------------------------// +void entry::set_header_value_gid(int64_t value) +{ + archive_entry_set_gid(_entry.get(), value); +} + +void entry::set_header_value_ino(int64_t value) +{ + archive_entry_set_ino(_entry.get(), value); +} + +void entry::set_header_value_ino64(int64_t value) +{ + archive_entry_set_ino64(_entry.get(), value); +} + +void entry::set_header_value_size(int64_t value) +{ + archive_entry_set_size(_entry.get(), value); +} + +void entry::set_header_value_uid(int64_t value) +{ + archive_entry_set_uid(_entry.get(), value); +} + +void entry::set_header_value_mode(mode_t value) +{ + archive_entry_set_mode(_entry.get(), value); +} + +void entry::set_header_value_perm(mode_t value) +{ + archive_entry_set_perm(_entry.get(), value); +} + +void entry::set_header_value_rdev(dev_t value) +{ + archive_entry_set_rdev(_entry.get(), value); +} + +void entry::set_header_value_rdevmajor(dev_t value) +{ + archive_entry_set_rdevmajor(_entry.get(), value); +} + +void entry::set_header_value_rdevminor(dev_t value) +{ + archive_entry_set_rdevminor(_entry.get(), value); +} + +void entry::set_header_value_gname(const std::string& value) +{ + archive_entry_set_gname(_entry.get(), value.c_str()); +} + +void entry::set_header_value_hardlink(const std::string& value) +{ + archive_entry_set_hardlink(_entry.get(), value.c_str()); +} + +void entry::set_header_value_link(const std::string& value) +{ + archive_entry_set_link(_entry.get(), value.c_str()); +} + +void entry::set_header_value_pathname(const std::string& value) +{ + archive_entry_set_pathname(_entry.get(), value.c_str()); +} + +void entry::set_header_value_symlink(const std::string& value) +{ + archive_entry_set_symlink(_entry.get(), value.c_str()); +} + +void entry::set_header_value_uname(const std::string& value) +{ + archive_entry_set_uname(_entry.get(), value.c_str()); +} + +void entry::set_header_value_nlink(unsigned int value) +{ + archive_entry_set_nlink(_entry.get(), value); +} + +void entry::set_header_value_mtime(time_t time, long value) +{ + archive_entry_set_mtime(_entry.get(), time, value); +} + +archive_entry* entry::get_entry() const +{ + return _entry.get(); +} + +std::istream& entry::get_stream() +{ + if(!_has_stream) + { + _has_stream = false; + + return _stream; + } + + throw archive_exception( "Archive entry stream was already read!" ); +} + +} diff --git a/archive_writer_entry.hpp b/archive_entry.hpp similarity index 72% rename from archive_writer_entry.hpp rename to archive_entry.hpp index d742354..7acf823 100644 --- a/archive_writer_entry.hpp +++ b/archive_entry.hpp @@ -33,17 +33,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include #include +#include "archive_reader_entry_buffer.hpp" + namespace ns_archive { -namespace ns_writer { class entry { public: - entry(std::istream& stream, size_t stream_size); + entry(archive_entry* entry, ns_reader::entry_buffer& entry_buffer); // TODO change to private and friend reader? + entry(std::istream& stream); + + void clear_entry(std::istream& stream); + + int64_t get_header_value_gid(); + int64_t get_header_value_ino(); + int64_t get_header_value_ino64(); + int64_t get_header_value_size(); + int64_t get_header_value_uid(); + mode_t get_header_value_mode(); + mode_t get_header_value_perm(); + dev_t get_header_value_rdev(); + dev_t get_header_value_rdevmajor(); + dev_t get_header_value_rdevminor(); + std::string get_header_value_gname(); + std::string get_header_value_hardlink(); + std::string get_header_value_pathname(); + std::string get_header_value_symlink(); + std::string get_header_value_uname(); + unsigned int get_header_value_nlink(); - void clear_entry(std::istream& stream, size_t stream_size); void set_header_value_gid(int64_t value); void set_header_value_ino(int64_t value); @@ -65,13 +87,14 @@ public: void set_header_value_mtime(time_t time, long value); archive_entry* get_entry() const; - std::istream& get_stream() const; + std::istream& get_stream(); + private: - archive_entry* _entry; - std::istream* _stream; + std::shared_ptr _entry; + std::istream _stream; + bool _has_stream; }; -} } #endif // ARCHIVE_WRITER_ENTRY_HPP_INCLUDED diff --git a/archive_reader.cpp b/archive_reader.cpp index 171f5f1..c5af16d 100644 --- a/archive_reader.cpp +++ b/archive_reader.cpp @@ -35,22 +35,23 @@ namespace ns_archive { reader::reader(std::istream& stream, size_t block_size) : _archive( archive_read_new(), [](archive* archive){ archive_read_free(archive); } ), // errors in destructor will be silently ignored + _buffer( new ns_reader::entry_buffer( _archive.get() ) ), _reader_container( stream, block_size ) { // } -ns_reader::entry* reader::get_next_entry() +std::shared_ptr reader::get_next_entry() { if(!has_next_entry()) { throw archive_exception( "get_next_entry was called after all the entries were read" ); } - ns_reader::entry* entry = _next_entry; + std::shared_ptr a_entry( _next_entry ); _next_entry = nullptr; - return entry; + return a_entry; } bool reader::has_next_entry() @@ -59,12 +60,12 @@ bool reader::has_next_entry() if(_next_entry == nullptr) { - archive_entry* entry; - has_next = (archive_read_next_header(_archive.get(), &entry) == ARCHIVE_OK); + archive_entry* a_entry; + has_next = (archive_read_next_header(_archive.get(), &a_entry) == ARCHIVE_OK); if(has_next) { - _next_entry = new ns_reader::entry(_archive.get(), entry); + _next_entry = std::make_shared( a_entry, *_buffer.get() ); } } @@ -149,4 +150,4 @@ ns_reader::iterator reader::end() return ns_reader::iterator( this, true ); } -} // ns_archive +} diff --git a/archive_reader.hpp b/archive_reader.hpp index 895fc0f..b595db6 100644 --- a/archive_reader.hpp +++ b/archive_reader.hpp @@ -36,11 +36,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "archive_reader_format.hpp" #include "archive_reader_filter.hpp" -#include "archive_reader_entry.hpp" +#include "archive_entry.hpp" #include "archive_reader_iterator.hpp" namespace ns_archive { - namespace ns_reader { ssize_t reader_callback( archive* archive, void* in_reader_container, const void** buff ); @@ -64,7 +63,7 @@ public: template static reader make_reader( std::istream& stream, size_t block_size); - ns_reader::entry* get_next_entry(); + std::shared_ptr get_next_entry(); bool has_next_entry(); ns_reader::iterator begin(); @@ -82,7 +81,8 @@ private: void init_data(); std::shared_ptr _archive; - ns_reader::entry *_next_entry = nullptr; + std::shared_ptr _next_entry = nullptr; + std::shared_ptr _buffer; class reader_container { @@ -100,7 +100,7 @@ private: friend ssize_t ns_reader::reader_callback( archive* archive, void* in_reader_container, const void** buff ); }; -} // ns_archive +} #include "archive_reader.ipp" diff --git a/archive_reader_entry.cpp b/archive_reader_entry.cpp deleted file mode 100644 index f6dab93..0000000 --- a/archive_reader_entry.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -BSD 2-Clause license - -Copyright (c) 2014, Domen Vrankar -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "archive_reader_entry.hpp" - -#include "archive_exception.hpp" - -namespace ns_archive { -namespace ns_reader { - -entry::entry(archive* archive, archive_entry* entry) : - _archive(archive), - _entry(entry), - _entry_buffer(_archive), - _entry_stream(&_entry_buffer) -{ - // -} - -// -------------------------------- // -template<> -std::string entry::get_header_value() const -{ - return archive_entry_hardlink(_entry); -} - -template<> -std::string entry::get_header_value() const -{ - return archive_entry_pathname(_entry); -} - -template<> -std::string entry::get_header_value() const -{ - return archive_entry_sourcepath(_entry); -} - -template<> -std::string entry::get_header_value() const -{ - return archive_entry_symlink(_entry); -} - -// -------------------------------- // -std::istream& entry::get_entry_content_stream() -{ - if(_already_requested_content_stream) - { - throw archive_exception( "get_entry_content_stream requested more than once for the same entry" ); - } - - _already_requested_content_stream = true; - - return _entry_stream; -} - -} -} diff --git a/archive_reader_entry.hpp b/archive_reader_entry.hpp deleted file mode 100644 index b39ab30..0000000 --- a/archive_reader_entry.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* -BSD 2-Clause license - -Copyright (c) 2014, Domen Vrankar -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef ARCHIVE_READER_ENTRY_HPP_INCLUDED -#define ARCHIVE_READER_ENTRY_HPP_INCLUDED - -#include -#include -#include "archive_entry.h" -#include "archive_reader_entry_buffer.hpp" - -namespace ns_archive { -namespace ns_reader { - -class entry -{ -public: - enum class string_value - { - HARDLINK, - PATHNAME, - SOURCEPATH, - SYMLINK - }; -public: - entry(archive* archive, archive_entry* entry); - - template - std::string get_header_value() const; - - std::istream& get_entry_content_stream(); -private: - archive *_archive; - archive_entry *_entry; - entry_buffer _entry_buffer; - std::istream _entry_stream; - bool _already_requested_content_stream = false; -}; - -} -} - -#endif // ARCHIVE_READER_ENTRY_HPP_INCLUDED diff --git a/archive_reader_entry_buffer.cpp b/archive_reader_entry_buffer.cpp index 2cce216..b7f0253 100644 --- a/archive_reader_entry_buffer.cpp +++ b/archive_reader_entry_buffer.cpp @@ -61,5 +61,4 @@ int entry_buffer::underflow() : std::char_traits::to_int_type(*gptr()); } -} -} +}} diff --git a/archive_reader_entry_buffer.hpp b/archive_reader_entry_buffer.hpp index 482717d..8486987 100644 --- a/archive_reader_entry_buffer.hpp +++ b/archive_reader_entry_buffer.hpp @@ -38,17 +38,16 @@ namespace ns_reader { class entry_buffer : public std::streambuf { public: - entry_buffer(archive* archive); + entry_buffer(archive* archive); - int underflow(); + int underflow(); private: - archive *_archive; - size_t _buff_max_size = 8192; - char _buff[8192]; + archive *_archive; + size_t _buff_max_size = 8192; + char _buff[8192]; }; -} -} +}} #endif // ARCHIVE_READER_ENTRY_BUFFER_HPP_INCLUDED diff --git a/archive_reader_filter.hpp b/archive_reader_filter.hpp index 5dce5e7..330e809 100644 --- a/archive_reader_filter.hpp +++ b/archive_reader_filter.hpp @@ -48,7 +48,6 @@ enum class filter _GRZIP }; -} -} +}} #endif // ARCHIVE_READER_FILTER_HPP_INCLUDED diff --git a/archive_reader_format.hpp b/archive_reader_format.hpp index 9b8787f..a18777d 100644 --- a/archive_reader_format.hpp +++ b/archive_reader_format.hpp @@ -49,7 +49,6 @@ enum class format _ZIP }; -} -} +}} #endif // ARCHIVE_READER_FORMAT_HPP_INCLUDED diff --git a/archive_reader_iterator.cpp b/archive_reader_iterator.cpp index 6878031..fa4bbd1 100644 --- a/archive_reader_iterator.cpp +++ b/archive_reader_iterator.cpp @@ -27,7 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "archive_reader_iterator.hpp" - #include "archive_reader.hpp" namespace ns_archive { @@ -45,7 +44,7 @@ bool iterator::operator!=(const iterator& other) const return _end_pos != other._end_pos; } -entry* iterator::operator*() +std::shared_ptr iterator::operator*() { return _p_reader->get_next_entry(); } @@ -60,5 +59,4 @@ const iterator& iterator::operator++() return *this; } -} -} +}} diff --git a/archive_reader_iterator.hpp b/archive_reader_iterator.hpp index 5cc24c0..aceae5e 100644 --- a/archive_reader_iterator.hpp +++ b/archive_reader_iterator.hpp @@ -29,7 +29,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ARCHIVE_READER_ITERATOR_HPP_INCLUDED #define ARCHIVE_READER_ITERATOR_HPP_INCLUDED -#include "archive_reader_entry.hpp" +#include "archive_entry.hpp" +#include namespace ns_archive { @@ -42,7 +43,7 @@ class iterator public: iterator(reader* p_reader, bool end_pos); bool operator!=(const iterator& other) const; - entry* operator*(); + std::shared_ptr operator*(); const iterator& operator++(); private: @@ -50,7 +51,6 @@ private: reader *_p_reader; }; -} -} +}} #endif // ARCHIVE_READER_ITERATOR_HPP_INCLUDED diff --git a/archive_writer.cpp b/archive_writer.cpp index 49b4710..bede5a4 100644 --- a/archive_writer.cpp +++ b/archive_writer.cpp @@ -31,15 +31,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "archive_exception.hpp" #include "string" -#include +#include +#include namespace ns_archive { -writer::writer(std::ostream& stream) : +writer::writer(std::ostream& stream, size_t block_size) : _archive( archive_write_new(), [](archive* archive){ archive_write_free(archive); } ), // errors in destructor will be silently ignored - _writer_container( stream ) + _writer_container( stream ), + _block_size( block_size ) { - // + // TODO enable setting of padding parameters in constructor + /// OTHER OPTION archive_write_set_bytes_per_block( _archive.get(), 0 ); // prevent zero padding of last block (this also causes write callback to be called on each write without blocking until a block is full) + archive_write_set_bytes_in_last_block( _archive.get(), 1 ); // prevent zero padding of last block } void writer::finish() @@ -47,18 +51,21 @@ void writer::finish() archive_write_close(_archive.get()); // TODO throw on error } -void writer::add_entry( ns_writer::entry& entry ) +void writer::add_entry( entry& a_entry ) { - if( archive_write_header( _archive.get(), entry.get_entry() ) != ARCHIVE_OK) + if( archive_write_header( _archive.get(), a_entry.get_entry() ) != ARCHIVE_OK) { throw archive_exception( "Error writing header to archive!" ); } - auto& stream = entry.get_stream(); - std::istreambuf_iterator eos; - std::string tmp( std::istreambuf_iterator(stream), eos ); + auto& stream = a_entry.get_stream(); + std::vector buffer( _block_size ); - archive_write_data( _archive.get(), tmp.c_str(), tmp.size() ); + while( stream ) + { + stream.read( &buffer[0], _block_size ); + archive_write_data( _archive.get(), &buffer[0], stream.gcount() ); + } } /// ---------------- init_format ---------------- // diff --git a/archive_writer.hpp b/archive_writer.hpp index 3b723ea..e30037b 100644 --- a/archive_writer.hpp +++ b/archive_writer.hpp @@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "archive_writer_format.hpp" #include "archive_writer_filter.hpp" -#include "archive_writer_entry.hpp" +#include "archive_entry.hpp" namespace ns_archive { @@ -56,15 +56,15 @@ public: void finish(); template - static writer make_writer(std::ostream& stream); + static writer make_writer(std::ostream& stream, size_t block_size); template - static writer make_writer(std::ostream& stream); + static writer make_writer(std::ostream& stream, size_t block_size); - void add_entry( ns_writer::entry& entry ); + void add_entry( entry& a_entry ); private: - writer(std::ostream& stream); + writer(std::ostream& stream, size_t block_size); template void init_format(); @@ -76,11 +76,12 @@ private: std::shared_ptr _archive; std::ostream& _writer_container; + size_t _block_size; friend ssize_t ns_writer::writer_callback( archive* archive, void* out_writer_container, const void* buff, size_t buff_size ); }; -} // ns_archive +} #include "archive_writer.ipp" diff --git a/archive_writer.ipp b/archive_writer.ipp index dee5273..4e033f3 100644 --- a/archive_writer.ipp +++ b/archive_writer.ipp @@ -29,9 +29,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace ns_archive { template -writer writer::make_writer(std::ostream& stream) +writer writer::make_writer(std::ostream& stream, size_t block_size) { - writer a_writer( stream ); + writer a_writer( stream, block_size ); a_writer.init_format(); a_writer.init_filter(); a_writer.init_data(); @@ -40,11 +40,9 @@ writer writer::make_writer(std::ostream& stream) } template -writer writer::make_writer(std::ostream& stream) +writer writer::make_writer(std::ostream& stream, size_t block_size) { - return make_writer( stream ); + return make_writer( stream, block_size ); } } - - diff --git a/archive_writer_entry.cpp b/archive_writer_entry.cpp deleted file mode 100644 index 13916c4..0000000 --- a/archive_writer_entry.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* -BSD 2-Clause license - -Copyright (c) 2014, Domen Vrankar -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "archive_writer_entry.hpp" - -namespace ns_archive { -namespace ns_writer { - -entry::entry(std::istream& stream, size_t stream_size) : - _entry( archive_entry_new() ), - _stream( &stream ) -{ - archive_entry_set_mode( _entry, S_IFREG ); - archive_entry_set_size( _entry, stream_size ); -} - -void entry::clear_entry(std::istream& stream, size_t stream_size) -{ - archive_entry_clear( _entry ); - _stream = &stream; - archive_entry_set_mode( _entry, S_IFREG ); - archive_entry_set_size( _entry, stream_size ); -} - -//----------------------------------------------------// -void entry::set_header_value_gid(int64_t value) -{ - archive_entry_set_gid(_entry, value); -} - -void entry::set_header_value_ino(int64_t value) -{ - archive_entry_set_ino(_entry, value); -} - -void entry::set_header_value_ino64(int64_t value) -{ - archive_entry_set_ino64(_entry, value); -} - -void entry::set_header_value_size(int64_t value) -{ - archive_entry_set_size(_entry, value); -} - -void entry::set_header_value_uid(int64_t value) -{ - archive_entry_set_uid(_entry, value); -} - -void entry::set_header_value_mode(mode_t value) -{ - archive_entry_set_mode(_entry, value); -} - -void entry::set_header_value_perm(mode_t value) -{ - archive_entry_set_perm(_entry, value); -} - -void entry::set_header_value_rdev(dev_t value) -{ - archive_entry_set_rdev(_entry, value); -} - -void entry::set_header_value_rdevmajor(dev_t value) -{ - archive_entry_set_rdevmajor(_entry, value); -} - -void entry::set_header_value_rdevminor(dev_t value) -{ - archive_entry_set_rdevminor(_entry, value); -} - -void entry::set_header_value_gname(const std::string& value) -{ - archive_entry_set_gname(_entry, value.c_str()); -} - -void entry::set_header_value_hardlink(const std::string& value) -{ - archive_entry_set_hardlink(_entry, value.c_str()); -} - -void entry::set_header_value_link(const std::string& value) -{ - archive_entry_set_link(_entry, value.c_str()); -} - -void entry::set_header_value_pathname(const std::string& value) -{ - archive_entry_set_pathname(_entry, value.c_str()); -} - -void entry::set_header_value_symlink(const std::string& value) -{ - archive_entry_set_symlink(_entry, value.c_str()); -} - -void entry::set_header_value_uname(const std::string& value) -{ - archive_entry_set_uname(_entry, value.c_str()); -} - -void entry::set_header_value_nlink(unsigned int value) -{ - archive_entry_set_nlink(_entry, value); -} - -void entry::set_header_value_mtime(time_t time, long value) -{ - archive_entry_set_mtime(_entry, time, value); -} - -archive_entry* entry::get_entry() const -{ - return _entry; -} - -std::istream& entry::get_stream() const -{ - return *_stream; -} - -} -} diff --git a/archive_writer_filter.hpp b/archive_writer_filter.hpp index b9143a0..22de886 100644 --- a/archive_writer_filter.hpp +++ b/archive_writer_filter.hpp @@ -47,7 +47,6 @@ enum class filter _XZ }; -} -} +}} #endif // ARCHIVE_WRITER_FILTER_HPP_INCLUDED diff --git a/archive_writer_format.hpp b/archive_writer_format.hpp index 1eac2ef..c339e0a 100644 --- a/archive_writer_format.hpp +++ b/archive_writer_format.hpp @@ -52,7 +52,6 @@ enum class format _ZIP }; -} -} +}} #endif // ARCHIVE_WRITER_FORMAT_HPP_INCLUDED