From 57aa270f25eb684094528a20f7966a2705aedcb0 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Fri, 1 Aug 2014 09:44:21 -0400 Subject: [PATCH] add new zip class to repo --- include/xlnt/common/zip_file.hpp | 195 +++---- include/xlnt/reader/reader.hpp | 8 +- source/reader.cpp | 14 +- source/workbook.cpp | 39 +- source/zip_file.cpp | 920 +++++++++++++++++++++---------- tests/runner-autogen.cpp | 133 +++++ tests/test_props.hpp | 16 +- tests/test_read.hpp | 16 +- tests/test_zip_file.hpp | 272 +++++++++ 9 files changed, 1160 insertions(+), 453 deletions(-) create mode 100644 tests/test_zip_file.hpp diff --git a/include/xlnt/common/zip_file.hpp b/include/xlnt/common/zip_file.hpp index 535a3fde..1334c1e9 100644 --- a/include/xlnt/common/zip_file.hpp +++ b/include/xlnt/common/zip_file.hpp @@ -1,134 +1,115 @@ -// Copyright (c) 2014 Thomas Fussell -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE -// -// @license: http://www.opensource.org/licenses/mit-license.php -// @author: see AUTHORS file #pragma once +#include +#include +#include +#include #include -#include #include -#define MINIZ_HEADER_FILE_ONLY -#include +struct mz_zip_archive_tag; namespace xlnt { -/// -/// Defines constants for read, write, or read/write access to a file. -/// -enum class file_access +struct zip_info { - /// - /// Read access to the file. Data can only be read from the file. Combine with write for read/write access. - /// - read = 0x01, - /// - /// Read and write access to the file. Data can be both written to and read from the file. - /// - read_write = 0x03, - /// - /// Write access to the file. Data can only be written to the file. Combine with read for read/write access. - /// - write = 0x02 + std::string filename; + struct + { + int year; + int month; + int day; + int hours; + int minutes; + int seconds; + } date_time; + std::string comment; + std::string extra; + uint16_t create_system; + uint16_t create_version; + uint16_t extract_version; + uint16_t flag_bits; + std::size_t volume; + uint32_t internal_attr; + uint32_t external_attr; + std::size_t header_offset; + uint32_t crc; + std::size_t compress_size; + std::size_t file_size; }; -/// -/// Specifies how the operating system should open a file. -/// -enum class file_mode -{ - /// - /// Opens the file if it exists and seeks to the end of the file, or creates a new file.This requires FileIOPermissionAccess.Append permission.file_mode.Append can be used only in conjunction with file_access.Write.Trying to seek to a position before the end of the file throws an IOException exception, and any attempt to read fails and throws a NotSupportedException exception. - /// - append, - /// - /// Specifies that the operating system should create a new file. If the file already exists, it will be overwritten. This requires FileIOPermissionAccess.Write permission. file_mode.Create is equivalent to requesting that if the file does not exist, use CreateNew; otherwise, use Truncate. If the file already exists but is a hidden file, an UnauthorizedAccessException exception is thrown. - /// - create, - /// - /// Specifies that the operating system should create a new file. This requires FileIOPermissionAccess.Write permission. If the file already exists, an IOException exception is thrown. - /// - create_new, - /// - /// Specifies that the operating system should open an existing file. The ability to open the file is dependent on the value specified by the file_access enumeration. A System.IO.FileNotFoundException exception is thrown if the file does not exist. - /// - open, - /// - /// Specifies that the operating system should open a file if it exists; otherwise, a new file should be created. If the file is opened with file_access.Read, FileIOPermissionAccess.Read permission is required. If the file access is file_access.Write, FileIOPermissionAccess.Write permission is required. If the file is opened with file_access.ReadWrite, both FileIOPermissionAccess.Read and FileIOPermissionAccess.Write permissions are required. - /// - open_or_create, - /// - /// Specifies that the operating system should open an existing file. When the file is opened, it should be truncated so that its size is zero bytes. This requires FileIOPermissionAccess.Write permission. Attempts to read from a file opened with file_mode.Truncate cause an ArgumentException exception. - /// - truncate -}; - class zip_file { -private: - enum class state - { - read, - write, - closed - }; - public: - zip_file(const std::string &filename, file_mode mode, file_access access = file_access::read); - + zip_file(); + zip_file(const std::string &filename); + zip_file(const std::vector &bytes); + zip_file(std::istream &stream); ~zip_file(); + + // to/from file + void load(const std::string &filename); + void save(const std::string &filename); + + // to/from byte vector + void load(const std::vector &bytes); + void save(std::vector &bytes); + + // to/from iostream + void load(std::istream &stream); + void save(std::ostream &stream); + + void reset(); + + zip_info getinfo(const std::string &name); + + std::vector infolist(); + std::vector namelist(); - std::string get_file_contents(const std::string &filename) const; + std::ostream &open(const std::string &name); + std::ostream &open(const zip_info &name); - void set_file_contents(const std::string &filename, const std::string &contents); + void extract(const std::string &name); + void extract(const std::string &name, const std::string &path); + void extract(const zip_info &name); + void extract(const zip_info &name, const std::string &path); - void delete_file(const std::string &filename); + void extractall(); + void extractall(const std::string &path); + void extractall(const std::string &path, const std::vector &members); + void extractall(const std::string &path, const std::vector &members); - bool has_file(const std::string &filename); + void printdir(); + void printdir(std::ostream &stream); - void flush(bool force_write = false); + std::string read(const std::string &name); + std::string read(const zip_info &name); + + std::pair testzip(); + + void write(const std::string &filename); + void write(const std::string &filename, const std::string &arcname); + + void writestr(const std::string &arcname, const std::string &bytes); + void writestr(const zip_info &arcname, const std::string &bytes); std::string get_filename() const { return filename_; } + std::string comment; + private: - void read_all(); - void write_all(); - std::string read_from_zip(const std::string &filename); - void write_to_zip(const std::string &filename, const std::string &content, bool append = true); - void write_directory_to_zip(const std::string &name, bool append = true); - void change_state(state new_state, bool append = true); - static bool file_exists(const std::string& name); void start_read(); - void stop_read(); - void start_write(bool append); - void stop_write(); + void start_write(); - mz_zip_archive zip_file_; - state current_state_; - std::string filename_; - std::unordered_map files_; - bool modified_; - file_access access_; - std::vector directories_; -}; - -} // namespace xlnt + void append_comment(); + void remove_comment(); + zip_info getinfo(int index); + + std::unique_ptr archive_; + std::vector buffer_; + std::stringstream open_stream_; + std::string filename_; +}; + +} // namespace xlnt \ No newline at end of file diff --git a/include/xlnt/reader/reader.hpp b/include/xlnt/reader/reader.hpp index 1fb3e685..f569898f 100644 --- a/include/xlnt/reader/reader.hpp +++ b/include/xlnt/reader/reader.hpp @@ -43,17 +43,17 @@ public: static const std::string CentralDirectorySignature; static std::string repair_central_directory(const std::string &original); static void fast_parse(worksheet ws, std::istream &xml_source, const std::vector &shared_string, const std::vector