blob: 097031169e754d2bc7d3ea859a31a63d24b279d2 [file] [log] [blame]
// Copyright 2014 The Chromium 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 CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_VOLUME_READER_JAVASCRIPT_STREAM_H_
#define CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_VOLUME_READER_JAVASCRIPT_STREAM_H_
#include <cstdint>
#include <memory>
#include <string>
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "chrome/browser/resources/chromeos/zip_archiver/cpp/volume_reader.h"
#include "ppapi/cpp/var_array_buffer.h"
class JavaScriptRequestorInterface;
// A VolumeReader that reads the content of the volume's archive from
// JavaScript. All methods including the constructor and destructor should be
// called from the same thread with the exception of SetBufferAndSignal and
// ReadErrorSignal which MUST be called from another thread.
class VolumeReaderJavaScriptStream : public VolumeReader {
public:
// archive_size is used by Seek method in order to seek from volume's
// archive end.
// requestor is used to request more data from JavaScript.
VolumeReaderJavaScriptStream(int64_t archive_size,
JavaScriptRequestorInterface* requestor);
virtual ~VolumeReaderJavaScriptStream();
// Sets the internal array buffer used for reads and signal the blocked
// VolumeReaderJavaScriptStream::Read to continue execution. Must be done in
// a different thread from VolumeReaderJavaScriptStream::Read method.
// read_offset represents the offset from which VolumeReaderJavaScriptStream
// requested a chunk read from JavaScriptRequestorInterface. May block for a
// few cycles in order to synchronize with VolumeReaderJavaScriptStream::Read.
void SetBufferAndSignal(const pp::VarArrayBuffer& array_buffer,
int64_t read_offset);
// Signal the blocked VolumeReaderJavaScriptStream::Read to continue execution
// and return an error code. Must be called from a different thread than
// VolumeReaderJavaScriptStream::Read. May block for a few cycles in order
// to synchronize with VolumeReaderJavaScriptStream::Read.
void ReadErrorSignal();
// Sets the passphrase and signals the blocked Passphrase() to continue
// execution. Must be done in a different thread from Passphrase() method.
// Reporting an error is not supported. Returning an empty string indicates
// an error.
void SetPassphraseAndSignal(const std::string& passphrase);
// Signal the blocked VolumeReaderJavaScriptStream::Passphrase to continue
// execution and return an error code. Must be called from a different thread
// than VolumeReaderJavaScriptStream::Passphrase. May block for a few cycles
// in order to synchronize with VolumeReaderJavaScriptStream::Passphrase.
void PassphraseErrorSignal();
// See volume_reader.h for description. This method blocks on
// available_data_cond_. SetBufferAndSignal should unblock it from another
// thread.
virtual int64_t Read(int64_t bytes_to_read, const void** destination_buffer);
// See volume_reader.h for description.
virtual int64_t Seek(int64_t offset, int whence);
// Sets the request Id to be used by the reader.
void SetRequestId(const std::string& request_id);
// See volume_reader.h for description. The method blocks on
// available_passphrase_cond_. SetPassphraseAndSignal should unblock it from
// another thread.
virtual std::unique_ptr<std::string> Passphrase();
virtual int64_t offset() { return offset_; }
int64_t archive_size() { return archive_size_; }
private:
// Request a chunk of length number of bytes from JavaScript starting from
// offset_ member. Should be run within a lock.
void RequestChunk(int64_t length);
std::string request_id_; // The request id for which the reader was
// created.
const int64_t archive_size_; // The archive size.
// A requestor that makes calls to JavaScript to obtain file chunks.
JavaScriptRequestorInterface* requestor_;
bool available_data_; // Indicates whether any data is available.
bool read_error_; // Marks an error in reading from JavaScript.
std::string available_passphrase_; // Stores a passphrase from JavaScript.
bool passphrase_error_; // Marks an error in getting the passphrase.
// The shared_state_lock_ is used to protect members which are accessed by
// more than one thread.
base::Lock shared_state_lock_;
base::ConditionVariable available_data_cond_;
base::ConditionVariable available_passphrase_cond_;
int64_t offset_; // The offset from where read should be done.
int64_t last_read_chunk_offset_; // The offset reached after last call to
// VolumeReaderJavaScriptStream::Read.
// Two buffers used to store the actual data used by minizip and the data
// read ahead.
pp::VarArrayBuffer first_array_buffer_;
pp::VarArrayBuffer second_array_buffer_;
// A pointer to first_arrray_buffer_ or second_array_buffer_. This is used in
// order to avoid an extra copy from the second buffer to the first buffer
// when data is available for VolumeReaderJavaScriptStream::Read method.
// It points to the array buffer used for reading ahead when data is received
// from JavaScript at VolumeReaderJavaScriptStream::SetBufferAndSignal.
pp::VarArrayBuffer* read_ahead_array_buffer_ptr_;
};
#endif // CHROME_BROWSER_RESOURCES_CHROMEOS_ZIP_ARCHIVER_CPP_VOLUME_READER_JAVASCRIPT_STREAM_H_