| // Copyright 2014 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef VOLUME_ARCHIVE_H_ |
| #define VOLUME_ARCHIVE_H_ |
| |
| #include <string> |
| |
| #include "volume_reader.h" |
| |
| // Defines a wrapper for operations executed on an archive. API is not meant |
| // to be thread safe and its methods shouldn't be called in parallel. |
| class VolumeArchive { |
| public: |
| explicit VolumeArchive(VolumeReader* reader) : reader_(reader) {} |
| |
| virtual ~VolumeArchive() {} |
| |
| // For functions that need to return more than pass/fail results. |
| enum Result { |
| RESULT_SUCCESS, |
| RESULT_EOF, |
| RESULT_FAIL, |
| }; |
| |
| // Initializes VolumeArchive. Should be called only once. |
| // In case of any errors call VolumeArchive::Cleanup and the error message can |
| // be obtained with VolumeArchive::error_message(). Encoding is the default |
| // encoding. Note, that other encoding may be used if specified in the |
| // archive file. |
| virtual bool Init(const std::string& encoding) = 0; |
| |
| // Gets the next header. In case of failure the error message can be |
| // obtained with VolumeArchive::error_message(). |
| virtual Result GetNextHeader() = 0; |
| virtual Result GetNextHeader(const char** path_name, |
| int64_t* size, |
| bool* is_directory, |
| time_t* modification_time) = 0; |
| |
| // Seeks to the |index|-th header. |
| virtual bool SeekHeader(int64_t index) = 0; |
| |
| // Gets data from offset to offset + length for the file reached with |
| // VolumeArchive::GetNextHeader. The data is stored in an internal buffer |
| // in the implementation of VolumeArchive and it will be returned |
| // via *buffer parameter to avoid an extra copy. *buffer is owned by |
| // VolumeArchive. |
| // |
| // Supports file seek by using the offset parameter. In case offset is less |
| // then last VolumeArchive::ReadData offset, then the read will be restarted |
| // from the beginning of the archive. |
| // |
| // For improving perfomance use VolumeArchive::MaybeDecompressAhead. Using |
| // VolumeArchive::MaybeDecompressAhead is not mandatory, but without it |
| // performance will suffer. |
| // |
| // The API assumes offset >= 0 and length > 0. length can be as big as |
| // possible, but its up to the implementation to avoid big memory usage. |
| // It can return up to length bytes of data, however 0 is returned only in |
| // case of EOF. |
| // |
| // Returns the actual number of read bytes. The API ensures that *buffer will |
| // have available as many bytes as returned. In case of failure, returns a |
| // negative value and the error message can be obtained with |
| // VolumeArchive::error_message(). |
| virtual int64_t ReadData(int64_t offset, |
| int64_t length, |
| const char** buffer) = 0; |
| |
| // Decompress ahead in case there are no more available bytes in the internal |
| // buffer. |
| virtual void MaybeDecompressAhead() = 0; |
| |
| // Cleans all resources. Should be called only once. Returns true if |
| // successful. In case of failure the error message can be obtained with |
| // VolumeArchive::error_message(). |
| virtual bool Cleanup() = 0; |
| |
| VolumeReader* reader() const { return reader_; } |
| std::string error_message() const { return error_message_; } |
| |
| protected: |
| // Cleans up the reader. Can be called multiple times, but once called reader |
| // cannot be reinitialized. |
| void CleanupReader() { |
| delete reader_; |
| reader_ = NULL; |
| } |
| |
| void set_error_message(const std::string& error_message) { |
| error_message_ = error_message; |
| } |
| |
| private: |
| VolumeReader* reader_; // The reader that actually reads the archive data. |
| std::string error_message_; // An error message set in case of any errors. |
| }; |
| |
| #endif // VOLUME_ARCHIVE_H_ |