blob: cd7aac90bbf916db0c93dfe6efb07000c47a1c7a [file] [log] [blame]
// 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_